Subversion Repositories DevTools

Rev

Go to most recent revision | Details | 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
{
283 dpurdie 102
    my $args = JatsError::ArgsToString( \@_);
227 dpurdie 103
    my $fname = $::AUTOLOAD;
104
    $fname =~ s~^\w+::~~;
105
    my ($package, $filename, $line) = caller;
106
 
107
    Error ("Directive not known or not allowed in this context: $fname",
283 dpurdie 108
           "Directive: $fname( $args );",
227 dpurdie 109
           "File: $filename, Line: $line" );
110
}
111
 
112
#-------------------------------------------------------------------------------
113
# Function        : ConfigLoad
114
#
115
# Description     : Loads the global configuration details
116
#                   Details are held within the interface directory in "build.cfg"
117
#
118
# Inputs          : None
119
#
120
# Returns         : Nothing
121
#                   Will populate the global environment space with the contents
122
#                   of the build.cfg file. These variables may need to be access
123
#                   with the :: syntax ($::Variable)
124
#
125
#                   This function will remove lumps of the configuration that
126
#                   are not needed by the current platform simply to reduce the
127
#                   data retaied in other config files.
128
#
129
#
130
sub ConfigLoad
131
{
132
   ReadBuildConfig("$::ScmRoot/$::ScmInterface", $::ScmPlatform );
133
}
134
 
135
 
136
#   ExpandPlatforms ---
137
#       Expand a platform list applying aliases.
138
#..
139
 
140
sub ExpandPlatforms
141
{
142
    our( @_expandarg ) = @_;
143
    our( @_expandresult, $_expandnest );
144
 
145
    @_expandresult = ();
146
    $_expandnest = 0;
147
 
148
    Debug3( "ExpandPlatforms(@_)" );
149
 
150
    sub ExpandPlatform
151
    {
152
        sub ExpandAlias
153
        {
154
            my( $key ) = @_;
155
 
369 dpurdie 156
            if (%::BUILDALIAS)         # buildlib.pl
227 dpurdie 157
            {
158
                return ExpandPlatform( split( ' ', $::BUILDALIAS{ $key } ) )
159
                    if ( $key !~ /^--/ && $::BUILDALIAS{ $key } );
160
            }
161
            else
162
            {
163
                return $key                     # argument || no aliases
369 dpurdie 164
                    if ( $key =~ /^--/ || !(%::ScmBuildAliases) );
227 dpurdie 165
 
166
                return ExpandPlatform( split( ' ', $::ScmBuildAliases{ $key } ) )
167
                    if ( $::ScmBuildAliases{ $key } );
168
            }
169
 
170
            return $key;
171
        }
172
 
173
        sub ExpandPush
174
        {
175
            my( $pResult, $operator, $pPlatforms, @arguments ) = @_;
176
 
177
            foreach my $platform ( @$pPlatforms )
178
            {                                   # unfold arguments
179
                push( @$pResult, $operator.$platform );
180
                next if ( $platform =~ /^--/ );
181
                push( @$pResult, @arguments );
182
            }
183
        }
184
 
185
        Error( "ExpandPlatforms( @_expandarg ) nesting error.",
186
               "",
187
               "Check for recursive definitions within the follow directives",
188
               "       - BuildAlias and BuildProduct."
189
             ) if ( $_expandnest++ > 42 );
190
 
191
        my( @result, $operator, @platforms, @arguments ) = ();
192
 
193
        Debug3( "  +$_expandnest: @_ " );
194
 
195
        foreach my $arg ( @_ ) {
196
            if ( $arg =~ /^--/ ) {              # argument, accumulate
197
                push( @arguments, $arg );
198
 
199
            } else {                            # group, product or platform
200
                ExpandPush( \@result, $operator, \@platforms, @arguments );
201
 
202
                if ( ($operator = substr($arg, 0, 1)) eq "!" ) {
203
                    @platforms = ExpandAlias( substr($arg, 1) );
204
                } else {
205
                    $operator = "";
206
                    @platforms = ExpandAlias( $arg );
207
                }
208
                @arguments = ();
209
            }
210
        }
211
        ExpandPush( \@result, $operator, \@platforms, @arguments );
212
 
213
        $_expandnest--;
214
        Debug3( "  -$_expandnest: @result" );
215
        return @result;
216
    }
217
 
218
    ############################################################################
219
    #   Function body
220
    #
221
 
222
    foreach (@_expandarg) {                      # break out embedded args
223
        if ( /^--/ ) {
224
            push @_expandresult, $_;
225
 
226
        } else {
227
 
228
            push @_expandresult, split( ',', $_ );
229
        }
230
    }
231
 
232
    @_expandresult = ExpandPlatform( @_expandresult );
233
    Debug2( "ExpandPlatforms(@_expandarg) = @_expandresult" );
234
    return @_expandresult;
235
}
236
 
237
#-------------------------------------------------------------------------------
238
# Function        : Exists( $path, $name, $msg, [@paths] ) ---
239
#
240
# Description     : Case insensitive 'exists'.
241
#
242
# Inputs          :
243
#       $path       Represents either the absolute path of the file
244
#                   named 'name' in the case of @path being an empty
245
#                   list, or the subdir appended to each entry
246
#                   contained within the @paths list.
247
#
248
#       $name       The file name
249
#
250
#       $desc       Text used to describe the file upon the image
251
#                   not being found.
252
#
253
#       @paths      Optional list of paths to be searched.
254
#
255
# Returns         : Full path of resolved filename, otherwise nothing.
256
#
257
#   Examples:
258
#
259
#       a)  Exists( "/mypath", "Myfile", "stuff" );
260
#
261
#           Resolve the name of the file called "myfile" within the
262
#           directory "/mypath", using the following matching order
263
#
264
#               1.  "/mypath/Myfile".       As supplied.
265
#               2.  "/mypath/myfile".       then Lower case
266
#               3.  "/mypath/MYFILE".       and finally upper case.
267
#
268
#           Upon being not found displays the message
269
#
270
#               "stuff (/mypath/Myfile) not found".
271
#
272
#       b)  @paths = ( '/dir1', '/dir2' );
273
#           Exists( "cfg", "Myfile", "stuff", @paths );
274
#
275
#           Resolve the name of the file called "Myfile" within the
276
#           set of directories "/dir1/cfg/" and "/dir2/cfg/", using
277
#           the following matching order:
278
#
279
#               1.  "/dir1/cfg/Myfile".
280
#               2.  "/dir1/cfg/myfile".
281
#               3.  "/dir1/cfg/MYFILE".
282
#               4.  "/dir2/cfg/Myfile".
283
#               5.  "/dir2/cfg/myfile".
284
#               6.  "/dir2/cfg/MYFILE".
285
#
286
#           Upon being not found displays the message
287
#
288
#               "stuff (cfg/Myfile) not found".
289
#
290
sub Exists
291
{
292
    my( $path, $name, $msg, @paths ) = @_;
293
    my( $dir, $file, $lc_name, $uc_name );
294
 
295
    Debug2 "Searching for $path/$name (" . ($msg || '') . ")";
296
    Debug2 " using @paths" if ( @paths );
297
 
298
    if ( scalar( @paths ) > 0 ) {
299
        $dir = pop( @paths );                   # search path
300
    } else {
301
        $dir = "";                              # path is absolute
302
    }
303
 
304
    $lc_name = lc( $name );
305
    $uc_name = uc( $name );
306
    do {
307
        $dir .= "/"                             # directory delimitor
308
            if ( $dir ne "" );
309
 
310
        $file = "$dir$path/$name";              # quoted, can be mixed case
311
 
312
        Debug2 " -> $file";
313
 
314
        if ( ! -f $file )
315
        {
316
            $file = "$dir$path/$lc_name";       # lower case
317
            if ( ! -f $file )
318
            {
319
                $file = "$dir$path/$uc_name";   # upper case
320
                $file = ""                      # NO MATCH
321
                    if ( ! -f $file );
322
            }
323
        }
324
    } while ( ($file eq "") &&
325
                ($dir ne "") && ($dir = pop( @paths )) );
326
 
327
    #
328
    #   If the user has defined an error message and the file does not
329
    #   exist, then generate an error message
330
    #
331
    Error("$msg","File: $path/$name not found.")
332
        if ($msg && $file eq "");
333
 
334
    Debug2 " == $file";
335
 
336
    Debug( "Exists:     = $file" );
337
    return $file;
338
}
339
 
340
 
341
#-------------------------------------------------------------------------------
342
#   Require( $path, $name, $msg, [@paths] ) ---
343
#
344
#   Description:
345
#       Case insensitive 'require', see Exists() for usage.
346
#
347
#   Returns:
348
#       Full path of resolved filename.
349
#..
350
 
351
sub Require
352
{
353
    my( $file );
354
 
355
    $file = Exists( @_ );
356
    require $file if ($file);
357
    return $file;
358
}
359
 
360
 
361
#   Require2( \@args, $path, $name, $msg, [@paths] ) ---
362
#       Case insensitive 'require' same as Require(), but allows the
363
#       argument list \@args to passed thru to the included image
364
#       via a localised @_.
365
#
366
#   Returns:
367
#       Full path of resolved filename.
368
#..
369
 
370
sub Require2
371
{
372
    my( $args ) = shift;
373
    my( $file, $result );
374
 
375
    $file = Exists( @_ );
376
    if (exists $::INC{$file}) {
377
        Error( "Included $file has already been loaded." );
378
    }
379
    unless (-f $file) {
380
        Error ("Can't locate the include $file");
381
    } else {
382
        local @_;                               # Include argument vector
383
 
384
        push @_, @$args;
385
        $::INC{$file} = $file;
386
        $result = do $file;                     # exec
387
    }
388
    if ($@) {
389
        $::INC{$file} = undef;
390
        Error ($@);
391
    } elsif (!$result) {
392
        delete $::INC{$file};
393
        Error ("Included $file did not return true value.");
394
    }
395
    return $file;
396
}
397
 
398
 
399
sub RequireTool
400
{
401
    my( $script, @arguments ) = @_;
402
    my( $file );
403
 
404
    Debug2( "RequireTool(@_)" );
405
 
406
    $file = Require( "", $script,
407
                "RequireTool", @::BUILDTOOLSPATH, $::GBE_TOOLS );
408
}
409
 
410
 
411
 
412
 
413
#   Trim( string ) ---
414
#       Trim leading/trailing whitespace
415
#..
416
 
417
sub Trim
418
{
419
    my( $str ) = @_;
420
 
421
    if ( $str )
422
    {
423
        $str =~ s/^\s*//g;                          # leading white space
424
        $str =~ s/\s*(\n|$)//;                      # trailing white space
425
    }
426
    return $str;
427
}
428
 
429
 
430
 
431
#   CommifySeries ---
432
#       Format the array into comma seperate list.
433
#..
434
 
435
sub CommifySeries
436
{
437
    my $sepchar = grep(/,/ => @_) ? ";" : ",";
438
 
439
    (@_ == 0) ? '' :
440
    (@_ == 1) ? $_[0] :
441
    (@_ == 2) ? join(" and ", @_)  :
442
                    join("$sepchar ", @_[0 .. ($#_-1)], "and $_[-1]");
443
}
444
 
445
 
446
1;  #success
447