ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/ActiveDoc/Switcher.pm
(Generate patch)

Comparing COMP/SCRAM/src/ActiveDoc/Switcher.pm (file contents):
Revision 1.3 by williamc, Wed Sep 29 11:52:28 1999 UTC vs.
Revision 1.18 by sashby, Fri Oct 11 14:23:24 2002 UTC

# Line 6 | Line 6
6   # processed.
7   # Interface
8   # ---------
9 + #
10   # new(file,objectref) : A new object -  filename of file to parse
11 < #                                   objectref->of the methods
11 > #                                       objectref->of the methods
12   # usetags(tagobjref)               : Specify a tagcontainer set to direct to
13   #                                    to the desired routines
14   # usegroupchecker(groupchecker)    : Set a groupchecker
15   # parse()                          : Parse the file                            
16 < # checkparam($name,$par)    : Exit with an error message if parameter
17 < #                             is undefined in tag $name
18 < # line()                    : return the current line number of the parse
19 <
16 > # line()                           : return the current line number of the parse
17 > # tagstartline()                   : return the line number on which the current
18 > #                                    tag was opened
19 > # stream(filehandle)               : stream output to the filehandle if not handled
20 > #                                    in any other way
21   package ActiveDoc::Switcher;
22 + use Utilities::Verbose;
23   require 5.001;
24   use Carp;
25  
26 + @ISA=qw(Utilities::Verbose);
27 +
28   sub new {
29          my $class=shift;
30          my $file=shift;
31          my $objectname=shift;
32          my $groupchecker=shift;
33  
34 <        my $self = {};
34 >        $self = {};
35          $self->{allw}=$objectname;
36          bless $self, $class;
37          $self->_initialise($file);
38          return $self;
39   }
40  
41 < sub _initialise (hash1) {
41 > sub stream {
42 >        my $self=shift;
43 >
44 >        $self->{stream}=shift;
45 > }
46 >
47 > sub streamexclude {
48          my $self=shift;
49 <        $self->{filename}=shift;
49 >        my $tag=shift;
50  
51 <        # add a default groupchecker
52 <          use ActiveDoc::GroupChecker;
42 <          $self->{groupchecker}=GroupChecker->new();
43 <          $self->{groupchecker}->include("all");
44 <
45 <        # Add a default TagContainer
46 <          use ActiveDoc::TagContainer;
47 <          $self->{tagcontainer}=ActiveDoc::TagContainer->new();
48 <        
51 >        $tag=~tr/A-Z/a-z/;
52 >        $self->{streamexclude}{$tag}=1;
53   }
54  
55 + sub _initialise (hash1)
56 +   {
57 +   my $self=shift;
58 +   $self->{filename}=shift;
59 +   $self->verbose(">> New ActiveDoc::Switcher created.");
60 +   # add a default groupchecker
61 +   use ActiveDoc::GroupChecker;
62 +   $self->{groupchecker}=GroupChecker->new();
63 +   $self->{groupchecker}->include("all");
64 +
65 +   # Add a default TagContainer
66 +   use ActiveDoc::TagContainer;
67 +   $self->{tagcontainer}=ActiveDoc::TagContainer->new();
68 +  
69 +   }
70 +
71   sub usetags {
72          my $self=shift;
73          my $tagcontainer=shift;
# Line 65 | Line 85 | sub usegroupchecker {
85   sub parse {
86          my $self=shift;
87          my $char;
88 +        my $buf;
89          $self->{linecount}=0;
90          $self->_resetvars();
91 +        $self->{streamstore}="";
92 +        $self->{streamtmp}="";
93  
94          # Open the file
95          use FileHandle;
96 <        my $filehandle=FileHandle->new();
97 <        open( $filehandle , "$self->{filename}" )
96 >        local $filehandle;
97 >        $filehandle=FileHandle->new();
98 >        
99 >        $self->verbose(">> Reading file: ".$self->{filename}." ");
100 >
101 >        $filehandle->open("<".$self->{filename})
102             or return 1;
103 < #               or carp "Switcher: Cannot open $self->{filename} $! \n";
103 >        # The buffering seems all messed up - best not to use it
104 >        $filehandle->setvbuf($buf, _IONBF, 3000);
105  
78        print "Starting Parse $self->{filename}\n";
106          # Start file processing
107 <        while ( <$filehandle> ) {
107 >        while ( ($_=<$filehandle>) ) {
108 >         # Skip lines that start with a hash. A better way
109 >         # of adding comments than ignore tags:
110 >         next if (/^#/);
111           $self->{linecount}++;
112           $self->{currentline}=$_;
113           $self->{stringpos}=0;
# Line 85 | Line 115 | sub parse {
115             $self->_checkchar($char);
116           } # end char while
117          } # End String while loop
118 <        close $filehandle;
119 <        print "Exiting Parse $self->{filename}\n";
120 < }
121 <
92 < sub checkparam($name, $key) {
93 <        my $self=shift;
94 <        my $name=shift;
95 <        my $key=shift;
96 <
97 <        if ( ! defined $self->{tagvar}{$key} ) {
98 <           print "Switcher: Badly formed $name tag -".
99 <                        " undefined $key parameter\n";
100 <           exit 1;
101 <        }
118 >        undef $filehandle;
119 >        # make sure we close the last buffer
120 >        $self->_calltag($self->{textcontext}, $self->{textcontext},
121 >                                                        $self->_getstore());
122   }
123  
124   #
# Line 108 | Line 128 | sub line {
128          my $self=shift;
129          return $self->{linecount};
130   }
131 +
132 + # return the line the current tag was opened
133 + sub tagstartline {
134 +        my $self=shift;
135 +        $self->{tagstart};
136 + }
137   # --------------- Utility routines ----------------------------
138  
139   #
# Line 130 | Line 156 | sub _checkchar {
156          my $char=shift;
157          my $string;
158  
159 +
160          # ---- In a tag
161          if ( $self->{tagcontext}=~/tag/ ) {
162 +           $self->{tagbuff}=$self->{tagbuff}.$char;
163             if ( ! $self->_quotetest($char) ) {
164              if ( ! $self->_labeltest($char) ) {
165               if ( $char eq ">") { $self->_closetag(); }
# Line 154 | Line 182 | sub _nextchar() {
182          my $self=shift;
183          my $char;
184          $char=substr($self->{currentline},$self->{stringpos}++,1);
185 < #       print "Debug : Fetching character $char\n";
185 >
186 >        # Keep a record for any stream processes
187 >        $self->{streamstore}=$self->{streamstore}.$char;
188 >
189          return $char;
190   }
191  
# Line 162 | Line 193 | sub _opentag {
193          my $self=shift;
194          my $char;
195  
196 +        # Keep a record of where the tag started
197 +        $self->{tagstart}=$self->line();
198 +
199          # Close the last text segment
200 +        $self->{streamtmp}=$self->_popstream();
201          $self->_calltag($self->{textcontext}, $self->{textcontext},
202                                                          $self->_getstore());
203          $self->_resetstore();
# Line 170 | Line 205 | sub _opentag {
205  
206          # Do we have an opening or closing tag?
207          if ( ($char=$self->_nextchar()) eq "/" ) { #we have a closing tag
208 +          $self->{tagbuff}="<".$char;
209            $self->{tagcontext}="endtag";
210          }
211          else { # an opening tag
212 +          $self->{tagbuff}="<";
213            $self->{tagcontext}="starttag";
214            $self->_checkchar($char);
215          }
179        #print "\nDebug : Opening $self->{tagcontext}\n";
216   }
217  
218   #
# Line 190 | Line 226 | sub _closetag {
226          $self->_closelabel();
227          
228          # -- Call the associated tag function if appropriate
229 <        $tagroutine=$self->{tagname}."_".$self->{tagcontext};
230 <        $self->_calltag($tagroutine, $self->{tagname},
229 >        if ( defined $self->{tagname} ) {
230 >         $tagroutine=$self->{tagname}."_".$self->{tagcontext};
231 >         $self->_calltag($tagroutine, $self->{tagname},
232                                                          $self->{tagvar});
196        #print "\nDebug : Closing Tag $tagroutine\n";
233  
234 <        # -- Now make sure the text context is set for calling routines to
235 <        # -- deal with text portions outside of tags
236 <        if ( $self->{tagcontext} eq "starttag" ) {
237 <          push @{$self->{textstack}} , $self->{textcontext};
238 <          $self->{textcontext}=$self->{tagname};
239 <        }
240 <        else {
234 >         # -- Now make sure the text context is set for calling routines to
235 >         # -- deal with text portions outside of tags
236 >         if ( ($self->{tagcontext} eq "starttag") ) {
237 >           if ( $self->{tagcontainer}->definescontext($self->{tagname}) ) {
238 >              push @{$self->{textstack}} , $self->{textcontext};
239 >              $self->{textcontext}=$self->{tagname};
240 >           }
241 >         }
242 >         else {
243            if ( $#{$self->{textstack}} > -1 ) {
244 <            if ( $self->{textcontext} eq $self->{tagname} ) {  
245 <               $self->{textcontext}=pop @{$self->{textstack}};
246 <            }
244 >           if ( $self->{textcontext} eq $self->{tagname} ) {    
245 >            if ( $self->{tagcontainer}->definescontext($self->{tagname}) ) {
246 >              # -- watch out for valid tags we ignore in this parse
247 >              $self->{textcontext}=pop @{$self->{textstack}};
248 >            }
249 >           }
250              else { #The tag we are closing is not the last one so
251                     # we keep our current context.
252                 $self->_removefromstack($self->{tagname},$self->{textstack});
# Line 213 | Line 254 | sub _closetag {
254  
255            }
256            else { # more close tags than open ones
257 +            if ( $self->{tagcontainer}->definescontext($self->{tagname}) ) {
258               print "Warning : Unmatched </...> tag on line ".
259                                          $self->line()."\n";    
260 +            }
261            }
262 +         }
263          }
264          # Reset context back to text
265          $self->{tagcontext}="text";
# Line 226 | Line 270 | sub _calltag {
270          my $tagroutine=shift;
271          my @args=@_;
272          my $rt;
273 +        my $found=0;
274  
275          if ( $self->{groupchecker}->status() ||
276                  ( $self->{tagcontainer}->inquiregroup($tagroutine)) ) {
277 <          $rt=$self->{tagcontainer}->getroutine($tagroutine);
277 >          ($rt,$obj)=$self->{tagcontainer}->getroutine($tagroutine);
278            if ( $rt ne "" ) {
279 +             if ( ! defined $obj ) {
280                 &{$rt}( $self->{allw},@_);
281 +             }
282 +             else {
283 +               &{$rt}( $obj,@_);
284 +             }
285 +             $found=1;
286            }
287          }
288 +        
289 +        # stream function
290 +        if ( ! exists $self->{streamexclude}{$tagroutine} ) {
291 +            $self->_printstream();
292 +        }
293 +        $self->_clearstream();
294 + }
295 +
296 + sub _clearstream {
297 +        my $self=shift;
298 +        $self->{streamstore}=(($self->{streamtmp} ne "")?$self->{streamtmp}:"");
299 +        $self->{streamtmp}="";
300 + }
301 +
302 + sub _popstream {
303 +        my $self=shift;
304 +        $self->{streamstore}=~s/(.*)(.)$/$1/;
305 +        return $2;
306 + }
307 +
308 + sub _printstream {
309 +
310 +        my $self=shift;
311 +
312 +        # Stream output functionality
313 +        if ( defined $self->{stream} ) {
314 +            print {$self->{stream}} "$self->{streamstore}";
315 +        }
316   }
317  
318   sub _removefromstack {
# Line 243 | Line 322 | sub _removefromstack {
322          my $this;
323  
324          undef @tempstack;
246        #print "In  ----".$#{$stack};
325          # Keep popping until we find our string
326          while ( ($this=(pop @{$stack})) ne "$name") {
327            push @tempstack, $this;
# Line 254 | Line 332 | sub _removefromstack {
332            $this=pop @tempstack;
333            push @{$stack}, $this;
334          }
257        #print " Out ----".$#{$stack};
335   }
336  
337   #
# Line 308 | Line 385 | sub _labeltest {
385   sub _resetlabels {
386          my $self=shift;
387          undef $self->{tagvar};
388 +        undef $self->{tagname};
389   }
390  
391   sub _closelabel {
# Line 315 | Line 393 | sub _closelabel {
393  
394          # Do we have a label name?
395          if ( $self->{lastlabel} ne "" ) {
396 <         $self->{tagvar}{$self->{lastlabel}}=$self->_getstore();
396 >         (my $label=$self->{lastlabel})=~tr[A-Z][a-z];
397 >         $self->{tagvar}{$label}=$self->_getstore();
398           $self->{lastlabel}="";
399          }
400          elsif ( $self->_getstore() ne "") {
401 <         #Then it must be the tag name
402 <         ($self->{tagname}=$self->_getstore())=~tr/A-Z/a-z/;
401 >         # Then it must be the tag name
402 >         if ( ! defined $self->{tagname} ) {
403 >            ($self->{tagname}=$self->_getstore())=~tr/A-Z/a-z/;
404 >         }
405 >         else {
406 >            # do not die anymore - breaks non tag documents
407 >            #die ">Tag syntax error in $self->{tagname} on line ".
408 >            #   $self->line()." of file \n$self->{filename}";
409 >            # -- assume that this is plain text
410 >            $self->{tagcontext}="text";
411 >            $self->_resetstore();
412 >            $self->_unshiftstore($self->{tagbuff});
413 >            $self->{tagbuff}="";
414 >            return;
415 >         }
416          }
417          $self->_resetstore();
418   }
# Line 335 | Line 427 | sub _putstore() {
427          $self->{stringbuff}=$self->{stringbuff}.$char;
428   }
429  
430 + sub _unshiftstore() {
431 +        my $self=shift;
432 +        my $char=shift;
433 +
434 +        $self->{stringbuff}=$char.$self->{stringbuff};
435 + }
436 +
437   sub _getstore() {
438          my $self=shift;
439  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines