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: }

Defined functions

optpath defined in line 23; used 3 times

Defined variables

parentdir defined in line 21; used 2 times

Defined macros

absolute_path defined in line 19; used 2 times
Last modified: 1985-07-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 688
Valid CSS Valid XHTML 1.0 Strict