From: Rusty Russell Date: Thu, 2 Jul 2009 03:26:25 +0000 (+0930) Subject: New junkcode. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=920193fee552482b1846667c379cb437f6c65c9c;ds=inline New junkcode. --- diff --git a/junkcode/fork0@users.sf.net-pathexpand/pathexpand.c b/junkcode/fork0@users.sf.net-pathexpand/pathexpand.c new file mode 100644 index 00000000..4b8bcf0f --- /dev/null +++ b/junkcode/fork0@users.sf.net-pathexpand/pathexpand.c @@ -0,0 +1,96 @@ +#include +#include +#include + +/* + * Returns the analog of "cd path" from a directory "cwd". + * The root is defined as empty path (instead of "/") + * An attempt to go past the root (with "..") leaves the path at root. + * The cwd is not expanded. + */ +char *pathexpand(const char *cwd, const char *path) +{ + static const char SEP[] = "/"; + if (!*path) /* empty path -> "." (don't move) */ + path = "."; + if (!*cwd || *SEP == *path) /* no cwd, or path begins with "/" */ + cwd = ""; + + while (*cwd && *SEP == *cwd) + ++cwd; + + size_t len = strlen(cwd); + char *out = malloc(len + 1 + strlen(path) + 1); + char *p = strcpy(out, cwd) + len; + + for (; *path; ++path) + { + char *pl; + if (p > out && p[-1] != *SEP) + *p++ = *SEP; + pl = p; + while (*path && *SEP != *path) + *p++ = *path++; + *p = '\0'; + /* ..."//"... */ + if (p == pl) + ; /* just ignore */ + /* ..."/./"... */ + else if ( p - pl == 1 && '.' == *pl ) + --p; /* just ignore */ + /* ..."/../"... */ + else if ( p - pl == 2 && '.' == pl[0] && '.' == pl[1] ) + { + /* drop the last element of the resulting path */ + if (pl > out && --pl > out) + for (--pl; pl > out && *SEP != *pl; --pl) + ; + p = pl > out ? ++pl: out; + } + /* ..."/path/"... */ + else if (*path) + *p++ = *path; /* just add the separator */ + + if (!*path) + break; + } + if (p > out+1 && *SEP == p[-1]) + --p; + *p = '\0'; + return out; +} + +#ifdef CHECK_PATHEXPAND +static void check(const char *cwd, const char *path, const char *good) +{ + static int n = 0; + printf("%-2d: %10s$ cd %s", ++n, cwd, path); + char *t = pathexpand(cwd, path); + if ( strcmp(t, good) ) + printf(" ____________________failed(%s)\n", t); + else + printf(" \033[32m%s\033[0m\n", t); + free(t); +} + +int main(int argc, char **argv) +{ + /* 1 */ check("/onelevel", "aa", "onelevel/aa"); + /* 2 */ check("/", "..", ""); + /* 3 */ check("/", "../..", ""); + /* 4 */ check("/one", "aa/../bb", "one/bb"); + /* 5 */ check("/one/two", "aa//bb", "one/two/aa/bb"); + /* 6 */ check("", "/aa//bb", "aa/bb"); + /* 7 */ check("/one/two", "", "one/two"); + /* 8 */ check("/one/two", "aa/..bb/x/../cc/", "one/two/aa/..bb/cc"); + /* 9 */ check("/one/two", "aa/x/././cc////", "one/two/aa/x/cc"); + /* 10 */ check("/one/two", "../../../../aa", "aa"); + /* 11 */ check("one/", "../one/two", "one/two"); + /* 12 */ check("", "../../two", "two"); + /* 13 */ check("a/b/c", "../../two", "a/two"); + /* 14 */ check("a/b/", "../two", "a/two"); + /* 15 */ check("///", "../two", "two"); + return 0; +} +#endif +