catpath -- library function to combine path names and simplify
forsyth
forsyth at minster.UUCP
Wed Jul 30 11:45:42 AEST 1986
# 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
More information about the Comp.sources.unix
mailing list