Initial import of the CDE 2.1.30 sources from the Open Group.

This commit is contained in:
Peter Howkins
2012-03-10 18:21:40 +00:00
commit 83b6996daa
18978 changed files with 3945623 additions and 0 deletions

View File

@@ -0,0 +1,162 @@
/*
* $XConsortium: pathcollapse.C /main/5 1996/06/21 17:36:32 ageorge $
*
* (c) Copyright 1996 Digital Equipment Corporation.
* (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
* (c) Copyright 1993,1994,1996 International Business Machines Corp.
* (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
* (c) Copyright 1993,1994,1996 Novell, Inc.
* (c) Copyright 1996 FUJITSU LIMITED.
* (c) Copyright 1996 Hitachi.
*/
#ifdef DOMAIN_ALLOW_MALLOC_OVERRIDE
#include "/usr/include/apollo/shlib.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/param.h>
#include <codelibs/nl_hack.h>
#include <codelibs/pathutils.h>
#define SEP(P) (CHARAT(P) == '\0' || CHARAT(P) == '/')
#define DOT(P) (CHARAT(P) == '.' && SEP((P) + 1))
#define DOTDOT(P) (CHARAT(P) == '.' && DOT((P) + 1))
#ifdef __cplusplus
extern "C"
#endif
char *
pathcollapse(const char *src, char *dst, boolean show_dir)
{
int ch;
const char *srcp;
char *dstp, *sep;
char *components[MAXPATHLEN / 2 + 1];
char **comp = components;
int length = src == NULL ? 0 : strlen(src);
int dir_comp; /* TRUE if last component was . or .. */
#ifdef apollo
int double_slash = 0;
#endif
wchar_t __nlh_char[1];
if (length == 0 || length > MAXPATHLEN)
{
errno = EINVAL;
return NULL;
}
if (dst == NULL)
if ((dst = (char *)malloc(length + 1)) == NULL)
return NULL;
#ifdef apollo
/*
* On apollo, a leading double-slash must be preserved, so we
* copy the first slash and hide it from the rest of the code.
*/
if (CHARAT(src) == '/' && CHARAT(src + 1) == '/')
{
*dst++ = '/';
src++;
double_slash = 1;
}
#endif
srcp = src;
dstp = dst;
do /* for each component of src */
{
*comp = dstp;
/* copy the component and trailing separator to dst */
do
{
ch = (int)CHARAT(srcp);
sep = dstp;
WCHARADV(ch, dstp);
if (ch == '\0')
break;
ADVANCE(srcp);
} while (ch != '/');
dir_comp = ch == '/'; /* true if trailing '/' */
/* skip all adjacent '/' characters [the first is preserved] */
while (CHARAT(srcp) == '/')
ADVANCE(srcp);
/* remove redundant trailing slash */
if (CHARAT(srcp) == '\0')
if (sep > dst)
*sep = ch = '\0';
if (DOT(*comp))
{
dir_comp = 1;
dstp = *comp;
if (dstp > dst)
{
sep = dstp - 1;
*dstp = '\0';
}
continue;
}
else if (DOTDOT(*comp))
{
dir_comp = 1;
if (*comp > dst)
{
comp--;
if (!DOTDOT(*comp))
{
dstp = *comp;
if (dstp > dst)
{
sep = dstp - 1;
*dstp = '\0';
}
else
{
if (CHARAT(dst) == '/')
{
/* /.. is same as / */
dstp = dst + 1;
*dstp = '\0';
comp++;
}
else
dst[0] = '.';
sep = dst + 1;
*sep = '\0';
}
continue;
}
}
}
comp++;
} while (ch != '\0');
if (show_dir)
{
if (dir_comp && (sep > dst + 1 || dst[0] != '/'))
{
*sep++ = '/';
*sep = '\0';
}
}
else if (sep > dst)
*sep = '\0'; /* remove trailing '/' */
#ifdef apollo
if (double_slash)
dst--;
#endif
return dst;
}