diff options
Diffstat (limited to 'src/mds-kbdc/paths.c')
-rw-r--r-- | src/mds-kbdc/paths.c | 222 |
1 files changed, 110 insertions, 112 deletions
diff --git a/src/mds-kbdc/paths.c b/src/mds-kbdc/paths.c index 53ae6fa..70bddf1 100644 --- a/src/mds-kbdc/paths.c +++ b/src/mds-kbdc/paths.c @@ -31,32 +31,32 @@ * * @return The current working directory */ -char* curpath(void) +char * +curpath(void) { - static size_t cwd_size = 4096; - char* cwd = NULL; - char* old = NULL; - int saved_errno; - - /* glibc offers ways to do this in just one function call, - * but we will not assume that glibc is used here. */ - for (;;) - { - fail_if (xxrealloc(old, cwd, cwd_size + 1, char)); - if (getcwd(cwd, cwd_size)) - break; - else - fail_if (errno != ERANGE); - cwd_size <<= 1; - } - - return cwd; - fail: - saved_errno = errno; - free(old); - free(cwd); - errno = saved_errno; - return NULL; + static size_t cwd_size = 4096; + char *cwd = NULL; + char *old = NULL; + int saved_errno; + + /* glibc offers ways to do this in just one function call, + * but we will not assume that glibc is used here. */ + for (;;) { + fail_if (xxrealloc(old, cwd, cwd_size + 1, char)); + if (getcwd(cwd, cwd_size)) + break; + else + fail_if (errno != ERANGE); + cwd_size <<= 1; + } + + return cwd; +fail: + saved_errno = errno; + free(old); + free(cwd); + errno = saved_errno; + return NULL; } @@ -66,53 +66,51 @@ char* curpath(void) * @param path The filename of the file * @return The file's absolute path, `NULL` on error */ -char* abspath(const char* path) +char * +abspath(const char *path) { - char* cwd = NULL; - char* buf = NULL; - int saved_errno, slash = 1; - size_t size, p; - - if (*path == '/') - { - fail_if (xstrdup(buf, path)); - return buf; - } - - fail_if (cwd = curpath(), cwd == NULL); - size = (p = strlen(cwd)) + strlen(path) + 2; - fail_if (xmalloc(buf, size + 1, char)); - memcpy(buf, cwd, (p + 1) * sizeof(char)); - if (buf[p - 1] != '/') - buf[p++] = '/'; - - while (*path) - if (slash && (path[0] == '/')) - path += 1; - else if (slash && (path[0] == '.') && (path[1] == '/')) - path += 2; - else if (slash && (path[0] == '.') && (path[1] == '.') && (path[2] == '/')) - { - path += 3; - p--; - while (p && (buf[--p] != '/')); - p++; - } - else - { - buf[p++] = *path; - slash = (*path++ == '/'); - } - - buf[p] = '\0'; - - free(cwd); - return buf; - fail: - saved_errno = errno; - free(cwd); - errno = saved_errno; - return NULL; + char *cwd = NULL; + char *buf = NULL; + int saved_errno, slash = 1; + size_t size, p; + + if (*path == '/') { + fail_if (xstrdup(buf, path)); + return buf; + } + + fail_if (!(cwd = curpath())); + size = (p = strlen(cwd)) + strlen(path) + 2; + fail_if (xmalloc(buf, size + 1, char)); + memcpy(buf, cwd, (p + 1) * sizeof(char)); + if (buf[p - 1] != '/') + buf[p++] = '/'; + + while (*path) { + if (slash && path[0] == '/') { + path += 1; + } else if (slash && path[0] == '.' && path[1] == '/') { + path += 2; + } else if (slash && path[0] == '.' && path[1] == '.' && path[2] == '/') { + path += 3; + p--; + while (p && buf[--p] != '/'); + p++; + } else { + buf[p++] = *path; + slash = *path++ == '/'; + } + } + + buf[p] = '\0'; + + free(cwd); + return buf; +fail: + saved_errno = errno; + free(cwd); + errno = saved_errno; + return NULL; } @@ -124,46 +122,46 @@ char* abspath(const char* path) * `NULL` for the current working directroy * @return The file's relative path, `NULL` on error */ -char* relpath(const char* path, const char* base) +char * +relpath(const char *path, const char *base) { - char* abs = abspath(path); - char* absbase = NULL; - char* buf = NULL; - char* old = NULL; - int saved_errno; - size_t p, slash = 1, back = 0; - - fail_if (abs == NULL); - absbase = base ? abspath(base) : curpath(); - fail_if (absbase == NULL); - - if (absbase[strlen(absbase) - 1] != '/') - /* Both `abspath` and `curpath` (and `relpath`) allocates one extra slot. */ - absbase[strlen(absbase) + 1] = '\0', absbase[strlen(absbase)] = '/'; - - for (p = 1; abs[p] && absbase[p] && (abs[p] == absbase[p]); p++) - if (abs[p] == '/') - slash = p + 1; - - for (p = slash; absbase[p]; p++) - if (absbase[p] == '/') - back++; - - fail_if (xmalloc(buf, back * 3 + strlen(abs + slash) + 2, char)); - - for (p = 0; back--;) - buf[p++] = '.', buf[p++] = '.', buf[p++] = '/'; - memcpy(buf + p, abs + slash, (strlen(abs + slash) + 1) * sizeof(char)); - - free(abs); - free(absbase); - return buf; - fail: - saved_errno = errno; - free(abs); - free(absbase); - free(old); - errno = saved_errno; - return NULL; -} + char *abs = abspath(path); + char *absbase = NULL; + char *buf = NULL; + char *old = NULL; + int saved_errno; + size_t p, slash = 1, back = 0; + fail_if (!abs); + absbase = base ? abspath(base) : curpath(); + fail_if (!absbase); + + if (absbase[strlen(absbase) - 1] != '/') + /* Both `abspath` and `curpath` (and `relpath`) allocates one extra slot. */ + absbase[strlen(absbase) + 1] = '\0', absbase[strlen(absbase)] = '/'; + + for (p = 1; abs[p] && absbase[p] && abs[p] == absbase[p]; p++) + if (abs[p] == '/') + slash = p + 1; + + for (p = slash; absbase[p]; p++) + if (absbase[p] == '/') + back++; + + fail_if (xmalloc(buf, back * 3 + strlen(abs + slash) + 2, char)); + + for (p = 0; back--;) + buf[p++] = '.', buf[p++] = '.', buf[p++] = '/'; + memcpy(buf + p, abs + slash, (strlen(abs + slash) + 1) * sizeof(char)); + + free(abs); + free(absbase); + return buf; +fail: + saved_errno = errno; + free(abs); + free(absbase); + free(old); + errno = saved_errno; + return NULL; +} |