ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/ActiveDoc/Switcher.pm
Revision: 1.2
Committed: Mon Sep 20 16:27:57 1999 UTC (25 years, 7 months ago) by williamc
Content type: text/plain
Branch: MAIN
Changes since 1.1: +2 -1 lines
Log Message:
Basic Working Level

File Contents

# User Rev Content
1 williamc 1.1 # Switcher Module
2     #
3     # Look for elements given in input has in a string
4     # If found then call a routine name with the same name
5     # Implemented as an object to maintain state info between each line
6     # processed.
7     # Interface
8     # ---------
9     # new(file,objectref) : A new object - filename of file to parse
10     # objectref->of the methods
11     # usetags(tagobjref) : Specify a tagcontainer set to direct to
12     # to the desired routines
13     # usegroupchecker(groupchecker) : Set a groupchecker
14     # parse() : Parse the file
15     # checkparam($name,$par) : Exit with an error message if parameter
16     # is undefined in tag $name
17     # line() : return the current line number of the parse
18    
19     package Switcher;
20     require 5.001;
21     use Carp;
22    
23     sub new {
24     my $class=shift;
25     my $file=shift;
26     my $objectname=shift;
27     my $groupchecker=shift;
28    
29     my $self = {};
30     $self->{allw}=$objectname;
31     bless $self, $class;
32     $self->_initialise($file);
33     return $self;
34     }
35    
36     sub _initialise (hash1) {
37     my $self=shift;
38     $self->{filename}=shift;
39    
40     # add a default groupchecker
41     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}=TagContainer->new();
48    
49     }
50    
51     sub usetags {
52     my $self=shift;
53     my $tagcontainer=shift;
54    
55     $self->{tagcontainer}=$tagcontainer;
56     }
57    
58     sub usegroupchecker {
59     my $self=shift;
60     my $ref=shift;
61    
62     $self->{groupchecker}=$ref;
63     }
64    
65     sub parse {
66     my $self=shift;
67     my $char;
68     $self->{linecount}=0;
69     $self->_resetvars();
70    
71     # Open the file
72     use FileHandle;
73     my $filehandle=FileHandle->new();
74     open( $filehandle , "$self->{filename}" )
75 williamc 1.2 or return 1;
76     # or carp "Switcher: Cannot open $self->{filename} $! \n";
77 williamc 1.1
78     # Start file processing
79     while ( <$filehandle> ) {
80     $self->{linecount}++;
81     $self->{currentline}=$_;
82     $self->{stringpos}=0;
83     while ( ($char=$self->_nextchar()) ne "" ) {
84     $self->_checkchar($char);
85     } # end char while
86     } # End String while loop
87     close $filehandle;
88     }
89    
90     sub checkparam($name, $key) {
91     my $self=shift;
92     my $name=shift;
93     my $key=shift;
94    
95     if ( ! defined $self->{tagvar}{$key} ) {
96     print "Switcher: Badly formed $name tag -".
97     " undefined $key parameter\n";
98     exit 1;
99     }
100     }
101    
102     #
103     # return the current line number
104     #
105     sub line {
106     my $self=shift;
107     return $self->{linecount};
108     }
109     # --------------- Utility routines ----------------------------
110    
111     #
112     # Some initialisation of test suites
113     #
114     sub _resetvars {
115     my $self=shift;
116     $self->{quotes}=0;
117     $self->{lastlabel}="";
118     $self->{textcontext}='none';
119     $self->{tagcontext}="text";
120     $self->_resetstore();
121     }
122    
123     #
124     # Check for control characters
125     #
126     sub _checkchar {
127     my $self=shift;
128     my $char=shift;
129     my $string;
130    
131     # ---- In a tag
132     if ( $self->{tagcontext}=~/tag/ ) {
133     if ( ! $self->_quotetest($char) ) {
134     if ( ! $self->_labeltest($char) ) {
135     if ( $char eq ">") { $self->_closetag(); }
136     else { $self->_putstore($char); }
137     }
138     }
139     }
140     # ------ Outside a tag
141     else {
142     if ( $char eq "<") { $self->_opentag() }
143     else { $self->_putstore($char) }
144     }
145     }
146    
147    
148     #
149     # Return the next character from the current string buffer
150     #
151     sub _nextchar() {
152     my $self=shift;
153     my $char;
154     $char=substr($self->{currentline},$self->{stringpos}++,1);
155     # print "Debug : Fetching character $char\n";
156     return $char;
157     }
158    
159     sub _opentag {
160     my $self=shift;
161     my $char;
162    
163     # Close the last text segment
164     $self->_calltag($self->{textcontext}, $self->{textcontext},
165     $self->_getstore());
166     $self->_resetstore();
167     $self->_resetlabels();
168    
169     # Do we have an opening or closing tag?
170     if ( ($char=$self->_nextchar()) eq "/" ) { #we have a closing tag
171     $self->{tagcontext}="endtag";
172     }
173     else { # an opening tag
174     $self->{tagcontext}="starttag";
175     $self->_checkchar($char);
176     }
177     #print "\nDebug : Opening $self->{tagcontext}\n";
178     }
179    
180     #
181     # Close a tag
182     #
183     sub _closetag {
184     my $self=shift;
185     my $tagroutine;
186    
187     # -- Finish off any labels/get tagname
188     $self->_closelabel();
189    
190     # -- Call the associated tag function if appropriate
191     $tagroutine=$self->{tagname}."_".$self->{tagcontext};
192     $self->_calltag($tagroutine, $self->{tagname},
193     $self->{tagvar});
194     #print "\nDebug : Closing Tag $tagroutine\n";
195    
196     # -- Now make sure the text context is set for calling routines to
197     # -- deal with text portions outside of tags
198     if ( $self->{tagcontext} eq "starttag" ) {
199     push @{$self->{textstack}} , $self->{textcontext};
200     $self->{textcontext}=$self->{tagname};
201     }
202     else {
203     if ( $#{$self->{textstack}} > -1 ) {
204     if ( $self->{textcontext} eq $self->{tagname} ) {
205     $self->{textcontext}=pop @{$self->{textstack}};
206     }
207     else { #The tag we are closing is not the last one so
208     # we keep our current context.
209     $self->_removefromstack($self->{tagname},$self->{textstack});
210     }
211    
212     }
213     else { # more close tags than open ones
214     print "Warning : Unmatched </...> tag on line ".
215     $self->line()."\n";
216     }
217     }
218     # Reset context back to text
219     $self->{tagcontext}="text";
220     }
221    
222     sub _calltag {
223     my $self=shift;
224     my $tagroutine=shift;
225     my @args=@_;
226     my $rt;
227    
228     if ( $self->{groupchecker}->status() ||
229     ( $self->{tagcontainer}->inquiregroup($tagroutine)) ) {
230     $rt=$self->{tagcontainer}->getroutine($tagroutine);
231     if ( $rt ne "" ) {
232     &{$rt}( $self->{allw},@_);
233     }
234     }
235     }
236    
237     sub _removefromstack {
238     my $self=shift;
239     my $name=shift;
240     my $stack=shift;
241     my $this;
242    
243     undef @tempstack;
244     #print "In ----".$#{$stack};
245     # Keep popping until we find our string
246     while ( ($this=(pop @{$stack})) ne "$name") {
247     push @tempstack, $this;
248     if ( $#{$stack} < 0 ) { last; }
249     }
250     # Now put them back
251     while ( $#tempstack>-1) {
252     $this=pop @tempstack;
253     push @{$stack}, $this;
254     }
255     #print " Out ----".$#{$stack};
256     }
257    
258     #
259     # Quote handling
260     #
261    
262     sub _quotetest {
263     my $self=shift;
264     my $char=shift;
265    
266     # --- Are we already in a quote context?
267     if ( $self->{quotes} ) {
268     if ( $char eq $self->{openquote} ) {
269     $self->{quotes}=0;
270     }
271     else {
272     $self->_putstore($char);
273     }
274     }
275     # --- Unquoted Context
276     elsif ( (($char eq "\"") || ($char eq "\'") || ($char eq "\`")) ) {
277     $self->{quotes}=1;
278     $self->{openquote}=$char;
279     }
280     else { return 0; } # Return zero if not quoted
281     return 1; # 1 otherwise
282     }
283    
284     #
285     # Label handling
286     #
287     sub _labeltest {
288     my $self=shift;
289     my $char=shift;
290    
291     # Spaces are markers between tags
292     if ( ($char eq " ") || ($char eq "\n") || ($char eq "\t")) {
293     $self->_closelabel();
294     }
295     # Check for a change in label status
296     elsif ( $char eq "=" ) {
297     $self->{lastlabel}=$self->_getstore();
298     $self->_resetstore();
299     }
300     else {
301     return 0;
302     }
303     return 1;
304     }
305    
306     sub _resetlabels {
307     my $self=shift;
308     undef $self->{tagvar};
309     }
310    
311     sub _closelabel {
312     my $self=shift;
313    
314     # Do we have a label name?
315     if ( $self->{lastlabel} ne "" ) {
316     $self->{tagvar}{$self->{lastlabel}}=$self->_getstore();
317     $self->{lastlabel}="";
318     }
319     elsif ( $self->_getstore() ne "") {
320     #Then it must be the tag name
321     ($self->{tagname}=$self->_getstore())=~tr/A-Z/a-z/;
322     }
323     $self->_resetstore();
324     }
325    
326     #
327     # Character Store management interface
328     #
329     sub _putstore() {
330     my $self=shift;
331     my $char=shift;
332    
333     $self->{stringbuff}=$self->{stringbuff}.$char;
334     }
335    
336     sub _getstore() {
337     my $self=shift;
338    
339     return $self->{stringbuff};
340     }
341    
342     sub _resetstore {
343     my $self=shift;
344     $self->{stringbuff}="";
345     }