Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7323 dpurdie 1
########################################################################
2
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
3
#
4
# Module name   : JatsFileSet.pm
5
# Module type   : Makefile system
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   : Package to simplify the process of locating one or more
10
#                 files with the JATS build environment.
11
#
12
#                 Specifically designed to assist in the creation of:
13
#                       Day0 file systems
14
#                       Debian Packages
15
#                       Deployable packages
16
#
17
#                 Intended to locate files in dependent packages
18
#                 Supports LinkPkgArchive and BuildPkgArchive
19
#
20
#                 Knows about the construction of programs and shared
21
#                 libraries as well as other special file types.
22
#
23
#                 Uses a set of options to identify the file
24
#                 The file specifier is of the form
25
#                       Name[,--Option]+
26
#
27
#                 Available Options are:
28
#                       --prog          - Name is a program
29
#                                         Search where programs are stored
30
#                                         Append the target specific suffix
31
#                       --bin           - Similar to --prog, but does not modify
32
#                                         the provided name.
33
#                       --header        - Searches header file locations
34
#                       --deb           - Name is the base of a Debian Package
35
#                                         Searchs in BIN directories
36
#                       --dir=SubDir    - Search for Name in a subdir of the
37
#                                         dependent packages
38
#                       --pkg           - Search for Name in a pkg subdir
39
#                                         Limited by the current target
40
#                       --etc           - Same as --dir=etc
41
#                       --jar           - Same as --dir=jar
42
#                       --scripts       - Same as --dir=scripts
43
#
44
#                       --AllowMultiple - Allow multiple files to be located
45
#                       --AllowNone     - Allow no file to be located
46
#                       --Verbose       - Be a bit verbose about the process
47
#
48
#                       --FilterOutRe=xxx - An Re to filter out
49
#                       --FilterOut=xxx   - An glob to filter out
50
#
51
# Usage:
52
#
53
#   @data = JatsFileSet::LocateFile('MyProg,--prog');
54
#
55
#......................................................................#
56
 
57
require 5.008_002;
58
 
59
package JatsFileSet;
60
 
61
use strict;
62
use warnings;
63
 
64
use JatsError;
65
use JatsMakeConfig;
66
use FileUtils;
67
 
68
#
69
#   Globals
70
#
71
my  $data;                                  # Global Data
72
my %DirCache;
73
my %ReadDirCache;
74
 
75
#
76
#   Hash of known file location specifications
77
#   Only allowed to have one in any one definition
78
#
79
my %LocSpec = (
80
    'local'         => { code => \&searchLocal },
81
    'header'        => { code => \&searchInc },
82
    'prog'          => { code => \&searchProg },
83
    'bin'           => { code => \&searchBin },
84
    'deb'           => { code => \&searchDeb },
85
    'dir'           => { code => \&searchDir },
86
    'pkg'           => { code => \&searchPkg },
87
    'lib'           => { code => \&searchLib },
88
    'etc'           => { code => \&searchSimple, dir => 'etc' },
89
    'jar'           => { code => \&searchSimple, dir => 'jar'},
90
    'scripts'       => { code => \&searchSimple, dir => 'scripts'},
91
    'doc'           => { code => \&searchSimple, dir => 'doc'},
92
#    'thx'           => 1,
93
#    'jar'           => 1,
94
#    'local'         => 1,
95
#    'interface'     => 1,
96
);
97
 
98
#-------------------------------------------------------------------------------
99
# Function        : BEGIN
100
#
101
# Description     : Standard Package Interface
102
#
103
# Inputs          :
104
#
105
# Returns         :
106
#
107
BEGIN {
108
    use Exporter   ();
109
    our @ISA         = qw(Exporter);
110
    our @EXPORT      = qw(
111
                    FileSet
112
                      );
113
 
114
    our %EXPORT_TAGS = ( );     # eg: TAG => [ qw!name1 name2! ],
115
    our @EXPORT_OK   = qw();    # Allowed exports
116
}
117
 
118
#-------------------------------------------------------------------------------
119
# Function        : import
120
#
121
# Description     : Package import function
122
#                   This function will examine arguments provided in the
123
#                   invoking 'uses' list and will configure the package
124
#                   accordingly.
125
#
126
# Inputs          : $pack           - Name of this package
127
#                   @vars           - User Config Options
128
#                   Config Options:
129
#                       :verbose=xxx
130
#                       :allowmultiple=xxx
131
#                       :allownone=xxx
132
#
133
# Returns         : 
134
#
135
sub import {
136
    my $pack = shift;
137
    my @vars;
138
    my @config;
139
 
140
    #
141
    #   Extract options of the form: :name=value and pass them to the
142
    #   ErrorConfig function. All other arguments will be passed to the
143
    #
144
    foreach ( @_ )
145
    {
146
        if ( m/^:verbose=(\d+)/i ) {
147
            $data->{'verbose'} = $1;
148
 
149
        } elsif ( m/^:allowmultiple=(\d+)/i ) {
150
            $data->{'allowmultiple'} = $1;
151
 
152
        } elsif ( m/^:allownone=(\d+)/i ) {
153
            $data->{'allownone'} = $1;
154
 
155
        } else {
156
            push @vars, $_;
157
        }
158
    }
159
 
160
    #
161
    #   Invoke Exporter function to handle the arguments that I don't understand
162
    #
163
    $pack->export_to_level(1, $pack , @vars);
164
}
165
 
166
 
167
#-------------------------------------------------------------------------------
168
# Function        : BEGIN
169
#
170
# Description     : Initialisation
171
#                   Load information create when the invoking makefile was
172
#                   created. This contains a lot of information
173
#                   as to the interface to the package
174
#
175
# Inputs          : None
176
#
177
# Returns         : Nothing
178
#
179
sub BEGIN
180
{
181
    #
182
    #   Load all the MakeFile generate information and  data structures
183
    #
184
    my $mi = JatsMakeConfigLoader::Load();
185
 
186
    #
187
    #   Document Class Variables
188
    #
189
    $data->{'platform'} = $mi->{'PLATFORM'};
190
    $data->{'type'}     = $mi->{'TYPE'};
191
 
192
    #
193
    #   Locate required entries
194
    #
195
    my @result;
196
    for my $entry ( @{$mi->GetDataItem('%ScmBuildPkgRules')} )
197
    {
198
        #
199
        #   If a BuildPkgArchive, then skip as its data will be embedded
200
        #   in the pseudo INTERFACE package
201
        #
202
        next if ( ($entry->{'TYPE'} eq 'build' ) );
203
        push @result, $entry->{'ROOT'};
204
 
205
    }
206
 
207
    $data->{'BuildPaths'} = \@result;
208
    $data->{'BuildParts'} = $mi->GetDataItem('%BUILDPLATFORM_PARTS');
209
 
210
    $data->{'a'}    =  $mi->GetDataItem('$a');
211
    $data->{'exe'}  =  $mi->GetDataItem('$exe');
212
    $data->{'so'}   =  $mi->GetDataItem('$so');
213
 
214
#    DebugDumpData(__PACKAGE__, $data );
215
}
216
 
217
#-------------------------------------------------------------------------------
218
# Function        : LocateFile
219
#
220
# Description     : Locate a file as specified by a user description
221
#
222
# Inputs          : $fspec                  - A file specification
223
#
224
# Returns         : A list of files that match
225
#                   May not return on error
226
#
227
sub LocateFile
228
{
229
    my ($fspec) = @_;
230
    my $mode;
231
    my $estate = ErrorReConfig ('function' => 'LocateFile');
232
 
233
    #
234
    #   Create a new instance using default data
235
    #
236
    my $self;
237
    while (my ($key, $value) = each %{$data} ) {
238
        $self->{$key} = $value;
239
    }
240
 
241
    bless ($self, __PACKAGE__);
242
 
243
    #
244
    #   Split the file spec into bits
245
    #   Extract options and the base file name
246
    #       Create a hash of options
247
    #       Convert options to lowercase
248
    #       Extract any assignments
249
    #       Treat --Flag as --Flag=1
250
    #
251
    $self->{'uspec'} = $fspec;
252
    while ( $fspec =~ m~^(.*),--(.*?)(=(.*?))?,*$~ )
253
    {
254
        $fspec = $1;
255
        my $opt = lc($2);
256
 
257
        #
258
        #   Process options
259
        #
260
        if ( $opt eq 'filteroutre' ) {
261
            push @{$self->{$opt}}, $4;
262
 
263
        } elsif ( $opt eq 'filterout' ) {
264
            push @{$self->{'filteroutre'}}, glob2pat($4);
265
 
266
        } elsif ( exists $LocSpec{$opt} ) {
267
            $mode = $LocSpec{$opt}
268
 
269
        } else {
270
            $self->{$opt} = defined($3) ? $4 : 1;
271
        }
272
    }
273
    #
274
    #   Merge system and user verbose mode
275
    #   Reconfigure the error control
276
    #
277
    if ( $self->{'verbose'} )
278
    {
279
        ErrorConfig ( 'verbose' =>  $self->{'verbose'} );
280
    }
281
 
282
    #
283
    #   Save the remainder as the filename
284
    #   It may not exist
285
    #
286
    $self->{'file'} = $fspec;
287
    $self->{'wildcard'} = ($fspec =~ m~[*?\[\]]~);
288
 
289
    #
290
    #   Determine the processing mode
291
    #
292
    $mode = $LocSpec{'local'} unless ( $mode );
293
    $self->{'Mode'} = $mode;
294
 
295
    #
296
    #   Error check - Internal sanity
297
    #
298
#    DebugDumpData(__PACKAGE__, $self );
299
    unless ( $mode->{'code'} )
300
    {
301
        DebugDumpData("File", $self);
302
        Error ("INTERNAL. Unknown search method: @_");
303
    }
304
 
305
    #
306
    #   Dispatch to a suitable processing routine
307
    #
308
    my @result = ( $mode->{'code'}( $self ) );
309
 
310
    @result = FilterRemove ( $self, \@result )
311
        if ( $self->{'wildcard'} );
312
 
313
    #
314
    #   Generate errors and warnings
315
    #
316
    if ( $#result < 0 )
317
    {
318
        Error ("No Files found: $self->{'uspec'}", $#result )
319
            unless ( $self->{'allownone'} );
320
    }
321
 
322
    if ( $#result > 0 )
323
    {
324
        Error ("Mutliple Files found: $self->{'uspec'}", @result )
325
            unless ( $self->{'allowmultiple'} );
326
 
327
        Warning("Mutliple Files found. Only the first will be used: $self->{'uspec'}", @result )
328
            unless ( wantarray );
329
    }
330
 
331
    #
332
    #   Create verbose output for the user
333
    #
334
    Verbose("LocateFiles: $self->{'uspec'}. Results:", @result );
335
 
336
    #
337
    #   Provide the user the required result
338
    #
339
    return wantarray ? @result : $result[0];
340
}
341
 
342
#-------------------------------------------------------------------------------
343
# Function        : searchLocal
344
#
345
# Description     : Looking for a file in the local file system
346
#                   This is the default mode of operation
347
#
348
# Inputs          : $self                   - Instance Data
349
#
350
# Returns         : Array of files that have been found
351
#
352
sub searchLocal
353
{
354
    my ($self) = @_;
355
    my @results;
356
    my $ufile = $self->{'file'};
357
 
358
    #
359
    #   Simple search
360
    #
361
    if ( ! $self->{'wildcard'} )
362
    {
363
        push @results, $ufile  if ( -f $ufile );
364
        return @results;
365
    }
366
 
367
    #
368
    #   Wildcarded Search
369
    #
370
    my $dir = StripFileExt( $ufile ) || '.';
371
    $ufile = StripDir( $ufile );
372
 
373
    foreach  ( ReadDir($dir) )
374
    {
375
        Verbose2 ("Test: $_, $ufile");
376
        push @results, $_  if ( $_ =~ "/$ufile\$" );
377
    }
378
    return @results;
379
}
380
 
381
 
382
#-------------------------------------------------------------------------------
383
# Function        : searchLib
384
#
385
# Description     : The user is looking for a shared library file
386
#                   It will have a specific extension
387
#                   It will be in one of the 'lib' directories known to JATS
388
#
389
#                   Current Limitations:
390
#                       Does not perform Unix Lib Prefix
391
#                       Does not handle Name.version.so
392
#                       Does not handle 'so' Name and 'real' name pairs
393
#
394
#
395
# Inputs          : $self                   - Instance Data
396
#
397
# Returns         : 
398
#
399
sub searchLib
400
{
401
    my ($self) = @_;
402
 
403
    my $ufile = $self->{'file'};
404
    my $ext =  $self->{so} ? '.' . $self->{a} : '';
405
    my @results;
406
    foreach my $dir ( @{ FancyDirs($self, 'lib') } )
407
    {
408
        foreach  ( ReadDir($dir) )
409
        {
410
            foreach my $type ( $self->{'type'}, '' )
411
            {
412
Verbose2 ("Test: $_, $ufile");
413
                push @results, $_  if ( $_ =~ "/$ufile$type$ext\$" );
414
            }
415
        }
416
    }
417
    return @results;
418
}
419
 
420
 
421
#-------------------------------------------------------------------------------
422
# Function        : searchProg
423
#
424
# Description     : The user is looking for a program file
425
#                   It will have a specific extension
426
#                   It will be in one of the 'Bin' directories known to JATS
427
#
428
# Inputs          : $self                   - Instance Data
429
#
430
# Returns         : 
431
#
432
sub searchProg
433
{
434
    my ($self) = @_;
435
 
436
    my $ufile = $self->{'file'} . $self->{exe};
437
    my @results;
438
    foreach my $dir ( @{ FancyDirs($self, 'bin') } )
439
    {
440
        foreach  ( ReadDir($dir) )
441
        {
442
Verbose2 ("Test: $_, $ufile");
443
            push @results, $_  if ( $_ =~ "/$ufile\$" );
444
        }
445
    }
446
    return @results;
447
}
448
 
449
#-------------------------------------------------------------------------------
450
# Function        : searchBin
451
#
452
# Description     : The user is looking for a program file
453
#                   It will be in one of the 'Bin' directories known to JATS
454
#
455
# Inputs          : $self                   - Instance Data
456
#
457
# Returns         : 
458
#
459
sub searchBin
460
{
461
    my ($self) = @_;
462
 
463
    my $ufile = $self->{'file'};
464
    my @results;
465
    foreach my $dir ( @{ FancyDirs($self, 'bin') } )
466
    {
467
        foreach  ( ReadDir($dir) )
468
        {
469
Verbose2 ("Test: $_, $ufile");
470
            push @results, $_  if ( $_ =~ "/$ufile\$" );
471
        }
472
    }
473
    return @results;
474
}
475
 
476
#-------------------------------------------------------------------------------
477
# Function        : searchInc
478
#
479
# Description     : The user is looking for a program file
480
#                   It will be in one of the 'include' directories known to JATS
481
#
482
# Inputs          : $self                   - Instance Data
483
#
484
# Returns         : 
485
#
486
sub searchInc
487
{
488
    my ($self) = @_;
489
 
490
    my $ufile = $self->{'file'};
491
    my @results;
492
    foreach my $dir ( @{ FancyDirs($self, 'include', 'inc') } )
493
    {
494
        foreach  ( ReadDir($dir) )
495
        {
496
Verbose2 ("Test: $_, $ufile");
497
            push @results, $_  if ( $_ =~ "/$ufile\$" );
498
        }
499
    }
500
    return @results;
501
}
502
 
503
 
504
 
505
#-------------------------------------------------------------------------------
506
# Function        : searchDeb
507
#
508
# Description     : The user is looking for a Debian Package
509
#                   It will have a specific extension
510
#                   It will be in one of the 'Bin' directories known to JATS
511
#
512
# Inputs          : $self                   - Instance Data
513
#
514
# Returns         : 
515
#
516
sub searchDeb
517
{
518
    my ($self) = @_;
519
 
520
    my $ufile = $self->{'file'};
521
    my @results;
522
    foreach my $dir ( @{ FancyDirs($self, 'bin') } )
523
    {
524
        foreach  ( ReadDir($dir) )
525
        {
526
Verbose2 ("Test: $_, $ufile");
527
            push @results, $_  if ( $_ =~ "$dir/$self->{file}_*.deb" );
528
        }
529
    }
530
    return @results;
531
}
532
 
533
#-------------------------------------------------------------------------------
534
# Function        : searchDir
535
#
536
# Description     : The user is looking for a file in a package subdir
537
#                   It will be in one of the package directories
538
#
539
# Inputs          : $self                   - Instance Data
540
#
541
# Returns         : 
542
#
543
sub searchDir
544
{
545
    my ($self) = @_;
546
 
547
    my $ufile = $self->{'file'};
548
    my @results;
549
    foreach my $dir ( @{ MiscDirs($self, $self->{'dir'}) } )
550
    {
551
        foreach  ( ReadDir($dir) )
552
        {
553
Verbose2 ("Test: $_, $ufile");
554
            push @results, $_  if ( $_ =~ "/$ufile\$" );
555
        }
556
    }
557
    return @results;
558
}
559
 
560
#-------------------------------------------------------------------------------
561
# Function        : searchSimple
562
#
563
# Description     : The user is looking for a file in known subdir subdir
564
#                   It will be in one of the package directories
565
#
566
# Inputs          : $self                   - Instance Data
567
#
568
# Returns         : 
569
#
570
sub searchSimple
571
{
572
    my ($self) = @_;
573
 
574
    my $mode = $self->{'Mode'}{'dir'};
575
    Error ("JatsFileSet. searchSimple. Internal Error. No 'dir' configured'",
576
            "Entry: $self->{'uspec'}") unless ( $mode );
577
 
578
    $self->{'dir'} = $mode;
579
    return searchDir( $self );
580
}
581
 
582
#-------------------------------------------------------------------------------
583
# Function        : searchPkg
584
#
585
# Description     : The user is looking for a file in a package pkg subdir
586
#                   It will be in one of the package directories
587
#
588
# Inputs          : $self                   - Instance Data
589
#
590
# Returns         : 
591
#
592
sub searchPkg
593
{
594
    my ($self) = @_;
595
 
596
    my $ufile = $self->{'file'};
597
    foreach my $dir ( @{ PkgDirs($self) } )
598
    {
599
        my $file = "$dir/$ufile";
600
        return $file
601
            if ( -f $file );
602
    }
603
    return undef;
604
}
605
 
606
#-------------------------------------------------------------------------------
607
# Function        : FancyDirs
608
#
609
# Description     : Return an array of directories to search for Lib/Bin files
610
#                   Cache results for future use
611
#
612
#                   Lib dirs are used to hold:
613
#                       Shared Libraries
614
#                       Static Libraries
615
#
616
#                   The file name should have an embedded type (P or D)
617
#
618
#                   Lookin:         {BASE}/DIR/{PLATFORM}
619
#                   Compatability:  {BASE}/DIR.{PLATFORM}
620
#                                   {BASE}/DIR/{PLATFORM}{TYPE}
621
#                                   {BASE}/DIR.{PLATFORM}{TYPE}
622
#                                   {BASE}/DIR/DIR.{PLATFORM}{TYPE}
623
#
624
# Inputs          : $self                   - Instance Data
625
#                   @dirs                   - Root dir name (lib or bin, include, inc)
626
#
627
# Returns         : An Array
628
#
629
sub FancyDirs
630
{
631
    my ($self, @dirs) = @_;
632
    #
633
    #   Return cached results
634
    #
635
    unless ( $DirCache{$dirs[0]} )
636
    {
637
        #
638
        #   Create an array of location to search
639
        #
640
        my @result;
641
        foreach my $base ( @{$self->{'BuildPaths'}} )
642
        {
643
            foreach my $type ( $self->{'type'}, '' )
644
            {
645
                foreach my $subdir ( @{$self->{'BuildParts'}})
646
                {
647
                    foreach my $dir ( @dirs )
648
                    {
649
                        foreach my $join ( '/', '.', "/$dir." )
650
                        {
651
                            my $tdir = "$base/$dir$join$subdir$type";
652
#print "----Try : $dir\n";
653
                            push @result, $tdir if ( -d $tdir );
654
                        }
655
                    }
656
                }
657
            }
658
        }
659
        $DirCache{$dirs[0]} = \@result;
660
    }
661
    return $DirCache{$dirs[0]}
662
}
663
 
664
#-------------------------------------------------------------------------------
665
# Function        : PkgDirs
666
#
667
# Description     : Return an array of directories to search for Pkg files
668
#                   Cache results for future use
669
#
670
#                   pkg dirs are used to contain foreign subdirectory trees
671
#                   Typically used to transparently transfer 3rd parts software
672
#
673
#                   There are two forms of pkg dir
674
#                   Both are not supported within the same package
675
#
676
#                   Form-1
677
#                   Template:       {BASE}/pkg
678
#
679
#                   Form-2
680
#                   Template:       {BASE}/pkg.{PLATFORM}
681
#                   Template:       {BASE}/pkg.{MACHTYPE}
682
#
683
#                   Currently NOT a very good pkg searcher
684
#                   It does not handle pkg/pkg.MACHTYPE dirs
685
#
686
# Inputs          : $self                   - Instance Data
687
#
688
# Returns         : An Array
689
#
690
sub PkgDirs
691
{
692
    my $self = shift;
693
    #
694
    #   Return cached results
695
    #
696
    unless ( $DirCache{'pkg'} )
697
    {
698
        #
699
        #   Create an array of location to search
700
        #
701
        my @dirs;
702
        foreach my $base ( @{$self->{'BuildPaths'}} )
703
        {
704
            next unless ( -d "$base/pkg" );
705
            foreach my $subdir ( @{$self->{'BuildParts'}} )
706
            {
707
                my $dir = "$base/pkg/$subdir";
708
#print "----Try : $dir\n";
709
                push @dirs, $dir if ( -d $dir );
710
            }
711
 
712
            unless ( @dirs )
713
            {
714
                push @dirs, $base;
715
            }
716
 
717
        }
718
        $DirCache{'pkg'} = \@dirs;
719
    }
720
    return $DirCache{'pkg'}
721
}
722
 
723
#-------------------------------------------------------------------------------
724
# Function        : MiscDirs
725
#
726
# Description     : Return an array of directories to search for Misc files
727
#                   Cache results for future use
728
#
729
#                   Misc dirs are used to contains files of known types
730
#                   Normally a flat directory structure
731
#                   No 'type' information
732
#
733
#                   Template:   {BASE}/{DIR}
734
#
735
#                   Used for dirs that are not special, like the Bin and Lib
736
#
737
# Inputs          : $self                   - Instance Data
738
#                   $root                   - Base of the section
739
#
740
# Returns         : An Array
741
#
742
sub MiscDirs
743
{
744
 
745
    my ($self, $root) = @_;
746
 
747
    #
748
    #   Clean up the user path
749
    #   Remove leading, trailing and multiple /
750
    #
751
    $root =~ s~/+~/~g;
752
    $root =~ s~^/~~;
753
    $root =~ s~/$~~;
754
 
755
    #
756
    #   Return cached results
757
    #
758
    unless ( $DirCache{$root} )
759
    {
760
        #
761
        #   Create an array of location to search
762
        #
763
        my @dirs;
764
        foreach my $base ( @{$self->{'BuildPaths'}} )
765
        {
766
            my $dir = "$base/$root";
767
#print "----Try : $dir\n";
768
            push @dirs, $dir if ( -d $dir );
769
        }
770
        $DirCache{$root} = \@dirs;
771
    }
772
    return $DirCache{$root}
773
}
774
 
775
#-------------------------------------------------------------------------------
776
# Function        : ReadDir
777
#
778
# Description     : Read in a directory entry or return the cached result
779
#                   of a previous read
780
#
781
# Inputs          : $dir                    - Dir to Read
782
#
783
# Returns         : Array of dir contents
784
#
785
sub ReadDir
786
{
787
    my ($dir) = @_;
788
 
789
    unless ( $ReadDirCache{$dir}  )
790
    {
791
        my @dirs = glob ( "$dir/*");;
792
        $ReadDirCache{$dir} = \@dirs;
793
    }
794
#    DebugDumpData("Cache", \%ReadDirCache );
795
    return @{$ReadDirCache{$dir}};
796
}
797
 
798
#-------------------------------------------------------------------------------
799
# Function        : FilterRemove
800
#
801
# Description     : Perform any required Filter Out operations
802
#
803
# Inputs          : $ref                - Ref to array of files to process
804
#
805
# Returns         : Nothing
806
#                   Modifies $ref
807
#
808
sub FilterRemove
809
{
810
    my ($self, $ref) = @_;
811
 
812
    return @{$ref} unless ( exists $self->{'filteroutre'} );
813
 
814
    foreach my $filter ( @{$self->{'filteroutre'}} )
815
    {
816
        my @results;
817
        foreach  ( @{$ref} )
818
        {
819
            push @results, $_ unless ( $_ =~ m~$filter~ );
820
        }
821
        $ref = \@results;
822
 
823
    }
824
    return @{$ref};
825
}
826
 
827
#-------------------------------------------------------------------------------
828
# Function        : glob2pat
829
#
830
# Description     : Convert four shell wildcard characters into their equivalent
831
#                   regular expression; all other characters are quoted to
832
#                   render them literals.
833
#
834
# Inputs          : Shell style wildcard pattern
835
#
836
# Returns         : Perl RE
837
#
838
 
839
sub glob2pat
840
{
841
    my $globstr = shift;
842
    $globstr =~ s~^/~~;
843
    my %patmap = (
844
        '*' => '[^/]*',
845
        '?' => '[^/]',
846
        '[' => '[',
847
        ']' => ']',
848
        '-' => '-',
849
    );
850
    $globstr =~ s{(.)} { $patmap{$1} || "\Q$1" }ge;
851
    return '/' . $globstr . '$';
852
}
853
 
854
 
855
#sub DESTROY
856
#{
857
#    DebugDumpData(__PACKAGE__, @_);
858
#}
859
 
860
1;
861
 
862
 
863