mirror of
				https://github.com/stedolan/jq.git
				synced 2024-05-11 05:55:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			121 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
 | 
						|
#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 */
 | 
						|
}
 | 
						|
 |