ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/ToolManager.pm
Revision: 1.16
Committed: Tue Feb 27 11:59:45 2007 UTC (18 years, 2 months ago) by sashby
Content type: text/plain
Branch: MAIN
CVS Tags: V110p6, V110p5, V110p4, V110p3
Branch point for: v200branch
Changes since 1.15: +107 -6 lines
Log Message:
Merged from XML branch to HEAD. Start release prep.

File Contents

# User Rev Content
1 sashby 1.2 #____________________________________________________________________
2     # File: ToolManager.pm
3     #____________________________________________________________________
4     #
5     # Author: Shaun Ashby <Shaun.Ashby@cern.ch>
6     # Update: 2003-11-12 15:04:16+0100
7 sashby 1.16 # Revision: $Id: ToolManager.pm,v 1.15.2.3 2007/02/27 11:38:39 sashby Exp $
8 sashby 1.2 #
9     # Copyright: 2003 (C) Shaun Ashby
10     #
11     #--------------------------------------------------------------------
12     package BuildSystem::ToolManager;
13     require 5.004;
14    
15     use Exporter;
16     use BuildSystem::ToolCache;
17     use BuildSystem::ToolParser;
18     use Utilities::AddDir;
19     use URL::URLhandler;
20     use Utilities::Verbose;
21    
22     @ISA=qw(BuildSystem::ToolCache Utilities::Verbose);
23     @EXPORT_OK=qw( );
24     #
25 sashby 1.9
26 sashby 1.2 sub new
27     ###############################################################
28     # new #
29     ###############################################################
30     # modified : Wed Nov 12 10:34:10 2003 / SFA #
31     # params : #
32     # : #
33     # function : #
34     # : #
35     ###############################################################
36     {
37     my $proto=shift;
38     my $class=ref($proto) || $proto;
39     my $self=$class->SUPER::new(); # Inherit from ToolCache
40     my $projectarea=shift;
41    
42     bless $self,$class;
43    
44     $self->{arch}=shift;
45     $self->{topdir}=$projectarea->location();
46     $self->{configdir}=$self->{topdir}."/".$projectarea->configurationdir();
47     $self->{cache}=$projectarea->cache(); # Download tool cache
48     $self->{toolfiledir}=$self->{topdir}."/.SCRAM/InstalledTools";
49     $self->{datastore}=$self->{topdir}."/.SCRAM";
50     $self->{archstore}=$self->{topdir}."/.SCRAM/".$ENV{SCRAM_ARCH};
51 sashby 1.16
52     if (exists $ENV{SCRAM_TOOL_TIMESTAMP_DIR})
53     {
54     $self->{tooltimestamp}=$ENV{SCRAM_TOOL_TIMESTAMP_DIR};
55     }
56     else
57     {
58     $self->{tooltimestamp}=$self->{archstore}."/timestamps";
59     }
60 sashby 1.2
61     # Make sure our tool download dir exists:
62     AddDir::adddir($self->{toolfiledir});
63     AddDir::adddir($self->{archstore});
64 sashby 1.16 AddDir::adddir($self->{tooltimestamp});
65 sashby 1.2
66     # Set the tool cache file to read/write:
67     $self->name($projectarea->toolcachename());
68    
69     # Check for the downloaded tools cache:
70     if (exists($self->{cache}))
71     {
72     $self->{urlhandler}=URL::URLhandler->new($self->{cache});
73     }
74    
75     return $self;
76     }
77    
78     sub clone()
79     {
80     my $self=shift;
81     my $projectarea=shift;
82 sashby 1.3
83 sashby 1.2 # Change cache settings to reflect the new location:
84     $self->{topdir}=$projectarea->location();
85    
86     $self->{configdir}=$self->{topdir}."/".$projectarea->configurationdir();
87     $self->{toolfiledir}=$self->{topdir}."/.SCRAM/InstalledTools";
88     $self->{datastore}=$self->{topdir}."/.SCRAM";
89     $self->{archstore}=$self->{topdir}."/.SCRAM/".$ENV{SCRAM_ARCH};
90    
91     # Change the cache name:
92     $self->name($projectarea->toolcachename());
93     $self->cloned_tm(1);
94    
95     return $self;
96     }
97    
98     sub arch_change_after_copy()
99     {
100     my $self=shift;
101     my ($newarch, $cachename)=@_;
102     # Make changes to arch-specific settings when copying tool manager
103     # object to another arch during setup:
104     $self->{arch} = $newarch;
105     $self->{archstore} = $self->{topdir}."/.SCRAM/".$newarch;
106     # Change the name of the cache to reflect new (arch-specific) location:
107     $self->name($cachename);
108     }
109    
110     sub interactive()
111     {
112     my $self=shift;
113     # Interactive mode on/off:
114     @_ ? $self->{interactive} = shift
115     : ((defined $self->{interactive}) ? $self->{interactive} : 0);
116     }
117    
118     sub setupalltools()
119     {
120     my $self = shift;
121     my ($arealocation,$setupopt) = @_;
122     my (@localtools);
123     my $selected;
124    
125     # Get the selected tool list. Handle the case where there might not be
126     # any selected tools: //FIXME: need to handle case where there are no
127     # selected tools (not very often but a possibility):
128     my $sel = $self->selected();
129    
130     if (defined ($sel))
131     {
132     $selected = [ keys %{$sel} ];
133     }
134    
135     # Setup option "setupopt" directs the setup: 1 is for booting from
136     # scratch, 0 is when just doing "scram setup" (in this case we don't
137     # want to pick up everything from any scram-managed projects):
138     if ($setupopt == 1) # We're booting from scratch
139     {
140     # Check to see if there are any SCRAM-managed projects in our local requirements:
141     my $scramprojects = $::scram->_loadscramdb();
142    
143     # Look for a match in the scram db:
144     foreach my $S (@$selected)
145     {
146     if (exists ($scramprojects->{$S}))
147     {
148     # Now check the version required exists in
149     # list of scram projects with this name:
150     while (my ($pdata,$plocation) = each %{$scramprojects->{$S}})
151     {
152     # Split the $pdata string to get the real name and the version:
153     my ($pname,$pversion) = split(":",$pdata);
154     if ($pversion eq $self->defaultversion($S))
155     {
156     # Get the tool manager for the scram project:
157     my $sa=$::scram->scramfunctions()->scramprojectdb()->getarea($pname,$pversion);
158     # Load the tool cache:
159     if ( -r $sa->toolcachename())
160     {
161     use Cache::CacheUtilities;
162     my $satoolmanager=&Cache::CacheUtilities::read($sa->toolcachename());
163 sashby 1.14 # Copy needed content from toolmanager for scram-managed project only
164     # if the projects have compatible configurations (compare first set of
165     # digits):
166     if ($self->check_compatibility($satoolmanager))
167     {
168     $self->inheritcontent($satoolmanager);
169     }
170 sashby 1.2 }
171     }
172     }
173     # Also add this scram-managed project to list of tools to set up:
174     push(@localtools,$S);
175     }
176     else
177     {
178     # Store other tools in ReqDoc in separate array. We will set up these tools later:
179     push(@localtools,$S);
180     }
181     }
182    
183     # Set up extra tools required in this project, in addition to
184     # any scram-managed projects
185     foreach my $localtool (@localtools)
186     {
187     # First check to see if it's already set up (i.e., was contained
188     # in list of requirements for scram project):
189     if (! $self->definedtool($localtool))
190     {
191     $self->toolsetup($arealocation,$localtool,$self->defaultversion($localtool));
192     $self->addtoselected($localtool);
193     }
194     else
195     {
196     print $localtool," already set up.","\n",if ($ENV{SCRAM_DEBUG});
197     }
198     }
199     }
200     else
201     {
202     # Just loop over all tools and setup again:
203     foreach my $localtool (@{$selected})
204     {
205     $self->toolsetup($arealocation,$localtool,$self->defaultversion($localtool));
206     }
207     }
208    
209     print "\n";
210     }
211    
212     sub coresetup()
213     {
214     my $self=shift;
215 sashby 1.13 my ($toolname, $toolversion, $toolfile, $force) = @_;
216 sashby 1.2 my ($toolcheck, $toolparser);
217    
218     print "\n";
219     print $::bold."Setting up ",$toolname," version ",$toolversion,": ".$::normal,"\n";
220    
221     # New ToolParser object for this tool if there isn't one already.
222     # Look in array of raw tools to see if this tool has a ToolParser object:
223     $toolcheck=0;
224    
225     map
226     {
227     if ($_->toolname() eq $toolname) {$toolcheck = 1; $toolparser = $_;}
228     } $self->rawtools();
229    
230     # Tool not known so we create a new ToolParser object and parse it:
231 sashby 1.13 if ($toolcheck != 1 || $force == 1)
232 sashby 1.2 {
233     $toolparser = BuildSystem::ToolParser->new();
234     # We only want to store the stuff relevant for one particular version:
235     $toolparser->parse($toolname, $toolversion, $toolfile);
236     # Store the ToolParser object in the cache:
237     $self->store($toolparser);
238 sashby 1.13 print "\nFile $toolfile reparsed (modified)","\n",if ($ENV{SCRAM_DEBUG});
239 sashby 1.2 }
240    
241     # Next, set up the tool:
242     my $store = $toolparser->processrawtool($self->interactive());
243     # Make sure that we have this tool in the list of selected tools (just in case this tool was
244     # set up by hand afterwards):
245     $self->addtoselected($toolname);
246 sashby 1.8
247     # Check to see if this tool is a compiler. If so, store it.
248     # Also store the language that this compiler supprots, and a
249     # compiler name (e.g. gcc323) which, in conjunction with a stem
250     # architecture name like slc3_ia32_, can be used to build a complete arch string:
251     if ($store->scram_compiler() == 1)
252     {
253     my @supported_language = $store->flags("SCRAM_LANGUAGE_TYPE");
254     my @compilername = $store->flags("SCRAM_COMPILER_NAME");
255     $self->scram_compiler($supported_language[0],$toolname,$compilername[0]);
256     }
257    
258 sashby 1.16 # Store the ToolData object in the cache:
259 sashby 1.2 $self->storeincache($toolparser->toolname(),$store);
260     return $self;
261     }
262    
263     sub toolsetup()
264     {
265     my $self=shift;
266     my ($arealocation, $toolname, $toolversion, $toolurl) = @_;
267     my ($urlcache, $url, $filename, $tfname);
268     my $toolfile;
269 sashby 1.13 my $force = 0; # we may have to force a reparse of a tool file
270 sashby 1.6
271 sashby 1.2 $toolname =~ tr[A-Z][a-z];
272     $toolversion ||= $self->defaultversion($toolname);
273     $urlcache=URL::URLcache->new($arealocation."/.SCRAM/cache"); # Download tool cache
274 sashby 1.6
275 sashby 1.2 # Check for the downloaded tools cache:
276     if (defined($urlcache))
277     {
278     $self->{urlhandler}=URL::URLhandler->new($urlcache);
279     }
280 sashby 1.6
281 sashby 1.2 $url = $self->toolurls()->{$toolname};
282     $filename = $self->{toolfiledir}."/".$toolname;
283    
284 sashby 1.4 # If .SCRAM/InstalledTools doesn't exist, create it:
285     if (! -d $self->{toolfiledir})
286     {
287     AddDir::adddir($self->{toolfiledir});
288     }
289    
290 sashby 1.2 # First, check to see if there was a tool URL given. If so, we might need to read
291     # from http or from a file: type URL:
292     if (my ($proto, $urlv) = ($toolurl =~ /(.*):(.*)/))
293     {
294     # See what kind of URL (file:, http:, cvs:, svn:, .. ):
295     if ($proto eq 'file')
296     {
297 sashby 1.10 # Check to see if there is a ~ and substitute the user
298 sashby 1.13 # home directory if there is (file:~/xyz):
299     if (my ($urlpath) = ($urlv =~ m|^\~/(.*)$|))
300     {
301     $urlv = $ENV{HOME}."/".$urlpath;
302     }
303     elsif (my ($urlpath) = ($urlv =~ m|^\./(.*)$|))
304     {
305     # Relative to current directory (file:./xyz):
306     use Cwd qw(&cwd);
307     $urlv = cwd()."/".$urlpath;
308     }
309    
310 sashby 1.2 # If the tool url is a file and the file exists,
311     # copy it to .SCRAM/InstalledTools and set the
312     # filename accordingly:
313     if ( -f $urlv)
314     {
315     use File::Copy;
316     copy($urlv, $filename);
317 sashby 1.5 my $mode = 0644; chmod $mode, $filename;
318 sashby 1.2 $toolfile=$filename;
319 sashby 1.13 # Here we must account for the fact that the file tool doc may be
320     # a modified version of an existing tool in the current config. we
321     # make sure that this file is reparsed, even if there is already a
322     # ToolParser object for the tool:
323     $force = 1;
324 sashby 1.2 }
325     else
326     {
327 sashby 1.13 $::scram->scramerror("Unable to set up $toolname from URL \"$toolurl\" - $urlv does not exist!");
328 sashby 1.2 }
329     }
330     elsif ($proto eq 'http')
331     {
332     print "SCRAM: downloading $toolname from $toolurl","\n";
333     # Download from WWW first:
334     use LWP::Simple qw(&getstore);
335     my $http_response_val = &getstore($toolurl, $filename);
336 sashby 1.13
337 sashby 1.2 # Check the HTTP status. If doc not found, exit:
338     if ($http_response_val != 200)
339     {
340     my ($server,$doc) = ($urlv =~ m|//(.*?)/(.*)|);
341     $::scram->scramerror("Unable to set up $toolname: $doc not found on $server!");
342     }
343     else
344     {
345     $toolfile=$filename;
346     }
347     }
348     elsif ($proto eq 'cvs')
349     {
350     print "SCRAM: downloading $toolname from $urlv using protocol $proto.","\n";
351     print "[ not yet supported ]","\n";
352     exit(0);
353     }
354     elsif ($proto eq 'svn')
355     {
356     print "SCRAM: downloading $toolname from $urlv using protocol $proto.","\n";
357     print "[ not yet supported ]","\n";
358     exit(0);
359     }
360     else
361     {
362     $::scram->scramerror("Unable to download $urlv! Unknown protocol \"$proto\". Bye.");
363     }
364     }
365     else
366     {
367     # Copy the downloaded tool file to InstalledTools directory:
368     if ( ! -f $filename )
369     {
370 sashby 1.7 # If the URL is empty, the chances are that this tool was not downloaded to .SCRAM/InstalledTools.
371     # We signal an error and exit:
372 sashby 1.6 if ($url eq '')
373     {
374 sashby 1.7 $::scram->scramerror("$toolname was selected in project requirements but is not in the configuration!");
375 sashby 1.6 }
376     else
377     {
378     # Otherwise, we try to download it:
379     $self->verbose("Attempting Download of $url");
380     # Get file from download cache:
381     ($url,$filename)=$self->{urlhandler}->get($url);
382     use File::Copy;
383     $tfname=$self->{toolfiledir}."/".$toolname;
384     copy($filename, $tfname);
385     my $mode = 0644; chmod $mode, $tfname;
386     $toolfile=$tfname;
387     }
388 sashby 1.2 }
389     else
390     {
391     # File already exists in the .SCRAM/InstallTools directory:
392     $toolfile=$filename;
393     }
394     }
395    
396     # Run the core setup routine:
397 sashby 1.13 $self->coresetup($toolname, $toolversion, $toolfile,$force);
398 sashby 1.2 return $self;
399     }
400    
401     sub setupself()
402     {
403     my $self=shift;
404     my ($location)=@_;
405     # Process the file "Self" in local config directory. This is used to
406     # set all the paths/runtime settings for this project:
407 sashby 1.16 my $filename=$location."/config/Self.xml";
408    
409 sashby 1.2 if ( -f $filename )
410     {
411     print "\n";
412     print $::bold."Setting up SELF:".$::normal,"\n";
413     # Self file exists so process it:
414     $selfparser = BuildSystem::ToolParser->new();
415     $selfparser->parse('self','SELF',$filename);
416    
417     # Next, set up the tool:
418     $store = $selfparser->processrawtool($self->interactive());
419    
420     # If we are in a developer area, also add RELEASETOP paths:
421     if (exists($ENV{RELEASETOP}))
422     {
423     print "\nAdding RELEASE area settings to self....OK","\n", if ($ENV{SCRAM_DEBUG});
424     $store->addreleasetoself();
425     }
426    
427     # Store the ToolData object in the cache:
428     $self->storeincache($selfparser->toolname(),$store);
429     print "\n";
430     }
431     else
432     {
433     print "\n";
434 sashby 1.16 print "SCRAM: No file config/Self.xml...nothing to do.";
435 sashby 1.2 print "\n";
436     return;
437     }
438     }
439    
440     sub defaultversion()
441     {
442     my $self = shift;
443     my ($tool) = @_;
444     # Return default versions as taken from configuration:
445     return (%{$self->defaultversions()}->{$tool});
446     }
447    
448     sub storeincache()
449     {
450     my $self=shift;
451     my ($toolname,$dataobject)=@_;
452    
453     # Store ToolData object (for a set-up tool) in cache:
454     if (ref($dataobject) eq 'BuildSystem::ToolData')
455     {
456 sashby 1.16 $self->updatetooltimestamp($dataobject, $toolname);
457 sashby 1.2 $self->{SETUP}->{$toolname} = $dataobject;
458     }
459     else
460     {
461     $::scram->scramerror("ToolManager: BuildSystem::ToolData object reference expected.")
462     }
463     }
464    
465     sub tools()
466     {
467     my $self = shift;
468     my @tools;
469    
470     map
471     {
472     if ($_ ne "self")
473     {
474     push(@tools, $_);
475     }
476     } keys %{$self->{SETUP}};
477    
478     # Return list of set-up tools:
479     return @tools;
480     }
481    
482     sub toolsdata()
483     {
484     my $self = shift;
485     my $tooldata = [];
486     my $rawsel = $self->selected();
487    
488     foreach my $tool ( sort { %{$rawsel}->{$a}
489     <=> %{$rawsel}->{$b}}
490     keys %{$rawsel} )
491     {
492     # Return tool data objects of all set-up tools, skipping the tool "self":
493     if ($_ ne "self")
494     {
495     # Keep only tools that have really been set up:
496     if (exists $self->{SETUP}->{$tool})
497     {
498     push(@tooldata,$self->{SETUP}->{$tool});
499     }
500     }
501     }
502    
503     # Return the array of tools, in order that they appear in RequirementsDoc:
504     return @tooldata;
505     }
506    
507     sub definedtool()
508     {
509     my $self=shift;
510     my ($tool)=@_;
511    
512     # Check to see if tool X is an external tool:
513     grep ($_ eq $tool, keys %{$self->{SETUP}}) ? return 1
514     : return 0;
515     }
516    
517     sub checkifsetup()
518     {
519     my $self=shift;
520     my ($tool)=@_;
521     # Return the ToolData object if the tool has been set up:
522     (exists $self->{SETUP}->{$tool}) ? return ($self->{SETUP}->{$tool})
523     : return undef;
524     }
525    
526     sub cloned_tm()
527     {
528     my $self=shift;
529     # Has this area already been cloned and brought in-line with current location:
530     @_ ? $self->{CLONED} = $_[0]
531     : $self->{CLONED};
532     }
533    
534     sub remove_tool()
535     {
536     my $self=shift;
537     my ($toolname)=@_;
538     my $tools = $self->{SETUP};
539     my $newtlist = {};
540    
541     while (my ($tool, $tooldata) = each %$tools)
542     {
543     if ($tool ne $toolname)
544     {
545     $newtlist->{$tool} = $tooldata;
546     }
547     else
548     {
549 sashby 1.10 # Is this tool a compiler?
550     if ($tooldata->scram_compiler() == 1)
551     {
552     # Also remove this from the compiler info if there happens to be an entry:
553     while (my ($langtype, $ctool) = each %{$self->{SCRAM_COMPILER}})
554     {
555     if ($toolname eq $ctool->[0])
556     {
557     delete $self->{SCRAM_COMPILER}->{$langtype};
558     print "Deleting compiler $toolname from cache.","\n";
559     }
560     }
561     }
562     else
563     {
564     print "Deleting $toolname from cache.","\n";
565     }
566 sashby 1.2 }
567     }
568    
569     $self->{SETUP} = $newtlist;
570 sashby 1.16 $self->updatetooltimestamp ("", $toolname);
571 sashby 1.2 # Now remove from the RAW tool list:
572     $self->cleanup_raw($toolname);
573     print "ToolManager: Updating tool cache.","\n";
574     $self->writecache();
575     }
576    
577     sub scram_projects()
578     {
579     my $self=shift;
580     my $scram_projects={};
581    
582     foreach my $t ($self->tools())
583     {
584     # Get the ToolData object:
585     my $td=$self->{SETUP}->{$t};
586     $scram_projects->{$t}=$td->variable_data(uc($t)."_BASE"), if ($td->scram_project());
587     }
588    
589     return $scram_projects;
590     }
591    
592 sashby 1.8 sub scram_compiler()
593     {
594     my $self=shift;
595     my ($langtype, $toolname, $compilername)=@_;
596    
597     if ($langtype)
598     {
599     # Store the compiler info according to supported
600     # language types.
601     #
602     # ---------------------- e.g C++ cxxcompiler gcc323
603     $self->{SCRAM_COMPILER}->{$langtype}=[ $toolname, $compilername ];
604     }
605     else
606     {
607     return $self->{SCRAM_COMPILER};
608     }
609     }
610    
611 sashby 1.12 sub updatetool()
612 sashby 1.11 {
613     my $self=shift;
614 sashby 1.12 my ($name, $obj) = @_;
615 sashby 1.11
616     # Replace the existing copy of the tool with the new one:
617 sashby 1.12 if (exists $self->{SETUP}->{$name})
618 sashby 1.11 {
619     # Check to make sure that we were really passed a compiler with
620     # the desired name:
621 sashby 1.12 if ($obj->toolname() eq $name)
622 sashby 1.11 {
623 sashby 1.16 $self->updatetooltimestamp ($obj, $name);
624 sashby 1.12 print "ToolManager: Updating the cached copy of ".$name."\n";
625     delete $self->{SETUP}->{$name};
626     $self->{SETUP}->{$name} = $obj;
627 sashby 1.11 $self->writecache();
628     }
629     else
630     {
631 sashby 1.12 print "WARNING: Tool name (".$name.") and tool obj name (".$obj->toolname().") don't match!","\n";
632 sashby 1.11 print " Not making any changes.","\n";
633     }
634     }
635     else
636     {
637 sashby 1.12 print "WARNING: No entry in cache for ".$name.". Not making any updates.\n";
638 sashby 1.11 }
639     }
640    
641 sashby 1.14 sub check_compatibility()
642     {
643     my $self=shift;
644     my ($itoolmgr)=@_;
645     # Get the version of the toolmanager. If the project fails to return a version
646     # string we return 0 for no compatibility (in which case, all tools will be set
647     # up in the traditional way):
648     my $itm_configversion = $itoolmgr->configversion();
649     if ($itm_configversion)
650     {
651     # The configurations won't be identical. We must compare the digits:
652     my ($numeric_version) = ($itm_configversion =~ /[a-zA-Z]*\_([0-9a-z]*).*?/);
653     my $current_configversion = $self->configversion();
654     my ($current_numeric_version) = ($current_configversion =~ /[a-zA-Z]*\_([0-9a-z]*).*?/);
655     ($current_numeric_version == $numeric_version) && return 1; # OK, compatible;
656     }
657     # Project does not define configuration version so just return:
658     return 0;
659     }
660    
661     sub configversion()
662     {
663     my $self=shift;
664     @_ ? $self->{CONFIGVERSION} = shift
665     : $self->{CONFIGVERSION};
666     }
667    
668 sashby 1.16 sub updatetooltimestamp ()
669     {
670     my $self=shift;
671     my $obj=shift;
672     my $toolname=shift;
673     my $samevalues=0;
674     if (exists $self->{SETUP}->{$toolname})
675     {
676     $samevalues=$self->comparetoolsdata($self->{SETUP}->{$toolname},$obj);
677     }
678     if (!$samevalues)
679     {
680     if (!-d $self->{tooltimestamp})
681     {
682     AddDir::adddir($self->{tooltimestamp});
683     }
684     open(TIMESTAMPFILE,">".$self->{tooltimestamp}."/$toolname");
685     close(TIMESTAMPFILE);
686     }
687     }
688    
689     sub comparetoolsdata ()
690     {
691     my $self=shift;
692     my $data1=shift || ();
693     my $data2=shift || ();
694    
695     my $ref1=ref($data1);
696     my $ref2=ref($data2);
697    
698     if ($ref1 ne $ref2)
699     {
700     return 0;
701     }
702     elsif ($ref1 eq "CODE")
703     {
704     return 1;
705     }
706     elsif(($ref1 eq "SCALAR") || ($ref1 eq ""))
707     {
708     if ($data1 eq $data2)
709     {
710     return 1;
711     }
712     return 0;
713     }
714     elsif ($ref1 eq "ARRAY")
715     {
716     my $count = scalar(@$data1);
717     if ($count != scalar(@$data2))
718     {
719     return 0;
720     }
721     for (my $i=0; $i<$count; $i++)
722     {
723     if (! $self->comparetoolsdata($data1->[$i],$data2->[$i]))
724     {
725     return 0;
726     }
727     }
728     return 1;
729     }
730     else
731     {
732     foreach my $k (keys %{$data1})
733     {
734     if (! exists $data2->{$k})
735     {
736     return 0;
737     }
738     }
739     foreach my $k (keys %{$data2})
740     {
741     if (! exists $data1->{$k})
742     {
743     return 0;
744     }
745     }
746     foreach my $k (keys %{$data2})
747     {
748     if (! $self->comparetoolsdata($data1->{$k},$data2->{$k}))
749     {
750     return 0;
751     }
752     }
753     return 1;
754     }
755     }
756    
757 sashby 1.2 1;