|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.