Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
227 dpurdie 1
########################################################################
2
# Copyright ( C ) 2005 ERG Limited, All rights reserved
3
#
4
# Module name   : jats.sh
5
# Module type   : Perl Package
6
# Compiler(s)   : n/a
7
# Environment(s): jats
8
#
9
# Description   : This package contains functions to manipulate file paths
10
#                 directories and names.
11
#
12
#                    Getcwd                     - Get current directory
13
#                    Realpath                   - Get real path
14
#                    Realfile                   - Get real path ?
15
#                    RelPath                    - Convert to relative path
16
#                    AbsPath                    - Convert to Abs path
17
#                    FullPath                   - Convert to Abs path with driver letter
257 dpurdie 18
#                    TruePath                   - Case Corrected pathname
227 dpurdie 19
#                    CleanPath                  - Clean up a path
20
#                    StripDrive                 - Remove drive letter
21
#                    StripDir                   - Return file + extension
22
#                    StripExt                   - Return dir + file
23
#                    StripFile                  - Returns extension
24
#                    StripFileExt               - Returns directory
25
#                    StripDirExt                - Returns filename ( with optional ext)
26
#                    CleanDirName               - Clean up a path
261 dpurdie 27
#                    TouchFile                  - Touch a file
28
#                    FileIsNewer                - Test if newer
227 dpurdie 29
#                    DisplayPath                - Genate a Path that can be displayed
261 dpurdie 30
#                    FileCreate                 - Create a simple text file
31
#                    FileAppend                 - Append to a simple text file
379 dpurdie 32
#                    RmDirTree                  - Remove a directory tree
227 dpurdie 33
#
34
#
35
#......................................................................#
36
 
255 dpurdie 37
use 5.006_001;
227 dpurdie 38
use strict;
39
use warnings;
40
 
41
################################################################################
42
#   Global variables used by functions in this package
43
#   For historical reasons many of these variabeles are global
44
#
45
 
46
package FileUtils;
283 dpurdie 47
use base qw(Exporter);
361 dpurdie 48
use File::Path;
283 dpurdie 49
 
227 dpurdie 50
use JatsError;
51
use Cwd;
283 dpurdie 52
our (@EXPORT, @EXPORT_OK, %EXPORT_TAGS, $VERSION);
227 dpurdie 53
 
54
$VERSION = 1.00;
55
 
56
# Symbols to autoexport (:DEFAULT tag)
57
@EXPORT = qw(   InitFileUtils
58
                Getcwd
59
                Realpath
60
                RelPath
61
                AbsPath
62
                FullPath
63
                CleanPath
64
                StripDrive
65
                StripDir
66
                StripExt
67
                StripFile
68
                StripFileExt
69
                StripDirExt
70
                CleanDirName
71
                TouchFile
72
                FileIsNewer
73
                DisplayPath
257 dpurdie 74
                TruePath
261 dpurdie 75
                FileCreate
76
                FileAppend
361 dpurdie 77
                RmDirTree
227 dpurdie 78
 
79
                $ScmPathSep
261 dpurdie 80
                $ScmDirSep
227 dpurdie 81
                $Cwd
82
                $CwdDrive
83
                $ScmHost
84
            );
85
#
86
# exported package globals go here
87
#
88
our $ScmPathSep;                # Windows/Unix path seperator
261 dpurdie 89
our $ScmDirSep;                 # Windows/Unix dir sep
227 dpurdie 90
our $Cwd       ;                # Current directory ( no drive letter )
247 dpurdie 91
our $CwdFull   ;                # Current directory ( with drive letter )
227 dpurdie 92
our $CwdDrive  ;                # Current drive
93
our $ScmHost   ;                # Host Type. Unix, WIN
94
 
95
#
96
#   Internal variables
97
#
98
my  $isCygWin;                 # Running under CygWin
99
my  $isUnix;                   # Is Unix
100
 
101
#-------------------------------------------------------------------------------
102
# Function        : BEGIN
103
#
104
# Description     : Determine some values very early
105
#
106
#
107
BEGIN
108
{
109
    $ScmHost = "Unix";                                # UNIX, default
110
 
111
    Debug( "PerlHost:  $^O" );
112
    $ScmHost = "DOS"      if ($^O eq "win95");        # DOS Perl dependent
113
    $ScmHost = "WIN"      if ($^O eq "MSWin32");      # ActivePerl
114
    $ScmHost = "WIN"      if ($^O eq "cygwin");       # Cygwin
115
 
116
    $isUnix = 1 if ( $ScmHost eq "Unix"  );
255 dpurdie 117
    $isCygWin = 1 if ( $ENV{'SHELL'} || $ENV{'CYGWIN'} );
227 dpurdie 118
 
119
    $ScmPathSep = $isUnix ? ':' : ';';     # Unix / Windows
261 dpurdie 120
    $ScmDirSep = $isUnix ? '/' : '\\';     # Unix / Windows
227 dpurdie 121
}
122
 
123
#-------------------------------------------------------------------------------
124
# Function        : InitFileUtils
125
#
126
# Description     : Initialise this package
127
#                   This function should be called once the user has determined
128
#                   settled on a working directory
129
#
130
#                   The function may be called multiple times
131
#                   to allow various globals to be reset - when the user has
132
#                   changed directory
133
#
134
# Inputs          : Nothing
135
#
136
# Returns         : Nothing
137
#
138
sub InitFileUtils
139
{
140
    #
141
    #   Setup current directory and drive
142
    #
143
 
247 dpurdie 144
    $CwdFull = Getcwd();                    # Current working dir
227 dpurdie 145
 
146
    $CwdDrive = '';
247 dpurdie 147
    $CwdDrive = substr( $CwdFull, 0, 2 )    # Saved Drive letter
227 dpurdie 148
        if ( ! $isUnix );
149
 
247 dpurdie 150
    $Cwd = StripDrive( $CwdFull );          # With drive spec striped
227 dpurdie 151
 
152
    Debug ("InitFileUtils: ScmHost     : $ScmHost");
247 dpurdie 153
    Debug ("InitFileUtils: CwdFull     : $CwdFull");
227 dpurdie 154
    Debug ("InitFileUtils: Cwd         : $Cwd");
155
    Debug ("InitFileUtils: CwdDrive    : $CwdDrive");
156
    Debug ("InitFileUtils: ScmPathSep  : $ScmPathSep");
157
}
158
 
159
 
160
#-------------------------------------------------------------------------------
161
# Function        : Getcwd
162
#
163
# Description     : Retrieve current working directory
164
#
165
# Inputs          : None
166
#
167
# Returns         : The current working directory
168
#
169
# Notes           : Don't use 'pwd' program as it gets symbolic links wrong
170
#
171
sub Getcwd
172
{
173
    my $cwd = getcwd();
174
    return $cwd;
175
}
176
 
177
#-------------------------------------------------------------------------------
261 dpurdie 178
# Function        : TouchFile 
227 dpurdie 179
#
180
# Description     : touch a file
181
#                   Real use is to touch a marker file
182
#
183
# Inputs          : path        - path to the file
184
#
185
# Returns         : TRUE if an error occured in creating the file
186
#
187
sub TouchFile
188
{
189
    my ($path, $text) = @_;
190
    my $result = 0;
283 dpurdie 191
    my $tfh;
192
 
227 dpurdie 193
    Verbose ("Touching file: $path" );
194
    if ( ! -f $path )
195
    {
283 dpurdie 196
        open ($tfh, ">>", $path) || ($result = 1);
197
        close $tfh;
227 dpurdie 198
    }
199
    else
200
    {
201
 
202
        #
203
        #   Modify the file
204
        #
205
        #   Need to physically modify the file
206
        #   Need to change the 'change time' on the file. Simply setting the
207
        #   last-mod and last-access is not enough to get past WIN32
208
        #   OR 'utime()' does not work as expected
209
        #
210
        #   Read in the first character of the file, rewind and write it
211
        #   out again.
212
        #
213
        my $data;
283 dpurdie 214
        open ($tfh , "+<", $path ) || return 1;
215
        if ( read ( $tfh, $data, 1 ) )
216
        {
217
            seek  ( $tfh, 0, 0 );
218
            print $tfh $data;
227 dpurdie 219
        }
220
        else
221
        {
222
            #
223
            #   File must have been of zero length
224
            #   Delete the file and create it
225
            #
283 dpurdie 226
            close ($tfh);
227 dpurdie 227
            unlink ( $path );
283 dpurdie 228
            open ($tfh, ">>", $path) || ($result = 1);
227 dpurdie 229
        }
283 dpurdie 230
        close ($tfh);
227 dpurdie 231
    }
232
    return $result;
233
}
234
 
235
#-------------------------------------------------------------------------------
261 dpurdie 236
# Function        : FileCreate
237
#                   FileAppend
238
#                   _FileWrite
239
#
240
# Description     : Simple Text File Creation function
241
#                   Suited to the creation of small, simple text files.
242
#
243
# Inputs          : Name of the file
244
#                   Remainder are:
245
#                       Lines of data to output to the file
246
#                       Or a reference to an array of lines
247
#                       Or a mixture
248
#                   All lines will be terminated with a "\n"
249
#
250
# Returns         : Nothing
251
#
252
sub FileCreate
253
{
254
    _FileWrite ( '>', @_ );
255
}
256
 
257
sub FileAppend
258
{
259
    _FileWrite ( '>>', @_ );
260
}
261
 
262
sub _FileWrite
263
{
264
    my $mode = shift @_;
265
    my $name = shift @_;
283 dpurdie 266
    my $fh;
261 dpurdie 267
 
268
    Error ("FileCreate: No file specified") unless ( $name );
269
    Error ("FileCreate: Path is directory") if ( -d $name );
270
 
283 dpurdie 271
    open  ($fh, $mode, $name ) || Error( "Cannot create file: $name", "Reason: $!" );
261 dpurdie 272
 
273
    foreach my $entry ( @_ ) {
274
        if ( ref ($entry ) eq 'ARRAY'  ) {
283 dpurdie 275
            print $fh $_ . "\n" foreach  ( @$entry );
261 dpurdie 276
        } else {
283 dpurdie 277
            print $fh $entry . "\n"
261 dpurdie 278
        }
279
    }
283 dpurdie 280
    close $fh;
261 dpurdie 281
}
282
 
283
#-------------------------------------------------------------------------------
227 dpurdie 284
# Function        : FileIsNewer
285
#
286
# Description     : Test two files to see if the files are newer
287
#
288
# Inputs          : file1
289
#                   file2
290
#
291
# Returns         : Returns true if file1 is newer than file2 or file2 does not
292
#                   exist.
293
#
294
#                   If file 1 does not exist then it will return false
295
#
296
sub FileIsNewer
297
{
298
    my ($file1, $file2) = @_;
299
 
300
    my $f1_timestamp = (stat($file1))[9] || 0;
301
    my $f2_timestamp = (stat($file2))[9] || 0;
302
    my $result = $f1_timestamp > $f2_timestamp ? 1 : 0;
303
 
304
    Verbose2 ("FileIsNewer: TS: $f1_timestamp, File: $file1");
305
    Verbose2 ("FileIsNewer: TS: $f2_timestamp, File: $file2");
306
    Verbose2 ("FileIsNewer: $result" );
307
 
308
    return $result;
309
}
310
 
311
#-------------------------------------------------------------------------------
312
# Function        : Realpath
313
#
314
# Description     : Returns the 'real path'
315
#
316
# Inputs          : $path       - Path to process
317
#
318
# Returns         : The real path
319
#
320
sub Realpath
321
{
322
    my( $path ) = @_;
323
    my( $real, $cwd );
324
 
325
    $cwd = Getcwd();
326
    if (!chdir( $path )) {
327
        $real = "";
328
    } else {
329
        $real = Getcwd();
330
        Error ("FATAL: Realpath($path) could not restore directory ($cwd)." )
331
            unless (chdir( $cwd ));
332
    }
333
    Debug( "Realpath:   = $real ($path)" );
334
    return $real;
335
}
336
 
337
#-------------------------------------------------------------------------------
338
# Function        : Realfile
339
#
340
# Description     : Returns the 'real path'
341
#
342
# Inputs          : $path       - Path to process
343
#
344
# Returns         : The real path
345
#
346
#sub Realfile
347
#{
348
#    my( $path ) = @_;
349
#    my( $real, $cwd );
350
#
351
#    $cwd = Getcwd();
352
#    if (!chdir( $path )) {
353
#        $real = "";
354
#    } else {
355
#        $real = Getcwd();
356
#        Error ("FATAL: Realpath($path) could not restore directory ($cwd)." )
357
#            unless (chdir( $cwd ));
358
#    }
359
#    Debug( "Realpath:   = $real ($path)" );
360
#    return $real;
361
#}
362
 
363
#-------------------------------------------------------------------------------
364
# Function        : RelPath
365
#
366
# Description     : Return the relative path to the current working directory
367
#                   as provided in $Cwd
368
#
285 dpurdie 369
# Inputs          : $base       - Base directory to convert
370
#                   $here       - Optional current directory
371
#                                 $Cwd will be used if non provided
227 dpurdie 372
#
373
# Returns         : Relative path from the current directory to the base directory
374
#
375
sub RelPath
376
{
285 dpurdie 377
    my ($base, $here) = @_;
227 dpurdie 378
 
285 dpurdie 379
    $here = $Cwd unless ( defined $here );
227 dpurdie 380
    my @base = split ('/', $base );
285 dpurdie 381
    my @here = split ('/', $here );
227 dpurdie 382
    my $result;
383
 
4265 dpurdie 384
    Debug("RelPath: Here  : $here");
227 dpurdie 385
    Debug("RelPath: Source: $base");
386
 
387
    return $base unless ( $base =~ m~^/~ );
388
 
389
    #
390
    #   Remove common bits from the head of both lists
391
    #
392
    while ( $#base >= 0 && $#here >= 0 && $base[0] eq $here[0] )
393
    {
394
        shift @base;
395
        shift @here;
396
    }
397
 
398
    #
399
    #   Need to go up some directories from here and then down into base
400
    #
401
    $result = '../' x ($#here + 1);
402
    $result .= join ( '/', @base);
403
    $result = '.' unless ( $result );
404
    $result =~ s~/$~~;
405
 
406
    Debug("RelPath: Result: $result");
407
    return $result;
408
}
409
 
410
#-------------------------------------------------------------------------------
411
# Function        : AbsPath
412
#
413
# Description     : Return the absolute path to the file
414
#                   Add the current directory if the path is absolute
415
#                   Clean up xxx/.. constructs
416
#
417
#                   If an absolute path is provided then it will simply be
418
#                   cleaned up.
419
#
420
# Assumption      : Absolute paths start with a "/" and do not have a drive letter
421
#
2450 dpurdie 422
# Inputs          : $dpath      - Source file path
325 dpurdie 423
#                   $here       - Optional current directory
424
#                                 $Cwd will be used if non provided
2450 dpurdie 425
#                   $mode       - Defined: No error
426
#                                 Used during error reporting
227 dpurdie 427
#
428
# Returns         : Cleaned abs path
429
#
430
sub AbsPath
431
{
2450 dpurdie 432
    my ($dpath, $here, $mode) = @_;
227 dpurdie 433
    my @result;
434
 
435
    #
436
    #   If we have a relative path then prepend the current directory
437
    #   An absolute path is:
438
    #           /aaa/aa/aa
439
    #       or  c:/aaa/aa/aa
440
    #
325 dpurdie 441
    $here = $Cwd unless ( defined $here );
3859 dpurdie 442
    $here =~ s~^\w:~~;
325 dpurdie 443
    $dpath = $here . '/' . $dpath
3832 dpurdie 444
        unless ( $dpath =~ m~^/|\w:[/\\]~  );
227 dpurdie 445
    $dpath =~ s~//~/~g;
446
 
447
    #
448
    #   Walk the bits and remove ".." directories
449
    #       Done by pushing non-.. elements and poping last entry for .. elements.
450
    #   Have a leading "/" which is good.
451
    #
452
    foreach ( split ( '/', $dpath ) )
453
    {
454
        next if ( $_ eq '.' );
455
        unless ( $_ eq '..' )
456
        {
457
            push @result, $_;
458
        }
459
        else
460
        {
2450 dpurdie 461
            if ( $#result <= 0 )
462
            {
463
                Error ("Bad Pathname: $dpath") unless ( $mode );
464
                return $dpath;
465
            }
466
            else
467
            {
468
                pop @result;
469
            }
227 dpurdie 470
        }
471
    }
472
 
473
    #
474
    #   Create a nice directory name again.
475
    #
476
    return join ( '/', @result );
477
}
478
 
479
#-------------------------------------------------------------------------------
480
# Function        : FullPath
481
#
482
# Description     : Return the absolute path to the file - with driver letter
483
#                   Add the current directory if the path is absolute
484
#                   Clean up xxx/.. constructs
485
#
486
#                   If an absolute path is provided then it will simply be
487
#                   cleaned up.
488
#
489
# Inputs          : Source file path
325 dpurdie 490
#                   $here       - Optional current directory
491
#                                 $Cwd will be used if non provided
227 dpurdie 492
#
493
# Returns         : Cleaned abs path
494
#
495
sub FullPath
496
{
497
    my $path = AbsPath (@_ );
229 dpurdie 498
    $path = $CwdDrive . $path unless ( $path =~ m~^\w:~  );
227 dpurdie 499
    return $path;
500
}
501
 
502
#-------------------------------------------------------------------------------
257 dpurdie 503
# Function        : TruePath
504
#
505
# Description     : Returns a case correct pathname
506
#                   Really only applicable to windows, under unix it returns
507
#                   its input path.
508
#
509
#                   Maintains a cache to speed up processing
510
#
511
# Inputs          : Confused path (Absolute with a driver letter)
512
#
513
# Returns         : Case Correct Path : Windows
514
#                   Input Path : Non Windows
515
#
516
my %TruePathCache;
517
my %DirRead;
518
sub TruePath
519
{
520
    my ($path) = @_;
521
    $path =~ tr~\\/~/~s;
522
 
523
    #
524
    #   On Unix systems the path is case sensitive to start with
525
    #   Can't get it wrong - can't do anything.
526
    #
527
    return $path if ( $isUnix );
528
 
529
    #
530
    #   If the path does not exist at all then return the user input
531
    #   Assume that the user will handle this later
532
    #
533
    unless ( -e $path )
534
    {
535
        Warning ("TruePath given invalid path: $path");
536
        return $path;
537
    }
538
 
539
    #
540
    #   Look in the cache - have we seen this before
541
    #
542
    if ( exists $TruePathCache{lc($path)} )
543
    {
544
        Verbose( "TruePath Cache Hit: $path");
545
        return $TruePathCache{lc($path)};
546
    }
547
 
548
    #
549
    #   Split the directory into components
550
    #
551
    my $TrueComponent = '';
552
    my @components = split ('/', $path );
553
    foreach my $elem ( @components )
554
    {
555
        Debug ("Process: $elem in $TrueComponent");
556
        my $tag;
557
        #
558
        #   Handle driver letter
559
        #
560
        if ( $elem =~ m~^[a-zA-Z]:$~ )
561
        {
562
            $elem = uc($elem);
563
            $TrueComponent = $elem;
564
 
565
            $tag = lc($TrueComponent);
566
            $TruePathCache{$tag} = $elem;
567
            Debug ("     Add: $elem");
568
            next;
569
        }
570
 
571
        #
572
        #   Ensure that we have read in containing directory
573
        #   Note: Append / to ensure we read root directories correctly
574
        #
575
        $TrueComponent .= '/';
576
        unless ( $DirRead{ $TrueComponent }  )
577
        {
578
            Debug ("Reading: $TrueComponent");
285 dpurdie 579
            opendir (my $tp, $TrueComponent ) or Error ("Cannot open $TrueComponent");
580
            my @dirlist = readdir $tp;
581
            closedir $tp;
257 dpurdie 582
            $DirRead {$TrueComponent } = 1;
583
 
584
            #
585
            #   Add cache entries for each path in the directory
586
            #
587
            foreach my $dir ( @dirlist )
588
            {
589
                next if ( $dir eq '.' );
590
                next if ( $dir eq '..' );
591
                my $fullpath = $TrueComponent . $dir;
592
                Debug ("     Add: $fullpath");
593
                $TruePathCache{lc($fullpath)} = $fullpath;
594
            }
595
        }
596
 
597
        #
598
        #   Now that we have populated the cache with data from the directory
599
        #   we can expect to find our desired entry in the cache.
600
        #
601
        $tag = lc($TrueComponent . $elem );
602
        if ( exists $TruePathCache{ $tag } )
603
        {
604
            $TrueComponent = $TruePathCache{ $tag };
605
        }
606
        else
607
        {
608
            DebugDumpData ("Cache", \%TruePathCache);
609
            Error ("TruePath Internal error. File may have been deleted: $tag");
610
        }
611
        Debug ("Have: $TrueComponent");
612
    }
613
 
614
    Verbose ("TruePath: $TrueComponent");
615
    return $TrueComponent;
616
}
617
 
618
#-------------------------------------------------------------------------------
227 dpurdie 619
# Function        : CleanPath
620
#
621
# Description     : Cleanup a path
622
#                   Remove xxx/.. constructs
623
#
624
# Note            : Will not perform error detection on badly formed
625
#                   absolute paths.
626
#
627
# Inputs          : Source file path
628
#
629
# Returns         : Clean absolute or relative path
630
#
631
#
632
sub CleanPath
633
{
634
    my ($dpath) = @_;
635
    my @result;
636
    Debug("CleanPath: Source: $dpath");
637
 
638
    #
639
    #   Cleanup the the user input. Remove double delimiters and ensure there
640
    #   is no trailing delemiter
641
    #
245 dpurdie 642
    $dpath =~ s~/+~/~g;
227 dpurdie 643
    $dpath =~ s~/$~~g;
644
 
645
    #
646
    #   Walk the bits and remove "xxx/.." directories
647
    #
648
    foreach ( split ( '/', $dpath ) )
649
    {
650
        if ( $_ ne '..' || $#result < 0 )
651
        {
652
            push @result, $_;
653
        }
654
        else
655
        {
656
            if ( $#result >= 0 )
657
            {
283 dpurdie 658
                my $last_dir = pop @result;
659
                push (@result, $last_dir, $_)
660
                    if ($last_dir eq '..' || $last_dir eq '');
227 dpurdie 661
            }
662
        }
663
    }
664
 
665
    my $result = join ( '/', @result );
666
    Debug("CleanPath: Result: $result");
667
    return $result;
668
}
669
 
670
#-------------------------------------------------------------------------------
671
# Function        : StripDrive
672
#
673
# Description     : Strip any leading drive speification
674
#
675
# Inputs          : $fname          - Path to process
676
#
677
# Returns         : Path, with drive letter stripped
678
#                   Will do nothing on Unix systems
679
#
680
sub StripDrive
681
{
682
    my( $fname ) = @_;                          # Full name
683
 
684
    $fname =~ s/^[A-Za-z]://g                  # leading drive spec
685
        if ( ! $isUnix );
686
    return $fname;
687
}
688
 
689
#-------------------------------------------------------------------------------
690
# Function        : StripDir
691
#
692
# Description     : Strip directory (returns file, including extension)
693
#
694
# Inputs          : $fname          - Path to process
695
#
696
# Returns         : filename + extension
697
#
698
sub StripDir
699
{
700
    my( $fname ) = @_;                          # Full name
701
    my( $idx );
702
 
703
    if (($idx = rindex($fname, "/")) == -1) {
704
        if (($idx = rindex($fname, "\\")) == -1) {
705
            return $fname;                      # No path ...
706
        }
707
    }
708
    return substr($fname, $idx+1, 512);
709
}
710
 
711
#-------------------------------------------------------------------------------
712
# Function        : StripExt
713
#
714
# Description     : Strip extension (return basename, plus any dir)
715
#
716
# Inputs          : $fname          - Path to process
717
#
718
# Returns         : basename, plus any dir
719
#                   Simply removes one extension
720
#
721
sub StripExt
722
{
723
    my( $fname ) = @_;
724
 
725
    $fname =~ s/(\S+)(\.\S+)/$1/;               # strip out trailing '.<ext>'
726
    return ($fname);
727
}
728
 
729
#-------------------------------------------------------------------------------
730
# Function        : StripFile
731
#
732
# Description     : Strip filename (returns extension)
733
#
734
# Inputs          : $fname          - Path to process
735
#
736
# Returns         : extension
737
#                   Will return an empty string if the input does not have an
738
#                   extension.
739
#
740
sub StripFile
741
{
742
    my( $fname ) = @_;
743
 
744
    $fname =~ s/(\S+)(\.\S+)/$2/;               # Strip out items before '.<ext>'
745
    return ("")                                 # No extension
746
        if ("$fname" eq "@_");
747
    return ($fname);
748
}
749
 
750
#-------------------------------------------------------------------------------
751
# Function        : StripFileExt
752
#
753
# Description     : Strip filename and ext (returns dir)
754
#
755
# Inputs          : $fname          - Path to process
756
#
757
# Returns         : Directory of a file path
758
#
759
 
760
 
761
#   StripFileExt( path ) ---
762
#       Strip filename and ext (returns dir)
763
#..
764
 
765
sub StripFileExt
766
{
767
    my( $fname ) = @_;                          # Full name
768
    my( $idx );
769
    my $dir;
770
 
771
    if (($idx = rindex($fname, "/")) == -1) {
772
        if (($idx = rindex($fname, "\\")) == -1) {
773
            return "";                          # No path ...
774
        }
775
    }
776
 
777
    return substr($fname, 0, $idx);
778
}
779
 
780
#-------------------------------------------------------------------------------
781
# Function        : StripDirExt
782
#
783
# Description     : Strip the directory and extension from a file
784
#                   Returning the base file. Optionally replace the extension
785
#                   with a user value
786
#
787
# Inputs          : Full path name
788
#                   Optional extension to be replaced
789
#
790
# Returns         :
791
#
792
sub StripDirExt
793
{
794
    my ($fname, $ext ) = (@_, '');
795
    $fname =~ s~.*[/\\]~~;                      # Strip directory
796
    $fname =~ s/\.[^.]+$/$ext/;
797
    return $fname;
798
}
799
 
800
 
801
#-------------------------------------------------------------------------------
802
# Function        : CleanDirName
803
#
804
# Description     : Clean up a directory path string
805
#                       1) Remove multiple //
806
#                       2) Remove multiple /./
807
#                       2) Remove leading ./
808
#                       3) Remove trailing /
809
#                       4) Remove /xxxx/../
810
#
811
# Inputs          : A dirty directory path
812
#
813
# Returns         : A clean directory path
814
#
815
sub CleanDirName
816
{
817
    my ( $dir ) = @_;
818
    $dir =~ s~//~/~g;                   # Kill multiple //
819
    $dir =~ s~/\./~/~g;                 # Kill multiple /./
820
    $dir =~ s~^\./~~;                   # Kill leading ./
821
    $dir = '.' unless ( $dir );         # Ensure we have a path
822
 
823
    #
824
    #   Remove /xxxxx/../ bits
825
    #
826
    unless ( $dir =~ m~^\.\./~  )
827
    {
828
        while ( $dir =~ s~
829
                        (^|/)               # Allow for stings that may not start with a /
830
                        [^/]+/\.\.          # xxxxx/.., where xxxx is anything other than a /
831
                        (/|$)               # Allow for strings ending with /..
832
                        ~$1~x               # Replace with the start character
833
              )
834
        {
835
            last if ( $dir =~ m~^\.\./~ );  # Too far. Stop now !
836
        }
837
    }
838
 
839
    $dir =~ s~/$~~;                     # No trailing /
840
    $dir =~ s~/\.$~~;                   # No trailing /.
841
    return $dir;
842
}
843
 
844
#-------------------------------------------------------------------------------
845
# Function        : DisplayPath
846
#
847
# Description     : Cleanup a path for display purposes
848
#                   Useful under windows to provide paths with \ that can be
849
#                   cut and pasted.
850
#
851
#                   If cygwin is located in the environment, then this function
852
#                   will not convert / to \.
853
#
854
# Inputs          : A path to modify
855
#
856
# Returns         : Modified path
857
#
858
sub DisplayPath
859
{
860
    my ($path) = @_;
861
    if ( ! $isUnix && ! $isCygWin )
862
    {
863
        $path =~ s~/~\\~g;
864
    }
865
    return $path;
866
}
867
 
361 dpurdie 868
#-------------------------------------------------------------------------------
869
# Function        : RmDirTree
870
#
871
# Description     : Delete a directory tree
872
#                   Really delete it. Allow for users to remove directory
873
#                   without search permissions under unix.
874
#
875
#                   Can also delete a file
876
#
2439 dpurdie 877
#                   This function has a bit of history
878
#                   I've tried the Perl rmtree(), but there were situations
879
#                   where the OS(WIN32) says the directory exists after its been
880
#                   deleted. Also the Jats-Win32 version of chmod would issue
881
#                   messages if it couldn't find the dir/file.
882
#
883
#                   The solution is to use JATS' own JatsFileUtil utility
884
#                   This appears to do the right thing
885
#
361 dpurdie 886
# Inputs          : $path                   - Path to directory
887
#
888
# Returns         : 1                       - Still there
889
#
890
sub RmDirTree
891
{
892
    my ($path) = @_;
893
    if ( -e $path )
894
    {
2439 dpurdie 895
        #  Need to know if its a file or a directory
896
        #
897
        my $mode = ( -d $path ) ? 'T' : 'r';
898
 
899
        #
900
        #   Use JATS's own utility to do the hardwork
901
        #   Used as it address a number of issues
902
        #
903
        #   Merge in verbosity
904
        #
905
        system ("$ENV{GBE_BIN}/JatsFileUtil", $mode . $::ScmVerbose, '', $path );
906
 
907
        #
908
        #   Shouldn't happen but ...
909
        #   If the path still exists try another (one this has known problems)
910
        #
911
        if ( -e $path )
912
        {
913
            Verbose3 ("RmDirTree: Directory still exists. Change permissions: $path");
914
            system ("$ENV{GBE_BIN}/chmod", '-R', 'u+wrx', $path);
915
            rmtree( $path );
916
        }
361 dpurdie 917
    }
918
    return ( -e $path );
919
}
920
 
227 dpurdie 921
1;
922
 
923