Subversion Repositories DevTools

Rev

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

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