Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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