diff options
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 120 |
1 files changed, 120 insertions, 0 deletions
@@ -0,0 +1,120 @@ + +#ifdef HAVE_MEMMEM +#define _GNU_SOURCE +#include <string.h> +#endif +#include <assert.h> +#ifndef WIN32 +#include <pwd.h> +#endif +#include <stdlib.h> +#include <unistd.h> +#include <limits.h> + + +#include "util.h" +#include "jv.h" + +jv expand_path(jv path) { + assert(jv_get_kind(path) == JV_KIND_STRING); + const char *pstr = jv_string_value(path); + jv ret = path; + if (jv_string_length_bytes(jv_copy(path)) > 1 && pstr[0] == '~' && pstr[1] == '/') { + jv home = get_home(); + if (jv_is_valid(home)) { + ret = jv_string_fmt("%s/%s",jv_string_value(home),pstr+2); + jv_free(home); + } else { + jv emsg = jv_invalid_get_msg(home); + ret = jv_invalid_with_msg(jv_string_fmt("Could not expand %s. (%s)", pstr, jv_string_value(emsg))); + jv_free(emsg); + } + jv_free(path); + } + return ret; +} + +jv get_home() { + jv ret; + char *home = getenv("HOME"); + if (!home) { +#ifndef WIN32 + struct passwd* pwd = getpwuid(getuid()); + if (pwd) + ret = jv_string(pwd->pw_dir); + else + ret = jv_invalid_with_msg(jv_string("Could not find home directory.")); +#else + home = getenv("USERPROFILE"); + if (!home) { + char *hd = getenv("HOMEDRIVE"); + if (!hd) hd = ""; + home = getenv("HOMEPATH"); + if (!home) { + ret = jv_invalid_with_msg(jv_string("Could not find home directory.")); + } else { + ret = jv_string_fmt("%s%s",hd,home); + } + } else { + ret = jv_string(home); + } +#endif + } else { + ret = jv_string(home); + } + return ret; +} + + +jv jq_realpath(jv path) { + int path_max; + char *buf = NULL; +#ifdef _PC_PATH_MAX + path_max = pathconf(jv_string_value(path),_PC_PATH_MAX); +#else + path_max = PATH_MAX; +#endif + if (path_max > 0) { + buf = malloc(sizeof(char) * path_max); + } +#ifdef WIN32 + char *tmp = _fullpath(buf, jv_string_value(path), path_max); +#else + char *tmp = realpath(jv_string_value(path), buf); +#endif + if (tmp == NULL) { + free(buf); + return path; + } + jv_free(path); + path = jv_string(tmp); + free(tmp); + return path; +} + +const void *jq_memmem(const void *haystack, size_t haystacklen, + const void *needle, size_t needlelen) { +#ifdef HAVE_MEMMEM + return (const void*)memmem(haystack, haystacklen, needle, needlelen); +#else + const char *h = haystack; + const char *n = needle; + size_t hi, hi2, ni; + + if (haystacklen < needlelen || haystacklen == 0) + return NULL; + for (hi = 0; hi < (haystacklen - needlelen + 1); hi++) { + for (ni = 0, hi2 = hi; ni < needlelen; ni++, hi2++) { + if (h[hi2] != n[ni]) + goto not_this; + } + + return &h[hi]; + +not_this: + continue; + } + return NULL; +#endif /* !HAVE_MEMMEM */ +} + |