4.3BSD/usr/contrib/mkmf/src/optpath.c
/* $Header: optpath.c,v 1.2 85/05/06 13:32:05 nicklin Exp $ */
/*
* Author: Peter J. Nicklin
*/
/*
* optpath() condenses a pathname by eliminating adjacent separator
* characters, and current and parent directory names. If optpath()
* encounters a parent directory, it backtracks to eliminate the
* previous directory. If the beginning of the pathname is reached
* during backtracking, then if the pathname is absolute, the parent
* directory is purged, otherwise it is shifted to the beginning of
* pathname. Special care is taken not to clobber a shifted parent
* by using a guard pointer. Returns pathname.
*/
#include "path.h"
#define absolute_path (*pathname == _RDIRC)
static char parentdir[] = PARENTDIR; /* parent directory name */
char *
optpath(pathname)
register char *pathname; /* pathname to be optimized */
{
register char *bp; /* back pathname pointer */
register char *fp; /* forward pathname pointer */
register char *up; /* pathname update guard pointer */
char p1; /* 1st parent directory character */
char p2; /* 2nd parent directory character */
p1 = parentdir[0];
p2 = parentdir[1];
bp = fp = up = pathname;
/* elimination of initial "./" causes no harmful side-effects */
if (fp[0] == _CDIRC && fp[1] == _PSC) fp += 2;
while (*fp != '\0')
if (fp[0] == _PSC)
if (fp[1] == _PSC || fp[1] == '\0')
fp += 1; /* "//" or trailing `/' */
else if (fp[1]==_CDIRC && (fp[2]==_PSC || fp[2]=='\0'))
fp += 2; /* `.' */
else if ((fp[1] == p1 && fp[2] == p2) &&
(fp[3] == _PSC || fp[3] == '\0'))
{ /* ".." (don't backtrack over a "..") */
if (absolute_path ||
(bp > up && bp-2 < pathname) ||
(bp > up && (bp[-2] != p1 || bp[-1] != p2)))
{
while (bp > up && *--bp != _PSC)
continue;
}
else {
/* don't clobber separator character */
if (bp[0] == _PSC) bp++;
bp[0] = fp[1];
bp[1] = fp[2];
bp[2] = fp[3];
up = bp += 2;
}
fp += 3;
}
else {
*bp++ = *fp++;
}
else {
*bp++ = *fp++;
}
if (bp == pathname && *pathname != '\0')
*bp++ = (absolute_path) ? _RDIRC : _CDIRC;
*bp = '\0';
return(pathname);
}