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

Comparing COMP/SCRAM/src/BuildSystem/ToolParser.pm (file contents):
Revision 1.2 by sashby, Fri Dec 10 13:41:37 2004 UTC vs.
Revision 1.6 by sashby, Tue Feb 27 11:59:45 2007 UTC

# Line 15 | Line 15 | require 5.004;
15   use Exporter;
16   use ActiveDoc::SimpleDoc;
17   use Utilities::Verbose;
18 use BuildSystem::ToolTagUtils;
18  
19   @ISA=qw(Exporter Utilities::Verbose);
20   @EXPORT=qw();
# Line 34 | Line 33 | sub new
33     {
34     my $proto=shift;
35     my $class=ref($proto) || $proto;
36 <   my $self={};
36 >   $self={};
37    
38     bless $self,$class;
39    
# Line 44 | Line 43 | sub new
43     $self->{interactive} = 0;
44     $self->{content} = {};
45     $self->{nested} = 0;
46 +   $self->{scramdoc}=ActiveDoc::SimpleDoc->new();
47 +   $self->{scramdoc}->newparse("setup", $self->{mydoctype},'Subs');
48 +
49 +   return $self;
50 +   }
51 +
52 + ### Tag handler methods ###
53 + sub tool()
54 +   {
55 +   my ($object,$name,%attributes)=@_;
56 +   my $hashref = \%attributes;  
57 +   # A way to distinguish the naming of different nested levels:
58 +   $self->{levels}=['','tag','nexttag'];
59 +   $$hashref{'name'} =~ tr[A-Z][a-z];
60 +
61 +   # Make sure we only pick up the tool requested:
62 +   if ( ($self->{tool} eq $$hashref{'name'}) &&
63 +        ($self->{version} eq $$hashref{'version'} ))
64 +      {
65 +      # These variables will be used when expanding settings
66 +      # in tool variable defs:
67 +      $ENV{SCRAMToolname} = $$hashref{'name'};
68 +      $ENV{SCRAMToolversion} = $$hashref{'version'};
69 +      $self->{content}->{TOOLNAME}=$$hashref{'name'};
70 +      $self->{content}->{TOOLVERSION}=$$hashref{'version'};
71 +      }
72 +   else
73 +      {
74 +      print "\n";
75 +      $::scram->scramerror("Configuration problem! Wanted/actual ".$self->{tool}." tool versions differ (wanted = ".$self->{version}.", downloaded = ".$$hashref{'version'}.")\n");
76 +      }
77 +  
78 +   # Test to see if this doc defines a
79 +   # scram-managed project or a compiler:
80 +   if (exists ($$hashref{'type'}))
81 +      {
82 +      $$hashref{'type'} =~ tr[A-Z][a-z];
83 +      $self->{content}->{SCRAM_PROJECT} = 0;
84 +
85 +      if ($$hashref{'type'} eq 'scram')
86 +         {
87 +         $self->{content}->{SCRAM_PROJECT} = 1;
88 +         }    
89 +      elsif ($$hashref{'type'} eq 'compiler')
90 +         {
91 +         # Is tool a compiler? Store this for retrieval from tool manager obj:
92 +         $self->{content}->{SCRAM_COMPILER} = 1;
93 +         }
94 +      else
95 +         {
96 +         $::scram->scramwarn("Unknown type \"".$$hashref{'type'}."\" in tool ".$$hashref{'name'}."\n");
97 +         }
98 +      }
99 +   }
100 +
101 + sub tool_()
102 +   {
103 +   delete $self->{levels};
104 +   delete $self->{id};
105 +   delete $self->{nested};
106 +   }
107 +
108 + sub lib()
109 +   {
110 +   my ($object,$name,%attributes)=@_;
111 +   push(@{$self->{"$self->{levels}->[$self->{nested}]".content}->{LIB}},$attributes{'name'});  
112 +   }
113 +
114 + sub info()
115 +   {
116 +   my ($object,$name,%attributes)=@_;
117 +   $self->{"$self->{levels}->[$self->{nested}]".content}->{INFO} = \%attributes;
118 +   }
119 +
120 + sub use()
121 +   {
122 +   my ($object,$name,%attributes)=@_;
123 +   push(@{$self->{"$self->{levels}->[$self->{nested}]".content}->{USE}},$attributes{'name'});
124 +   }
125 +
126 + sub runtime()
127 +   {
128 +   my ($object,$name,%attributes)=@_;
129 +   my $hashref = \%attributes;  
130 +   my $envname;
131 +   # Break the value/default value into its constituent parts:
132 +   foreach my $t (qw(value default))
133 +      {
134 +      if (exists ($$hashref{$t}))
135 +         {
136 +         $hashref->{ELEMENTS} = [];
137 +         map
138 +            {
139 +            # In some cases, we might set a runtime path (e.g. LD_LIBRARY_PATH) to
140 +            # a proper path value i.e. X:Y. In this case, don't bother adding the string
141 +            # as a "variable" to ELEMENTS:
142 +            if ($_ =~ m|\$(.*)?| && $_ !~ /:/)
143 +               {
144 +               push(@{$hashref->{ELEMENTS}},$1);
145 +               }
146 +            } split("/",$hashref->{$t});
147 +         }
148 +      }
149 +  
150 +   # Check to see if we have a "type" arg. If so, we use this to create the key:
151 +   if (exists ($hashref->{'type'}))
152 +      {
153 +      my $type=$hashref->{'type'};
154 +      # Make the type uppercase:
155 +      $type =~ tr/[a-z]/[A-Z]/;
156 +      # Rename the environment as "<type>:<env name>":
157 +      $envname = $type.":".$$hashref{'name'};
158 +      }
159 +   else
160 +      {
161 +      $envname = $$hashref{'name'};
162 +      }
163    
164 <   $self->_initparser();
164 >   # Delete name entry so hash is more tidy
165 >   delete $$hashref{'name'};
166    
167 <   return $self;
167 >   # Before we save $hashref we need to know if there are already
168 >   # any runtime tags with the same name. If there are, we must save all
169 >   # data to an aray of hashes:
170 >   if (exists ($self->{"$self->{levels}->[$self->{nested}]".content}->{RUNTIME}->{$envname}))
171 >      {
172 >      push(@{$self->{"$self->{levels}->[$self->{nested}]".content}->{RUNTIME}->{$envname}},$hashref);
173 >      }
174 >   else
175 >      {
176 >      # No entry yet so just store the hashref:
177 >      $self->{"$self->{levels}->[$self->{nested}]".content}->{RUNTIME}->{$envname} = [ $hashref ];
178 >      }  
179     }
180  
181 < sub _initparser
181 > sub flags()
182     {
183 <   my $self=shift;
183 >   my ($object,$name,%attributes)=@_;
184 >   # Extract the flag name and its value:
185 >   my ($flagname,$flagvaluestring) = each %attributes;
186 >   $flagname =~ tr/[a-z]/[A-Z]/; # Keep flag name uppercase
187 >   chomp($flagvaluestring);
188 >   # Split the value on whitespace so we can push all
189 >   # individual flags into an array:
190 >   my @flagvalues = split(' ',$flagvaluestring);
191 >  
192 >   # Is current tag within another tag block?
193 >   if ($self->{nested} > 0)
194 >      {
195 >      # Check to see if the current flag name is already stored in the hash. If so,
196 >      # just add the new values to the array of flag values:
197 >      if (exists ($self->{"$self->{levels}->[$self->{nested}]".content}->{FLAGS}->{$flagname}))
198 >         {
199 >         push(@{$self->{"$self->{levels}->[$self->{nested}]".content}->{FLAGS}->{$flagname}},@flagvalues);
200 >         }
201 >      else
202 >         {
203 >         $self->{"$self->{levels}->[$self->{nested}]".content}->{FLAGS}->{$flagname} = [ @flagvalues ];
204 >         }
205 >      }
206 >   else
207 >      {
208 >      if (exists ($self->{content}->{FLAGS}->{$flagname}))
209 >         {
210 >         push(@{$self->{content}->{FLAGS}->{$flagname}},@flagvalues);
211 >         }
212 >      else
213 >         {
214 >         $self->{content}->{FLAGS}->{$flagname} = [ @flagvalues ];
215 >         }
216 >      }
217 >   }
218 >
219 > sub client()
220 >   {
221 >   $self->pushlevel();
222 >   }
223 >
224 > sub client_()
225 >   {
226 >   if ($self->{isarch} == 1)
227 >      {
228 >      # If we already have an architecture tag, we must write to tagcontent hash:
229 >      $self->{tagcontent}->{CLIENT}=$self->{nexttagcontent};
230 >      delete $self->{nexttagcontent};
231 >      }
232 >   else
233 >      {
234 >      $self->{content}->{CLIENT}=$self->{tagcontent};
235 >      }
236    
237 <   $self->{simpledoc}=ActiveDoc::SimpleDoc->new();
238 <   $self->{simpledoc}->newparse("setup");
239 <   $self->{simpledoc}->addtag("setup","Tool",
240 <                              \&BuildSystem::ToolTagUtils::tooltagOpen, $self,  
241 <                              "", $self,
242 <                              \&BuildSystem::ToolTagUtils::tooltagClose, $self);
243 <  
244 <   $self->{simpledoc}->addtag("setup","Lib",
245 <                              \&BuildSystem::ToolTagUtils::libtagOpen, $self,  
246 <                              "", $self,
247 <                              "", $self);
248 <  
249 <   $self->{simpledoc}->addtag("setup","info",
250 <                              \&BuildSystem::ToolTagUtils::infotagOpen, $self,  
251 <                              "", $self,
252 <                              "", $self);
253 <  
254 <   $self->{simpledoc}->addtag("setup","Use",
255 <                              \&BuildSystem::ToolTagUtils::usetagOpen, $self,  
256 <                              "", $self,
257 <                              "", $self);
258 <  
259 <   $self->{simpledoc}->addtag("setup","Runtime",
260 <                              \&BuildSystem::ToolTagUtils::runtimetagOpen, $self,      
261 <                              "", $self,
82 <                              "", $self);
83 <  
84 <   $self->{simpledoc}->addtag("setup","Flags",
85 <                              \&BuildSystem::ToolTagUtils::flagstagOpen, $self,
86 <                              "", $self,
87 <                              "", $self);
88 <  
89 <   $self->{simpledoc}->addtag("setup","Client",
90 <                              \&BuildSystem::ToolTagUtils::clienttagOpen, $self,        
91 <                              "", $self,
92 <                              \&BuildSystem::ToolTagUtils::clienttagClose, $self);
93 <  
94 <   $self->{simpledoc}->addtag("setup","Environment",
95 <                              \&BuildSystem::ToolTagUtils::environmenttagOpen, $self,  
96 <                              "", $self,
97 <                              "", $self);
98 <  
99 <   $self->{simpledoc}->addtag("setup","Makefile",
100 <                              \&BuildSystem::ToolTagUtils::makefiletagOpen, $self,
101 <                              \&BuildSystem::ToolTagUtils::makefiletagContent, $self,
102 <                              \&BuildSystem::ToolTagUtils::makefiletagClose, $self);
103 <  
104 <   $self->{simpledoc}->grouptag("Tool","setup");
105 <   $self->{simpledoc}->addtag("setup","Architecture",
106 <                              \&BuildSystem::ToolTagUtils::archtagOpen,$self,
107 <                              "", $self,
108 <                              \&BuildSystem::ToolTagUtils::archtagClose,$self);
237 >   $self->poplevel();
238 >   }
239 >
240 > sub environment()
241 >   {
242 >   my ($object,$name,%attributes)=@_;
243 >   my $hashref = \%attributes;
244 >   # Save a copy of the name of this environment:
245 >   my $envname=$$hashref{'name'};
246 >   delete $$hashref{'name'}; # Delete name entry so hash is more tidy
247 >   # Break the value/default value into its constituent parts:
248 >   foreach my $t (qw(value default))
249 >      {
250 >      if (exists ($$hashref{$t}))
251 >         {
252 >         $hashref->{ELEMENTS} = [];
253 >         map
254 >            {
255 >            if ($_ =~ m|\$(.*)?|)
256 >               {
257 >               push(@{$hashref->{ELEMENTS}},$1);
258 >               }
259 >            } split("/",$hashref->{$t});
260 >         }
261 >      }
262    
263 +   # Before we save $hashref we need to know if there are already
264 +   # any env tags with the same name. If there are, we must save all
265 +   # data to an aray of hashes:
266 +   if (exists ($self->{"$self->{levels}->[$self->{nested}]".content}->{ENVIRONMENT}->{$envname}))
267 +      {
268 +      push(@{$self->{"$self->{levels}->[$self->{nested}]".content}->{ENVIRONMENT}->{$envname}},$hashref);
269 +      }
270 +   else
271 +      {
272 +      # No entry yet so just store the hashref:
273 +      $self->{"$self->{levels}->[$self->{nested}]".content}->{ENVIRONMENT}->{$envname} = [ $hashref ];
274 +      }
275 +   }
276 +
277 + sub makefile()
278 +   {
279 +   my ($object,$name,%attributes)=@_;
280 +   # Set our own Char handler so we can collect the content
281 +   # of the Makefile tag:
282 +   $object->setHandlers(Char => \&makefile_content);
283 +   $self->{makefilecontent} = [];
284     }
285  
286 + sub makefile_content()
287 +   {
288 +   my ($object, @strings) = @_;
289 +   push(@{$self->{makefilecontent}},@strings);
290 +   }
291 +
292 + sub makefile_()
293 +   {
294 +   my ($object,$name)=@_;
295 +   push(@{$self->{"$self->{levels}->[$self->{nested}]".content}->{MAKEFILE}},
296 +        join('',@{$self->{makefilecontent}}));
297 +   delete $self->{makefilecontent};
298 +   # Unset the Char handler to revert to the default behaviour:
299 +   $object->setHandlers(Char => 0);
300 +   }
301 +
302 + sub architecture()
303 +   {
304 +   my ($object,$name,%attributes)=@_;
305 +   $self->pushlevel(\%attributes,1); # Set nested to 1;
306 +   }
307 +
308 + sub architecture_()
309 +   {
310 +   # Need to be able to cope with multiple arch blocks with same arch string:
311 +   if (exists ($self->{content}->{ARCH}->{$self->{id}->{'name'}}))
312 +      {
313 +      # Already have an architecture tag for this arch:
314 +      while (my ($k,$v) = each %{$self->{tagcontent}})
315 +         {
316 +         # If this tag (e.g. LIB, USE, MAKEFILE) already exists and (as we know
317 +         # it should be) its data is an ARRAY, push it to the store:
318 +         if (exists ($self->{content}->{ARCH}->{$self->{id}->{'name'}}->{$k}) &&
319 +             ref($v) eq 'ARRAY')
320 +            {
321 +            push(@{$self->{content}->{ARCH}->{$self->{id}->{'name'}}->{$k}},@$v);
322 +            }
323 +         else
324 +            {
325 +            # Otherwise (for HASH data) we just store it. Note that, because we do
326 +            # not loop over the HASH content and check for already existsing keys,
327 +            # if two arch blocks with same arch name define the same tag (e.g, ENV),
328 +            # the last occurrence will be kept (i.e. the two values won't be added
329 +            # to one ENV hash: //FIXME for later....)
330 +            $self->{content}->{ARCH}->{$self->{id}->{'name'}}->{$k} = $v;
331 +            }
332 +         }
333 +      }
334 +   else
335 +      {
336 +      $self->{content}->{ARCH}->{$self->{id}->{'name'}}=$self->{tagcontent};
337 +      }
338 +  
339 +   delete $self->{isarch};
340 +   $self->poplevel();
341 +   }
342 +        
343   sub parse
344     {
345     my $self=shift;
346 <   my ($tool,$toolver,$file)=@_;
116 <  
346 >   my ($tool,$toolver,$file)=@_;  
347     $self->{tool}=$tool;
348     $self->{version}=$toolver;
349 <   $self->{simpledoc}->filetoparse($file);  
349 >   $self->{scramdoc}->filetoparse($file);  
350     $self->verbose("Setup Parse");
351 <   $self->{simpledoc}->parse("setup");
352 <    
123 <   delete $self->{simpledoc};
351 >   $self->{scramdoc}->parse("setup");
352 >   delete $self->{scramdoc};
353     return $self;
354     }
355  
# Line 438 | Line 667 | sub processrawtool()
667        {
668        $tooldataobj->scram_project($self->{content}->{SCRAM_PROJECT});
669        }
670 +  
671 +   # And check to see if this tool is a compiler. If so, set
672 +   # the SCRAM_COMPILER variable in the ToolData object:
673 +   if (exists ($self->{content}->{SCRAM_COMPILER}))
674 +      {
675 +      $tooldataobj->scram_compiler($self->{content}->{SCRAM_COMPILER});
676 +      }
677  
678     # Establish the order of parsing the value strings:
679     my $order = $self->process_environments($environments);
# Line 552 | Line 788 | sub find_settings()
788        elsif (exists($ENV{$envname}))
789           {
790           # Nothing to do here:
791 +         push(@$runtime, $envname); # FIX From Shahzad.
792           next;
793           }
794        else
# Line 572 | Line 809 | sub find_settings()
809        my $type = 'RUNTIME';      
810        my $envdata = $tsv->environment($type, $rtname);
811        my ($rttype,$realrtname) = split(':',$rtname);      
812 <
812 >      
813        # Only validate paths:
814        if ($rtname =~ /:/)
815           {      
# Line 923 | Line 1160 | sub _check_system_libs()
1160     return $found;
1161     }
1162  
1163 + sub AUTOLOAD()
1164 +   {
1165 +   my ($xmlparser,$name,%attributes)=@_;
1166 +   return if $AUTOLOAD =~ /::DESTROY$/;
1167 +   my $name=$AUTOLOAD;
1168 +   $name =~ s/.*://;
1169 +   }
1170 +
1171   1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines