[net.sources] catpath -- library function to combine path names and simplify

forsyth@minster.UUCP (forsyth) (07/30/86)

# To unbundle, sh this file
echo 'catpath.3' >&2
sed 's/^-//' >catpath.3 << 'End of catpath.3'
-.TH CATPATH 3 local
-.SH NAME
-catpath \- concatenate path name components and simplify
-.SH SYNOPSIS
-.nf
-.B "char \(**catpath(buf, bufsiz, comps)"
-.br
-.B char \(**buf;
-.br
-.B unsigned bufsiz;
-.br
-.B char \(**comps[\|];
-.fi
-.SH DESCRIPTION
-.I Catpath
-concatenates the
-file name components represented by
-null-terminated strings in the array
-.IR comps ,
-which is terminated by a null pointer,
-to form a complete path name
-which is left in
-.IR buf .
-A pointer to
-.I buf
-is returned (but see below).
-.I Buf
-is taken to be
-.I bufsiz
-characters long, and the result must fit in that space,
-including the terminating null byte.
-.PP
-Each element string in
-the array
-.I comps
-can contain a portion of a path name,
-including several directory components separated by `/'.
-.I Catpath
-will simplify the resulting path name
-by removing redundant references to
-.RB ` . '
-and
-.RB ` .. '.
-.SH SEE ALSO
-basename(1), getcwd(3)
-.SH DIAGNOSTICS
-If
-.I buf
-is too small,
-.I catpath
-returns a null pointer and sets
-the external cell
-.I errno
-to
-ERANGE
-(see
-.IR intro (2)).
End of catpath.3
echo 'catpath.c' >&2
sed 's/^-//' >catpath.c << 'End of catpath.c'
-/*
- *	make the simplified pathname, of a catenation of components
- *
- *	M C Atkins, University of York (mcvax!minster.york.ac.uk!martin)
- */
-#include <errno.h>
-
-extern int errno;
-
-#define isend(cp) (*(cp) == '/' || *(cp) == '\0')
-#define isdot(cp) (*(cp) == '.' && isend(cp+1))
-#define isdotdot(cp) (*(cp) == '.' && isdot(cp+1))
-
-char *
-catpath(buf, bufsiz, comps)
-char *buf;
-int bufsiz;
-char *comps[];
-{
-	register char *fcp;
-	register char *start = buf;
-	register char *tcp;
-	register char *lcp;
-	register char *endp = &buf[bufsiz-4];
-
-	if(comps[0] != 0 && comps[0][0] == '/')
-		*start++ = '/';
-	*start = '\0';
-	tcp = start;
-	while((fcp = comps[0]) != 0 && tcp < endp) {
-		while(*fcp) {
-			if(*fcp == '/') {
-				fcp++;
-				continue;
-			}
-			if(isdot(fcp)) {
-				fcp++;
-				continue;
-			}
-			if(isdotdot(fcp)) {
-				fcp += 2;
-				if(tcp != start) {
-					lcp = tcp - 2;
-					while(lcp > start && *lcp != '/')
-						lcp--;
-					if(lcp > start)
-						lcp++;
-					else
-						lcp = start;
-					if(!isdotdot(lcp)) {
-						tcp = lcp;
-						*tcp = '\0';
-						continue;
-					}
-				}
-				*tcp++ = '.';
-				*tcp++ = '.';
-				*tcp++ = '/';
-				continue;
-			}
-			while(*fcp != '\0' && *fcp != '/' && tcp < endp)
-				*tcp++ = *fcp++;
-			*tcp++ = '/';
-		}
-		comps++;
-	}
-	if(tcp >= endp) {
-		errno = ERANGE;
-		return 0;
-	}
-	if(tcp > buf+1)
-		tcp[-1] = '\0';
-	return buf;
-}
End of catpath.c