Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
4778 dpurdie 1
########################################################################
6177 dpurdie 2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
4778 dpurdie 3
#
4
# Module name   : jats_runutf.pm
5
# Module type   : JATS Utility
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   : JATS Make Time Test Harness Support
10
#                 This package contains fucntions that will be used by JATS
11
#                 to invoke the tests.
12
#
13
#                 This is more powerful that the previous shell-based solution
14
#                 that had problems under windows.
15
#
16
#                 The functions are designed to be invoked as:
17
#                   $(GBE_PERL) -Mjats_runutf -e <function> -- <args>+
18
#
19
#                 The functions in this packages are designed to take parameters
20
#                 from @ARVG as this makes the interface easier to read.
21
#
22
# Usage         : See POD at the end of this file
23
#
24
#......................................................................#
25
 
26
require 5.008_002;
27
use strict;
28
use warnings;
29
 
30
package jats_runutf;
31
 
32
our (@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $VERSION);
33
use Exporter;
34
use JatsError qw(:name=jats_runutf);
4780 dpurdie 35
use Pod::Usage;                             # required for help support
4778 dpurdie 36
use Getopt::Long;
37
use File::Spec;
5035 dpurdie 38
use XML::Simple;
4778 dpurdie 39
 
40
$VERSION = 1.00;
41
@ISA = qw(Exporter);
42
 
43
# Symbols to autoexport (:DEFAULT tag)
4780 dpurdie 44
@EXPORT = qw( processUtf help man );
4778 dpurdie 45
 
46
#
47
#   Global Variables
48
#
49
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
4780 dpurdie 50
my $opt_help = 0;
4778 dpurdie 51
 
52
#   Data to be passed into the filter function
53
#   Defined values are:
4781 dpurdie 54
#       ARGS            - An hash of user arguments
55
#       DIR             - Optional. Name of test subdir
4778 dpurdie 56
#       FILTER          - Name of the filter 
4781 dpurdie 57
#       IDIR            - Path to original directory
4778 dpurdie 58
#       INTERFACE       - Abs Path to Interface directory
59
#       LOCAL           - Abs Path to Local directory
60
#       OUTDIR          - Abs Path to output directory
4780 dpurdie 61
#       OUTFILE         - Abs Path to suggested output file
4778 dpurdie 62
#       PKGDIR          - Abs Path to Packaging directory
63
#       ROOT            - Abs Path to Root of the build
64
#       TARGET          - Current make target
65
#       TYPE            - Built type P or D
5387 dpurdie 66
#       UTFUID          - Unique Test Identifier
4781 dpurdie 67
#       UTFNAME         - Test Name
6619 dpurdie 68
#       UTFTEST         - Recommended file root for test results
5035 dpurdie 69
#       UTFRC           - Result Code from Unit Test run
6898 dpurdie 70
#       RCFILE          - Path to the RC File (optional)
4778 dpurdie 71
#
4780 dpurdie 72
our %filterData;
4778 dpurdie 73
 
4780 dpurdie 74
#-------------------------------------------------------------------------------
75
# Function        : help
76
#                   man 
77
#
78
# Description     : Utility functions to make is easier for users to get POD
79
#                   from this module
80
#
81
# Inputs          : 
82
#
83
# Returns         : 
84
#
4778 dpurdie 85
 
4780 dpurdie 86
sub help
87
{
88
    pod2usage(-verbose => 0, -input =>  __FILE__);
89
}
90
 
91
sub man
92
{
93
    pod2usage(-verbose => 2, -input =>  __FILE__);
94
}
95
 
4778 dpurdie 96
#-------------------------------------------------------------------------------
97
# Function        : processUtf  
98
#
99
# Description     : Main function to process UTF results
4787 dpurdie 100
#                   This function will locate a suitable filter process and invoke
101
#                   it to process the results
4778 dpurdie 102
#
4787 dpurdie 103
#                   The filter process will be provided in a Perl Module
4778 dpurdie 104
#                   It may be a part of JATS or an external modules provided
4787 dpurdie 105
#                   within an external package. ie(utf may provide its own filter)
4778 dpurdie 106
#
4787 dpurdie 107
#
4778 dpurdie 108
# Inputs          : None. Parameters are passed via @ARGV
109
#
110
# Returns         : Nothing
111
#
112
 
113
sub processUtf
114
{
4780 dpurdie 115
    my $argCount = scalar @ARGV;
4778 dpurdie 116
    my $result = GetOptions (
4780 dpurdie 117
                    "help|h:+"      => \$opt_help,
118
                    "manual:3"      => \$opt_help,
4778 dpurdie 119
                    "verbose:+"     => \$opt_verbose,       # Only set to to 0,1 or 3
4780 dpurdie 120
                    "root=s"        => \$filterData{ROOT},
121
                    "filter=s"      => \$filterData{FILTER},
122
                    "interface=s"   => \$filterData{INTERFACE},
123
                    "local=s"       => \$filterData{LOCAL},
124
                    "target=s"      => \$filterData{TARGET},
125
                    "pkgdir=s"      => \$filterData{PKGDIR},
126
                    "type=s"        => \$filterData{TYPE},
4781 dpurdie 127
                    "dir=s"         => \$filterData{DIR},
6898 dpurdie 128
                    "rcfile=s"      => \$filterData{RCFILE},
129
                    "arg=s"         => sub {my ( $key, $value) = split('=', $_[1], 2); $filterData{ARGS}{uc $key} = $value;},
4778 dpurdie 130
                    );
131
 
4780 dpurdie 132
    pod2usage(-verbose => 0, -input =>  __FILE__) if ($opt_help == 1 || ! $result || $argCount < 1);
133
    pod2usage(-verbose => 1, -input =>  __FILE__) if ($opt_help == 2 );
134
    pod2usage(-verbose => 2, -input =>  __FILE__) if ($opt_help  > 2);
135
 
4778 dpurdie 136
    #   Reconfigure the verbosity level
137
    ErrorConfig( 'verbose', $opt_verbose);
4780 dpurdie 138
    Error("Internal: No Filter specified") unless defined $filterData{FILTER};
139
    Error("Internal: No PkgDir specified") unless defined $filterData{PKGDIR};
4778 dpurdie 140
 
141
    #
142
    #   Locate the required filter module
143
    #   Filter modules have a name of the form:
144
    #       UtfFilter_<FilterName>.pm
145
    #   And can be located:
146
    #       within JATS
147
    #           in 'TOOLS/LIB'
148
    #       within a Package declared
149
    #           with a BuildPkgArchive or a LinkPkgArchive
150
    #           within the packages 'tools/scripts' subdirectory
151
    #       within the current package
4996 dpurdie 152
    #           Perl modules with ROOT/gbe/utfFilters
4778 dpurdie 153
    #                         or in the current directory
154
 
4787 dpurdie 155
    my $module_name = join('_','UtfFilter', lc $filterData{FILTER});
4778 dpurdie 156
    Verbose("Filter Module: $module_name");
157
 
158
    #   Extend Perl Module search path for package-local filters
159
    #   Check the current directory
160
    #       The current directory is also within @INC, but it is at the end
161
    #       thus local filter will not override external filters. Place the
162
    #       current directory first - if it conatins a filter.
163
 
164
    if (-f "$module_name.pm" )
165
    {
166
        Verbose("Extend the filter module search path: Current Directory");
167
        unshift @INC, '.';
168
    }
169
    else
170
    {
171
        #
172
        #   Check package-local directory
173
        #       <root>/gbe/utfFilters
174
        #
4780 dpurdie 175
        my $localUtfPath = File::Spec->catfile($filterData{ROOT}, 'gbe', 'utfFilters');
4778 dpurdie 176
        if ( -f( "$localUtfPath/$module_name.pm") )
177
        {
178
            Verbose("Extend the filter module search path: $localUtfPath");
179
            unshift @INC, $localUtfPath;
180
        }
181
    }
182
 
183
    #
184
    #   Locate a Perl Module of the required name
185
    #
186
    eval "require $module_name";
187
    if ($@)
188
    {
189
        Error ("Could not load required filter module: $module_name");
190
    }
191
 
192
    #
193
    #   Ensure that the filter contains the required interface methods
194
    #
195
    foreach my $fname ( qw(processUtf))
196
    {
197
        ReportError("Required function DOES NOT exist: $fname")
198
            unless (defined($module_name->can($fname)));
199
    }
200
    ErrorDoExit();
201
 
202
    #
203
    #   Convert potentially local paths to absolute paths
204
    #       Simplifies use when the CWD is changed
205
    #
206
    foreach my $entry ( qw(INTERFACE LOCAL PKGDIR ROOT))
207
    {
4780 dpurdie 208
        $filterData{$entry}  = File::Spec->rel2abs($filterData{$entry} );
4778 dpurdie 209
    }
210
 
211
    #
212
    #   Add in known values from the environment
213
    #
4780 dpurdie 214
    $filterData{TYPE} = $ENV{'GBE_MAKE_TYPE'};
215
    Error("Internal: EnvVar 'GBE_MAKE_TYPE' not specified") unless $filterData{TYPE};
4778 dpurdie 216
 
5387 dpurdie 217
    $filterData{UTFUID} = $ENV{'GBE_UTFUID'};
218
    Error("Internal: EnvVar 'GBE_UTFUID' not specified") unless $filterData{UTFUID};
4781 dpurdie 219
 
220
    $filterData{UTFNAME} = $ENV{'GBE_UTFNAME'};
221
    Error("Internal: EnvVar 'GBE_UTFNAME' not specified") unless $filterData{UTFNAME};
222
 
4996 dpurdie 223
    $filterData{OUTFILE} = $ENV{'GBE_UTFFILE'};
224
    Error("Internal: EnvVar 'GBE_UTFFILE' not specified") unless $filterData{OUTFILE};
225
 
6619 dpurdie 226
    $filterData{UTFTEST} = $ENV{'GBE_UTFTEST'};
227
    Error("Internal: EnvVar 'GBE_UTFTEST' not specified") unless $filterData{UTFTEST};
228
 
4781 dpurdie 229
    $filterData{IDIR} = File::Spec->rel2abs('.');
230
 
4778 dpurdie 231
    #
4996 dpurdie 232
    # The environment provides a recommended (unqiue) output file
233
    #   Extact the directory part and ensure that it exists
234
    #   Brute file filename chop
4778 dpurdie 235
    #
4996 dpurdie 236
    $filterData{OUTDIR} = $filterData{OUTFILE};
237
    $filterData{OUTDIR} =~ s~/[^/]*$~~;
238
    Error("Internal: OUTDIR is empty") unless (length($filterData{OUTDIR}) > 1);
4778 dpurdie 239
 
4996 dpurdie 240
    mkdir $filterData{OUTDIR};
241
    Error("Creating utfResults directory", "Path: $filterData{OUTDIR}") unless -d $filterData{OUTDIR};
242
 
4781 dpurdie 243
    #   Allow the output file to be used
244
    #       Not in the build system, but in a user development area
4996 dpurdie 245
    #
246
    my $filename = $filterData{OUTFILE};
4781 dpurdie 247
    unlink $filename if -e $filename;
4996 dpurdie 248
    Error("Output file: Cannot delete $filename: $!") if -e $filename;
249
    Verbose("Writing output to: $filename");
4778 dpurdie 250
 
251
    #
5035 dpurdie 252
    #   Recover the result code of the unit test run
7219 dpurdie 253
    #   Do this before changing directory as the paths are relative
5035 dpurdie 254
    #
6898 dpurdie 255
    if (defined $filterData{RCFILE}) {
256
        my $rcFile = $filterData{RCFILE};
257
        Verbose("Result Code File:", $rcFile);
258
        if (-f $rcFile)
259
        {
260
            open( my $rcFile, '<', $rcFile) || Error ("Cannot open file : $!");
261
            $filterData{UTFRC} = <$rcFile>;
262
            $filterData{UTFRC} =~ s~\s+$~~;
263
            $filterData{UTFRC} =~ s~^\s+~~;
264
            Verbose("Recover Result Code: ", $filterData{UTFRC});
265
            close $rcFile;
266
        } else {
267
            Error("ResultCode file specified, but not found: $rcFile");
268
        }
7219 dpurdie 269
    }
270
 
5035 dpurdie 271
    #
7219 dpurdie 272
    #   Change to the test directory
273
    #       Only if required
274
    #       Ensure that the specified directory exists
275
    #
276
    if (defined $filterData{DIR})
277
    {
278
        Verbose("Change directory:", $filterData{DIR});
279
        Error("Internal: Test directory does not exist: $filterData{DIR}")
280
            unless (-d $filterData{DIR});
281
        chdir $filterData{DIR} || Error("Internal: Could not chdir to: $filterData{DIR}");
282
    }
283
 
284
    #
4780 dpurdie 285
    #   Diagnostics
286
    #
287
    if (IsVerbose(1))
288
    {
289
        DebugDumpData("Filter Parameters", \%filterData);
290
    }
291
 
292
    #
4778 dpurdie 293
    #   Invoke the process method
294
    #   If it has a problem it should use 'Error(...)' to report it
4996 dpurdie 295
    #   There is no exit code processing, but if there is - needs to be false
4778 dpurdie 296
    #
4780 dpurdie 297
    Message("Processing UTF test results using filter: $filterData{FILTER}");
4996 dpurdie 298
    my $rv = $module_name->processUtf(\%filterData);
299
    Error ("Unit Test Failure: Errors detected in the result set")
300
        if ( defined($rv) && ! $rv );
4778 dpurdie 301
}
302
 
5035 dpurdie 303
#-------------------------------------------------------------------------------
304
# Function        : Write XML 
305
#
306
# Description     : Write user XML results to file
307
#                   Will insert standard data
308
#
309
# Inputs          : $options    - Ref to a hash of options
310
#                   $results    - Ref to an array of results
311
#                                 Expect a ref to an array of Hash Values
312
#
313
# Returns         : Nothing 
314
#
315
sub writeXmlResults
316
{
317
    my ($options, $results) = @_;
6898 dpurdie 318
 
319
    # Create a summary report - more for the user
320
    my $summary;
321
    my $total = 0;
322
    foreach my $entry ( @$results) {
323
        if (exists $entry->{OUTCOME}) {
324
            $summary->{$entry->{OUTCOME}}++;
325
            $total++;
326
        }
327
    }
328
    my $summaryString = '';
329
    my $joiner = '';
330
    foreach my $entry ( sort keys %{$summary}) {
331
        $summaryString .= $joiner . $entry . ':' . $summary->{$entry};
332
        $joiner = ', ';
333
    }
334
    Message("Total: $total. $summaryString");
335
 
336
 
5035 dpurdie 337
    #
338
    #   Create a data structure to contain the dummy test result
339
    #   Insert TARGET and TYPE attributes
340
    #
341
    my %xml;
342
    $xml{TestResults}{TARGET} = $options->{TARGET};
343
    $xml{TestResults}{TYPE} = $options->{TYPE};
344
 
345
    @{$xml{TestResults}{TestResult}} = @$results;
346
 
347
    #   The 'MESSAGE' key for failed tests forms the content of the
348
    #   <TestResult> element. Other keys are converted to attributes.
349
    #   Assign <TestResults> as the root XML node.
350
    my $xmlData = XMLout(\%xml, ContentKey => 'MESSAGE', RootName => 'TestResults', KeepRoot => 1);
351
 
352
    #   Write the data to the XML file.
353
    my $filename = $options->{OUTFILE};
354
    open ( my $outFile, ">", $filename)
355
        || Error(" Cannot open results file:$filename for writing: $!\n");
356
    print $outFile $xmlData;
357
    close $outFile;
358
}
359
 
360
 
4780 dpurdie 361
=pod 1
4778 dpurdie 362
 
4780 dpurdie 363
=for htmltoc    SYSUTIL::
364
 
365
=head1 NAME
366
 
367
jats_runutf - Post Process UTF results for build system
368
 
369
=head1 SYNOPSIS
370
 
371
  $(GBE_PERL) -Mjats_runutf -e processUtf -- <args>
372
 
373
 Options:
6898 dpurdie 374
    -help[=n]           - Brief help message
375
    -help -help         - Detailed help message
376
    -man                - Full documentation
377
    -verbose[=n]        - Verbose operation
378
    -filter=name        - Name of the required processing filter
379
    -target=name        - Current build target
380
    -root=path          - Path to the root of the build
381
    -pkgdir=path        - Path to the packaging directory
382
    -interface=path     - Path to the build interface directory
383
    -local=path         - Path to the local build directory
384
    -dir=path           - Path to test directory
385
    -rcfile=path        - Path to a file that contains the test result code
4780 dpurdie 386
 
387
=head1 OPTIONS
388
 
389
=over 8
390
 
391
=item B<-help>
392
 
393
Print a brief help message and exits.
394
 
395
=item B<-help -help>
396
 
397
Print a detailed help message with an explanation for each option.
398
 
399
=item B<-man>
400
 
401
Prints the manual page and exits.
402
 
403
=item B<-verbose>
404
 
405
This option will display progress information as the program executes.
406
 
407
=item B<-filter=name>
408
 
409
Name of the required processing filter.
410
 
411
=item B<-target=name>
412
 
413
The current build target.
414
 
415
=item B<-root=path>
416
 
417
The path to the root of the current build.
418
 
419
=item B<-pkgdir=path>
420
 
421
The path to the packaging directory
422
 
423
=item B<-interface=path>
424
 
425
The path to the build interface directory
426
 
427
=item B<-local=path>
428
 
429
The path to the local build directory
430
 
4781 dpurdie 431
=item B<-dir=path>
432
 
433
The path to the directory in which the test was run.
434
 
435
This is optional. If provided the filter will be invoked with the 
436
current working directory
437
 
6898 dpurdie 438
=item B<-rcfile=path>
439
 
440
The path to the file that will contain the rsult code of the test run.
441
This is optional, but if provided it should exist
442
 
4780 dpurdie 443
=back
444
 
445
=head1 DESCRIPTION
446
 
447
This tool is not designed to be run directly by users. It is intended to be run by the 
448
JATS generated makefiles in conjunction with unit tests to process the output from a unit 
449
test to provide a common output format to be passed on the build system.
450
 
451
Normally this process only occurs with the Auto BuildTool environment.
452
 
453
The tool provides the following operations:
454
 
455
=over 4
456
 
457
=item *
458
 
459
Sanitize environment
460
 
461
The environment passed to the filter processing module will be verified. 
462
The path to the output directory will be created if required. All paths will be absolute.
463
 
464
=item *
465
 
466
Locate the required filter processing module. The module must be a Perl Module with a name of the form 'UtfFilter_<name>'
467
 
468
=item *
469
 
470
Invoke the required filter module.
471
 
472
=back
473
 
474
=head2 Locating the Filter Module
475
 
476
The filter module may be located, in order of precedence, within:
477
 
478
=over 4
479
 
480
=item *
481
 
482
The package currently being built.
483
 
484
The package may provide its own UTF post processing module. This is not encouraged.
485
 
486
The following locations will be examined for a suitable module:
487
 
488
=over 4
489
 
490
=item *
491
 
492
The current directory. The directory of the makefile.pl that is running the unit test.
493
 
494
=item *
495
 
496
A directory in the Build Root called 'gbe/UtfFilters'
497
 
498
=back
499
 
500
=item *
501
 
502
An external Package, within the gbe/scripts directory.
503
 
504
The package can be specified with either LinkPkgArchive or BuildPkgArchive directive 
505
within the current packages build.pl file.
506
 
507
=item *
508
 
509
Within JATS.
510
 
511
Jats may provide useful filter modules.
512
 
513
=back
514
 
515
=head2 Filter Module Interface
516
 
517
The filter module Interface consists of four items:
518
 
519
=over 4
520
 
521
=item 1 The name of the Package
522
 
523
=item 1 The named function with the package
524
 
525
=item 1 Arguments passed to the named function
526
 
527
=item 1 The processing expected to be done by the named function
528
 
529
=item 1 The Output Format
530
 
531
=back
532
 
533
=head3 The name of the Package
534
 
535
Each filter function is in its own package. The package name is created by concatenating the 
536
text 'UtfFilter_' with the name of the required filter. 
537
 
538
ie: If the required filter is 'junit4', then the name of the filter package must 
539
be UtfFilter_junit4 and it will be held in a file named UtfFilter_junit4.pm.
540
 
541
=head3 The named function with the package
542
 
543
The filter package must provide a function called 'processUtf'
544
 
545
=head3 Arguments passed to the named function
546
 
547
The processing function 'processUtf' is called with two arguments:
548
 
549
=over 4
550
 
551
=item 1
552
 
553
The name of the package
554
 
555
=item 2
556
 
4787 dpurdie 557
A reference to a Perl hash. The hash will contain the following named items:
4780 dpurdie 558
 
559
=over 4
560
 
4781 dpurdie 561
=item       ARGS          
562
 
563
Optional. A hash of User Arguments passed into the filter. Use of these is filter specific.
564
 
565
Arguments of the form '--UtfArg=UserArg1=Value1' will be stored with a key of 'UserArg1 and a value of 'Value1'.
566
 
567
Arguments of the form '--UtfArg=UserArg2' will be stored with a key of 'UserArg2' and an undefined value.
568
 
569
=item       DIR          
570
 
571
Optional. If the Unit Test is executed in a subdirectory of the current build 
572
location, then DIR will be set to the name of the subdirectory. 
573
 
574
The current working directory will be changed to DIR before the filter function is invoked. 
575
 
576
This item will aways exist, but it may not be defined.
577
 
4780 dpurdie 578
=item       FILTER          
579
 
580
The Name of the filter 
581
 
4781 dpurdie 582
=item       IDIR
583
 
584
The absolute path to the working directory, when the module is invoked, before the working
4996 dpurdie 585
directory has been changed to 'DIR'.
4781 dpurdie 586
 
4780 dpurdie 587
=item       INTERFACE       
588
 
4781 dpurdie 589
The absolute path to Interface directory
4780 dpurdie 590
 
591
=item       LOCAL
592
 
4781 dpurdie 593
The absolute path to Local directory
4780 dpurdie 594
 
595
=item       OUTDIR
596
 
4781 dpurdie 597
The absolute path to output directory
4780 dpurdie 598
 
599
=item       OUTFILE
600
 
4781 dpurdie 601
The absolute path to suggested output file. The user does not need to use this name. It is 
4780 dpurdie 602
provided to remove the need for each filter to create a unique name.
603
 
604
This file will not exist.
605
 
606
=item       PKGDIR
607
 
4781 dpurdie 608
The absolute path to Packaging directory. This directory will exist.
4780 dpurdie 609
 
610
=item       ROOT
611
 
4781 dpurdie 612
The absolute path to Root of the build
4780 dpurdie 613
 
614
=item       TARGET
615
 
616
The current make target
617
 
618
=item       TYPE
619
 
620
The build type P or D
621
 
4781 dpurdie 622
=item       UTFNAME
623
 
624
The name of the test.
625
 
626
This may be provided by the user, or it may be system generated. Intended to be used by 
627
test filters that do not have test names generated as a part of the test
628
 
629
=item       UTFUID
630
 
631
A unique test identifier. This is unique with the build and is intended to:
632
 
633
=over 4
634
 
635
=item   *
636
 
637
Allow the generation of test-unique file names for the storage of results.
638
 
639
=item *
640
 
641
Allow the reuse of output file names.
642
 
4780 dpurdie 643
=back
644
 
5035 dpurdie 645
=item       UTFRC
646
 
647
The result code from the unit test run.
648
 
649
This will only be defined for JATS run unit tests.
650
 
4781 dpurdie 651
=back
652
 
4787 dpurdie 653
The return value from the function 'processUtf' is ignored. If the function encounters 
654
any error it should use the Jats 'Error' function to report the error.
4780 dpurdie 655
 
656
=back
657
 
658
=head3 The processing expected to be done by the named function
659
 
4787 dpurdie 660
The processing function is expected to transform the results of a unit test into 
661
a constient form so that they can be processed by the remainder of the build tool.
4780 dpurdie 662
 
663
The processing should:
664
 
665
=over 4
666
 
667
=item *
668
 
669
Create information in the OUTDIR directory. 
670
 
671
The filter may create a new file or insert information into an existing file. 
672
 
673
The user may make use of the OUTFILE path, but this is not mandatory.
674
 
675
=item *
676
 
677
Report errors by calling the Jats 'Error' function. This will terminate processing.
678
 
679
=back
680
 
681
=head3 The Output Format
682
 
683
Yet to be defined.
684
 
4781 dpurdie 685
The output format is known to the build system. It should not be 
7219 dpurdie 686
changed without also change it for the consuming tools.
4781 dpurdie 687
 
4780 dpurdie 688
=cut
689
 
690
 
4778 dpurdie 691
1;