home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / lang / perl / 7369 < prev    next >
Encoding:
Text File  |  1992-12-11  |  4.1 KB  |  171 lines

  1. Newsgroups: comp.lang.perl
  2. Path: sparky!uunet!wupost!howland.reston.ans.net!sol.ctr.columbia.edu!eff!news.oc.com!convex!tchrist
  3. From: Tom Christiansen <tchrist@convex.COM>
  4. Subject: Re: Perl-side globbing (was Re: Perl Shell...)
  5. Originator: tchrist@pixel.convex.com
  6. Sender: usenet@news.eng.convex.com (news access account)
  7. Message-ID: <1992Dec11.212055.21505@news.eng.convex.com>
  8. Date: Fri, 11 Dec 1992 21:20:55 GMT
  9. Reply-To: tchrist@convex.COM (Tom Christiansen)
  10. References: <18086@autodesk.COM> <1992Dec10.073900.16503@spillman.uucp>
  11. Nntp-Posting-Host: pixel.convex.com
  12. Organization: Convex Computer Corporation, Colorado Springs, CO
  13. X-Disclaimer: This message was written by a user at CONVEX Computer
  14.               Corp. The opinions expressed are those of the user and
  15.               not necessarily those of CONVEX.
  16. Lines: 153
  17.  
  18. I've always used this...
  19.  
  20. --tom
  21.  
  22. ###############################################################
  23. # glob.pl by Tom Christiansen <tchrist@convex.com>
  24. #
  25. # globbing package for perl that doesn't blow up 
  26. # due to shell arg list expansion limits because it
  27. # uses its own readdir()s.
  28. #
  29. # entry points are:
  30. #    &SHglob for shell expr globbing (like perl's <*>) 
  31. #    &REglob for perl expr globbing
  32. #
  33. # set $glob'debug for trace and debug info
  34. #
  35. # extra features: ~user expansions and {f{u,oo}ba{r,z},gl{arch,ork}}
  36. # (latter for SHglob only -- REglob can use perl's alternation)
  37. ###############################################################
  38.  
  39.  
  40. package glob;
  41.  
  42. sub main'SHglob {
  43.     local($_) = @_;
  44.     local(@retlist) = ();
  45.     local($pre, $alt, $post);
  46.  
  47.     printf "SHglob: globbing $_\n" if $debug;
  48.  
  49.     s/([.+\\])/\\$1/g;
  50.     s/\*/.*/g;
  51.     s/\?/./g;
  52.  
  53.     while ( ($pre, $alt, $post) = /^(.*)\{([^{]*)\}(.*)$/ ) {
  54.         $alt =~ s/,/|/g;
  55.         $_ = "$pre($alt)$post";
  56.     }
  57.     s/\(\|/(\\.|/g;
  58.     s/\|\)/|\\.)/g;
  59.  
  60.     for (split(' ')) {
  61.     push(@retlist, &main'REglob($_));
  62.     } 
  63.  
  64.     sort @retlist;
  65.  
  66. sub main'REglob {
  67.     local($path) = @_;
  68.     local($_);
  69.     local(@retlist) = ();
  70.     local($root,$expr,$pos);
  71.     local($relative) = 0;
  72.     local(@dirs);
  73.     local($haveglobbed);
  74.  
  75.     @dirs = split(/\/+/, $path);
  76.  
  77.     if ($dirs[$[] =~ m!~(.*)!) {
  78.     $dirs[$[] = &homedir($1);
  79.     return @retlist unless $dirs[$[];
  80.     } elsif ($dirs[$[] eq '') {
  81.     $dirs[$[] = '/' unless $dirs[$[] =~ m!^\.{1,2}$!;
  82.     } else {
  83.     unshift(@dirs, '.');
  84.     $relative = 1;
  85.     } 
  86.  
  87.     print "REglob: globbing ", join('/',@dirs), "\n" if $debug;
  88.  
  89.     @retlist = &expand(@dirs);
  90.  
  91.     for (@retlist) {
  92.     s!^\./!! if $relative;
  93.     s!/{2,}!/!g;
  94.     } 
  95.  
  96.     return sort @retlist;
  97. }
  98.  
  99. sub expand {
  100.     local($dir, $thisdir, @rest) = @_;
  101.     local($nextdir);
  102.     local($_);
  103.     local(@retlist) = ();
  104.     local(*DIR);
  105.  
  106.     print "glob'expand: $dir $thisdir @rest\n" if $debug;
  107.  
  108.     unless ($haveglobbed || $thisdir =~ /([^\\]?)[?.*{[+\\]/ && $1 ne '\\') {
  109.     @retlist = ($thisdir);
  110.     } else {
  111.     unless (opendir(DIR,$dir)) {
  112.         warn "glob'expand: can't opendir $dir: $!\n" if $debug;
  113.     } else {
  114.         @retlist = grep(/^$thisdir$/,readdir(DIR));
  115.         @retlist = grep(!/^\./, @retlist) unless $thisdir =~ /\\\./;
  116.         $haveglobbed++;
  117.     } 
  118.     closedir DIR;
  119.     } 
  120.  
  121.     for (@retlist) {
  122.     $_ = $dir . '/' . $_;
  123.     }
  124.  
  125.     if ($nextdir = shift @rest) {
  126.     local(@newlist) = ();
  127.     for (@retlist) {
  128.         push(@newlist,&expand($_,$nextdir,@rest));
  129.     } 
  130.     @retlist = @newlist;
  131.     } 
  132.     for (@retlist) { s#/./#/#g; }
  133.  
  134.     return @retlist;
  135.  
  136. sub homedir {
  137.     local($user) = @_;
  138.     local(@pwent);
  139.     # global %homedir
  140.  
  141.     if (!$user) {
  142.     return $ENV{'HOME'}         if $ENV{'HOME'};
  143.     unless ($user = $ENV{'USER'}) {
  144.         @pwent = getpwnam($>);
  145.         $homedir{$user = $pwent[$[]} = $pwent[$#pwent-1];
  146.     } 
  147.     warn "glob'homedir: who are you, user #$>?" 
  148.         if $debug && !$user;
  149.     } 
  150.     unless (defined $homedir{$user}) {
  151.     if (@pwent = getpwnam($user)) {
  152.         $homedir{$user} = $pwent[$#pwent - 1];
  153.     } else {
  154.         warn "glob'homedir: who is user $user?\n" if $debug;
  155.         #$homedir{$user} = '/';
  156.     }
  157.     }
  158.     $homedir{$user};
  159.  
  160. 1;
  161.  
  162. __END__
  163. -- 
  164.     Tom Christiansen      tchrist@convex.com      convex!tchrist
  165.  
  166.  
  167. There are two ways to write error-free programs.  Only the third one works.
  168.