ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/Utilities/Switcher.pm
Revision: 1.7
Committed: Thu Jun 17 15:10:01 1999 UTC (25 years, 11 months ago) by williamc
Content type: text/plain
Branch: MAIN
Changes since 1.6: +0 -10 lines
Log Message:
 remove old fashined context routine - groupchecker now performs this function

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