source: trunk/gsdl/perllib/doc.pm@ 1379

Last change on this file since 1379 was 1379, checked in by paynter, 24 years ago

Fixed bug that gave gsdlsourcedocument metadata relative path instead
of absolute, and then didn't test if it existed, causing NULL hash values.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 22.2 KB
Line 
1###########################################################################
2#
3# doc.pm --
4# A component of the Greenstone digital library software
5# from the New Zealand Digital Library Project at the
6# University of Waikato, New Zealand.
7#
8# Copyright (C) 1999 New Zealand Digital Library Project
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24###########################################################################
25
26# base class to hold documents
27
28package doc;
29
30BEGIN {
31 die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
32 unshift (@INC, "$ENV{'GSDLHOME'}/perllib/dynamic/lib/site_perl/5.005/i686-linux");
33}
34
35use unicode;
36use util;
37use ghtml;
38##use hashdoc;
39
40# the document type may be indexed_doc, nonindexed_doc, or
41# classification
42
43sub new {
44 my $class = shift (@_);
45 my ($source_filename, $doc_type) = @_;
46
47 my $self = bless {'associated_files'=>[],
48 'subsection_order'=>[],
49 'next_subsection'=>1,
50 'subsections'=>{},
51 'metadata'=>[],
52 'text'=>""}, $class;
53
54 $self->set_source_filename ($source_filename) if defined $source_filename;
55 $self->set_doc_type ($doc_type) if defined $doc_type;
56
57 return $self;
58}
59
60# clone the $self object
61sub duplicate {
62 my $self = shift (@_);
63
64 my $newobj = {};
65
66 foreach $k (keys %$self) {
67 $newobj->{$k} = &clone ($self->{$k});
68 }
69
70 bless $newobj, ref($self);
71 return $newobj;
72}
73
74sub clone {
75 my ($from) = @_;
76 my $type = ref ($from);
77
78 if ($type eq "HASH") {
79 my $to = {};
80 foreach $key (keys %$from) {
81 $to->{$key} = &clone ($from->{$key});
82 }
83 return $to;
84 } elsif ($type eq "ARRAY") {
85 my $to = [];
86 foreach $v (@$from) {
87 push (@$to, &clone ($v));
88 }
89 return $to;
90 } else {
91 return $from;
92 }
93}
94
95
96sub set_source_filename {
97 my $self = shift (@_);
98 my ($source_filename) = @_;
99
100 $self->set_metadata_element ($self->get_top_section(),
101 "gsdlsourcefilename",
102 $source_filename);
103}
104
105# returns the source_filename as it was provided
106sub get_source_filename {
107 my $self = shift (@_);
108
109 return $self->get_metadata_element ($self->get_top_section(), "gsdlsourcefilename");
110}
111
112sub set_doc_type {
113 my $self = shift (@_);
114 my ($doc_type) = @_;
115
116 $self->set_metadata_element ($self->get_top_section(),
117 "gsdldoctype",
118 $doc_type);
119}
120
121# returns the source_filename as it was provided
122# the default of "indexed_doc" is used if no document
123# type was provided
124sub get_doc_type {
125 my $self = shift (@_);
126
127 my $doc_type = $self->get_metadata_element ($self->get_top_section(), "gsdldoctype");
128 return $doc_type if (defined $doc_type);
129 return "indexed_doc";
130}
131
132sub _escape_text {
133 my ($text) = @_;
134
135 # special characters in the gml encoding
136 $text =~ s/&/&/g; # this has to be first...
137 $text =~ s/</&lt;/g;
138 $text =~ s/>/&gt;/g;
139 $text =~ s/\"/&quot;/g;
140
141 return $text;
142}
143
144
145sub buffer_section {
146 my $self = shift (@_);
147 my ($section, $suppress_subject_info) = @_;
148
149 $suppress_subject_info = 0 unless defined $suppress_subject_info;
150 my ($all_text,$data, $subsection);
151
152 my $section_ptr = $self->_lookup_section ($section);
153 my ($section_num) = $section =~ /(\d+)$/;
154
155 return "" unless defined $section_ptr;
156
157 # output the section header (including the section number
158 # and metadata)
159
160 $all_text = "<gsdlsection";
161 $all_text .= " gsdlnum=\"$section_num\"" if defined $section_num;
162 foreach $data (@{$section_ptr->{'metadata'}}) {
163 $all_text .= " $data->[0]=\"" . &_escape_text($data->[1]) . "\""
164 unless $suppress_subject_info && $data->[0] eq "Subject";
165 }
166 $all_text .= ">";
167
168 # output the text
169 $all_text .= &_escape_text($section_ptr->{'text'});
170
171 # output all the subsections
172 foreach $subsection (@{$section_ptr->{'subsection_order'}}) {
173 $all_text .= $self->buffer_section("$section.$subsection", $suppress_subject_info);
174 }
175
176 # output the closing tag
177 $all_text .= "</gsdlsection>\n";
178
179 return $all_text;
180}
181
182sub output_section {
183 my $self = shift (@_);
184 my ($handle, $section, $suppress_subject_info) = @_;
185
186 my $all_text = $self->buffer_section($section, $suppress_subject_info);
187 print $handle $all_text;
188}
189
190# look up the reference to the a particular section
191sub _lookup_section {
192 my $self = shift (@_);
193 my ($section) = @_;
194
195 my ($num);
196 my $sectionref = $self;
197
198 while (defined $section && $section ne "") {
199 ($num, $section) = $section =~ /^\.?(\d+)(.*)$/;
200 $num =~ s/^0+(\d)/$1/; # remove leading 0s
201 $section = "" unless defined $section;
202
203 if (defined $num && defined $sectionref->{'subsections'}->{$num}) {
204 $sectionref = $sectionref->{'subsections'}->{$num};
205 } else {
206 return undef;
207 }
208 }
209
210 return $sectionref;
211}
212
213sub _calc_OID {
214 my $self = shift (@_);
215 my ($filename) = @_;
216
217 my $osexe = &util::get_os_exe();
218
219 my $hashfile_exe = &util::filename_cat($ENV{'GSDLHOME'},"bin",
220 $ENV{'GSDLOS'},"hashfile$osexe");
221 my $result = "NULL";
222
223 if (-e "$hashfile_exe") {
224 $result = `$hashfile_exe \"$filename\"`;
225 ($result) = $result =~ /:\s*([0-9a-f]+)/i;
226
227 } else {
228 print STDERR "doc::_calc_OID $hashfile_exe could not be found\n";
229 }
230
231 return "HASH$result";
232}
233
234# methods dealing with OID, not groups of them.
235
236# if $OID is not provided one is calculated from hashing the
237# current contents of the document
238# An OID are actually stored as metadata of the document
239sub set_OID {
240 my $self = shift (@_);
241 my ($OID) = @_;
242
243 # if an OID wasn't provided then feed this document to
244 # hashfile.exe
245 if (!defined $OID) {
246 $OID = "NULL";
247
248 my $filename = $self->get_source_filename();
249 if (defined($filename) && -e $filename) {
250
251 $OID = $self->_calc_OID ($filename);
252
253 } else {
254
255 print STDERR "doc::set_OID source filename undefined/non-existant (continuing)\n";
256
257 $filename = &util::get_tmp_filename();
258 if (!open (OUTFILE, ">$tmp_filename")) {
259 print STDERR "doc::set_OID could not write to $tmp_filename\n";
260 } else {
261 $self->output_section('OUTFILE', $self->get_top_section(), 1);
262 close (OUTFILE);
263 }
264
265 $OID = $self->_calc_OID ($filename);
266 &util::rm ($tmp_filename);
267 }
268 }
269
270 $self->set_metadata_element ($self->get_top_section(), "Identifier", $OID);
271}
272
273# this uses hashdoc (embedded c thingy) which is faster but still
274# needs a little work to be suffiently stable
275sub ___set_OID {
276 my $self = shift (@_);
277 my ($OID) = @_;
278
279 # if an OID wasn't provided then calculate hash value based on document
280 if (!defined $OID)
281 {
282 my $hash_text = $self->buffer_section($self->get_top_section(), 1);
283 my $hash_len = length($hash_text);
284
285 $OID = &hashdoc::buffer($hash_text,$hash_len);
286 }
287
288 $self->set_metadata_element ($self->get_top_section(), "Identifier", $OID);
289}
290
291# returns the OID for this document
292sub get_OID {
293 my $self = shift (@_);
294 my $OID = $self->get_metadata_element ($self->get_top_section(), "Identifier");
295 return $OID if (defined $OID);
296 return "NULL";
297}
298
299sub delete_OID {
300 my $self = shift (@_);
301
302 $self->set_metadata_element ($self->get_top_section(), "Identifier", "NULL");
303}
304
305
306# methods for manipulating section names
307
308# returns the name of the top-most section (the top
309# level of the document
310sub get_top_section {
311 my $self = shift (@_);
312
313 return "";
314}
315
316# returns a section
317sub get_parent_section {
318 my $self = shift (@_);
319 my ($section) = @_;
320
321 $section =~ s/(^|\.)\d+$//;
322
323 return $section;
324}
325
326# returns the first child section (or the end child
327# if there isn't any)
328sub get_begin_child {
329 my $self = shift (@_);
330 my ($section) = @_;
331
332 my $section_ptr = $self->_lookup_section($section);
333 return "" unless defined $section_ptr;
334
335 if (defined $section_ptr->{'subsection_order'}->[0]) {
336 return "$section.$section_ptr->{'subsection_order'}->[0]";
337 }
338
339 return $self->get_end_child ($section);
340}
341
342# returns the next child of a parent section
343sub get_next_child {
344 my $self = shift (@_);
345 my ($section) = @_;
346
347 my $parent_section = $self->get_parent_section($section);
348 my $parent_section_ptr = $self->_lookup_section($parent_section);
349 return undef unless defined $parent_section_ptr;
350
351 my ($section_num) = $section =~ /(\d+)$/;
352 return undef unless defined $section_num;
353
354 my $i = 0;
355 my $section_order = $parent_section_ptr->{'subsection_order'};
356 while ($i < scalar(@$section_order)) {
357 last if $section_order->[$i] eq $section_num;
358 $i++;
359 }
360
361 $i++; # the next child
362 if ($i < scalar(@$section_order)) {
363 return $section_order->[$i] if $parent_section eq "";
364 return "$parent_section.$section_order->[$i]";
365 }
366
367 # no more sections in this level
368 return undef;
369}
370
371# returns a reference to a list of children
372sub get_children {
373 my $self = shift (@_);
374 my ($section) = @_;
375
376 my $section_ptr = $self->_lookup_section($section);
377 return [] unless defined $section_ptr;
378
379 my @children = @{$section_ptr->{'subsection_order'}};
380
381 map {$_ = "$section.$_"; $_ =~ s/^\.+//;} @children;
382 return \@children;
383}
384
385# returns the child section one past the last one (which
386# is coded as "0")
387sub get_end_child {
388 my $self = shift (@_);
389 my ($section) = @_;
390
391 return $section . ".0" unless $section eq "";
392 return "0";
393}
394
395# returns the next section in book order
396sub get_next_section {
397 my $self = shift (@_);
398 my ($section) = @_;
399
400 return undef unless defined $section;
401
402 my $section_ptr = $self->_lookup_section($section);
403 return undef unless defined $section_ptr;
404
405 # first try to find first child
406 if (defined $section_ptr->{'subsection_order'}->[0]) {
407 return $section_ptr->{'subsection_order'}->[0] if ($section eq "");
408 return "$section.$section_ptr->{'subsection_order'}->[0]";
409 }
410
411 do {
412 # try to find sibling
413 my $next_child = $self->get_next_child ($section);
414 return $next_child if (defined $next_child);
415
416 # move up one level
417 $section = $self->get_parent_section ($section);
418 } while $section =~ /\d/;
419
420 return undef;
421}
422
423sub is_leaf_section {
424 my $self = shift (@_);
425 my ($section) = @_;
426
427 my $section_ptr = $self->_lookup_section($section);
428 return 1 unless defined $section_ptr;
429
430 return (scalar (@{$section_ptr->{'subsection_order'}}) == 0);
431}
432
433# methods for dealing with sections
434
435# returns the name of the inserted section
436sub insert_section {
437 my $self = shift (@_);
438 my ($before_section) = @_;
439
440 # get the child to insert before and its parent section
441 my $parent_section = "";
442 my $before_child = "0";
443 my @before_section = split (/\./, $before_section);
444 if (scalar(@before_section) > 0) {
445 $before_child = pop (@before_section);
446 $parent_section = join (".", @before_section);
447 }
448
449 my $parent_section_ptr = $self->_lookup_section($parent_section);
450 if (!defined $parent_section_ptr) {
451 print STDERR "doc::insert_section couldn't find parent section " .
452 "$parent_section\n";
453 return;
454 }
455
456 # get the next section number
457 my $section_num = $parent_section_ptr->{'next_subsection'}++;
458
459 my $i = 0;
460 while ($i < scalar(@{$parent_section_ptr->{'subsection_order'}}) &&
461 $parent_section_ptr->{'subsection_order'}->[$i] ne $before_child) {
462 $i++;
463 }
464
465 # insert the section number into the order list
466 splice (@{$parent_section_ptr->{'subsection_order'}}, $i, 0, $section_num);
467
468 # add this section to the parent section
469 my $section_ptr = {'subsection_order'=>[],
470 'next_subsection'=>1,
471 'subsections'=>{},
472 'metadata'=>[],
473 'text'=>""};
474 $parent_section_ptr->{'subsections'}->{$section_num} = $section_ptr;
475
476 # work out the full section number
477 my $section = $parent_section;
478 $section .= "." unless $section eq "";
479 $section .= $section_num;
480
481 return $section;
482}
483
484# creates a pre-named section
485sub create_named_section {
486 my $self = shift (@_);
487 my ($mastersection) = @_;
488
489 my ($num);
490 my $section = $mastersection;
491 my $sectionref = $self;
492
493#### print STDERR "*** mastersection = $mastersection\n";
494
495 while ($section ne "") {
496 ($num, $section) = $section =~ /^\.?(\d+)(.*)$/;
497 $num =~ s/^0+(\d)/$1/; # remove leading 0s
498 $section = "" unless defined $section;
499
500 if (defined $num) {
501 if (!defined $sectionref->{'subsections'}->{$num}) {
502 push (@{$sectionref->{'subsection_order'}}, $num);
503 $sectionref->{'subsections'}->{$num} = {'subsection_order'=>[],
504 'next_subsection'=>1,
505 'subsections'=>{},
506 'metadata'=>[],
507 'text'=>""};
508 if ($num >= $sectionref->{'next_subsection'}) {
509 $sectionref->{'next_subsection'} = $num + 1;
510 }
511 }
512 $sectionref = $sectionref->{'subsections'}->{$num};
513
514 } else {
515 print STDERR "doc::create_named_section couldn't create section ";
516 print STDERR "$mastersection\n";
517 last;
518 }
519 }
520}
521
522# returns a reference to a list of subsections
523sub list_subsections {
524 my $self = shift (@_);
525 my ($section) = @_;
526
527 my $section_ptr = $self->_lookup_section ($section);
528 if (!defined $section_ptr) {
529 print STDERR "doc::list_subsections couldn't find section $section\n";
530 return [];
531 }
532
533 return [@{$section_ptr->{'subsection_order'}}];
534}
535
536sub delete_section {
537 my $self = shift (@_);
538 my ($section) = @_;
539
540# my $section_ptr = {'subsection_order'=>[],
541# 'next_subsection'=>1,
542# 'subsections'=>{},
543# 'metadata'=>[],
544# 'text'=>""};
545
546 # if this is the top section reset everything
547 if ($section eq "") {
548 $self->{'subsection_order'} = [];
549 $self->{'subsections'} = {};
550 $self->{'metadata'} = [];
551 $self->{'text'} = "";
552 return;
553 }
554
555 # find the parent of the section to delete
556 my $parent_section = "";
557 my $child = "0";
558 my @section = split (/\./, $section);
559 if (scalar(@section) > 0) {
560 $child = pop (@section);
561 $parent_section = join (".", @section);
562 }
563
564 my $parent_section_ptr = $self->_lookup_section($parent_section);
565 if (!defined $parent_section_ptr) {
566 print STDERR "doc::delete_section couldn't find parent section " .
567 "$parent_section\n";
568 return;
569 }
570
571 # remove this section from the subsection_order list
572 my $i = 0;
573 while ($i < scalar (@{$parent_section_ptr->{'subsection_order'}})) {
574 if ($parent_section_ptr->{'subsection_order'}->[$i] eq $child) {
575 splice (@{$parent_section_ptr->{'subsection_order'}}, $i, 1);
576 last;
577 }
578 $i++;
579 }
580
581 # remove this section from the subsection hash
582 if (defined ($parent_section_ptr->{'subsections'}->{$child})) {
583 undef $parent_section_ptr->{'subsections'}->{$child};
584 }
585}
586
587#--
588# methods for dealing with metadata
589
590# set_metadata_element and get_metadata_element are for metadata
591# which should only have one value. add_meta_data and get_metadata
592# are for metadata which can have more than one value.
593
594# returns the first metadata value which matches field
595sub get_metadata_element {
596 my $self = shift (@_);
597 my ($section, $field) = @_;
598 my ($data);
599
600 my $section_ptr = $self->_lookup_section($section);
601 if (!defined $section_ptr) {
602 print STDERR "doc::get_metadata_element couldn't find section " .
603 "$section\n";
604 return;
605 }
606
607 foreach $data (@{$section_ptr->{'metadata'}}) {
608 return $data->[1] if (scalar(@$data) >= 2 && $data->[0] eq $field);
609 }
610
611 return undef; # was not found
612}
613
614
615# returns a list of the form [value1, value2, ...]
616sub get_metadata {
617 my $self = shift (@_);
618 my ($section, $field) = @_;
619 my ($data);
620
621 my $section_ptr = $self->_lookup_section($section);
622 if (!defined $section_ptr) {
623 print STDERR "doc::get_metadata couldn't find section " .
624 "$section\n";
625 return;
626 }
627
628 my @metadata = ();
629 foreach $data (@{$section_ptr->{'metadata'}}) {
630 push (@metadata, $data->[1]) if ($data->[0] eq $field);
631 }
632
633 return \@metadata;
634}
635
636# returns a list of the form [[field,value],[field,value],...]
637sub get_all_metadata {
638 my $self = shift (@_);
639 my ($section) = @_;
640
641 my $section_ptr = $self->_lookup_section($section);
642 if (!defined $section_ptr) {
643 print STDERR "doc::get_all_metadata couldn't find section " .
644 "$section\n";
645 return;
646 }
647
648 return $section_ptr->{'metadata'};
649}
650
651# $value is optional
652sub delete_metadata {
653 my $self = shift (@_);
654 my ($section, $field, $value) = @_;
655
656 my $section_ptr = $self->_lookup_section($section);
657 if (!defined $section_ptr) {
658 print STDERR "doc::delete_metadata couldn't find section " .
659 "$section\n";
660 return;
661 }
662
663 my $i = 0;
664 while ($i < scalar (@{$section_ptr->{'metadata'}})) {
665 if (($section_ptr->{'metadata'}->[$i]->[0] eq $field) &&
666 (!defined $value || $section_ptr->{'metadata'}->[$i]->[1] eq $value)) {
667 splice (@{$section_ptr->{'metadata'}}, $i, 1);
668 } else {
669 $i++;
670 }
671 }
672}
673
674sub delete_all_metadata {
675 my $self = shift (@_);
676 my ($section) = @_;
677
678 my $section_ptr = $self->_lookup_section($section);
679 if (!defined $section_ptr) {
680 print STDERR "doc::delete_all_metadata couldn't find section " .
681 "$section\n";
682 return;
683 }
684
685 $section_ptr->{'metadata'} = [];
686}
687
688sub set_metadata_element {
689 my $self = shift (@_);
690 my ($section, $field, $value) = @_;
691
692 $self->set_utf8_metadata_element ($section, $field,
693 &unicode::ascii2utf8($value));
694}
695
696# set_utf8_metadata_element assumes the text has already been
697# converted to the UTF-8 encoding.
698sub set_utf8_metadata_element {
699 my $self = shift (@_);
700 my ($section, $field, $value) = @_;
701
702 $self->delete_metadata ($section, $field);
703 $self->add_utf8_metadata ($section, $field, $value);
704}
705
706
707# add_metadata assumes the text is in (extended) ascii form. For
708# text which hash been already converted to the UTF-8 format use
709# add_utf8_metadata.
710sub add_metadata {
711 my $self = shift (@_);
712 my ($section, $field, $value) = @_;
713
714 $self->add_utf8_metadata ($section, $field,
715 &unicode::ascii2utf8($value));
716}
717
718# add_utf8_metadata assumes the text has already been converted
719# to the UTF-8 encoding.
720sub add_utf8_metadata {
721 my $self = shift (@_);
722 my ($section, $field, $value) = @_;
723
724 my $section_ptr = $self->_lookup_section($section);
725 if (!defined $section_ptr) {
726 print STDERR "doc::add_utf8_metadata couldn't find section " .
727 "$section\n";
728 return;
729 }
730
731 push (@{$section_ptr->{'metadata'}}, [$field, $value]);
732}
733
734
735# methods for dealing with text
736
737# returns the text for a section
738sub get_text {
739 my $self = shift (@_);
740 my ($section) = @_;
741
742 my $section_ptr = $self->_lookup_section($section);
743 if (!defined $section_ptr) {
744 print STDERR "doc::get_text couldn't find section " .
745 "$section\n";
746 return "";
747 }
748
749 return $section_ptr->{'text'};
750}
751
752# returns the (utf-8 encoded) length of the text for a section
753sub get_text_length {
754 my $self = shift (@_);
755 my ($section) = @_;
756
757 my $section_ptr = $self->_lookup_section($section);
758 if (!defined $section_ptr) {
759 print STDERR "doc::get_text_length couldn't find section " .
760 "$section\n";
761 return 0;
762 }
763
764 return length ($section_ptr->{'text'});
765}
766
767sub delete_text {
768 my $self = shift (@_);
769 my ($section) = @_;
770
771 my $section_ptr = $self->_lookup_section($section);
772 if (!defined $section_ptr) {
773 print STDERR "doc::delete_text couldn't find section " .
774 "$section\n";
775 return;
776 }
777
778 $section_ptr->{'text'} = "";
779}
780
781# add_text assumes the text is in (extended) ascii form. For
782# text which has been already converted to the UTF-8 format
783# use add_utf8_text.
784sub add_text {
785 my $self = shift (@_);
786 my ($section, $text) = @_;
787
788 # convert the text to UTF-8 encoded unicode characters
789 # and add the text
790 $self->add_utf8_text($section, &unicode::ascii2utf8($text));
791}
792
793
794# add_utf8_text assumes the text to be added has already
795# been converted to the UTF-8 encoding. For ascii text use
796# add_text
797sub add_utf8_text {
798 my $self = shift (@_);
799 my ($section, $text) = @_;
800
801 my $section_ptr = $self->_lookup_section($section);
802 if (!defined $section_ptr) {
803 print STDERR "doc::add_utf8_text couldn't find section " .
804 "$section\n";
805 return;
806 }
807
808 $section_ptr->{'text'} .= $text;
809}
810
811
812# methods for dealing with associated files
813
814# a file is associated with a document, NOT a section.
815# if section is defined it is noted in the data structure
816# only so that files associated from a particular section
817# may be removed later (using delete_section_assoc_files)
818sub associate_file {
819 my $self = shift (@_);
820 my ($real_filename, $assoc_filename, $mime_type, $section) = @_;
821 $mime_type = &ghtml::guess_mime_type ($real_filename) unless defined $mime_type;
822
823 # remove all associated files with the same name
824 $self->delete_assoc_file ($assoc_filename);
825
826 push (@{$self->{'associated_files'}},
827 [$real_filename, $assoc_filename, $mime_type, $section]);
828}
829
830# returns a list of associated files in the form
831# [[real_filename, assoc_filename, mimetype], ...]
832sub get_assoc_files {
833 my $self = shift (@_);
834
835 return $self->{'associated_files'};
836}
837
838sub delete_section_assoc_files {
839 my $self = shift (@_);
840 my ($section) = @_;
841
842 my $i=0;
843 while ($i < scalar (@{$self->{'associated_files'}})) {
844 if (defined $self->{'associated_files'}->[$i]->[3] &&
845 $self->{'associated_files'}->[$i]->[3] eq $section) {
846 splice (@{$self->{'associated_files'}}, $i, 1);
847 } else {
848 $i++;
849 }
850 }
851}
852
853sub delete_assoc_file {
854 my $self = shift (@_);
855 my ($assoc_filename) = @_;
856
857 my $i=0;
858 while ($i < scalar (@{$self->{'associated_files'}})) {
859 if ($self->{'associated_files'}->[$i]->[1] eq $assoc_filename) {
860 splice (@{$self->{'associated_files'}}, $i, 1);
861 } else {
862 $i++;
863 }
864 }
865}
866
867sub reset_nextsection_ptr {
868 my $self = shift (@_);
869 my ($section) = @_;
870
871 my $section_ptr = $self->_lookup_section($section);
872 $section_ptr->{'next_subsection'} = 1;
873}
874
8751;
Note: See TracBrowser for help on using the repository browser.