+static int avl_strcmp_var(const void *k1, const void *k2, void *ptr)
+{
+ const char *s1 = k1;
+ const char *s2 = k2;
+ char c1, c2;
+
+ while (*s1 && *s1 == *s2) {
+ s1++;
+ s2++;
+ }
+
+ c1 = *s1;
+ c2 = *s2;
+ if (c1 == '=')
+ c1 = 0;
+ if (c2 == '=')
+ c2 = 0;
+
+ return c1 - c2;
+}
+
+static int jshn_parse_file(const char *path)
+{
+ struct stat sb;
+ int ret = 0;
+ char *fbuf;
+ int fd;
+
+ if ((fd = open(path, O_RDONLY)) == -1) {
+ fprintf(stderr, "Error opening %s\n", path);
+ return 3;
+ }
+
+ if (fstat(fd, &sb) == -1) {
+ fprintf(stderr, "Error getting size of %s\n", path);
+ close(fd);
+ return 3;
+ }
+
+ if (!(fbuf = calloc(1, sb.st_size+1))) {
+ fprintf(stderr, "Error allocating memory for %s\n", path);
+ close(fd);
+ return 3;
+ }
+
+ if (read(fd, fbuf, sb.st_size) != sb.st_size) {
+ fprintf(stderr, "Error reading %s\n", path);
+ free(fbuf);
+ close(fd);
+ return 3;
+ }
+
+ ret = jshn_parse(fbuf);
+ free(fbuf);
+ close(fd);
+
+ return ret;
+}
+
+static int jshn_format_file(const char *path, bool no_newline, bool indent)
+{
+ FILE *fp = NULL;
+ int ret = 0;
+
+ fp = fopen(path, "w");
+ if (!fp) {
+ fprintf(stderr, "Error opening %s\n", path);
+ return 3;
+ }
+
+ ret = jshn_format(no_newline, indent, fp);
+ fclose(fp);
+
+ return ret;
+}
+