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

# Content
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 or return 1;
76 # or carp "Switcher: Cannot open $self->{filename} $! \n";
77
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 }