cc_fprintf:
  145|     20|int cc_fprintf(cc_color_t color, FILE* stream, const char* format, ...) {
  146|     20|    va_list ap;
  147|     20|    va_start(ap, format);
  148|     20|    int result = -EINVAL;
  149|       |
  150|     20|    if (stream != stdout && stream != stderr) {
  ------------------
  |  Branch (150:9): [True: 0, False: 20]
  |  Branch (150:29): [True: 0, False: 0]
  ------------------
  151|      0|        result = Write(stream, format, ap);
  152|      0|        goto finish;
  153|      0|    }
  154|       |
  155|     20|    const unsigned int fg =
  156|     20|        color & ((1 << CC_COLOR_BITS) - 1);
  ------------------
  |  |   28|     20|#define CC_COLOR_BITS 5
  ------------------
  157|     20|    const unsigned int bg =
  158|     20|        (color >> CC_COLOR_BITS) & ((1 << CC_COLOR_BITS) - 1);
  ------------------
  |  |   28|     20|#define CC_COLOR_BITS 5
  ------------------
                      (color >> CC_COLOR_BITS) & ((1 << CC_COLOR_BITS) - 1);
  ------------------
  |  |   28|     20|#define CC_COLOR_BITS 5
  ------------------
  159|       |
  160|       |#ifdef _WIN32
  161|       |    const HANDLE console = GetStdHandle(
  162|       |            stream == stdout ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
  163|       |    if (console == INVALID_HANDLE_VALUE) {
  164|       |        result = Write(stream, format, ap);
  165|       |        goto finish;
  166|       |    }
  167|       |    CONSOLE_SCREEN_BUFFER_INFO csbi;
  168|       |    if (!GetConsoleScreenBufferInfo(console, &csbi)) {
  169|       |        result = Write(stream, format, ap);
  170|       |        goto finish;
  171|       |    }
  172|       |    SetConsoleTextAttribute(console, Generate(fg, bg, csbi.wAttributes));
  173|       |    result = Write(stream, format, ap);
  174|       |    SetConsoleTextAttribute(console, csbi.wAttributes);
  175|       |#else
  176|     20|    UnixTerminalColorize(stream, fg, bg);
  177|     20|    Write(stream, format, ap);
  178|     20|    UnixTerminalRestore(stream);
  179|     20|#endif  /* _WIN32 */
  180|       |
  181|     20|finish:
  182|     20|    va_end(ap);
  183|     20|    return result;
  184|     20|}
console-colors.c:Write:
   34|     20|static int Write(FILE *stream, const char *format, va_list ap) {
   35|       |#if defined(_WIN32) && !defined(__MINGW32__)
   36|       |    return vfprintf_s(stream, format, ap);
   37|       |#else
   38|     20|    return vfprintf(stream, format, ap);
   39|     20|#endif
   40|     20|}
console-colors.c:UnixTerminalColorize:
  136|     20|        FILE* stream, unsigned int fg, unsigned int bg) {
  137|     20|    fprintf(stream, "\x1B[39;49;%u;%um", Shift(fg, 30, 90), Shift(bg, 40, 100));
  138|     20|}
console-colors.c:Shift:
  123|     40|        unsigned int val, unsigned int normal, unsigned int bright) {
  124|     40|    if (val == 0) {
  ------------------
  |  Branch (124:9): [True: 20, False: 20]
  ------------------
  125|     20|        return 9 + normal;
  126|     20|    }
  127|     20|    val -= 1;
  128|       |    /* background */
  129|     20|    if (val >= 8) {
  ------------------
  |  Branch (129:9): [True: 20, False: 0]
  ------------------
  130|     20|        return (val - 8) + bright;
  131|     20|    }
  132|      0|    return val + normal;
  133|     20|}
console-colors.c:UnixTerminalRestore:
  140|     20|static void UnixTerminalRestore(FILE* stream) {
  141|     20|    fputs("\x1B[39;49m", stream);
  142|     20|}

debug_is_enabled:
   53|      1|debug_is_enabled(const char *name) {
   54|      1|  char *env = NULL;
   55|      1|  char *tmp = NULL;
   56|      1|  char *debugger = NULL;
   57|      1|  int enabled = 0;
   58|       |
   59|       |  // get DEBUG env var
   60|      1|  if (!(env = getenv("DEBUG"))) return 0;
  ------------------
  |  Branch (60:7): [True: 1, False: 0]
  ------------------
   61|      0|  if (!(tmp = strdup(env))) return 0;
  ------------------
  |  Branch (61:7): [True: 0, False: 0]
  ------------------
   62|       |
   63|      0|  debugger = strtok(tmp, DELIMITER);
  ------------------
  |  |   28|      0|#define DELIMITER ","
  ------------------
   64|      0|  while (debugger) {
  ------------------
  |  Branch (64:10): [True: 0, False: 0]
  ------------------
   65|       |    // support DEBUG=foo*
   66|      0|    if (1 == wildcardcmp(debugger, name)) {
  ------------------
  |  Branch (66:9): [True: 0, False: 0]
  ------------------
   67|      0|      enabled = 1;
   68|      0|      break;
   69|      0|    }
   70|      0|    debugger = strtok(NULL, DELIMITER);
  ------------------
  |  |   28|      0|#define DELIMITER ","
  ------------------
   71|      0|  }
   72|       |
   73|      0|  free(tmp);
   74|      0|  return enabled;
   75|      0|}
debug_init:
   78|      1|debug_init(debug_t *debugger, const char *name) {
   79|       |  // seed, if necessary
   80|      1|  if (0 == seeded) {
  ------------------
  |  Branch (80:7): [True: 1, False: 0]
  ------------------
   81|      1|    srand(clock());
   82|      1|    seeded = 1;
   83|      1|  }
   84|       |
   85|       |  // random color
   86|      1|  debugger->color = 1 + (rand() % 6);
   87|       |  // set enabled flag
   88|      1|  debugger->enabled = debug_is_enabled(name);
   89|       |  // name, stream
   90|      1|  debugger->name = name;
   91|      1|  debugger->stream = stderr;
   92|      1|  return 0;
   93|      1|}
debug:
   96|     16|debug(debug_t *debugger, const char *fmt, ...) {
   97|       |  // noop when disabled
   98|     16|  if (0 == debugger->enabled) return;
  ------------------
  |  Branch (98:7): [True: 16, False: 0]
  ------------------
   99|       |
  100|      0|  char *pre = NULL;
  101|      0|  char *post = NULL;
  102|      0|  va_list args;
  103|       |
  104|      0|  va_start(args, fmt);
  105|       |
  106|      0|  if (use_colors(debugger->stream)) {
  ------------------
  |  Branch (106:7): [True: 0, False: 0]
  ------------------
  107|       |    // [color][name][/color]
  108|      0|    if (-1 == asprintf(&pre, FMT, debugger->color, debugger->name)) {
  ------------------
  |  |   22|      0|#define FMT "\x1B[3%dm%s\033[0m"
  ------------------
  |  Branch (108:9): [True: 0, False: 0]
  ------------------
  109|      0|      va_end(args);
  110|      0|      return;
  111|      0|    }
  112|      0|  } else {
  113|       |    // [name]
  114|      0|    if (!(pre = strdup(debugger->name))) {
  ------------------
  |  Branch (114:9): [True: 0, False: 0]
  ------------------
  115|      0|      va_end(args);
  116|      0|      return;
  117|      0|    }
  118|      0|  }
  119|       |
  120|       |  // format args
  121|      0|  if (-1 == vasprintf(&post, fmt, args)) {
  ------------------
  |  Branch (121:7): [True: 0, False: 0]
  ------------------
  122|      0|    free(pre);
  123|      0|    va_end(args);
  124|      0|    return;
  125|      0|  }
  126|       |
  127|       |  // print to stream
  128|      0|  fprintf(debugger->stream, " %s : %s\n", pre, post);
  129|       |
  130|       |  // release memory
  131|      0|  free(pre);
  132|      0|  free(post);
  133|      0|}

fs_open:
   29|     10|fs_open (const char *path, const char *flags) {
   30|     10|  return fopen(path, flags);
   31|     10|}
fs_fsize:
  158|     10|fs_fsize (FILE *file) {
  159|       |  // store current position
  160|     10|  unsigned long pos = ftell(file);
  161|     10|  rewind(file);
  162|     10|  fseek(file, 0, SEEK_END);
  163|     10|  size_t size = ftell(file);
  164|     10|  fseek(file, pos, SEEK_SET);
  165|     10|  return size;
  166|     10|}
fs_read:
  170|     10|fs_read (const char *path) {
  171|     10|  FILE *file = fs_open(path, FS_OPEN_READ);
  ------------------
  |  |   20|     10|#define FS_OPEN_READ "r"
  ------------------
  172|     10|  if (NULL == file) return NULL;
  ------------------
  |  Branch (172:7): [True: 0, False: 10]
  ------------------
  173|     10|  char *data = fs_fread(file);
  174|     10|  fclose(file);
  175|     10|  return data;
  176|     10|}
fs_fread:
  190|     10|fs_fread (FILE *file) {
  191|     10|  size_t fsize = fs_fsize(file);
  192|     10|  return fs_fnread(file, fsize);
  193|     10|}
fs_fnread:
  197|     10|fs_fnread (FILE *file, int len) {
  198|     10|  char *buffer = (char*) malloc(sizeof(char) * (len + 1));
  199|     10|  size_t n = fread(buffer, 1, len, file);
  200|     10|  buffer[n] = '\0';
  201|     10|  return buffer;
  202|     10|}
fs_exists:
  250|     10|fs_exists (const char *path) {
  251|     10|  struct stat b;
  252|     10|  return stat(path, &b);
  253|     10|}

json_parse_string:
  903|     10|JSON_Value * json_parse_string(const char *string) {
  904|     10|    if (string == NULL)
  ------------------
  |  Branch (904:9): [True: 0, False: 10]
  ------------------
  905|      0|        return NULL;
  906|     10|    SKIP_WHITESPACES(&string);
  ------------------
  |  |   43|     10|#define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
  |  |  ------------------
  |  |  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  |  |  ------------------
  ------------------
  907|     10|    if (*string != '{' && *string != '[')
  ------------------
  |  Branch (907:9): [True: 6, False: 4]
  |  Branch (907:27): [True: 1, False: 5]
  ------------------
  908|      1|        return NULL;
  909|      9|    return parse_value((const char**)&string, 0);
  910|     10|}
json_object_get_value:
  934|     72|JSON_Value * json_object_get_value(const JSON_Object *object, const char *name) {
  935|     72|    if (object == NULL || name == NULL)
  ------------------
  |  Branch (935:9): [True: 0, False: 72]
  |  Branch (935:27): [True: 0, False: 72]
  ------------------
  936|      0|        return NULL;
  937|     72|    return json_object_nget_value(object, name, strlen(name));
  938|     72|}
json_object_get_string:
  940|     44|const char * json_object_get_string(const JSON_Object *object, const char *name) {
  941|     44|    return json_value_get_string(json_object_get_value(object, name));
  942|     44|}
json_object_get_object:
  948|      8|JSON_Object * json_object_get_object(const JSON_Object *object, const char *name) {
  949|      8|    return json_value_get_object(json_object_get_value(object, name));
  950|      8|}
json_object_get_array:
  952|     16|JSON_Array * json_object_get_array(const JSON_Object *object, const char *name) {
  953|     16|    return json_value_get_array(json_object_get_value(object, name));
  954|     16|}
json_object_get_count:
  988|    144|size_t json_object_get_count(const JSON_Object *object) {
  989|    144|    return object ? object->count : 0;
  ------------------
  |  Branch (989:12): [True: 144, False: 0]
  ------------------
  990|    144|}
json_value_get_type:
 1030|     99|JSON_Value_Type json_value_get_type(const JSON_Value *value) {
 1031|     99|    return value ? value->type : JSONError;
  ------------------
  |  Branch (1031:12): [True: 31, False: 68]
  ------------------
 1032|     99|}
json_value_get_object:
 1034|     16|JSON_Object * json_value_get_object(const JSON_Value *value) {
 1035|     16|    return json_value_get_type(value) == JSONObject ? value->value.object : NULL;
  ------------------
  |  Branch (1035:12): [True: 8, False: 8]
  ------------------
 1036|     16|}
json_value_get_array:
 1038|     21|JSON_Array * json_value_get_array(const JSON_Value *value) {
 1039|     21|    return json_value_get_type(value) == JSONArray ? value->value.array : NULL;
  ------------------
  |  Branch (1039:12): [True: 5, False: 16]
  ------------------
 1040|     21|}
json_value_get_string:
 1042|     44|const char * json_value_get_string(const JSON_Value *value) {
 1043|     44|    return json_value_get_type(value) == JSONString ? value->value.string : NULL;
  ------------------
  |  Branch (1043:12): [True: 0, False: 44]
  ------------------
 1044|     44|}
json_value_free:
 1054|     18|void json_value_free(JSON_Value *value) {
 1055|     18|    switch (json_value_get_type(value)) {
 1056|      4|        case JSONObject:
  ------------------
  |  Branch (1056:9): [True: 4, False: 14]
  ------------------
 1057|      4|            json_object_free(value->value.object);
 1058|      4|            break;
 1059|      0|        case JSONString:
  ------------------
  |  Branch (1059:9): [True: 0, False: 18]
  ------------------
 1060|      0|            if (value->value.string) { parson_free(value->value.string); }
  ------------------
  |  Branch (1060:17): [True: 0, False: 0]
  ------------------
 1061|      0|            break;
 1062|      5|        case JSONArray:
  ------------------
  |  Branch (1062:9): [True: 5, False: 13]
  ------------------
 1063|      5|            json_array_free(value->value.array);
 1064|      5|            break;
 1065|      9|        default:
  ------------------
  |  Branch (1065:9): [True: 9, False: 9]
  ------------------
 1066|      9|            break;
 1067|     18|    }
 1068|     18|    parson_free(value);
 1069|     18|}
json_value_init_object:
 1071|      4|JSON_Value * json_value_init_object(void) {
 1072|      4|    JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
 1073|      4|    if (!new_value)
  ------------------
  |  Branch (1073:9): [True: 0, False: 4]
  ------------------
 1074|      0|        return NULL;
 1075|      4|    new_value->type = JSONObject;
 1076|      4|    new_value->value.object = json_object_init();
 1077|      4|    if (!new_value->value.object) {
  ------------------
  |  Branch (1077:9): [True: 0, False: 4]
  ------------------
 1078|      0|        parson_free(new_value);
 1079|      0|        return NULL;
 1080|      0|    }
 1081|      4|    return new_value;
 1082|      4|}
json_value_init_array:
 1084|      5|JSON_Value * json_value_init_array(void) {
 1085|      5|    JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
 1086|      5|    if (!new_value)
  ------------------
  |  Branch (1086:9): [True: 0, False: 5]
  ------------------
 1087|      0|        return NULL;
 1088|      5|    new_value->type = JSONArray;
 1089|      5|    new_value->value.array = json_array_init();
 1090|      5|    if (!new_value->value.array) {
  ------------------
  |  Branch (1090:9): [True: 0, False: 5]
  ------------------
 1091|      0|        parson_free(new_value);
 1092|      0|        return NULL;
 1093|      0|    }
 1094|      5|    return new_value;
 1095|      5|}
json_value_init_number:
 1115|      9|JSON_Value * json_value_init_number(double number) {
 1116|      9|    JSON_Value *new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
 1117|      9|    if (!new_value)
  ------------------
  |  Branch (1117:9): [True: 0, False: 9]
  ------------------
 1118|      0|        return NULL;
 1119|      9|    new_value->type = JSONNumber;
 1120|      9|    new_value->value.number = number;
 1121|      9|    return new_value;
 1122|      9|}
parson.c:parse_value:
  555|     18|static JSON_Value * parse_value(const char **string, size_t nesting) {
  556|     18|    if (nesting > MAX_NESTING)
  ------------------
  |  |   38|     18|#define MAX_NESTING               19
  ------------------
  |  Branch (556:9): [True: 0, False: 18]
  ------------------
  557|      0|        return NULL;
  558|     18|    SKIP_WHITESPACES(string);
  ------------------
  |  |   43|     18|#define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
  |  |  ------------------
  |  |  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  |  |  ------------------
  ------------------
  559|     18|    switch (**string) {
  560|      4|        case '{':
  ------------------
  |  Branch (560:9): [True: 4, False: 14]
  ------------------
  561|      4|            return parse_object_value(string, nesting + 1);
  562|      5|        case '[':
  ------------------
  |  Branch (562:9): [True: 5, False: 13]
  ------------------
  563|      5|            return parse_array_value(string, nesting + 1);
  564|      0|        case '\"':
  ------------------
  |  Branch (564:9): [True: 0, False: 18]
  ------------------
  565|      0|            return parse_string_value(string);
  566|      0|        case 'f': case 't':
  ------------------
  |  Branch (566:9): [True: 0, False: 18]
  |  Branch (566:19): [True: 0, False: 18]
  ------------------
  567|      0|            return parse_boolean_value(string);
  568|      0|        case '-':
  ------------------
  |  Branch (568:9): [True: 0, False: 18]
  ------------------
  569|      7|        case '0': case '1': case '2': case '3': case '4':
  ------------------
  |  Branch (569:9): [True: 2, False: 16]
  |  Branch (569:19): [True: 5, False: 13]
  |  Branch (569:29): [True: 0, False: 18]
  |  Branch (569:39): [True: 0, False: 18]
  |  Branch (569:49): [True: 0, False: 18]
  ------------------
  570|      9|        case '5': case '6': case '7': case '8': case '9':
  ------------------
  |  Branch (570:9): [True: 2, False: 16]
  |  Branch (570:19): [True: 0, False: 18]
  |  Branch (570:29): [True: 0, False: 18]
  |  Branch (570:39): [True: 0, False: 18]
  |  Branch (570:49): [True: 0, False: 18]
  ------------------
  571|      9|            return parse_number_value(string);
  572|      0|        case 'n':
  ------------------
  |  Branch (572:9): [True: 0, False: 18]
  ------------------
  573|      0|            return parse_null_value(string);
  574|      0|        default:
  ------------------
  |  Branch (574:9): [True: 0, False: 18]
  ------------------
  575|      0|            return NULL;
  576|     18|    }
  577|     18|}
parson.c:parse_object_value:
  579|      4|static JSON_Value * parse_object_value(const char **string, size_t nesting) {
  580|      4|    JSON_Value *output_value = json_value_init_object(), *new_value = NULL;
  581|      4|    JSON_Object *output_object = json_value_get_object(output_value);
  582|      4|    char *new_key = NULL;
  583|      4|    if (output_value == NULL)
  ------------------
  |  Branch (583:9): [True: 0, False: 4]
  ------------------
  584|      0|        return NULL;
  585|      4|    SKIP_CHAR(string);
  ------------------
  |  |   42|      4|#define SKIP_CHAR(str)        ((*str)++)
  ------------------
  586|      4|    SKIP_WHITESPACES(string);
  ------------------
  |  |   43|      4|#define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
  |  |  ------------------
  |  |  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  |  |  ------------------
  ------------------
  587|      4|    if (**string == '}') { /* empty object */
  ------------------
  |  Branch (587:9): [True: 0, False: 4]
  ------------------
  588|      0|        SKIP_CHAR(string);
  ------------------
  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  ------------------
  589|      0|        return output_value;
  590|      0|    }
  591|      4|    while (**string != '\0') {
  ------------------
  |  Branch (591:12): [True: 4, False: 0]
  ------------------
  592|      4|        new_key = get_quoted_string(string);
  593|      4|        SKIP_WHITESPACES(string);
  ------------------
  |  |   43|      4|#define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
  |  |  ------------------
  |  |  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  |  |  ------------------
  ------------------
  594|      4|        if (new_key == NULL || **string != ':') {
  ------------------
  |  Branch (594:13): [True: 0, False: 4]
  |  Branch (594:32): [True: 0, False: 4]
  ------------------
  595|      0|            json_value_free(output_value);
  596|      0|            return NULL;
  597|      0|        }
  598|      4|        SKIP_CHAR(string);
  ------------------
  |  |   42|      4|#define SKIP_CHAR(str)        ((*str)++)
  ------------------
  599|      4|        new_value = parse_value(string, nesting);
  600|      4|        if (new_value == NULL) {
  ------------------
  |  Branch (600:13): [True: 0, False: 4]
  ------------------
  601|      0|            parson_free(new_key);
  602|      0|            json_value_free(output_value);
  603|      0|            return NULL;
  604|      0|        }
  605|      4|        if(json_object_add(output_object, new_key, new_value) == JSONFailure) {
  ------------------
  |  Branch (605:12): [True: 0, False: 4]
  ------------------
  606|      0|            parson_free(new_key);
  607|      0|            parson_free(new_value);
  608|      0|            json_value_free(output_value);
  609|      0|            return NULL;
  610|      0|        }
  611|      4|        parson_free(new_key);
  612|      4|        SKIP_WHITESPACES(string);
  ------------------
  |  |   43|      4|#define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
  |  |  ------------------
  |  |  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  |  |  ------------------
  ------------------
  613|      4|        if (**string != ',')
  ------------------
  |  Branch (613:13): [True: 4, False: 0]
  ------------------
  614|      4|            break;
  615|      0|        SKIP_CHAR(string);
  ------------------
  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  ------------------
  616|      0|        SKIP_WHITESPACES(string);
  ------------------
  |  |   43|      0|#define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
  |  |  ------------------
  |  |  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  |  |  ------------------
  ------------------
  617|      0|    }
  618|      4|    SKIP_WHITESPACES(string);
  ------------------
  |  |   43|      4|#define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
  |  |  ------------------
  |  |  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  |  |  ------------------
  ------------------
  619|      4|    if (**string != '}' || /* Trim object after parsing is over */
  ------------------
  |  Branch (619:9): [True: 0, False: 4]
  ------------------
  620|      4|        json_object_resize(output_object, json_object_get_count(output_object)) == JSONFailure) {
  ------------------
  |  Branch (620:9): [True: 0, False: 4]
  ------------------
  621|      0|            json_value_free(output_value);
  622|      0|            return NULL;
  623|      0|    }
  624|      4|    SKIP_CHAR(string);
  ------------------
  |  |   42|      4|#define SKIP_CHAR(str)        ((*str)++)
  ------------------
  625|      4|    return output_value;
  626|      4|}
parson.c:get_quoted_string:
  545|      4|static char * get_quoted_string(const char **string) {
  546|      4|    const char *string_start = *string;
  547|      4|    size_t string_len = 0;
  548|      4|    skip_quotes(string);
  549|      4|    if (**string == '\0')
  ------------------
  |  Branch (549:9): [True: 0, False: 4]
  ------------------
  550|      0|        return NULL;
  551|      4|    string_len = *string - string_start - 2; /* length without quotes */
  552|      4|    return process_string(string_start + 1, string_len);
  553|      4|}
parson.c:skip_quotes:
  438|      4|static void skip_quotes(const char **string) {
  439|      4|    SKIP_CHAR(string);
  ------------------
  |  |   42|      4|#define SKIP_CHAR(str)        ((*str)++)
  ------------------
  440|  4.19M|    while (**string != '\"') {
  ------------------
  |  Branch (440:12): [True: 4.19M, False: 4]
  ------------------
  441|  4.19M|        if (**string == '\0')
  ------------------
  |  Branch (441:13): [True: 0, False: 4.19M]
  ------------------
  442|      0|            return;
  443|  4.19M|        if (**string == '\\') {
  ------------------
  |  Branch (443:13): [True: 0, False: 4.19M]
  ------------------
  444|      0|            SKIP_CHAR(string);
  ------------------
  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  ------------------
  445|      0|            if (**string == '\0')
  ------------------
  |  Branch (445:17): [True: 0, False: 0]
  ------------------
  446|      0|                return;
  447|      0|        }
  448|  4.19M|        SKIP_CHAR(string);
  ------------------
  |  |   42|  4.19M|#define SKIP_CHAR(str)        ((*str)++)
  ------------------
  449|  4.19M|    }
  450|      4|    SKIP_CHAR(string);
  ------------------
  |  |   42|      4|#define SKIP_CHAR(str)        ((*str)++)
  ------------------
  451|      4|}
parson.c:process_string:
  495|      4|static char* process_string(const char *input, size_t len) {
  496|      4|    const char *input_ptr = input;
  497|      4|    size_t initial_size = (len + 1) * sizeof(char);
  498|      4|    size_t final_size = 0;
  499|      4|    char *output = (char*)parson_malloc(initial_size);
  500|      4|    char *output_ptr = output;
  501|      4|    char *resized_output = NULL;
  502|  4.19M|    while ((*input_ptr != '\0') && (size_t)(input_ptr - input) < len) {
  ------------------
  |  Branch (502:12): [True: 4.19M, False: 0]
  |  Branch (502:36): [True: 4.19M, False: 4]
  ------------------
  503|  4.19M|        if (*input_ptr == '\\') {
  ------------------
  |  Branch (503:13): [True: 0, False: 4.19M]
  ------------------
  504|      0|            input_ptr++;
  505|      0|            switch (*input_ptr) {
  506|      0|                case '\"': *output_ptr = '\"'; break;
  ------------------
  |  Branch (506:17): [True: 0, False: 0]
  ------------------
  507|      0|                case '\\': *output_ptr = '\\'; break;
  ------------------
  |  Branch (507:17): [True: 0, False: 0]
  ------------------
  508|      0|                case '/':  *output_ptr = '/';  break;
  ------------------
  |  Branch (508:17): [True: 0, False: 0]
  ------------------
  509|      0|                case 'b':  *output_ptr = '\b'; break;
  ------------------
  |  Branch (509:17): [True: 0, False: 0]
  ------------------
  510|      0|                case 'f':  *output_ptr = '\f'; break;
  ------------------
  |  Branch (510:17): [True: 0, False: 0]
  ------------------
  511|      0|                case 'n':  *output_ptr = '\n'; break;
  ------------------
  |  Branch (511:17): [True: 0, False: 0]
  ------------------
  512|      0|                case 'r':  *output_ptr = '\r'; break;
  ------------------
  |  Branch (512:17): [True: 0, False: 0]
  ------------------
  513|      0|                case 't':  *output_ptr = '\t'; break;
  ------------------
  |  Branch (513:17): [True: 0, False: 0]
  ------------------
  514|      0|                case 'u':
  ------------------
  |  Branch (514:17): [True: 0, False: 0]
  ------------------
  515|      0|                    if (parse_utf_16(&input_ptr, &output_ptr) == JSONFailure)
  ------------------
  |  Branch (515:25): [True: 0, False: 0]
  ------------------
  516|      0|                        goto error;
  517|      0|                    break;
  518|      0|                default:
  ------------------
  |  Branch (518:17): [True: 0, False: 0]
  ------------------
  519|      0|                    goto error;
  520|      0|            }
  521|  4.19M|        } else if ((unsigned char)*input_ptr < 0x20) {
  ------------------
  |  Branch (521:20): [True: 0, False: 4.19M]
  ------------------
  522|      0|            goto error; /* 0x00-0x19 are invalid characters for json string (http://www.ietf.org/rfc/rfc4627.txt) */
  523|  4.19M|        } else {
  524|  4.19M|            *output_ptr = *input_ptr;
  525|  4.19M|        }
  526|  4.19M|        output_ptr++;
  527|  4.19M|        input_ptr++;
  528|  4.19M|    }
  529|      4|    *output_ptr = '\0';
  530|       |    /* resize to new length */
  531|      4|    final_size = (size_t)(output_ptr-output) + 1;
  532|      4|    resized_output = (char*)parson_malloc(final_size);
  533|      4|    if (resized_output == NULL)
  ------------------
  |  Branch (533:9): [True: 0, False: 4]
  ------------------
  534|      0|        goto error;
  535|      4|    memcpy(resized_output, output, final_size);
  536|      4|    parson_free(output);
  537|      4|    return resized_output;
  538|      0|error:
  539|      0|    parson_free(output);
  540|      0|    return NULL;
  541|      4|}
parson.c:json_object_resize:
  324|      8|static JSON_Status json_object_resize(JSON_Object *object, size_t new_capacity) {
  325|      8|    char **temp_names = NULL;
  326|      8|    JSON_Value **temp_values = NULL;
  327|       |
  328|      8|    if ((object->names == NULL && object->values != NULL) ||
  ------------------
  |  Branch (328:10): [True: 4, False: 4]
  |  Branch (328:35): [True: 0, False: 4]
  ------------------
  329|      8|        (object->names != NULL && object->values == NULL) ||
  ------------------
  |  Branch (329:10): [True: 4, False: 4]
  |  Branch (329:35): [True: 0, False: 4]
  ------------------
  330|      8|        new_capacity == 0) {
  ------------------
  |  Branch (330:9): [True: 0, False: 8]
  ------------------
  331|      0|            return JSONFailure; /* Shouldn't happen */
  332|      0|    }
  333|       |
  334|      8|    temp_names = (char**)parson_malloc(new_capacity * sizeof(char*));
  335|      8|    if (temp_names == NULL)
  ------------------
  |  Branch (335:9): [True: 0, False: 8]
  ------------------
  336|      0|        return JSONFailure;
  337|       |
  338|      8|    temp_values = (JSON_Value**)parson_malloc(new_capacity * sizeof(JSON_Value*));
  339|      8|    if (temp_names == NULL) {
  ------------------
  |  Branch (339:9): [True: 0, False: 8]
  ------------------
  340|      0|        parson_free(temp_names);
  341|      0|        return JSONFailure;
  342|      0|    }
  343|       |
  344|      8|    if (object->names != NULL && object->values != NULL && object->count > 0) {
  ------------------
  |  Branch (344:9): [True: 4, False: 4]
  |  Branch (344:34): [True: 4, False: 0]
  |  Branch (344:60): [True: 4, False: 0]
  ------------------
  345|      4|        memcpy(temp_names, object->names, object->count * sizeof(char*));
  346|      4|        memcpy(temp_values, object->values, object->count * sizeof(JSON_Value*));
  347|      4|    }
  348|      8|    parson_free(object->names);
  349|      8|    parson_free(object->values);
  350|      8|    object->names = temp_names;
  351|      8|    object->values = temp_values;
  352|      8|    object->capacity = new_capacity;
  353|      8|    return JSONSuccess;
  354|      8|}
parson.c:parse_array_value:
  628|      5|static JSON_Value * parse_array_value(const char **string, size_t nesting) {
  629|      5|    JSON_Value *output_value = json_value_init_array(), *new_array_value = NULL;
  630|      5|    JSON_Array *output_array = json_value_get_array(output_value);
  631|      5|    if (!output_value)
  ------------------
  |  Branch (631:9): [True: 0, False: 5]
  ------------------
  632|      0|        return NULL;
  633|      5|    SKIP_CHAR(string);
  ------------------
  |  |   42|      5|#define SKIP_CHAR(str)        ((*str)++)
  ------------------
  634|      5|    SKIP_WHITESPACES(string);
  ------------------
  |  |   43|      5|#define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
  |  |  ------------------
  |  |  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  |  |  ------------------
  ------------------
  635|      5|    if (**string == ']') { /* empty array */
  ------------------
  |  Branch (635:9): [True: 0, False: 5]
  ------------------
  636|      0|        SKIP_CHAR(string);
  ------------------
  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  ------------------
  637|      0|        return output_value;
  638|      0|    }
  639|      5|    while (**string != '\0') {
  ------------------
  |  Branch (639:12): [True: 5, False: 0]
  ------------------
  640|      5|        new_array_value = parse_value(string, nesting);
  641|      5|        if (!new_array_value) {
  ------------------
  |  Branch (641:13): [True: 0, False: 5]
  ------------------
  642|      0|            json_value_free(output_value);
  643|      0|            return NULL;
  644|      0|        }
  645|      5|        if(json_array_add(output_array, new_array_value) == JSONFailure) {
  ------------------
  |  Branch (645:12): [True: 0, False: 5]
  ------------------
  646|      0|            parson_free(new_array_value);
  647|      0|            json_value_free(output_value);
  648|      0|            return NULL;
  649|      0|        }
  650|      5|        SKIP_WHITESPACES(string);
  ------------------
  |  |   43|      5|#define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
  |  |  ------------------
  |  |  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  |  |  ------------------
  ------------------
  651|      5|        if (**string != ',')
  ------------------
  |  Branch (651:13): [True: 5, False: 0]
  ------------------
  652|      5|            break;
  653|      0|        SKIP_CHAR(string);
  ------------------
  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  ------------------
  654|      0|        SKIP_WHITESPACES(string);
  ------------------
  |  |   43|      0|#define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
  |  |  ------------------
  |  |  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  |  |  ------------------
  ------------------
  655|      0|    }
  656|      5|    SKIP_WHITESPACES(string);
  ------------------
  |  |   43|      5|#define SKIP_WHITESPACES(str) while (isspace(**str)) { SKIP_CHAR(str); }
  |  |  ------------------
  |  |  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  |  |  ------------------
  ------------------
  657|      5|    if (**string != ']' || /* Trim array after parsing is over */
  ------------------
  |  Branch (657:9): [True: 5, False: 0]
  ------------------
  658|      5|        json_array_resize(output_array, json_array_get_count(output_array)) == JSONFailure) {
  ------------------
  |  Branch (658:9): [True: 0, False: 0]
  ------------------
  659|      5|            json_value_free(output_value);
  660|      5|            return NULL;
  661|      5|    }
  662|      0|    SKIP_CHAR(string);
  ------------------
  |  |   42|      0|#define SKIP_CHAR(str)        ((*str)++)
  ------------------
  663|      0|    return output_value;
  664|      5|}
parson.c:json_array_resize:
  402|      5|static JSON_Status json_array_resize(JSON_Array *array, size_t new_capacity) {
  403|      5|    JSON_Value **new_items = NULL;
  404|      5|    if (new_capacity == 0) {
  ------------------
  |  Branch (404:9): [True: 0, False: 5]
  ------------------
  405|      0|        return JSONFailure;
  406|      0|    }
  407|      5|    new_items = (JSON_Value**)parson_malloc(new_capacity * sizeof(JSON_Value*));
  408|      5|    if (new_items == NULL) {
  ------------------
  |  Branch (408:9): [True: 0, False: 5]
  ------------------
  409|      0|        return JSONFailure;
  410|      0|    }
  411|      5|    if (array->items != NULL && array->count > 0) {
  ------------------
  |  Branch (411:9): [True: 0, False: 5]
  |  Branch (411:33): [True: 0, False: 0]
  ------------------
  412|      0|        memcpy(new_items, array->items, array->count * sizeof(JSON_Value*));
  413|      0|    }
  414|      5|    parson_free(array->items);
  415|      5|    array->items = new_items;
  416|      5|    array->capacity = new_capacity;
  417|      5|    return JSONSuccess;
  418|      5|}
parson.c:parse_number_value:
  692|      9|static JSON_Value * parse_number_value(const char **string) {
  693|      9|    char *end;
  694|      9|    double number = strtod(*string, &end);
  695|      9|    JSON_Value *output_value;
  696|      9|    if (is_decimal(*string, end - *string)) {
  ------------------
  |  Branch (696:9): [True: 9, False: 0]
  ------------------
  697|      9|        *string = end;
  698|      9|        output_value = json_value_init_number(number);
  699|      9|    } else {
  700|      0|        output_value = NULL;
  701|      0|    }
  702|      9|    return output_value;
  703|      9|}
parson.c:is_decimal:
  215|      9|static int is_decimal(const char *string, size_t length) {
  216|      9|    if (length > 1 && string[0] == '0' && string[1] != '.')
  ------------------
  |  Branch (216:9): [True: 5, False: 4]
  |  Branch (216:23): [True: 0, False: 5]
  |  Branch (216:43): [True: 0, False: 0]
  ------------------
  217|      0|        return 0;
  218|      9|    if (length > 2 && !strncmp(string, "-0", 2) && string[2] != '.')
  ------------------
  |  Branch (218:9): [True: 5, False: 4]
  |  Branch (218:23): [True: 0, False: 5]
  |  Branch (218:52): [True: 0, False: 0]
  ------------------
  219|      0|        return 0;
  220|  5.24M|    while (length--)
  ------------------
  |  Branch (220:12): [True: 5.24M, False: 9]
  ------------------
  221|  5.24M|        if (strchr("xX", string[length]))
  ------------------
  |  Branch (221:13): [True: 0, False: 5.24M]
  ------------------
  222|      0|            return 0;
  223|      9|    return 1;
  224|      9|}
parson.c:parson_strdup:
  138|      4|static char * parson_strdup(const char *string) {
  139|      4|    return parson_strndup(string, strlen(string));
  140|      4|}
parson.c:json_object_nget_value:
  356|     72|static JSON_Value * json_object_nget_value(const JSON_Object *object, const char *name, size_t n) {
  357|     72|    size_t i, name_length;
  358|    140|    for (i = 0; i < json_object_get_count(object); i++) {
  ------------------
  |  Branch (358:17): [True: 68, False: 72]
  ------------------
  359|     68|        name_length = strlen(object->names[i]);
  360|     68|        if (name_length != n)
  ------------------
  |  Branch (360:13): [True: 68, False: 0]
  ------------------
  361|     68|            continue;
  362|      0|        if (strncmp(object->names[i], name, n) == 0)
  ------------------
  |  Branch (362:13): [True: 0, False: 0]
  ------------------
  363|      0|            return object->values[i];
  364|      0|    }
  365|     72|    return NULL;
  366|     72|}
parson.c:json_object_free:
  368|      4|static void json_object_free(JSON_Object *object) {
  369|      8|    while(object->count--) {
  ------------------
  |  Branch (369:11): [True: 4, False: 4]
  ------------------
  370|      4|        parson_free(object->names[object->count]);
  371|      4|        json_value_free(object->values[object->count]);
  372|      4|    }
  373|      4|    parson_free(object->names);
  374|      4|    parson_free(object->values);
  375|      4|    parson_free(object);
  376|      4|}
parson.c:json_array_free:
  420|      5|static void json_array_free(JSON_Array *array) {
  421|     10|    while (array->count--)
  ------------------
  |  Branch (421:12): [True: 5, False: 5]
  ------------------
  422|      5|        json_value_free(array->items[array->count]);
  423|      5|    parson_free(array->items);
  424|      5|    parson_free(array);
  425|      5|}
parson.c:json_object_init:
  290|      4|static JSON_Object * json_object_init(void) {
  291|      4|    JSON_Object *new_obj = (JSON_Object*)parson_malloc(sizeof(JSON_Object));
  292|      4|    if (!new_obj)
  ------------------
  |  Branch (292:9): [True: 0, False: 4]
  ------------------
  293|      0|        return NULL;
  294|      4|    new_obj->names = (char**)NULL;
  295|      4|    new_obj->values = (JSON_Value**)NULL;
  296|      4|    new_obj->capacity = 0;
  297|      4|    new_obj->count = 0;
  298|      4|    return new_obj;
  299|      4|}
parson.c:json_array_init:
  379|      5|static JSON_Array * json_array_init(void) {
  380|      5|    JSON_Array *new_array = (JSON_Array*)parson_malloc(sizeof(JSON_Array));
  381|      5|    if (!new_array)
  ------------------
  |  Branch (381:9): [True: 0, False: 5]
  ------------------
  382|      0|        return NULL;
  383|      5|    new_array->items = (JSON_Value**)NULL;
  384|      5|    new_array->capacity = 0;
  385|      5|    new_array->count = 0;
  386|      5|    return new_array;
  387|      5|}
parson.c:parson_strndup:
  129|      4|static char * parson_strndup(const char *string, size_t n) {
  130|      4|    char *output_string = (char*)parson_malloc(n + 1);
  131|      4|    if (!output_string)
  ------------------
  |  Branch (131:9): [True: 0, False: 4]
  ------------------
  132|      0|        return NULL;
  133|      4|    output_string[n] = '\0';
  134|      4|    strncpy(output_string, string, n);
  135|      4|    return output_string;
  136|      4|}
parson.c:json_array_add:
  389|      5|static JSON_Status json_array_add(JSON_Array *array, JSON_Value *value) {
  390|      5|    if (array->count >= array->capacity) {
  ------------------
  |  Branch (390:9): [True: 5, False: 0]
  ------------------
  391|      5|        size_t new_capacity = MAX(array->capacity * 2, STARTING_CAPACITY);
  ------------------
  |  |   44|      5|#define MAX(a, b)             ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (44:32): [True: 0, False: 5]
  |  |  ------------------
  ------------------
  392|      5|        if (new_capacity > ARRAY_MAX_CAPACITY)
  ------------------
  |  |   36|      5|#define ARRAY_MAX_CAPACITY    122880 /* 15*(2^13) */
  ------------------
  |  Branch (392:13): [True: 0, False: 5]
  ------------------
  393|      0|            return JSONFailure;
  394|      5|        if (json_array_resize(array, new_capacity) == JSONFailure)
  ------------------
  |  Branch (394:13): [True: 0, False: 5]
  ------------------
  395|      0|            return JSONFailure;
  396|      5|    }
  397|      5|    array->items[array->count] = value;
  398|      5|    array->count++;
  399|      5|    return JSONSuccess;
  400|      5|}
parson.c:json_object_add:
  301|      4|static JSON_Status json_object_add(JSON_Object *object, const char *name, JSON_Value *value) {
  302|      4|    size_t index = 0;
  303|      4|    if (object == NULL || name == NULL || value == NULL) {
  ------------------
  |  Branch (303:9): [True: 0, False: 4]
  |  Branch (303:27): [True: 0, False: 4]
  |  Branch (303:43): [True: 0, False: 4]
  ------------------
  304|      0|        return JSONFailure;
  305|      0|    }
  306|      4|    if (object->count >= object->capacity) {
  ------------------
  |  Branch (306:9): [True: 4, False: 0]
  ------------------
  307|      4|        size_t new_capacity = MAX(object->capacity * 2, STARTING_CAPACITY);
  ------------------
  |  |   44|      4|#define MAX(a, b)             ((a) > (b) ? (a) : (b))
  |  |  ------------------
  |  |  |  Branch (44:32): [True: 0, False: 4]
  |  |  ------------------
  ------------------
  308|      4|        if (new_capacity > OBJECT_MAX_CAPACITY)
  ------------------
  |  |   37|      4|#define OBJECT_MAX_CAPACITY      960 /* 15*(2^6)  */
  ------------------
  |  Branch (308:13): [True: 0, False: 4]
  ------------------
  309|      0|            return JSONFailure;
  310|      4|        if (json_object_resize(object, new_capacity) == JSONFailure)
  ------------------
  |  Branch (310:13): [True: 0, False: 4]
  ------------------
  311|      0|            return JSONFailure;
  312|      4|    }
  313|      4|    if (json_object_get_value(object, name) != NULL)
  ------------------
  |  Branch (313:9): [True: 0, False: 4]
  ------------------
  314|      0|        return JSONFailure;
  315|      4|    index = object->count;
  316|      4|    object->names[index] = parson_strdup(name);
  317|      4|    if (object->names[index] == NULL)
  ------------------
  |  Branch (317:9): [True: 0, False: 4]
  ------------------
  318|      0|        return JSONFailure;
  319|      4|    object->values[index] = value;
  320|      4|    object->count++;
  321|      4|    return JSONSuccess;
  322|      4|}

strdup:
   18|      6|strdup(const char *str) {
   19|      6|  if (NULL == (char *) str) {
  ------------------
  |  Branch (19:7): [True: 0, False: 6]
  ------------------
   20|      0|    return NULL;
   21|      0|  }
   22|       |
   23|      6|  int len = strlen(str) + 1;
   24|      6|  char *buf = malloc(len);
   25|       |
   26|      6|  if (buf) {
  ------------------
  |  Branch (26:7): [True: 6, False: 0]
  ------------------
   27|      6|    memset(buf, 0, len);
   28|      6|    memcpy(buf, str, len - 1);
   29|      6|  }
   30|      6|  return buf;
   31|      6|}

clib_package_load_from_manifest:
  245|     10|                                                int verbose) {
  246|     10|  clib_package_t *pkg = NULL;
  247|       |
  248|     10|  if (-1 == fs_exists(manifest)) {
  ------------------
  |  Branch (248:7): [True: 0, False: 10]
  ------------------
  249|      0|    logger_error("error", "Missing %s", manifest);
  ------------------
  |  |   45|      0|#define logger_error(type, ...) ({                           \
  |  |   46|      0|  cc_fprintf(CC_FG_DARK_RED, stderr, CLIB_LOGGER_FMT, type); \
  |  |  ------------------
  |  |  |  |   16|      0|#  define CLIB_LOGGER_FMT "  %10s"
  |  |  ------------------
  |  |   47|      0|  fprintf(stderr, " : ");                                    \
  |  |   48|      0|  cc_fprintf(CC_FG_DARK_GRAY, stderr, __VA_ARGS__);          \
  |  |   49|      0|  fprintf(stderr, "\n");                                     \
  |  |   50|      0|});
  ------------------
  250|      0|    return NULL;
  251|      0|  }
  252|       |
  253|     10|  logger_info("info", "reading local %s", manifest);
  ------------------
  |  |   23|     10|#define logger_info(type, ...) ({                          \
  |  |   24|     10|  cc_fprintf(CC_FG_CYAN, stdout, CLIB_LOGGER_FMT, type);   \
  |  |  ------------------
  |  |  |  |   16|     10|#  define CLIB_LOGGER_FMT "  %10s"
  |  |  ------------------
  |  |   25|     10|  fprintf(stdout, " : ");                                  \
  |  |   26|     10|  cc_fprintf(CC_FG_DARK_GRAY, stdout, __VA_ARGS__);        \
  |  |   27|     10|  fprintf(stdout, "\n");                                   \
  |  |   28|     10|});
  ------------------
  254|       |
  255|     10|  char *json = fs_read(manifest);
  256|     10|  if (NULL == json)
  ------------------
  |  Branch (256:7): [True: 0, False: 10]
  ------------------
  257|      0|    goto e1;
  258|       |
  259|     10|  pkg = clib_package_new(json, verbose);
  260|       |
  261|     10|e1:
  262|     10|  free(json);
  263|       |
  264|     10|  return pkg;
  265|     10|}
clib_package_new:
  443|     10|clib_package_t *clib_package_new(const char *json, int verbose) {
  444|     10|  clib_package_t *pkg = NULL;
  445|     10|  JSON_Value *root = NULL;
  446|     10|  JSON_Object *json_object = NULL;
  447|     10|  JSON_Array *src = NULL;
  448|     10|  JSON_Object *deps = NULL;
  449|     10|  JSON_Object *devs = NULL;
  450|     10|  int error = 1;
  451|       |
  452|     10|  if (!json) {
  ------------------
  |  Branch (452:7): [True: 0, False: 10]
  ------------------
  453|      0|    if (verbose) {
  ------------------
  |  Branch (453:9): [True: 0, False: 0]
  ------------------
  454|      0|      logger_error("error", "missing JSON to parse");
  ------------------
  |  |   45|      0|#define logger_error(type, ...) ({                           \
  |  |   46|      0|  cc_fprintf(CC_FG_DARK_RED, stderr, CLIB_LOGGER_FMT, type); \
  |  |  ------------------
  |  |  |  |   16|      0|#  define CLIB_LOGGER_FMT "  %10s"
  |  |  ------------------
  |  |   47|      0|  fprintf(stderr, " : ");                                    \
  |  |   48|      0|  cc_fprintf(CC_FG_DARK_GRAY, stderr, __VA_ARGS__);          \
  |  |   49|      0|  fprintf(stderr, "\n");                                     \
  |  |   50|      0|});
  ------------------
  455|      0|    }
  456|      0|    goto cleanup;
  457|      0|  }
  458|       |
  459|     10|  if (!(root = json_parse_string(json))) {
  ------------------
  |  Branch (459:7): [True: 6, False: 4]
  ------------------
  460|      6|    if (verbose) {
  ------------------
  |  Branch (460:9): [True: 0, False: 6]
  ------------------
  461|      0|      logger_error("error", "unable to parse JSON");
  ------------------
  |  |   45|      0|#define logger_error(type, ...) ({                           \
  |  |   46|      0|  cc_fprintf(CC_FG_DARK_RED, stderr, CLIB_LOGGER_FMT, type); \
  |  |  ------------------
  |  |  |  |   16|      0|#  define CLIB_LOGGER_FMT "  %10s"
  |  |  ------------------
  |  |   47|      0|  fprintf(stderr, " : ");                                    \
  |  |   48|      0|  cc_fprintf(CC_FG_DARK_GRAY, stderr, __VA_ARGS__);          \
  |  |   49|      0|  fprintf(stderr, "\n");                                     \
  |  |   50|      0|});
  ------------------
  462|      0|    }
  463|      6|    goto cleanup;
  464|      6|  }
  465|       |
  466|      4|  if (!(json_object = json_value_get_object(root))) {
  ------------------
  |  Branch (466:7): [True: 0, False: 4]
  ------------------
  467|      0|    if (verbose) {
  ------------------
  |  Branch (467:9): [True: 0, False: 0]
  ------------------
  468|      0|      logger_error("error", "invalid clib.json or package.json file");
  ------------------
  |  |   45|      0|#define logger_error(type, ...) ({                           \
  |  |   46|      0|  cc_fprintf(CC_FG_DARK_RED, stderr, CLIB_LOGGER_FMT, type); \
  |  |  ------------------
  |  |  |  |   16|      0|#  define CLIB_LOGGER_FMT "  %10s"
  |  |  ------------------
  |  |   47|      0|  fprintf(stderr, " : ");                                    \
  |  |   48|      0|  cc_fprintf(CC_FG_DARK_GRAY, stderr, __VA_ARGS__);          \
  |  |   49|      0|  fprintf(stderr, "\n");                                     \
  |  |   50|      0|});
  ------------------
  469|      0|    }
  470|      0|    goto cleanup;
  471|      0|  }
  472|       |
  473|      4|  if (!(pkg = malloc(sizeof(clib_package_t)))) {
  ------------------
  |  Branch (473:7): [True: 0, False: 4]
  ------------------
  474|      0|    goto cleanup;
  475|      0|  }
  476|       |
  477|      4|  memset(pkg, 0, sizeof(clib_package_t));
  478|       |
  479|      4|  pkg->json = strdup(json);
  480|      4|  pkg->name = json_object_get_string_safe(json_object, "name");
  481|      4|  pkg->repo = json_object_get_string_safe(json_object, "repo");
  482|      4|  pkg->version = json_object_get_string_safe(json_object, "version");
  483|      4|  pkg->license = json_object_get_string_safe(json_object, "license");
  484|      4|  pkg->description = json_object_get_string_safe(json_object, "description");
  485|      4|  pkg->configure = json_object_get_string_safe(json_object, "configure");
  486|      4|  pkg->install = json_object_get_string_safe(json_object, "install");
  487|      4|  pkg->makefile = json_object_get_string_safe(json_object, "makefile");
  488|      4|  pkg->prefix = json_object_get_string_safe(json_object, "prefix");
  489|      4|  pkg->flags = json_object_get_string_safe(json_object, "flags");
  490|       |
  491|      4|  if (!pkg->flags) {
  ------------------
  |  Branch (491:7): [True: 4, False: 0]
  ------------------
  492|      4|    pkg->flags = json_object_get_string_safe(json_object, "cflags");
  493|      4|  }
  494|       |
  495|       |  // try as array
  496|      4|  if (!pkg->flags) {
  ------------------
  |  Branch (496:7): [True: 4, False: 0]
  ------------------
  497|      4|    JSON_Array *flags = json_object_get_array(json_object, "flags");
  498|       |
  499|      4|    if (!flags) {
  ------------------
  |  Branch (499:9): [True: 4, False: 0]
  ------------------
  500|      4|      flags = json_object_get_array(json_object, "cflags");
  501|      4|    }
  502|       |
  503|      4|    if (flags) {
  ------------------
  |  Branch (503:9): [True: 0, False: 4]
  ------------------
  504|      0|      for (unsigned int i = 0; i < json_array_get_count(flags); i++) {
  ------------------
  |  Branch (504:32): [True: 0, False: 0]
  ------------------
  505|      0|        char *flag = json_array_get_string_safe(flags, i);
  506|      0|        if (flag) {
  ------------------
  |  Branch (506:13): [True: 0, False: 0]
  ------------------
  507|      0|          if (!pkg->flags) {
  ------------------
  |  Branch (507:15): [True: 0, False: 0]
  ------------------
  508|      0|            pkg->flags = "";
  509|      0|          }
  510|       |
  511|      0|          if (-1 == asprintf(&pkg->flags, "%s %s", pkg->flags, flag)) {
  ------------------
  |  Branch (511:15): [True: 0, False: 0]
  ------------------
  512|      0|            goto cleanup;
  513|      0|          }
  514|       |
  515|      0|          free(flag);
  516|      0|        }
  517|      0|      }
  518|      0|    }
  519|      4|  }
  520|       |
  521|      4|  if (!pkg->repo && pkg->author && pkg->name) {
  ------------------
  |  Branch (521:7): [True: 4, False: 0]
  |  Branch (521:21): [True: 0, False: 4]
  |  Branch (521:36): [True: 0, False: 0]
  ------------------
  522|      0|    asprintf(&pkg->repo, "%s/%s", pkg->author, pkg->name);
  523|      0|    _debug("creating package: %s", pkg->repo);
  ------------------
  |  |   86|      0|  ({                                                                           \
  |  |   87|      0|    if (!(_debugger.name))                                                     \
  |  |  ------------------
  |  |  |  Branch (87:9): [True: 0, False: 0]
  |  |  ------------------
  |  |   88|      0|      debug_init(&_debugger, "clib-package");                                  \
  |  |   89|      0|    debug(&_debugger, __VA_ARGS__);                                            \
  |  |   90|      0|  })
  ------------------
  524|      0|  }
  525|       |
  526|      4|  if (!pkg->author) {
  ------------------
  |  Branch (526:7): [True: 4, False: 0]
  ------------------
  527|      4|    _debug("unable to determine package author for: %s", pkg->name);
  ------------------
  |  |   86|      4|  ({                                                                           \
  |  |   87|      4|    if (!(_debugger.name))                                                     \
  |  |  ------------------
  |  |  |  Branch (87:9): [True: 1, False: 3]
  |  |  ------------------
  |  |   88|      4|      debug_init(&_debugger, "clib-package");                                  \
  |  |   89|      4|    debug(&_debugger, __VA_ARGS__);                                            \
  |  |   90|      4|  })
  ------------------
  528|      4|  }
  529|       |
  530|       |  // TODO npm-style "repository" (thlorenz/gumbo-parser.c#1)
  531|      4|  if (pkg->repo) {
  ------------------
  |  Branch (531:7): [True: 0, False: 4]
  ------------------
  532|      0|    pkg->author = parse_repo_owner(pkg->repo, DEFAULT_REPO_OWNER);
  ------------------
  |  |   47|      0|#define DEFAULT_REPO_OWNER "clibs"
  ------------------
  533|       |    // repo name may not be package name (thing.c -> thing)
  534|      0|    pkg->repo_name = parse_repo_name(pkg->repo);
  535|      4|  } else {
  536|      4|    if (verbose) {
  ------------------
  |  Branch (536:9): [True: 0, False: 4]
  ------------------
  537|      0|      logger_warn("warning",
  ------------------
  |  |   34|      0|#define logger_warn(type, ...) ({                               \
  |  |   35|      0|  cc_fprintf(CC_FG_DARK_YELLOW, stdout, CLIB_LOGGER_FMT, type); \
  |  |  ------------------
  |  |  |  |   16|      0|#  define CLIB_LOGGER_FMT "  %10s"
  |  |  ------------------
  |  |   36|      0|  fprintf(stdout, " : ");                                       \
  |  |   37|      0|  cc_fprintf(CC_FG_DARK_GRAY, stdout, __VA_ARGS__);             \
  |  |   38|      0|  fprintf(stdout, "\n");                                        \
  |  |   39|      0|});
  ------------------
  538|      0|                  "missing repo in clib.json or package.json file for %s",
  539|      0|                  pkg->name);
  540|      0|    }
  541|      4|    pkg->author = NULL;
  542|      4|    pkg->repo_name = NULL;
  543|      4|  }
  544|       |
  545|      4|  src = json_object_get_array(json_object, "src");
  546|       |
  547|      4|  if (!src) {
  ------------------
  |  Branch (547:7): [True: 4, False: 0]
  ------------------
  548|      4|    src = json_object_get_array(json_object, "files");
  549|      4|  }
  550|       |
  551|      4|  if (src) {
  ------------------
  |  Branch (551:7): [True: 0, False: 4]
  ------------------
  552|      0|    if (!(pkg->src = list_new()))
  ------------------
  |  Branch (552:9): [True: 0, False: 0]
  ------------------
  553|      0|      goto cleanup;
  554|      0|    pkg->src->free = free;
  555|      0|    for (unsigned int i = 0; i < json_array_get_count(src); i++) {
  ------------------
  |  Branch (555:30): [True: 0, False: 0]
  ------------------
  556|      0|      char *file = json_array_get_string_safe(src, i);
  557|      0|      _debug("file: %s", file);
  ------------------
  |  |   86|      0|  ({                                                                           \
  |  |   87|      0|    if (!(_debugger.name))                                                     \
  |  |  ------------------
  |  |  |  Branch (87:9): [True: 0, False: 0]
  |  |  ------------------
  |  |   88|      0|      debug_init(&_debugger, "clib-package");                                  \
  |  |   89|      0|    debug(&_debugger, __VA_ARGS__);                                            \
  |  |   90|      0|  })
  ------------------
  558|      0|      if (!file)
  ------------------
  |  Branch (558:11): [True: 0, False: 0]
  ------------------
  559|      0|        goto cleanup;
  560|      0|      if (!(list_rpush(pkg->src, list_node_new(file))))
  ------------------
  |  Branch (560:11): [True: 0, False: 0]
  ------------------
  561|      0|        goto cleanup;
  562|      0|    }
  563|      4|  } else {
  564|      4|    _debug("no src files listed in clib.json or package.json file");
  ------------------
  |  |   86|      4|  ({                                                                           \
  |  |   87|      4|    if (!(_debugger.name))                                                     \
  |  |  ------------------
  |  |  |  Branch (87:9): [True: 0, False: 4]
  |  |  ------------------
  |  |   88|      4|      debug_init(&_debugger, "clib-package");                                  \
  |  |   89|      4|    debug(&_debugger, __VA_ARGS__);                                            \
  |  |   90|      4|  })
  ------------------
  565|      4|    pkg->src = NULL;
  566|      4|  }
  567|       |
  568|      4|  if ((deps = json_object_get_object(json_object, "dependencies"))) {
  ------------------
  |  Branch (568:7): [True: 0, False: 4]
  ------------------
  569|      0|    if (!(pkg->dependencies = parse_package_deps(deps))) {
  ------------------
  |  Branch (569:9): [True: 0, False: 0]
  ------------------
  570|      0|      goto cleanup;
  571|      0|    }
  572|      4|  } else {
  573|      4|    _debug("no dependencies listed in clib.json or package.json file");
  ------------------
  |  |   86|      4|  ({                                                                           \
  |  |   87|      4|    if (!(_debugger.name))                                                     \
  |  |  ------------------
  |  |  |  Branch (87:9): [True: 0, False: 4]
  |  |  ------------------
  |  |   88|      4|      debug_init(&_debugger, "clib-package");                                  \
  |  |   89|      4|    debug(&_debugger, __VA_ARGS__);                                            \
  |  |   90|      4|  })
  ------------------
  574|      4|    pkg->dependencies = NULL;
  575|      4|  }
  576|       |
  577|      4|  if ((devs = json_object_get_object(json_object, "development"))) {
  ------------------
  |  Branch (577:7): [True: 0, False: 4]
  ------------------
  578|      0|    if (!(pkg->development = parse_package_deps(devs))) {
  ------------------
  |  Branch (578:9): [True: 0, False: 0]
  ------------------
  579|      0|      goto cleanup;
  580|      0|    }
  581|      4|  } else {
  582|      4|    _debug(
  ------------------
  |  |   86|      4|  ({                                                                           \
  |  |   87|      4|    if (!(_debugger.name))                                                     \
  |  |  ------------------
  |  |  |  Branch (87:9): [True: 0, False: 4]
  |  |  ------------------
  |  |   88|      4|      debug_init(&_debugger, "clib-package");                                  \
  |  |   89|      4|    debug(&_debugger, __VA_ARGS__);                                            \
  |  |   90|      4|  })
  ------------------
  583|      4|        "no development dependencies listed in clib.json or package.json file");
  584|      4|    pkg->development = NULL;
  585|      4|  }
  586|       |
  587|      4|  error = 0;
  588|       |
  589|     10|cleanup:
  590|     10|  if (root)
  ------------------
  |  Branch (590:7): [True: 4, False: 6]
  ------------------
  591|      4|    json_value_free(root);
  592|     10|  if (error && pkg) {
  ------------------
  |  Branch (592:7): [True: 6, False: 4]
  |  Branch (592:16): [True: 0, False: 6]
  ------------------
  593|      0|    clib_package_free(pkg);
  594|      0|    pkg = NULL;
  595|      0|  }
  596|     10|  return pkg;
  597|      4|}
clib_package_free:
 1664|      4|void clib_package_free(clib_package_t *pkg) {
 1665|      4|  if (NULL == pkg) {
  ------------------
  |  Branch (1665:7): [True: 0, False: 4]
  ------------------
 1666|      0|    return;
 1667|      0|  }
 1668|       |
 1669|      4|  if (0 != pkg->refs) {
  ------------------
  |  Branch (1669:7): [True: 0, False: 4]
  ------------------
 1670|      0|    return;
 1671|      0|  }
 1672|       |
 1673|      4|#define FREE(k)                                                                \
 1674|      4|  if (pkg->k) {                                                                \
 1675|      4|    free(pkg->k);                                                              \
 1676|      4|    pkg->k = 0;                                                                \
 1677|      4|  }
 1678|      4|  FREE(author);
  ------------------
  |  | 1674|      4|  if (pkg->k) {                                                                \
  |  |  ------------------
  |  |  |  Branch (1674:7): [True: 0, False: 4]
  |  |  ------------------
  |  | 1675|      0|    free(pkg->k);                                                              \
  |  | 1676|      0|    pkg->k = 0;                                                                \
  |  | 1677|      0|  }
  ------------------
 1679|      4|  FREE(description);
  ------------------
  |  | 1674|      4|  if (pkg->k) {                                                                \
  |  |  ------------------
  |  |  |  Branch (1674:7): [True: 0, False: 4]
  |  |  ------------------
  |  | 1675|      0|    free(pkg->k);                                                              \
  |  | 1676|      0|    pkg->k = 0;                                                                \
  |  | 1677|      0|  }
  ------------------
 1680|      4|  FREE(install);
  ------------------
  |  | 1674|      4|  if (pkg->k) {                                                                \
  |  |  ------------------
  |  |  |  Branch (1674:7): [True: 0, False: 4]
  |  |  ------------------
  |  | 1675|      0|    free(pkg->k);                                                              \
  |  | 1676|      0|    pkg->k = 0;                                                                \
  |  | 1677|      0|  }
  ------------------
 1681|      4|  FREE(json);
  ------------------
  |  | 1674|      4|  if (pkg->k) {                                                                \
  |  |  ------------------
  |  |  |  Branch (1674:7): [True: 4, False: 0]
  |  |  ------------------
  |  | 1675|      4|    free(pkg->k);                                                              \
  |  | 1676|      4|    pkg->k = 0;                                                                \
  |  | 1677|      4|  }
  ------------------
 1682|      4|  FREE(license);
  ------------------
  |  | 1674|      4|  if (pkg->k) {                                                                \
  |  |  ------------------
  |  |  |  Branch (1674:7): [True: 0, False: 4]
  |  |  ------------------
  |  | 1675|      0|    free(pkg->k);                                                              \
  |  | 1676|      0|    pkg->k = 0;                                                                \
  |  | 1677|      0|  }
  ------------------
 1683|      4|  FREE(name);
  ------------------
  |  | 1674|      4|  if (pkg->k) {                                                                \
  |  |  ------------------
  |  |  |  Branch (1674:7): [True: 0, False: 4]
  |  |  ------------------
  |  | 1675|      0|    free(pkg->k);                                                              \
  |  | 1676|      0|    pkg->k = 0;                                                                \
  |  | 1677|      0|  }
  ------------------
 1684|      4|  FREE(makefile);
  ------------------
  |  | 1674|      4|  if (pkg->k) {                                                                \
  |  |  ------------------
  |  |  |  Branch (1674:7): [True: 0, False: 4]
  |  |  ------------------
  |  | 1675|      0|    free(pkg->k);                                                              \
  |  | 1676|      0|    pkg->k = 0;                                                                \
  |  | 1677|      0|  }
  ------------------
 1685|      4|  FREE(configure);
  ------------------
  |  | 1674|      4|  if (pkg->k) {                                                                \
  |  |  ------------------
  |  |  |  Branch (1674:7): [True: 0, False: 4]
  |  |  ------------------
  |  | 1675|      0|    free(pkg->k);                                                              \
  |  | 1676|      0|    pkg->k = 0;                                                                \
  |  | 1677|      0|  }
  ------------------
 1686|      4|  FREE(repo);
  ------------------
  |  | 1674|      4|  if (pkg->k) {                                                                \
  |  |  ------------------
  |  |  |  Branch (1674:7): [True: 0, False: 4]
  |  |  ------------------
  |  | 1675|      0|    free(pkg->k);                                                              \
  |  | 1676|      0|    pkg->k = 0;                                                                \
  |  | 1677|      0|  }
  ------------------
 1687|      4|  FREE(repo_name);
  ------------------
  |  | 1674|      4|  if (pkg->k) {                                                                \
  |  |  ------------------
  |  |  |  Branch (1674:7): [True: 0, False: 4]
  |  |  ------------------
  |  | 1675|      0|    free(pkg->k);                                                              \
  |  | 1676|      0|    pkg->k = 0;                                                                \
  |  | 1677|      0|  }
  ------------------
 1688|      4|  FREE(url);
  ------------------
  |  | 1674|      4|  if (pkg->k) {                                                                \
  |  |  ------------------
  |  |  |  Branch (1674:7): [True: 0, False: 4]
  |  |  ------------------
  |  | 1675|      0|    free(pkg->k);                                                              \
  |  | 1676|      0|    pkg->k = 0;                                                                \
  |  | 1677|      0|  }
  ------------------
 1689|      4|  FREE(version);
  ------------------
  |  | 1674|      4|  if (pkg->k) {                                                                \
  |  |  ------------------
  |  |  |  Branch (1674:7): [True: 0, False: 4]
  |  |  ------------------
  |  | 1675|      0|    free(pkg->k);                                                              \
  |  | 1676|      0|    pkg->k = 0;                                                                \
  |  | 1677|      0|  }
  ------------------
 1690|      4|  FREE(flags);
  ------------------
  |  | 1674|      4|  if (pkg->k) {                                                                \
  |  |  ------------------
  |  |  |  Branch (1674:7): [True: 0, False: 4]
  |  |  ------------------
  |  | 1675|      0|    free(pkg->k);                                                              \
  |  | 1676|      0|    pkg->k = 0;                                                                \
  |  | 1677|      0|  }
  ------------------
 1691|      4|#undef FREE
 1692|       |
 1693|      4|  if (pkg->src)
  ------------------
  |  Branch (1693:7): [True: 0, False: 4]
  ------------------
 1694|      0|    list_destroy(pkg->src);
 1695|      4|  pkg->src = 0;
 1696|       |
 1697|      4|  if (pkg->dependencies)
  ------------------
  |  Branch (1697:7): [True: 0, False: 4]
  ------------------
 1698|      0|    list_destroy(pkg->dependencies);
 1699|      4|  pkg->dependencies = 0;
 1700|       |
 1701|      4|  if (pkg->development)
  ------------------
  |  Branch (1701:7): [True: 0, False: 4]
  ------------------
 1702|      0|    list_destroy(pkg->development);
 1703|      4|  pkg->development = 0;
 1704|       |
 1705|      4|  free(pkg);
 1706|      4|  pkg = 0;
 1707|      4|}
clib-package.c:json_object_get_string_safe:
  181|     44|                                                const char *key) {
  182|     44|  const char *val = json_object_get_string(obj, key);
  183|     44|  if (!val)
  ------------------
  |  Branch (183:7): [True: 44, False: 0]
  ------------------
  184|     44|    return NULL;
  185|      0|  return strdup(val);
  186|     44|}

LLVMFuzzerTestOneInput:
    7|     10|int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    8|     10|    if(size<3){
  ------------------
  |  Branch (8:8): [True: 0, False: 10]
  ------------------
    9|      0|            return 0;
   10|      0|    }
   11|     10|    char filename[256];
   12|     10|    sprintf(filename, "libfuzzer.json");
   13|       |
   14|     10|    FILE *fp = fopen(filename, "wb");
   15|     10|    if (!fp)
  ------------------
  |  Branch (15:9): [True: 0, False: 10]
  ------------------
   16|      0|            return 0;
   17|     10|    fwrite(data, size, 1, fp);
   18|     10|    fclose(fp);
   19|       |    
   20|     10|    clib_package_t *pkg = 
   21|     10|	    clib_package_load_from_manifest(filename, 0);
   22|     10|    if(pkg) {
  ------------------
  |  Branch (22:8): [True: 4, False: 6]
  ------------------
   23|      4|	    clib_package_free(pkg);
   24|      4|    }
   25|     10|    unlink(filename);
   26|     10|    return 0;
   27|     10|}

