Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
227 dpurdie 1
#! perl
2
########################################################################
3
# Copyright ( C ) 2004 ERG Limited, All rights reserved
4
#
5
# Module name   : MugFiles.pl
6
# Module type   : JATS Build System
7
# Compiler(s)   : n/a
8
# Environment(s): jats
9
#
10
# Description   : This is a  JATS toolset extension package
11
#                 The package will add seeral directives to allow the
12
#                 creation of MUG files.
13
#
14
#                 The package is platform independant
15
#
16
# Usage:
17
#
18
# Version   Who      Date        Description
19
#
20
#......................................................................#
21
 
22
require 5.6.1;
23
use strict;
24
use warnings;
25
use File::Basename;
26
use File::Path;
27
use File::Copy;
28
 
29
#
30
#   Global data
31
#
32
my %Tiers;                             # Hash of Tiers already seen
33
my $verbose = 0;
34
 
35
MugInit();
36
 
37
#-------------------------------------------------------------------------------
38
# Function        : MugInit
39
#
40
# Description     : Module initialisation
41
#                   Setup and sanity testing.
42
#                   This function is run automaticlly when the package is loaded
43
#
44
# Inputs          :
45
#
46
# Returns         :
47
#
48
sub MugInit
49
{
50
    #
51
    #   Ensure that required utilities can be located
52
    #
53
    my @not_found;
54
    foreach my $util ( qw(genappa.exe modcrc.exe) )
55
    {
56
        unless ( my $path = ToolExtensionProgram( $util ) )
57
        {
58
            push @not_found, $util;
59
        }
60
    }
61
 
62
    Error ("MugFiles: Required utility programs not found:", @not_found )
63
        if ( @not_found );
64
 
65
}
66
 
67
#-------------------------------------------------------------------------------
68
# Function        : MugFiles
69
#
70
# Description     : Collect MugFile information
71
#                   information
72
#
73
# Inputs          : $1  - platform(s)
74
#                   $*  - an argument list
75
#
76
# Returns         :
77
#
78
 
79
sub MugFiles
80
{
81
    my( $platforms, @elements ) = @_;
82
    my (%muginfo);
83
    my $tier;
84
 
85
    #
86
    #   Is this platform currently active
87
    #
88
    return if ( ! ActivePlatform($platforms) );
89
    DebugPush("MugFiles");
90
 
91
    #
92
    #   Process directive arguments
93
    #
94
    for (@elements)
95
    {
96
        if ( m/^--DeviceId=(.*)/ ) {
97
            $muginfo{'Device'} = $1;
98
 
99
        } elsif ( m/^--Name=(.*)/ ) {
100
            $muginfo{'Name'} = $1;
101
 
102
        } elsif ( m/^--Tier=(.*)/ ) {
103
            $muginfo{'Tier'} = $1;
104
            $tier = $1;
105
 
106
        } elsif ( m/^--Package=(.*)/ ) {
107
            my $package_name = $1;
108
            my @dirs = 'thx';
109
            if ( $package_name =~ m/(.*?),--Subdir=(.*)/ )
110
            {
111
                $package_name = $1;
112
                @dirs = split( ',', $2 );
113
            }
114
 
115
            my $package = LocatePackage( $package_name );
116
            foreach my $subdir ( @dirs )
117
            {
118
                my $dir = "$package->{'ROOT'}/$subdir";
119
                if ( -d $dir )
120
                {
121
                    UniquePush( \@{$muginfo{'Dirs'}}, $dir );
122
                }
123
                else
124
                {
125
                    Warning("Directory not found in package: $package_name, Subdir: $subdir")
126
                        unless ( $subdir eq 'thx' );
127
                }
128
            }
129
            UniquePush( \@{$muginfo{'Dirs'}}, "$package->{'ROOT'}" );
130
 
131
        } elsif ( m/^--Dir=(.*)/ ) {
132
            my $dir = $1;
133
 
134
            Error("Directory not found: $dir") unless ( -d $dir );
135
            UniquePush( \@{$muginfo{'Dirs'}}, $dir );
136
 
137
        } elsif ( m/^--Load=(.*)/ ) {
138
            Error("Multiple Load files specified") if ( $muginfo{'Load'} );
139
            $muginfo{'Load'} = $1;
140
 
141
        } elsif ( m/^--Exclude=(.*)/ ) {
142
            foreach ( split( ',', lc($1)) )
143
            {
144
                $muginfo{'Exclude'}{$_} = 0;
145
            }
146
 
147
 
148
        } elsif ( m/^--ThxDir=(.*)/ ) {
149
            $muginfo{'ThxCopyDir'} = $1;
150
 
151
        } else {
152
            Error("Unknown option: $_ ");
153
        }
154
    }
155
 
156
    #
157
    #   Ensure the user has provided all the parameters
158
    #
159
    Error("No Device specified") unless ( $muginfo{'Device'} );
160
    Error("No Name specified") unless ( $muginfo{'Name'} );
161
    Error("No Tierspecified") unless ( $muginfo{'Tier'} );
162
    Error("No Packages or directories specified") unless ( $muginfo{'Dirs'} );
163
    Error("Duplicated Tier: $tier") if ( exists $Tiers{$tier} );
164
 
165
    #
166
    #   Process Name
167
    #   It MUST be 4 characters padded with '-'
168
    #
169
    my $name = $muginfo{'Name'};
170
    Error( "Name too long. Must be less that 4: $name") if ( length($name) > 4 );
171
    $name .= '----';
172
    $name = substr($name,0,4);
173
    $muginfo{'Name'} = $name;
174
 
175
    $Tiers{$tier} = \%muginfo;
176
 
177
    DebugPop();
178
}
179
 
180
#-------------------------------------------------------------------------------
181
# Function        : MugGenerate
182
#
183
# Description     : Process all the collected data and generate MUG files
184
#
185
#                   Create a genappa.ini file as required for genappa.exe
186
#                   Create load.cmd files as required for genappa.exe
187
#
188
# Inputs          : None
189
#
190
# Returns         : Even less
191
#
192
 
193
sub MugGenerate
194
{
195
    my (@args) = @_;
196
    foreach ( @args )
197
    {
198
        if ( /^--Debug$/ ) {
199
            $verbose++;
200
 
201
        } elsif ( /^--Debug=(\d+)/ ) {
202
            $verbose = $1;
203
 
204
        } else {
205
            Warning("MugFiles: Unknown option: $_");
206
        }
207
    }
208
 
209
    #
210
    #   Set new Debug header and level
211
    #   These will be popped later
212
    #
213
    $verbose = DebugPush("MugGenerate", $verbose);
214
    Debug("Mugfiles: Set Verbosity: $verbose");
215
 
216
    #
217
    #   Determine the system version
218
    #   This is based on the Build Version ( XX.YY.ZZ )
219
    #   This is massaged into the required system version, which is required
220
    #   in two forms:
221
    #       1) As hex XX.YY
222
    #       2) As the decimal version of 1)
223
    #
224
    #   The version is held in two bytes so it is limited
225
    #
226
    my @versions = split( /\./, $::ScmBuildVersion );
227
    Error ("MugFiles: Cannot encode versions with a patch number: $::ScmBuildVersion",
228
            "Major: $versions[0]",
229
            "Minor: $versions[1]",
230
            "Patch: $versions[2]")
231
        if ( $versions[2] > 0 ) ;
232
 
233
    my $version_hex = $versions[0] * 100 + $versions[1];
234
    my $version_decimal = hex $version_hex;
235
    Debug ("MugSet version: $version_decimal, HEX:$version_hex");
236
 
237
    #
238
    #   Create the list of THX files to be used for each device
239
    #   These files are calculated by:
240
    #       Merging all the THX files in the specified packages
241
    #       Excluding the specified files
242
    #
243
    foreach my $mugref ( values %Tiers )
244
    {
245
 
246
        #
247
        #   If the user has specified a load file, then use it to provide
248
        #   the complete list of files to load
249
        #
250
        if ( $mugref->{'Load'} )
251
        {
252
            ReadLoadFile( $mugref, LocateLoadFile( $mugref, $mugref->{'Load'} ));
253
        }
254
 
255
        my %files_found;
256
        my @ffiles;
257
        foreach my $dir ( @{$mugref->{'Dirs'}} )
258
        {
259
            #
260
            #   Locate the THX files within the package ( directory )
261
            #   Exclude any user specified files
262
            #
263
            my @files = glob( "$dir/*.thx" );
264
            Debug("Searching for THX files in directory: $dir");
265
            foreach  ( @files )
266
            {
267
                my $base = lc(basename($_));
268
 
269
                #
270
                #   Include only loaded files
271
                #
272
                if ( exists $mugref->{'LoadList'} )
273
                {
274
                    next unless( exists $mugref->{'LoadList'}{$base} );
275
                    $mugref->{'LoadList'}{$base}++;
276
                }
277
 
278
                #
279
                #   Skip excluded files
280
                #
281
                if ( exists $mugref->{'Exclude'}{$base} )
282
                {
283
                    $mugref->{'Exclude'}{$base}++;
284
                    Debug2 ("   Excluding: $base");
285
                    next;
286
                }
287
 
288
                #
289
                #   Test for duplicated files
290
                #
291
                if ( exists($files_found{$base}) )
292
                {
293
                    Warning("Multiple instances a file ignored: $base",
294
                            "Using file: $files_found{$base}",
295
                            "Ignoring  : $_");
296
                    next;
297
                }
298
                $files_found{$base} = $_;
299
 
300
                push @ffiles, $_;
301
                Debug2 ("   File: $_");
302
 
303
            }
304
        }
305
        $mugref->{'Files'} = \@ffiles;
306
 
307
        #
308
        #   If using a Load file then reprocess the complete file list
309
        #   to retain only those
310
 
311
 
312
        #
313
        #   Report excluded files that were not excluded
314
        #
315
        foreach ( keys %{$mugref->{'Exclude'}} )
316
        {
317
            next if ( $mugref->{'Exclude'}{$_} );
318
            Warning ("Excluded THX file not encountered: $_" );
319
        }
320
 
321
        #
322
        #   Report loaded files that are not located
323
        #
324
        my @not_nice;
325
        foreach ( keys %{$mugref->{'LoadList'}} )
326
        {
327
            next if ( $mugref->{'LoadList'}{$_} );
328
            push @not_nice, $_;
329
        }
330
        Error ("Incomplete THX file set. Missing files", @not_nice)
331
            if ( $#not_nice >= 0 );
332
 
333
 
334
        #
335
        #   Generate the loadfull.ini file
336
        #   This file simply contains the full path names to all THXs
337
        #   Unique INI files will be created in the "interface" directory
338
        #
339
        my $loadname = "$::ScmRoot/$::ScmInterface/load_$mugref->{'Tier'}.ini";
340
        $mugref->{'IniName'} = $loadname;
341
 
342
        Debug("Generating loadfile: $loadname" );
343
        open (INI, ">$loadname" ) || Error ("Cannot create: $loadname" );
344
        foreach ( @{$mugref->{'Files'}} )
345
        {
346
            (my $dos_path = $_) =~ s~/~\\~g;
347
            print INI "e=o:$dos_path\n";
348
        }
349
        close INI;
350
 
351
 
352
        #
353
        #   Transfer THX files into the package
354
        #
355
        if ( $mugref->{'ThxCopyDir'} )
356
        {
357
            my $thxdir = "$::ScmRoot/pkg/$::ScmBuildPackage/thx/$mugref->{'ThxCopyDir'}";
358
            $thxdir =~ s/-$//g;
359
            Debug("THX files will be placed in: $thxdir" );
360
            mkpath( $thxdir );
361
            foreach ( @{$mugref->{'Files'}}, @{$mugref->{'LoadFiles'}} )
362
            {
363
                Debug2("Copy Thx: $_" );
364
                copy($_ ,$thxdir);
365
            }
366
        }
367
 
368
        DebugDumpData("Processed Mug", $mugref)
369
            if $verbose > 2;
370
    }
371
 
372
    #
373
    #   Create the master genappi.ini file
374
    #   This file will be created in the interface directory
375
    #
376
    my $genappa = "$::ScmRoot/$::ScmInterface/genappa.ini";
377
    Debug("Generating genappa control file: $genappa" );
378
    open (INI, ">$genappa" ) || Error ("Cannot create: $genappa" );
379
 
380
    #
381
    #   Insert the header
382
    #
383
    print INI "[Header]\n";
384
    print INI "SystemVer                = ",$version_hex, "\n";
385
    print INI "NumDevTypes              = ", scalar keys %Tiers, "\n";
386
    print INI "\n";
387
 
388
    #
389
    #   Insert per device information
390
    #   This is performed in reverse Tier order
391
    #
392
    my $device_number = 0;
393
    foreach my $tier ( reverse sort keys %Tiers )
394
    {
395
        $device_number++;
396
        my $mugref = $Tiers{$tier};
397
 
398
        print INI "[DeviceType$device_number]\n";
399
        print INI "Name                     = ", $mugref->{'Name'}, "\n";
400
        print INI "Id                       = ", $mugref->{'Device'}, "\n";
401
        print INI "Ver                      = ", $version_decimal, "\n";
402
        print INI "Tier                     = ", $mugref->{'Tier'}, "\n";
403
        print INI "ModulesPath              = ", $mugref->{'IniName'}, "\n";
404
        print INI "ScanMemBackupSuper       = N\n";
405
        print INI "ScanMemBackupUserSuper   = N\n";
406
        print INI "ScanMemFlashSuper        = Y\n";
407
        print INI "ScanMemFlashUserSuper    = Y\n";
408
        print INI "\n";
409
    }
410
 
411
    #
412
    #   Insert options
413
    #
414
    print INI "[Options]\n";
415
    print INI "SuppressCDHeader         = TRUE\n";
416
    print INI "\n";
417
 
418
 
419
    close INI;
420
 
421
    #
422
    #   Run the GENAPPA utility
423
    #   This will create a directory full of MUG files
424
    #   Generate the files directly into the pkg subdirectory
425
    #
426
    my $mugdir = "$::ScmRoot/pkg/$::ScmBuildPackage/mug";
427
    Debug("Mugfiles will be placed in: $mugdir" );
428
    mkpath( $mugdir );
429
 
430
    #
431
    #   Extend the PATH to include the toolset extensions
432
    #   to allow use to find genappa and modcrc
433
    #
434
    my $PATH = join ';', ToolExtensionPaths(), $ENV{'PATH'};
435
    $ENV{'PATH'} = $PATH;
436
 
437
    my $opts = ($verbose > 1) ? " -d" : "";
438
    Debug( "Running GENAPPA");
439
    System( "genappa $genappa$opts -o $mugdir" ) && Error( "Problem running genappa" );
440
 
441
    #
442
    #   Cleanup the debugging interface
443
    #
444
    DebugPop();
445
}
446
 
447
#-------------------------------------------------------------------------------
448
# Function        : LocateLoadFile
449
#
450
# Description     : Locate a specified loadfile
451
#
452
# Inputs          : $mugref         - Per device Data store
453
#                   $cmdfile        - The full path to the load file
454
#
455
# Returns         : Path to the load file
456
#                   Will not return on error
457
#
458
sub LocateLoadFile
459
{
460
    my( $mugref, $cmdfile) = @_;
461
    my @load_list;
462
    #
463
    #   Has the load file been sourced
464
    #
465
    Debug ("   Locate command file: $cmdfile");
466
    push @load_list, $::SRCS{$cmdfile}
467
        if ( exists $::SRCS{$cmdfile} && -f $::SRCS{$cmdfile} );
468
 
469
    #
470
    #   The load file must exist in one of the packages or directories
471
    #   Locate the file and warn if multiple files are found
472
    #
473
    foreach my $dir ( @{$mugref->{'Dirs'}} )
474
    {
475
        my $path = "$dir/$cmdfile";
476
        Debug2 ("   Locate command file. Try: $path");
477
        push @load_list, $path if ( -f $path );
478
    }
479
 
480
    Error ("Load file not found in any package or directory: $cmdfile")
481
        unless ( $#load_list >= 0 );
482
 
483
    Warning ("Multiple load files found. The first one will be used",
484
             @load_list ) if( $#load_list > 0) ;
485
 
486
    #
487
    #   Return the full path to the first loadfile located
488
    #
489
    return $load_list[0];
490
}
491
 
492
#-------------------------------------------------------------------------------
493
# Function        : ReadLoadFile
494
#
495
# Description     : Read and Process a load.cmd file
496
#                   This file will provide the complete list of files to be
497
#                   mugged
498
#
499
# Inputs          : $mugref         - Per device Data store
500
#                   $cmdfile        - The full path to the load file
501
#
502
# Returns         :
503
#
504
sub ReadLoadFile
505
{
506
    my( $mugref, @cmdfile) = @_;
507
    my %filelist;
508
    my %seen;
509
 
510
    while ( @cmdfile )
511
    {
512
        my $cmdfile = pop( @cmdfile );
513
        $cmdfile =~ tr~\\/~/~s;
514
        $seen{$cmdfile} = 1;
515
        push @{$mugref->{'LoadFiles'}}, $cmdfile;
516
 
517
        Debug ("Reading load file: $cmdfile");
518
 
519
        #
520
        #   Process the cmdfile and extract the names of files to transfer
521
        #   Extract data of the form
522
        #       e=o:pathname
523
        #       f=pathname
524
        #
525
        open (CMD, "<$cmdfile") || Error ("Cannot open command file: $cmdfile" );
526
        while ( <CMD> )
527
        {
528
            #
529
            #   Clean up whitespace and comments
530
            #
531
            chomp;
532
            s~^\s*~~;
533
            s~\*.*$~~;
534
            s~\s*$~~;
535
            next if ( length( $_) <= 0 );
536
 
537
            #
538
            #   Clean pathnames
539
            #
540
            tr~\\/~/~s;
541
 
542
            if ( m/e=o:(.*)/ )
543
            {
544
                    #
545
                    #   Ignore any path information
546
                    #       - Its not valid within the context of the package
547
                    #   Process excluded files
548
                    #
549
                    my $file = lc StripDir($1);
550
                    if ( exists $mugref->{'Exclude'}{$file} )
551
                    {
552
                        $mugref->{'Exclude'}{$file}++;
553
                        Debug2 ("   Excluding: $file");
554
                    }
555
                    else
556
                    {
557
                        Debug2 ("   Entry: $file");
558
                        $filelist{$file} = 0;
559
                    }
560
 
561
            } elsif ( m/f=(.*)/ )
562
            {
563
                my $file = lc StripDir($1);
564
                Debug2 ("   Included load file: $file");
565
 
566
                $file = LocateLoadFile($mugref, $file );
567
 
568
                Error ("Load file already processed: $file")
569
                    if ( exists $seen{ $file } );
570
 
571
                unshift @cmdfile, $file;
572
                $seen{$file} = 1;
573
            }
574
        }
575
        close( CMD );
576
    }
577
 
578
    $mugref->{'LoadList'} = \%filelist;
579
 
580
}
581
 
582
#-------------------------------------------------------------------------------
583
# Function        : LocatePackage
584
#
585
# Description     : Locate a package entry
586
#
587
# Inputs          : $pname          - Name of the package
588
#
589
# Returns         : Ref to package data
590
#
591
sub LocatePackage
592
{
593
    my($pname) = @_;
594
 
595
    #
596
    #   Locate the Package
597
    #
598
    my $packagebase = $::ScmBuildPkgRules{$::ScmPlatform};
599
    my $package;
600
 
601
    foreach my $pptr ( @{$packagebase} )
602
    {
603
        if ( $pptr->{'NAME'} eq $pname )
604
        {
605
            $package = $pptr;
606
            last;
607
        }
608
    }
609
 
610
    Error("Required Package cannot be located: $pname") unless ( $package );
611
    return $package;
612
}
613
 
614
 
615
 
616
1;