Subversion Repositories DevTools

Rev

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