home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume1 / 8712 / mkmf / 2 / src / optpath.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-13  |  2.1 KB  |  78 lines

  1. /* $Header: optpath.c,v 1.2 85/05/06 13:32:05 nicklin Exp $ */
  2.  
  3. /*
  4.  * Author: Peter J. Nicklin
  5.  */
  6.  
  7. /*
  8.  * optpath() condenses a pathname by eliminating adjacent separator
  9.  * characters, and current and parent directory names. If optpath()
  10.  * encounters a parent directory, it backtracks to eliminate the
  11.  * previous directory. If the beginning of the pathname is reached
  12.  * during backtracking, then if the pathname is absolute, the parent
  13.  * directory is purged, otherwise it is shifted to the beginning of
  14.  * pathname. Special care is taken not to clobber a shifted parent
  15.  * by using a guard pointer. Returns pathname.
  16.  */
  17. #include "path.h"
  18.  
  19. #define absolute_path    (*pathname == _RDIRC)
  20.  
  21. static char parentdir[] = PARENTDIR;    /* parent directory name */
  22.  
  23. char *
  24. optpath(pathname)
  25.     register char *pathname;    /* pathname to be optimized */
  26. {
  27.     register char *bp;        /* back pathname pointer */
  28.     register char *fp;        /* forward pathname pointer */
  29.     register char *up;        /* pathname update guard pointer */
  30.     char p1;            /* 1st parent directory character */
  31.     char p2;            /* 2nd parent directory character */
  32.  
  33.     p1 = parentdir[0];
  34.     p2 = parentdir[1];
  35.  
  36.     bp = fp = up = pathname;
  37.  
  38.     /* elimination of initial "./" causes no harmful side-effects */
  39.     if (fp[0] == _CDIRC && fp[1] == _PSC) fp += 2;
  40.  
  41.     while (*fp != '\0')
  42.         if (fp[0] == _PSC)
  43.             if (fp[1] == _PSC || fp[1] == '\0')
  44.                 fp += 1;    /* "//" or trailing `/' */
  45.             else if (fp[1]==_CDIRC && (fp[2]==_PSC || fp[2]=='\0'))
  46.                 fp += 2;    /* `.' */
  47.             else if ((fp[1] == p1 && fp[2] == p2) &&
  48.                  (fp[3] == _PSC || fp[3] == '\0'))
  49.                 {    /* ".." (don't backtrack over a "..") */
  50.                 if (absolute_path || 
  51.                    (bp > up && bp-2 < pathname) ||
  52.                    (bp > up && (bp[-2] != p1 || bp[-1] != p2)))
  53.                     {
  54.                     while (bp > up && *--bp != _PSC)
  55.                         continue;
  56.                     }
  57.                 else    {
  58.                     /* don't clobber separator character */
  59.                     if (bp[0] == _PSC) bp++;
  60.                     bp[0] = fp[1];
  61.                     bp[1] = fp[2];
  62.                     bp[2] = fp[3];
  63.                     up = bp += 2;
  64.                     }
  65.                 fp += 3;
  66.                 }
  67.             else    {
  68.                 *bp++ = *fp++;
  69.                 }
  70.         else    {
  71.             *bp++ = *fp++;
  72.             }
  73.     if (bp == pathname && *pathname != '\0')
  74.         *bp++ = (absolute_path) ? _RDIRC : _CDIRC;
  75.     *bp = '\0';
  76.     return(pathname);
  77. }
  78.