home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / lang / perl / 5435 < prev    next >
Encoding:
Text File  |  1992-08-22  |  5.9 KB  |  272 lines

  1. Newsgroups: comp.lang.perl
  2. Path: sparky!uunet!fmrco!fmrco!asherman
  3. From: asherman@laser.fmrco.com (Aaron Sherman)
  4. Subject: Re: Filename expansion ("~user")
  5. In-Reply-To: merlyn@romulus.reed.edu's message of 21 Aug 92 16:23:01 GMT
  6. Message-ID: <ASHERMAN.92Aug22193046@laser.fmrco.com>
  7. Sender: news@fmrco.uucp
  8. Reply-To: asherman@fmrco.COM
  9. Organization: I-Kinetics, 19 Bishop-Allen Dr., Cambridge, MA
  10. References: <1992Aug20.153727.167@cbnews.cb.att.com>
  11.     <MERLYN.92Aug21092257@romulus.reed.edu>
  12. Distribution: usa
  13. Date: Sun, 23 Aug 1992 00:30:46 GMT
  14. Lines: 256
  15.  
  16.  
  17. This is a library based on my "apath" program, which allows you to
  18. resolve path names in various ways. To see what it is capable of, look
  19. at the get_options subroutine, or try the following calls:
  20.  
  21.     require 'apathlib.pl';
  22.     print &apath('t','~root'),"\n";
  23.     print &apath('ve','/usr/bin/${PAGER}'),"\n";
  24.     print join("\n",&apath('sl','/bin','/etc/route')),"\n";
  25.     print &apath('tsa','~bin/bin'),"\n";
  26.  
  27. To sum up:
  28.  
  29.     &apath(OPTIONS,LIST)
  30.  
  31.     where OPTIONS is one of: a, n, l, u, t, v or s.
  32.     and LIST is a list of paths to resolve.
  33.  
  34. TODO:
  35.  
  36.     o Allow setting of options ONCE to increase speed for later
  37.       calls.
  38.  
  39.     o Add support for Domain/OS style paths (i.e. //foo, where foo
  40.       is a machine name).
  41.  
  42.     o Always have to make it just a LITTLE faster...
  43.  
  44. -------------CUT HERE-----------------
  45. # Apathlib: a library for Analyzing and simplifying path-names.
  46. # Copyright (C) 1992  Aaron Sherman
  47. #
  48. #    This program is free software; you can redistribute it to your
  49. #    heart's content, just don't claim that you wrote it, and leave
  50. #    this copyright section alone.
  51. #
  52. #    If you make changes, note this in the code.
  53.  
  54. #    This program is distributed in the hope that it will be useful,
  55. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  56. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  57.  
  58. # You can contact the author via electronic-mail as:
  59. #
  60. #    asherman@fmrco.com
  61. #
  62.  
  63. package apath;
  64.  
  65. $version = '$Id: apathlib.pl,v 1.3 1992/08/22 23:14:17 asherman Exp $';
  66.  
  67. package main;
  68.  
  69. sub apath
  70. {
  71.     package apath;
  72.  
  73.     local($options,@list) = @_;
  74.     local(*_,%done,$file,$line,@return);
  75.  
  76.     &get_options($options);
  77.  
  78.     foreach(@list)
  79.     {
  80.     # I don't increment $done{$_} here, since it is done below.
  81.     
  82.     &expand_name($_) if ($tilde || $variable);
  83.  
  84.     next if ($unique && $done{$_});
  85.     
  86.     if ($validate && ! -e $_)
  87.     {
  88.         push(@return,undef);
  89.         next;
  90.     }
  91.     ($file,$line) = &follow($_);
  92.  
  93.     unless(($unique && $done{$file}++) || ($delete && $_ eq $file))
  94.     {
  95.         push(@return,$line);
  96.     }
  97.     }
  98.  
  99.     @return;
  100. }
  101.  
  102.  
  103. package apath;
  104.  
  105. sub get_options
  106. {
  107.     local($opt) = @_;
  108.  
  109.     $long        = 0;
  110.     $abbrv        = 0;
  111.     $delete        = 0;
  112.     $unique        = 0;
  113.     $validate        = 0;
  114.     $links        = 0;
  115.     $variable        = 0;
  116.     $tilde        = 0;
  117.  
  118.     foreach(split(//,$opt))
  119.     {
  120.     if ($_ eq 'a')        # Abbreviated long-output
  121.     {
  122.         $long = 1;
  123.         $abbrv = 1;
  124.     }
  125.     elsif ($_ eq 'n')        # Delete paths that are not simplified.
  126.     {
  127.         $delete = 1;
  128.     }
  129.     elsif ($_ eq 'e')        # Validate that files exist
  130.     {
  131.         $validate = 1;
  132.     }
  133.     elsif ($_ eq 'l')        # Long output
  134.     {
  135.         $long = 1;
  136.         $abbrv = 0;
  137.     }
  138.     elsif ($_ eq 'u')        # Uniquify output
  139.     {
  140.         $unique = 1;
  141.     }
  142.     elsif ($_ eq 't')        # Tilde (~) expansion
  143.     {
  144.         $tilde = 1;
  145.     }
  146.     elsif ($_ eq 'v')        # Variable (/foo/${BAR}) expansion
  147.     {
  148.         $variable = 1;
  149.     }
  150.     elsif ($_ eq 's')        # Resolve symlinks
  151.     {
  152.         $links = 1;
  153.     }
  154.     }
  155. }
  156.  
  157. # This subroutine resolves ~ and variable abbreviations
  158.  
  159. sub expand_name
  160. {
  161.     local($file) = @_;
  162.  
  163.     if ($tilde && $file =~ /^\~/)
  164.     {
  165.     $file =~ s%^\~([^/]*)%%;
  166.     $tname = $1;
  167.     if ($tname eq '')
  168.     {
  169.         $tname = getlogin;
  170.     }
  171.     @pwd = getpwnam($tname);
  172.     if (@pwd)
  173.     {
  174.         $file = $pwd[7] . $file;
  175.     }
  176.     }
  177.  
  178.     while ($variable && $file =~ /\$\{(\w+)\}/)
  179.     {
  180.     local($var) = $ENV{$1};
  181.     $file =~ s/\$\{\w+\}/$var/;
  182.     }
  183.     $_[0] = $file;
  184. }
  185.  
  186. # This subroutine follows a file-path, element by element, and determines what
  187. # it's hard path is (i.e. the path without any symbolic links, and no .'s or
  188. # ..'s, except at the beginnings of relative-paths).
  189. #
  190. # It's return is a two-element list of the hard path, and the line to print.
  191. # The format of the line to print is dependant on the values of $long and
  192. # $abbrv.
  193. #
  194. # No globals are modified.
  195. sub follow
  196. {
  197.     local($exist,$_) = ((-e $_[0]), @_);
  198.     local($line,$abs,$tmp,$link,@path_stack);
  199.  
  200.     if ($long)
  201.     {
  202.     $line = "$_:";
  203.     $line .= "\n" unless ($abbrv);
  204.     }
  205.  
  206.     # Split up the path, and initialize the stack.
  207.     if (/^\/+$/)
  208.     {
  209.     push(@path_stack,'');
  210.     }
  211.     else
  212.     {
  213.     @path_stack = split(m./+.,$_);
  214.     }
  215.  
  216.     # Pop each element off of the stack, pushing elements on, when a
  217.     # symbolic-link is encountered. As elements are poped off, they
  218.     # are added to the end of $abs, which is the file's "hard path-name"
  219.     while(defined($elem = shift(@path_stack)))
  220.     {
  221.     # $elem eq '' means a null path-element. Could be ''/'foo'
  222.     if ($elem eq '' || $elem eq '.')
  223.     {
  224.         $abs = '/' if ($elem eq '' && $abs eq '');
  225.         next;
  226.     }
  227.  
  228.     # Resolve .. in path-names.
  229.     if ($abs && $elem eq '..')
  230.     {
  231.         if ($abs =~ m%^\.\.(/\.\.)*$%)
  232.         {
  233.         $abs .= '/..';
  234.         }
  235.         elsif ($abs ne '/')
  236.         {
  237.             $abs =~ s%[^/]+$%%;
  238.             $abs = '.' if $abs eq '';
  239.             $abs =~ s%/+$%% unless $abs eq '/';
  240.         }
  241.         next;
  242.     }
  243.  
  244.     # Don't add a / if nothing there yet.
  245.     $tmp = $abs . (($abs eq '' || $abs =~ m%/$%)?'':'/') . $elem;
  246.  
  247.     # Check for symbolic-links.
  248.     if ($exist && $links && defined($link = readlink($tmp)))
  249.     {
  250.         $line .= "\t\t$tmp -> $link\n" if ($long && !$abbrv);
  251.         $abs = '' if substr($link,0,1) eq '/';
  252.         unshift(@path_stack,split(m./+.,$link));
  253.     }
  254.     else
  255.     {
  256.         $abs = $tmp;
  257.     }
  258.     }
  259.     $abs = '.' if $abs eq '';
  260.     $line .= "\t" if ($long && !$abbrv);
  261.     $line .= $abs;
  262.     ($abs,$line);
  263. }
  264.  
  265. 1;
  266. -----------------CUT HERE-----------
  267. --
  268. --------
  269. Disclaimer: I am solely responsible for the content of this message.
  270. The views expressed here may not be the views of I-Kinetics, Fidelity,
  271. any of the Fidelity-owned corporations or my mother.
  272.