Subversion Repositories DevTools

Rev

Rev 347 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
#! perl
2
########################################################################
3
# Copyright ( C ) 2005 ERG Limited, All rights reserved
4
#
5
# Module name   : jats.sh
6
# Module type   : Perl Package
7
# Compiler(s)   : n/a
8
# Environment(s): jats
9
#
10
# Description   : This package contains functions to access system commands
11
#                 and programs.
12
#
13
#
14
#......................................................................#
15
 
255 dpurdie 16
use 5.006_001;
227 dpurdie 17
use strict;
18
use warnings;
19
 
263 dpurdie 20
#
21
#   System Wide Globals
22
#
23
our $GBE_BIN;                                   # From ENV
24
our $GBE_PERL;
25
our $GBE_CORE;
26
 
27
 
227 dpurdie 28
package JatsSystem;
29
use JatsError;
30
use FileUtils;
263 dpurdie 31
use JatsEnv;
227 dpurdie 32
 
33
 
34
our (@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $VERSION);
35
use Exporter;
36
 
37
$VERSION = 1.00;
38
@ISA = qw(Exporter);
39
 
40
# Symbols to autoexport (:DEFAULT tag)
41
@EXPORT = qw(
42
            System
43
            SystemConfig
44
            JatsCmd
263 dpurdie 45
            JatsTool
227 dpurdie 46
            LocateProgInPath
47
            QuoteCommand
48
            );
49
 
50
# Non exported package globals go here
51
 
52
my $opt_test_mode           = 0;                # Test Mode disabled
53
my $opt_use_shell           = 0;                # Force a shell to be used
54
my $opt_exit_on_error       = 0;                # Force exit on error
55
 
56
#-------------------------------------------------------------------------------
57
# Function        : SystemConfig
58
#
59
# Description     : Set the system command to TEST mode
60
#                   Command will not be executed. Only displayed
61
#
62
# Inputs          : Test        => Test Mode
63
#                   UseShell    => Default Shell Mode
64
#                   ExitOnError => Exit on Error Mode
65
#
66
# Returns         : Nothing
67
#
68
sub SystemConfig
69
{
70
    my %args = @_;
71
 
72
    while (my($key, $value) = each %args)
73
    {
74
        if (       $key =~ /^Test/i ) {
75
            $opt_test_mode = $value;
76
            Message("SystemTest Enabled") if $value;
77
 
78
        } elsif ( $key =~ /^UseShell/i ) {
79
            $opt_use_shell = $value;
80
 
81
        } elsif ( $key =~ /^ExitOnError/i ) {
82
            $opt_exit_on_error = $value;
83
 
84
        } else {
85
            Error("SystemConfig, Unknown option: $key");
86
        }
87
    }
88
}
89
 
90
#-------------------------------------------------------------------------------
91
# Function        : System
92
#
93
# Description     : Exec the specified command ...
94
#
95
# Inputs          : Options [Must be first]
96
#                       --Show              Force argument display
97
#                       --Shell             Force use of a Shell
98
#                       --NoShell           Force no Shell use
99
#                       --Exit              Force Exit on Error
100
#                       --ExitQuiet         Force Exit on Error, without display
101
#                       --NoExit            Force no exit on error
102
#                   Command
103
#                   Command args
104
#
105
# Returns         : Result code
106
#
107
sub System
108
{
109
    my @cmd;
110
    my( $rv );
111
    my $opt_show = 0;
112
    my $opt_prefix = "System:";
113
    my $shell = $opt_use_shell;
114
    my $exit = $opt_exit_on_error;
115
 
116
    #
117
    #   Strip off any leading options
118
    #
119
    my $just_collect;
120
    foreach ( @_ )
121
    {
122
        if ( $just_collect ) {
123
            push @cmd, $_;
124
            next;
125
 
126
        } elsif ( m/^--Show/ ) {
127
            $opt_show = 1;
128
        } elsif ( m/^--Shell/ ) {
129
            $shell = 1;
130
        } elsif ( m/^--NoShell/ ) {
131
            $shell = 0;
132
        } elsif ( m/^--ExitQuiet/ ) {
133
            $exit = 2;
134
        } elsif ( m/^--Exit/ ) {
135
            $exit = 1;
136
        } elsif ( m/^--NoExit/ ) {
137
            $exit = 0;
138
        } elsif ( m/^--/ ) {
139
            Warning("System: Unknown option(ignored): $_" );
140
        } else {
141
            $just_collect = 1;
142
            redo;
143
        }
144
    }
145
 
146
    #
147
    #   Prefix with Shell if required
148
    #
149
    if ( $shell )
150
    {
151
        #
152
        #   Fetch and cache GBE_BIN
153
        #
263 dpurdie 154
        EnvImport ('GBE_BIN')
155
            unless ( $::GBE_BIN );
227 dpurdie 156
 
263 dpurdie 157
        #
158
        #   Reform command
159
        #   With -c shell takes one argumemnt - not an array of args
345 dpurdie 160
        #   Escape the users command and enclose in quotes
263 dpurdie 161
        #
345 dpurdie 162
        @cmd = ( "$::GBE_BIN/sh", "-c", EscapeCommand(@cmd) );
227 dpurdie 163
    }
164
 
165
    #
166
    #   Display the command
167
    #
168
    $opt_prefix = "System TEST:" if ($opt_test_mode);
169
    if ( $opt_show || $::ScmVerbose >= 2  )
170
    {
171
        my $line = $opt_prefix . ' ' . join ',', map ( "\"$_\"" , @cmd);
172
        Verbose2 ( $line) ;
173
        Message  ( $line ) if ( $opt_show );
174
    }
175
 
176
    #
177
    #   Simply return OK if in test mode
178
    #
179
    return 0 if ( $opt_test_mode );
180
 
181
    #
182
    #   Now do the hard bit
183
    #
184
    $rv = system( @cmd );
185
 
186
    #
187
    #   Report the result code
188
    #
189
    Verbose2 "System Result Code: $rv";
190
    Verbose2 "System Result Code: $!" if ($rv);
191
    $rv = $rv / 256;
192
 
193
    #
194
    #   If ExitOnError is enabled, then force program termination
195
    #
196
    if ( $rv && $exit )
197
    {
198
        if ( $exit == 2 )
199
        {
200
            Error("Program terminated. Errors previously reported");
201
        }
202
 
203
        Error("System cmd failure. Exit Code: $rv",
204
              "Command: " . join ',', map ( "\"$_\"" , @cmd) );
205
    }
206
 
207
    return $rv;
208
}
209
 
210
#-------------------------------------------------------------------------------
211
# Function        : JatsCmd
212
#
213
# Description     : Issue a command to JATS.PL
214
#
215
# Inputs          : Command line
263 dpurdie 216
#                   This should be an array of arguments
217
#                   It will not be processed by a shell
227 dpurdie 218
# Returns         : Error code
219
#
220
sub JatsCmd
221
{
263 dpurdie 222
    EnvImport ('GBE_PERL');
223
    EnvImport ('GBE_CORE');
227 dpurdie 224
 
263 dpurdie 225
    System (  '--NoShell', $::GBE_PERL, "$::GBE_CORE/TOOLS/jats.pl", @_ );
227 dpurdie 226
}
227
 
263 dpurdie 228
#-------------------------------------------------------------------------------
229
# Function        : JatsTool
230
#
231
# Description     : Issue a command to JATS tool
232
#                   Don't invoke JATS wrapper - go straight to the tool
233
#
234
# Inputs          : Tool                        - With optional .pl extension
235
#                   Command line                - Tool command line
236
#
237
# Returns         : Error code
238
#
239
sub JatsTool
240
{
241
    EnvImport ('GBE_PERL');
242
    EnvImport ('GBE_CORE');
227 dpurdie 243
 
263 dpurdie 244
    my $cmd = shift;
245
    $cmd .= '.pl' unless ( $cmd =~ m~\.pl$~i );
246
 
247
    #
248
    #   Look in the standard places for a JATS tool
249
    #   These are all perl tools
250
    #
251
    my $path;
252
    foreach my $dir (  '/TOOLS/', '/TOOLS/DEPLOY/', '/TOOLS/LOCAL/', '')
253
    {
254
        Error ("JatsTool not found: $cmd") unless ( $dir );
255
        $path = $::GBE_CORE . $dir . $cmd;
256
        last if ( -f $path );
257
    }
258
 
259
    System ( '--NoShell', $::GBE_PERL, $path, @_ );
260
}
261
 
227 dpurdie 262
#-------------------------------------------------------------------------------
263
# Function        : LocateProgInPath
264
#
265
# Description     : Locate a program in the users path
266
#                   (Default) Stop if we get the the JATS bin directory
267
#                   The user should NOT be using programs that are not
268
#                   provided by JATS
269
#
270
# Inputs          : prog            - Program to locate
271
#                   args            - Options
272
#                                     --All : Search all of PATH
273
#                                             Used by build tools
261 dpurdie 274
#                                     --Path= User provided pathlist
227 dpurdie 275
#
276
# Returns         : Path name of the file
277
#
278
sub LocateProgInPath
279
{
280
    my ($prog, @args ) = @_;
281
    my $all = 0;
282
    my $stop_dir;
261 dpurdie 283
    my $upath = $ENV{PATH};
227 dpurdie 284
 
285
    #
286
    #   Extract arguments
287
    #
288
    foreach ( @args )
289
    {
261 dpurdie 290
        #
291
        #   Search in all paths: Don't limit ourselves to JATS
292
        #
227 dpurdie 293
        if ( m/^--All/ ) {
294
            $all = 1;
295
        }
261 dpurdie 296
 
297
        #
298
        #   User provided pathlist
299
        #   Allow for an empty list - which will use the default path
300
        #
301
        if ( m/^--Path=(.+)/ ) {
302
            if ( $1 ) {
303
                $upath = $1;
304
                $all = 1;
305
            }
306
        }
227 dpurdie 307
    }
308
 
309
    #
310
    #   Stop at the JATS BIN directory, unless requested otherwise
311
    #
312
    unless ( $all )
313
    {
314
        $stop_dir = "$ENV{GBE_CORE}/BIN.";
315
        $stop_dir =~ tr~\\/~/~s;
316
    }
317
 
318
    #
319
    #   A list of known extensions to scan
320
    #   Basically present so that we can use .exe files without the .exe name
321
    #
322
    my @elist;
323
    push @elist, '.exe' if ( $ScmHost ne "Unix" );
324
    push @elist, '.pl', '.sh', '.ksh', '';
325
 
326
    #
327
    #   If elist is empty then insert a defined entry
328
    #
329
    push @elist, '' unless ( @elist );
330
 
331
    #
332
    #   Scan all toolset directories
333
    #   for the program
334
    #
261 dpurdie 335
    for my $dir ( split ( $ScmPathSep, $upath ) )
227 dpurdie 336
    {
337
        for my $ext ( @elist )
338
        {
343 dpurdie 339
            my $tool = "$dir/$prog$ext";
227 dpurdie 340
            Debug2( "LocateProgInPath: Look for: $tool" );
341
 
342
            return $tool if ( -f $tool );
343
        }
344
 
345
        #
346
        #   Don't process any dirs beyond the JATS BIN directory
347
        #   The program MUST be provided by the JATS framework and not
348
        #   random user configuration
349
        #
350
        if (  $stop_dir )
351
        {
352
            $dir =~ tr~\\/~/~s;
353
            if ( $dir =~ /^$stop_dir/i)
354
            {
355
                Message ("LocateProgInPath: Stopped at JATS BIN");
356
                last;
357
            }
358
        }
359
    }
360
}
361
 
362
#-------------------------------------------------------------------------------
363
# Function        : QuoteCommand
364
#
365
# Description     : Return a string command that is quoted
366
#                   Do not quote empty elements
263 dpurdie 367
#                   Don't quote if already quoted
368
#                   Handle embedded quotes
227 dpurdie 369
#
370
# Inputs          : Array of element to quote
371
#
263 dpurdie 372
# Returns         : A string or an array
373
#                   Try to keep as an array
227 dpurdie 374
#
375
sub QuoteCommand
376
{
263 dpurdie 377
    my @cmd;
378
    foreach ( @_ )
227 dpurdie 379
    {
263 dpurdie 380
        next unless ( defined $_);             # Ignore empty
381
        next if ( $_ eq '' );
382
 
383
        if ( m~^"(.+)"$~ )                      # Ignore already quoted
384
        {
385
            push @cmd, $_;
386
            next;
387
        }
388
 
389
        my $data = $_;                          # Escape embedded "
390
        $data =~ s~"~\\"~g;
391
        push @cmd, '"' . $data . '"';           # Quote the argument
227 dpurdie 392
    }
263 dpurdie 393
 
394
    #
395
    #   Attempt to keep it as an array
396
    #
397
    return (wantarray) ? @cmd : join (' ', @cmd);
227 dpurdie 398
}
399
 
263 dpurdie 400
#-------------------------------------------------------------------------------
345 dpurdie 401
# Function        : EscapeCommand
263 dpurdie 402
#
345 dpurdie 403
# Description     : Escape input commands
347 dpurdie 404
#                   Can be called with two forms of arguments.
405
#                   If the there is only one item in the input list, then the
406
#                   command will be a single command that is to be processed
407
#                   by the shell. We cannot do escaping of space characters.
408
#
409
#                   If there is more than one item, then assume that each
410
#                   item will be a standalone command parameter - and we can
411
#                   quote spaces within the command stream.
412
#
263 dpurdie 413
#                   Must handle:
414
#                       Embedded "
345 dpurdie 415
#                       Embeded spaces
263 dpurdie 416
#                   Doesn't (yet) handle embedded \
417
#
418
# Inputs          : Array of elements to process
419
#
420
# Returns         : Return an escaped string
421
#
345 dpurdie 422
sub EscapeCommand
263 dpurdie 423
{
424
    my @cmd;
347 dpurdie 425
    my $arg_count = $#_;
263 dpurdie 426
 
427
    foreach ( @_ )
428
    {
429
        my $data = $_;
430
        next unless ( $data );
431
        $data =~ s~"~\\"~g;
347 dpurdie 432
        $data =~ s~ ~\\ ~g if ($arg_count > 0);
263 dpurdie 433
        push @cmd, $data;
434
    }
435
    return join (' ', @cmd);
436
}
437
 
227 dpurdie 438
1;
439