diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2007-01-22 18:41:23 +0000 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2007-01-22 18:41:23 +0000 |
commit | 6d249aafcbfd612398274300cccda4f1028ac63b (patch) | |
tree | 24f4fb31038a2c05c86cf43261627a2c324d2477 /xps/xpsmem.c | |
parent | 6aac431a30e05933071eaff2692962a3b26a8145 (diff) | |
download | ghostpdl-6d249aafcbfd612398274300cccda4f1028ac63b.tar.gz |
Add a function to normalize a path name in-place by stripping out extra slashes and resolving dotdots.
git-svn-id: http://svn.ghostscript.com/ghostpcl/trunk/ghostpcl@2740 06663e23-700e-0410-b217-a244a6096597
Diffstat (limited to 'xps/xpsmem.c')
-rw-r--r-- | xps/xpsmem.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/xps/xpsmem.c b/xps/xpsmem.c index fb7a299e3..a7435fb07 100644 --- a/xps/xpsmem.c +++ b/xps/xpsmem.c @@ -1,6 +1,5 @@ #include "ghostxps.h" - char * xps_strdup_imp(xps_context_t *ctx, const char *str, const char *cname) { @@ -12,3 +11,60 @@ xps_strdup_imp(xps_context_t *ctx, const char *str, const char *cname) return cpy; } +#define SEP(x) ((x)=='/' || (x) == 0) + +char * +xps_clean_path(char *name) +{ + char *p, *q, *dotdot; + int rooted; + + rooted = name[0] == '/'; + + /* + * invariants: + * p points at beginning of path element we're considering. + * q points just past the last path element we wrote (no slash). + * dotdot points just past the point where .. cannot backtrack + * any further (no slash). + */ + p = q = dotdot = name + rooted; + while (*p) + { + if(p[0] == '/') /* null element */ + p++; + else if (p[0] == '.' && SEP(p[1])) + p += 1; /* don't count the separator in case it is nul */ + else if (p[0] == '.' && p[1] == '.' && SEP(p[2])) + { + p += 2; + if (q > dotdot) /* can backtrack */ + { + while(--q > dotdot && *q != '/') + ; + } + else if (!rooted) /* /.. is / but ./../ is .. */ + { + if (q != name) + *q++ = '/'; + *q++ = '.'; + *q++ = '.'; + dotdot = q; + } + } + else /* real path element */ + { + if (q != name+rooted) + *q++ = '/'; + while ((*q = *p) != '/' && *q != 0) + p++, q++; + } + } + + if (q == name) /* empty string is really "." */ + *q++ = '.'; + *q = '\0'; + + return name; +} + |