summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'util.c')
-rw-r--r--util.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/util.c b/util.c
new file mode 100644
index 00000000..da0b40c4
--- /dev/null
+++ b/util.c
@@ -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 */
+}
+