Subversion Repositories DevTools

Rev

Rev 227 | Rev 283 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
# -*- mode: perl; tabs: 8; indent-width: 4; -*-
2
#
3
# Module name   : common.pl
4
# Module type   : Makefile system
5
#
6
# Description   : Some function common to build and makefile processing tools.
7
#
8
#.........................................................................#
9
 
10
use strict;
11
use warnings;
12
use JatsError;
13
use JatsSystem;
14
use ConfigurationFile;
15
use FileUtils;
16
use ArrayHashUtils;
17
use ReadBuildConfig qw(:All);
18
use JatsMakeConfig;
19
 
20
our $CommonVersion          = "1.03";
21
 
22
our $ScmWho                 = "";
23
our $ScmDebug               = 0;
24
our $ScmVerbose             = 0;
25
 
26
our $CurrentYear            = "";
27
our $CurrentTime            = "";
28
our $CurrentDate            = "";
29
our $All;
30
 
31
our @BUILD_ACTIVEPLATFORMS  = ();               # Array of active platforms
32
our @DEFBUILDPLATFORMS = ();
263 dpurdie 33
our $GBE_TOOLS;
227 dpurdie 34
 
35
#-------------------------------------------------------------------------------
36
# Function        : CommonInit
37
#
38
# Description     : Initialisation routine for this common code
39
#                   The function MUST be called after the package has been
40
#                   loaded with a "require" statement.
41
#
42
#
43
# Inputs          : $who            - Name of the package using the routines
44
#                                     Used for error reporting
45
#
46
# Returns         : Nothing
47
#
48
sub CommonInit
49
{
50
    my( $who ) = @_;
51
 
52
#.. Import diagnostic levels
53
#
54
    $::ScmWho = $who;
55
    $::ScmDebug = $ENV{ "GBE_DEBUG" }       if ( exists( $ENV{ "GBE_DEBUG" } ) );
56
    $::ScmVerbose = $ENV{ "GBE_VERBOSE" }   if ( exists( $ENV{ "GBE_VERBOSE" } ) );
57
 
58
    ErrorConfig( 'name'    => $::ScmWho,
59
                 'debug'   => $::ScmDebug,
60
                 'verbose' => $::ScmVerbose );
61
 
62
    SystemConfig ('UseShell' => 1 );
63
 
64
    Debug( "Common ($::ScmWho)" );
65
    Debug( "version:   $::CommonVersion" );
66
    Debug( "Debug:     $::ScmDebug" );
67
    Debug( "Verbose:   $::ScmVerbose" );
68
 
69
    #
70
    #   Init the FileUtils package
71
    #   Sets various globals used throughout the program
72
    #
73
    InitFileUtils();
74
 
75
    #
76
    #   Init global time variables
77
    #
78
    $::CurrentTime = localtime;
79
 
80
    my ($sec, $min, $hour, $mday, $mon, $year) = localtime();
81
    $::CurrentYear = 1900 + $year;
82
    $::CurrentDate                              # eg. 13/10/86
83
        = sprintf ("%02u/%02u/%02u", $mday, $mon+1, $year % 100);
84
}
85
 
86
#-------------------------------------------------------------------------------
87
# Function        : AUTOLOAD
88
#
89
# Description     : Intercept bad user directives and issue a nice error message
90
#                   This is a simple routine to report unknown user directives
91
#                   It does not attempt to distinguish between user errors and
92
#                   programming errors. It assumes that the program has been
93
#                   tested. The function simply report filename and line number
94
#                   of the bad directive.
95
#
96
# Inputs          : Original function arguments ( not used )
97
#
98
# Returns         : This function does not return
99
#
100
sub AUTOLOAD
101
{
102
    my $fname = $::AUTOLOAD;
103
    $fname =~ s~^\w+::~~;
104
    my ($package, $filename, $line) = caller;
105
 
106
    Error ("Directive not known or not allowed in this context: $fname",
107
           "Directive: $fname( @_ );",
108
           "File: $filename, Line: $line" );
109
}
110
 
111
#-------------------------------------------------------------------------------
112
# Function        : ConfigLoad
113
#
114
# Description     : Loads the global configuration details
115
#                   Details are held within the interface directory in "build.cfg"
116
#
117
# Inputs          : None
118
#
119
# Returns         : Nothing
120
#                   Will populate the global environment space with the contents
121
#                   of the build.cfg file. These variables may need to be access
122
#                   with the :: syntax ($::Variable)
123
#
124
#                   This function will remove lumps of the configuration that
125
#                   are not needed by the current platform simply to reduce the
126
#                   data retaied in other config files.
127
#
128
#
129
sub ConfigLoad
130
{
131
   ReadBuildConfig("$::ScmRoot/$::ScmInterface", $::ScmPlatform );
132
}
133
 
134
 
135
#   ExpandPlatforms ---
136
#       Expand a platform list applying aliases.
137
#..
138
 
139
sub ExpandPlatforms
140
{
141
    our( @_expandarg ) = @_;
142
    our( @_expandresult, $_expandnest );
143
 
144
    @_expandresult = ();
145
    $_expandnest = 0;
146
 
147
    Debug3( "ExpandPlatforms(@_)" );
148
 
149
    sub ExpandPlatform
150
    {
151
        sub ExpandAlias
152
        {
153
            my( $key ) = @_;
154
 
155
            if (defined(%::BUILDALIAS))         # buildlib.pl
156
            {
157
                return ExpandPlatform( split( ' ', $::BUILDALIAS{ $key } ) )
158
                    if ( $key !~ /^--/ && $::BUILDALIAS{ $key } );
159
            }
160
            else
161
            {
162
                return $key                     # argument || no aliases
163
                    if ( $key =~ /^--/ || !defined(%::ScmBuildAliases) );
164
 
165
                return ExpandPlatform( split( ' ', $::ScmBuildAliases{ $key } ) )
166
                    if ( $::ScmBuildAliases{ $key } );
167
            }
168
 
169
            return $key;
170
        }
171
 
172
        sub ExpandPush
173
        {
174
            my( $pResult, $operator, $pPlatforms, @arguments ) = @_;
175
 
176
            foreach my $platform ( @$pPlatforms )
177
            {                                   # unfold arguments
178
                push( @$pResult, $operator.$platform );
179
                next if ( $platform =~ /^--/ );
180
                push( @$pResult, @arguments );
181
            }
182
        }
183
 
184
        Error( "ExpandPlatforms( @_expandarg ) nesting error.",
185
               "",
186
               "Check for recursive definitions within the follow directives",
187
               "       - BuildAlias and BuildProduct."
188
             ) if ( $_expandnest++ > 42 );
189
 
190
        my( @result, $operator, @platforms, @arguments ) = ();
191
 
192
        Debug3( "  +$_expandnest: @_ " );
193
 
194
        foreach my $arg ( @_ ) {
195
            if ( $arg =~ /^--/ ) {              # argument, accumulate
196
                push( @arguments, $arg );
197
 
198
            } else {                            # group, product or platform
199
                ExpandPush( \@result, $operator, \@platforms, @arguments );
200
 
201
                if ( ($operator = substr($arg, 0, 1)) eq "!" ) {
202
                    @platforms = ExpandAlias( substr($arg, 1) );
203
                } else {
204
                    $operator = "";
205
                    @platforms = ExpandAlias( $arg );
206
                }
207
                @arguments = ();
208
            }
209
        }
210
        ExpandPush( \@result, $operator, \@platforms, @arguments );
211
 
212
        $_expandnest--;
213
        Debug3( "  -$_expandnest: @result" );
214
        return @result;
215
    }
216
 
217
    ############################################################################
218
    #   Function body
219
    #
220
 
221
    foreach (@_expandarg) {                      # break out embedded args
222
        if ( /^--/ ) {
223
            push @_expandresult, $_;
224
 
225
        } else {
226
 
227
            push @_expandresult, split( ',', $_ );
228
        }
229
    }
230
 
231
    @_expandresult = ExpandPlatform( @_expandresult );
232
    Debug2( "ExpandPlatforms(@_expandarg) = @_expandresult" );
233
    return @_expandresult;
234
}
235
 
236
#-------------------------------------------------------------------------------
237
# Function        : Exists( $path, $name, $msg, [@paths] ) ---
238
#
239
# Description     : Case insensitive 'exists'.
240
#
241
# Inputs          :
242
#       $path       Represents either the absolute path of the file
243
#                   named 'name' in the case of @path being an empty
244
#                   list, or the subdir appended to each entry
245
#                   contained within the @paths list.
246
#
247
#       $name       The file name
248
#
249
#       $desc       Text used to describe the file upon the image
250
#                   not being found.
251
#
252
#       @paths      Optional list of paths to be searched.
253
#
254
# Returns         : Full path of resolved filename, otherwise nothing.
255
#
256
#   Examples:
257
#
258
#       a)  Exists( "/mypath", "Myfile", "stuff" );
259
#
260
#           Resolve the name of the file called "myfile" within the
261
#           directory "/mypath", using the following matching order
262
#
263
#               1.  "/mypath/Myfile".       As supplied.
264
#               2.  "/mypath/myfile".       then Lower case
265
#               3.  "/mypath/MYFILE".       and finally upper case.
266
#
267
#           Upon being not found displays the message
268
#
269
#               "stuff (/mypath/Myfile) not found".
270
#
271
#       b)  @paths = ( '/dir1', '/dir2' );
272
#           Exists( "cfg", "Myfile", "stuff", @paths );
273
#
274
#           Resolve the name of the file called "Myfile" within the
275
#           set of directories "/dir1/cfg/" and "/dir2/cfg/", using
276
#           the following matching order:
277
#
278
#               1.  "/dir1/cfg/Myfile".
279
#               2.  "/dir1/cfg/myfile".
280
#               3.  "/dir1/cfg/MYFILE".
281
#               4.  "/dir2/cfg/Myfile".
282
#               5.  "/dir2/cfg/myfile".
283
#               6.  "/dir2/cfg/MYFILE".
284
#
285
#           Upon being not found displays the message
286
#
287
#               "stuff (cfg/Myfile) not found".
288
#
289
sub Exists
290
{
291
    my( $path, $name, $msg, @paths ) = @_;
292
    my( $dir, $file, $lc_name, $uc_name );
293
 
294
    Debug2 "Searching for $path/$name (" . ($msg || '') . ")";
295
    Debug2 " using @paths" if ( @paths );
296
 
297
    if ( scalar( @paths ) > 0 ) {
298
        $dir = pop( @paths );                   # search path
299
    } else {
300
        $dir = "";                              # path is absolute
301
    }
302
 
303
    $lc_name = lc( $name );
304
    $uc_name = uc( $name );
305
    do {
306
        $dir .= "/"                             # directory delimitor
307
            if ( $dir ne "" );
308
 
309
        $file = "$dir$path/$name";              # quoted, can be mixed case
310
 
311
        Debug2 " -> $file";
312
 
313
        if ( ! -f $file )
314
        {
315
            $file = "$dir$path/$lc_name";       # lower case
316
            if ( ! -f $file )
317
            {
318
                $file = "$dir$path/$uc_name";   # upper case
319
                $file = ""                      # NO MATCH
320
                    if ( ! -f $file );
321
            }
322
        }
323
    } while ( ($file eq "") &&
324
                ($dir ne "") && ($dir = pop( @paths )) );
325
 
326
    #
327
    #   If the user has defined an error message and the file does not
328
    #   exist, then generate an error message
329
    #
330
    Error("$msg","File: $path/$name not found.")
331
        if ($msg && $file eq "");
332
 
333
    Debug2 " == $file";
334
 
335
    Debug( "Exists:     = $file" );
336
    return $file;
337
}
338
 
339
 
340
#-------------------------------------------------------------------------------
341
#   Require( $path, $name, $msg, [@paths] ) ---
342
#
343
#   Description:
344
#       Case insensitive 'require', see Exists() for usage.
345
#
346
#   Returns:
347
#       Full path of resolved filename.
348
#..
349
 
350
sub Require
351
{
352
    my( $file );
353
 
354
    $file = Exists( @_ );
355
    require $file if ($file);
356
    return $file;
357
}
358
 
359
 
360
#   Require2( \@args, $path, $name, $msg, [@paths] ) ---
361
#       Case insensitive 'require' same as Require(), but allows the
362
#       argument list \@args to passed thru to the included image
363
#       via a localised @_.
364
#
365
#   Returns:
366
#       Full path of resolved filename.
367
#..
368
 
369
sub Require2
370
{
371
    my( $args ) = shift;
372
    my( $file, $result );
373
 
374
    $file = Exists( @_ );
375
    if (exists $::INC{$file}) {
376
        Error( "Included $file has already been loaded." );
377
    }
378
    unless (-f $file) {
379
        Error ("Can't locate the include $file");
380
    } else {
381
        local @_;                               # Include argument vector
382
 
383
        push @_, @$args;
384
        $::INC{$file} = $file;
385
        $result = do $file;                     # exec
386
    }
387
    if ($@) {
388
        $::INC{$file} = undef;
389
        Error ($@);
390
    } elsif (!$result) {
391
        delete $::INC{$file};
392
        Error ("Included $file did not return true value.");
393
    }
394
    return $file;
395
}
396
 
397
 
398
sub RequireTool
399
{
400
    my( $script, @arguments ) = @_;
401
    my( $file );
402
 
403
    Debug2( "RequireTool(@_)" );
404
 
405
    $file = Require( "", $script,
406
                "RequireTool", @::BUILDTOOLSPATH, $::GBE_TOOLS );
407
}
408
 
409
 
410
 
411
 
412
#   Trim( string ) ---
413
#       Trim leading/trailing whitespace
414
#..
415
 
416
sub Trim
417
{
418
    my( $str ) = @_;
419
 
420
    if ( $str )
421
    {
422
        $str =~ s/^\s*//g;                          # leading white space
423
        $str =~ s/\s*(\n|$)//;                      # trailing white space
424
    }
425
    return $str;
426
}
427
 
428
 
429
 
430
#   CommifySeries ---
431
#       Format the array into comma seperate list.
432
#..
433
 
434
sub CommifySeries
435
{
436
    my $sepchar = grep(/,/ => @_) ? ";" : ",";
437
 
438
    (@_ == 0) ? '' :
439
    (@_ == 1) ? $_[0] :
440
    (@_ == 2) ? join(" and ", @_)  :
441
                    join("$sepchar ", @_[0 .. ($#_-1)], "and $_[-1]");
442
}
443
 
444
 
445
1;  #success
446