LLVMFuzzerTestOneInput:
   26|  2.13k|{
   27|  2.13k|	plist_t root_node = NULL;
   28|  2.13k|	plist_from_json(reinterpret_cast<const char*>(data), size, &root_node);
   29|  2.13k|	plist_free(root_node);
   30|       |
   31|  2.13k|	return 0;
   32|  2.13k|}

node_destroy:
   31|   188k|{
   32|   188k|	if(!node) return;
  ------------------
  |  Branch (32:5): [True: 0, False: 188k]
  ------------------
   33|       |
   34|   188k|	if (node->children && node->children->count > 0) {
  ------------------
  |  Branch (34:6): [True: 29.8k, False: 158k]
  |  Branch (34:24): [True: 0, False: 29.8k]
  ------------------
   35|      0|		node_t ch;
   36|      0|		while ((ch = node->children->begin)) {
  ------------------
  |  Branch (36:10): [True: 0, False: 0]
  ------------------
   37|      0|			node_list_remove(node->children, ch);
   38|      0|			node_destroy(ch);
   39|      0|		}
   40|      0|	}
   41|   188k|	node_list_destroy(node->children);
   42|   188k|	node->children = NULL;
   43|       |
   44|   188k|	free(node);
   45|   188k|}
node_create:
   48|   188k|{
   49|   188k|	int error = 0;
   50|       |
   51|   188k|	node_t node = (node_t)calloc(1, sizeof(struct node));
   52|   188k|	if (node == NULL) {
  ------------------
  |  Branch (52:6): [True: 0, False: 188k]
  ------------------
   53|      0|		return NULL;
   54|      0|	}
   55|       |
   56|   188k|	node->data = data;
   57|   188k|	node->next = NULL;
   58|   188k|	node->prev = NULL;
   59|   188k|	node->count = 0;
   60|   188k|	node->parent = NULL;
   61|   188k|	node->children = NULL;
   62|       |
   63|       |	// Pass NULL to create a root node
   64|   188k|	if(parent != NULL) {
  ------------------
  |  Branch (64:5): [True: 0, False: 188k]
  ------------------
   65|       |		// This is a child node so attach it to it's parent
   66|      0|		error = node_attach(parent, node);
   67|      0|		if(error < 0) {
  ------------------
  |  Branch (67:6): [True: 0, False: 0]
  ------------------
   68|       |			// Unable to attach nodes
   69|      0|			printf("ERROR: %d \"Unable to attach nodes\"\n", error);
   70|      0|			node_destroy(node);
   71|      0|			return NULL;
   72|      0|		}
   73|      0|	}
   74|       |
   75|   188k|	return node;
   76|   188k|}
node_attach:
   79|   179k|{
   80|   179k|	if (!parent || !child) return -1;
  ------------------
  |  Branch (80:6): [True: 0, False: 179k]
  |  Branch (80:17): [True: 0, False: 179k]
  ------------------
   81|   179k|	child->parent = parent;
   82|   179k|	if(!parent->children) {
  ------------------
  |  Branch (82:5): [True: 29.8k, False: 149k]
  ------------------
   83|  29.8k|		parent->children = node_list_create();
   84|  29.8k|	}
   85|   179k|	int res = node_list_add(parent->children, child);
   86|   179k|	if (res == 0) {
  ------------------
  |  Branch (86:6): [True: 179k, False: 0]
  ------------------
   87|   179k|		parent->count++;
   88|   179k|	}
   89|   179k|	return res;
   90|   179k|}
node_detach:
   93|   188k|{
   94|   188k|	if (!parent || !child) return -1;
  ------------------
  |  Branch (94:6): [True: 5.09k, False: 183k]
  |  Branch (94:17): [True: 0, False: 183k]
  ------------------
   95|   183k|	int node_index = node_list_remove(parent->children, child);
   96|   183k|	if (node_index >= 0) {
  ------------------
  |  Branch (96:6): [True: 183k, False: 0]
  ------------------
   97|   183k|		parent->count--;
   98|   183k|	}
   99|   183k|	return node_index;
  100|   188k|}
node_insert:
  103|  4.03k|{
  104|  4.03k|	if (!parent || !child) return -1;
  ------------------
  |  Branch (104:6): [True: 0, False: 4.03k]
  |  Branch (104:17): [True: 0, False: 4.03k]
  ------------------
  105|  4.03k|	child->parent = parent;
  106|  4.03k|	if(!parent->children) {
  ------------------
  |  Branch (106:5): [True: 0, False: 4.03k]
  ------------------
  107|      0|		parent->children = node_list_create();
  108|      0|	}
  109|  4.03k|	int res = node_list_insert(parent->children, node_index, child);
  110|  4.03k|	if (res == 0) {
  ------------------
  |  Branch (110:6): [True: 4.03k, False: 0]
  ------------------
  111|  4.03k|		parent->count++;
  112|  4.03k|	}
  113|  4.03k|	return res;
  114|  4.03k|}
node_first_child:
  170|   254k|{
  171|   254k|	if (!node || !node->children) return NULL;
  ------------------
  |  Branch (171:6): [True: 0, False: 254k]
  |  Branch (171:15): [True: 159k, False: 95.1k]
  ------------------
  172|  95.1k|	return node->children->begin;
  173|   254k|}
node_prev_sibling:
  176|  4.03k|{
  177|  4.03k|	if (!node) return NULL;
  ------------------
  |  Branch (177:6): [True: 0, False: 4.03k]
  ------------------
  178|  4.03k|	return node->prev;
  179|  4.03k|}
node_next_sibling:
  182|  15.4M|{
  183|  15.4M|	if (!node) return NULL;
  ------------------
  |  Branch (183:6): [True: 0, False: 15.4M]
  ------------------
  184|  15.4M|	return node->next;
  185|  15.4M|}

node_list_destroy:
   32|   188k|{
   33|   188k|	free(list);
   34|   188k|}
node_list_create:
   37|  29.8k|{
   38|  29.8k|	node_list_t list = (node_list_t)calloc(1, sizeof(struct node_list));
   39|  29.8k|	if (list == NULL) {
  ------------------
  |  Branch (39:6): [True: 0, False: 29.8k]
  ------------------
   40|      0|		return NULL;
   41|      0|	}
   42|       |
   43|       |	// Initialize structure
   44|  29.8k|	list->begin = NULL;
   45|  29.8k|	list->end = NULL;
   46|  29.8k|	list->count = 0;
   47|  29.8k|	return list;
   48|  29.8k|}
node_list_add:
   51|   182k|{
   52|   182k|	if (!list || !node) return -1;
  ------------------
  |  Branch (52:6): [True: 0, False: 182k]
  |  Branch (52:15): [True: 0, False: 182k]
  ------------------
   53|       |
   54|       |	// Find the last element in the list
   55|   182k|	node_t last = list->end;
   56|       |
   57|       |	// Setup our new node as the new last element
   58|   182k|	node->next = NULL;
   59|   182k|	node->prev = last;
   60|       |
   61|       |	// Set the next element of our old "last" element
   62|   182k|	if (last) {
  ------------------
  |  Branch (62:6): [True: 152k, False: 29.8k]
  ------------------
   63|       |		// but only if the node list is not empty
   64|   152k|		last->next = node;
   65|   152k|	} else {
   66|       |		// otherwise this is the start of the list
   67|  29.8k|		list->begin = node;
   68|  29.8k|	}
   69|       |
   70|       |	// Set the lists prev to the new last element
   71|   182k|	list->end = node;
   72|       |
   73|       |	// Increment our node count for this list
   74|   182k|	list->count++;
   75|   182k|	return 0;
   76|   182k|}
node_list_insert:
   79|  4.03k|{
   80|  4.03k|	if (!list || !node) return -1;
  ------------------
  |  Branch (80:6): [True: 0, False: 4.03k]
  |  Branch (80:15): [True: 0, False: 4.03k]
  ------------------
   81|  4.03k|	if (node_index >= list->count) {
  ------------------
  |  Branch (81:6): [True: 3.19k, False: 842]
  ------------------
   82|  3.19k|		return node_list_add(list, node);
   83|  3.19k|	}
   84|       |
   85|       |	// Get the first element in the list
   86|    842|	node_t cur = list->begin;
   87|       |
   88|    842|	unsigned int pos = 0;
   89|    842|	node_t prev = NULL;
   90|       |
   91|    842|	if (node_index > 0) {
  ------------------
  |  Branch (91:6): [True: 842, False: 0]
  ------------------
   92|   139k|		while (pos < node_index) {
  ------------------
  |  Branch (92:10): [True: 138k, False: 842]
  ------------------
   93|   138k|			prev = cur;
   94|   138k|			cur = cur->next;
   95|   138k|			pos++;
   96|   138k|		}
   97|    842|	}
   98|       |
   99|    842|	if (prev) {
  ------------------
  |  Branch (99:6): [True: 842, False: 0]
  ------------------
  100|       |		// Set previous node
  101|    842|		node->prev = prev;
  102|       |		// Set next node of our new node to next node of the previous node
  103|    842|		node->next = prev->next;
  104|       |		// Set next node of previous node to our new node
  105|    842|		prev->next = node;
  106|    842|	} else {
  107|      0|		node->prev = NULL;
  108|       |		// get old first element in list
  109|      0|		node->next = list->begin;
  110|       |		// set new node as first element in list
  111|      0|		list->begin = node;
  112|      0|	}
  113|       |
  114|    842|	if (node->next == NULL) {
  ------------------
  |  Branch (114:6): [True: 0, False: 842]
  ------------------
  115|       |		// Set the lists prev to the new last element
  116|      0|		list->end = node;
  117|    842|	} else {
  118|       |		// set prev of the new next element to our node
  119|    842|		node->next->prev = node;
  120|    842|	}
  121|       |
  122|       |	// Increment our node count for this list
  123|    842|	list->count++;
  124|    842|	return 0;
  125|  4.03k|}
node_list_remove:
  128|   183k|{
  129|   183k|	if (!list || !node) return -1;
  ------------------
  |  Branch (129:6): [True: 0, False: 183k]
  |  Branch (129:15): [True: 0, False: 183k]
  ------------------
  130|   183k|	if (list->count == 0) return -1;
  ------------------
  |  Branch (130:6): [True: 0, False: 183k]
  ------------------
  131|       |
  132|   183k|	int node_index = 0;
  133|   183k|	node_t n;
  134|   338k|	for (n = list->begin; n; n = n->next) {
  ------------------
  |  Branch (134:24): [True: 338k, False: 0]
  ------------------
  135|   338k|		if (node == n) {
  ------------------
  |  Branch (135:7): [True: 183k, False: 155k]
  ------------------
  136|   183k|			node_t newnode = node->next;
  137|   183k|			if (node->prev) {
  ------------------
  |  Branch (137:8): [True: 4.03k, False: 179k]
  ------------------
  138|  4.03k|				node->prev->next = newnode;
  139|  4.03k|				if (newnode) {
  ------------------
  |  Branch (139:9): [True: 842, False: 3.19k]
  ------------------
  140|    842|					newnode->prev = node->prev;
  141|  3.19k|				} else {
  142|       |					// last element in the list
  143|  3.19k|					list->end = node->prev;
  144|  3.19k|				}
  145|   179k|			} else {
  146|       |				// we just removed the first element
  147|   179k|				if (newnode) {
  ------------------
  |  Branch (147:9): [True: 149k, False: 29.8k]
  ------------------
  148|   149k|					newnode->prev = NULL;
  149|   149k|				} else {
  150|  29.8k|					list->end = NULL;
  151|  29.8k|				}
  152|   179k|				list->begin = newnode;
  153|   179k|			}
  154|   183k|			list->count--;
  155|   183k|			return node_index;
  156|   183k|		}
  157|   155k|		node_index++;
  158|   155k|	}
  159|      0|	return -1;
  160|   183k|}

plist_bin_init:
  217|      2|{
  218|       |    /* init binary plist stuff */
  219|      2|#ifdef DEBUG
  220|      2|    char *env_debug = getenv("PLIST_BIN_DEBUG");
  221|      2|    if (env_debug && !strcmp(env_debug, "1")) {
  ------------------
  |  Branch (221:9): [True: 0, False: 2]
  |  Branch (221:22): [True: 0, False: 0]
  ------------------
  222|      0|        plist_bin_debug = 1;
  223|      0|    }
  224|      2|#endif
  225|      2|}

hash_table_new:
   24|    233|{
   25|    233|	hashtable_t* ht = (hashtable_t*)malloc(sizeof(hashtable_t));
   26|    233|	int i;
   27|   954k|	for (i = 0; i < 4096; i++) {
  ------------------
  |  Branch (27:14): [True: 954k, False: 233]
  ------------------
   28|   954k|		ht->entries[i] = NULL;
   29|   954k|	}
   30|    233|	ht->count = 0;
   31|    233|	ht->hash_func = hash_func;
   32|    233|	ht->compare_func = compare_func;
   33|    233|	ht->free_func = free_func;
   34|    233|	return ht;
   35|    233|}
hash_table_destroy:
   38|  12.1k|{
   39|  12.1k|	if (!ht) return;
  ------------------
  |  Branch (39:6): [True: 11.9k, False: 233]
  ------------------
   40|       |
   41|    233|	int i = 0;
   42|   954k|	for (i = 0; i < 4096; i++) {
  ------------------
  |  Branch (42:14): [True: 954k, False: 233]
  ------------------
   43|   954k|		if (ht->entries[i]) {
  ------------------
  |  Branch (43:7): [True: 57.4k, False: 896k]
  ------------------
   44|  57.4k|			hashentry_t* e = ht->entries[i];
   45|   116k|			while (e) {
  ------------------
  |  Branch (45:11): [True: 58.9k, False: 57.4k]
  ------------------
   46|  58.9k|				if (ht->free_func) {
  ------------------
  |  Branch (46:9): [True: 0, False: 58.9k]
  ------------------
   47|      0|					ht->free_func(e->value);
   48|      0|				}
   49|  58.9k|				hashentry_t* old = e;
   50|  58.9k|				e = (hashentry_t*)e->next;
   51|  58.9k|				free(old);
   52|  58.9k|			}
   53|  57.4k|		}
   54|   954k|	}
   55|    233|	free(ht);
   56|    233|}
hash_table_insert:
   59|  59.4k|{
   60|  59.4k|	if (!ht || !key) return;
  ------------------
  |  Branch (60:6): [True: 0, False: 59.4k]
  |  Branch (60:13): [True: 0, False: 59.4k]
  ------------------
   61|       |
   62|  59.4k|	unsigned int hash = ht->hash_func(key);
   63|       |
   64|  59.4k|	int idx0 = hash & 0xFFF;
   65|       |
   66|       |	// get the idx0 list
   67|  59.4k|	hashentry_t* e = ht->entries[idx0];
   68|  61.6k|	while (e) {
  ------------------
  |  Branch (68:9): [True: 2.69k, False: 58.9k]
  ------------------
   69|  2.69k|		if (ht->compare_func(e->key, key)) {
  ------------------
  |  Branch (69:7): [True: 548, False: 2.14k]
  ------------------
   70|       |			// element already present. replace value.
   71|    548|			e->value = value;
   72|    548|			return;
   73|    548|		}
   74|  2.14k|		e = (hashentry_t*)e->next;
   75|  2.14k|	}
   76|       |
   77|       |	// if we get here, the element is not yet in the list.
   78|       |
   79|       |	// make a new entry.
   80|  58.9k|	hashentry_t* entry = (hashentry_t*)malloc(sizeof(hashentry_t));
   81|  58.9k|	entry->key = key;
   82|  58.9k|	entry->value = value;
   83|  58.9k|	if (!ht->entries[idx0]) {
  ------------------
  |  Branch (83:6): [True: 57.4k, False: 1.46k]
  ------------------
   84|       |		// first entry
   85|  57.4k|		entry->next = NULL;
   86|  57.4k|	} else {
   87|       |		// add to list
   88|  1.46k|		entry->next = ht->entries[idx0];
   89|  1.46k|	}
   90|  58.9k|	ht->entries[idx0] = entry;
   91|  58.9k|	ht->count++;
   92|  58.9k|}
hash_table_lookup:
   95|    974|{
   96|    974|	if (!ht || !key) return NULL;
  ------------------
  |  Branch (96:6): [True: 0, False: 974]
  |  Branch (96:13): [True: 0, False: 974]
  ------------------
   97|    974|	unsigned int hash = ht->hash_func(key);
   98|       |
   99|    974|	int idx0 = hash & 0xFFF;
  100|       |
  101|    974|	hashentry_t* e = ht->entries[idx0];
  102|  1.56k|	while (e) {
  ------------------
  |  Branch (102:9): [True: 1.13k, False: 426]
  ------------------
  103|  1.13k|		if (ht->compare_func(e->key, key)) {
  ------------------
  |  Branch (103:7): [True: 548, False: 587]
  ------------------
  104|    548|			return e->value;
  105|    548|		}
  106|    587|		e = (hashentry_t*)e->next;
  107|    587|	}
  108|    426|	return NULL;
  109|    974|}

plist_json_init:
   52|      2|{
   53|       |    /* init JSON stuff */
   54|      2|#ifdef DEBUG
   55|      2|    char *env_debug = getenv("PLIST_JSON_DEBUG");
   56|      2|    if (env_debug && !strcmp(env_debug, "1")) {
  ------------------
  |  Branch (56:9): [True: 0, False: 2]
  |  Branch (56:22): [True: 0, False: 0]
  ------------------
   57|      0|        plist_json_debug = 1;
   58|      0|    }
   59|      2|#endif
   60|      2|}
plist_from_json:
  786|  2.13k|{
  787|  2.13k|    if (!plist) {
  ------------------
  |  Branch (787:9): [True: 0, False: 2.13k]
  ------------------
  788|      0|        return PLIST_ERR_INVALID_ARG;
  789|      0|    }
  790|  2.13k|    *plist = NULL;
  791|  2.13k|    if (!json || (length == 0)) {
  ------------------
  |  Branch (791:9): [True: 0, False: 2.13k]
  |  Branch (791:18): [True: 0, False: 2.13k]
  ------------------
  792|      0|        return PLIST_ERR_INVALID_ARG;
  793|      0|    }
  794|       |
  795|  2.13k|    jsmn_parser parser;
  796|  2.13k|    jsmn_init(&parser);
  797|  2.13k|    int maxtoks = 256;
  798|  2.13k|    int curtoks = 0;
  799|  2.13k|    int r = 0;
  800|  2.13k|    jsmntok_t *tokens = NULL;
  801|       |
  802|  12.8k|    do {
  803|  12.8k|        jsmntok_t* newtokens = (jsmntok_t*)realloc(tokens, sizeof(jsmntok_t)*maxtoks);
  804|  12.8k|        if (!newtokens) {
  ------------------
  |  Branch (804:13): [True: 0, False: 12.8k]
  ------------------
  805|      0|            PLIST_JSON_ERR("%s: Out of memory\n", __func__);
  ------------------
  |  |   44|      0|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  806|      0|            return PLIST_ERR_NO_MEM;
  807|      0|        }
  808|  12.8k|        memset((unsigned char*)newtokens + sizeof(jsmntok_t)*curtoks, '\0', sizeof(jsmntok_t)*(maxtoks-curtoks));
  809|  12.8k|        tokens = newtokens;
  810|  12.8k|        curtoks = maxtoks;
  811|       |
  812|  12.8k|        r = jsmn_parse(&parser, json, length, tokens, maxtoks);
  813|  12.8k|        if (r == JSMN_ERROR_NOMEM) {
  ------------------
  |  Branch (813:13): [True: 10.7k, False: 2.13k]
  ------------------
  814|  10.7k|            maxtoks+=16;
  815|  10.7k|            continue;
  816|  10.7k|        }
  817|  12.8k|    } while (r == JSMN_ERROR_NOMEM);
  ------------------
  |  Branch (817:14): [True: 10.7k, False: 2.13k]
  ------------------
  818|       |
  819|  2.13k|    switch(r) {
  820|      0|        case JSMN_ERROR_NOMEM:
  ------------------
  |  Branch (820:9): [True: 0, False: 2.13k]
  ------------------
  821|      0|            PLIST_JSON_ERR("%s: Out of memory...\n", __func__);
  ------------------
  |  |   44|      0|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  822|      0|            free(tokens);
  823|      0|            return PLIST_ERR_NO_MEM;
  824|     71|        case JSMN_ERROR_INVAL:
  ------------------
  |  Branch (824:9): [True: 71, False: 2.06k]
  ------------------
  825|     71|            PLIST_JSON_ERR("%s: Invalid character inside JSON string\n", __func__);
  ------------------
  |  |   44|     71|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 71]
  |  |  ------------------
  ------------------
  826|     71|            free(tokens);
  827|     71|            return PLIST_ERR_PARSE;
  828|    285|        case JSMN_ERROR_PART:
  ------------------
  |  Branch (828:9): [True: 285, False: 1.84k]
  ------------------
  829|    285|            PLIST_JSON_ERR("%s: Incomplete JSON, more bytes expected\n", __func__);
  ------------------
  |  |   44|    285|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 285]
  |  |  ------------------
  ------------------
  830|    285|            free(tokens);
  831|    285|            return PLIST_ERR_PARSE;
  832|  1.77k|        default:
  ------------------
  |  Branch (832:9): [True: 1.77k, False: 356]
  ------------------
  833|  1.77k|            break;
  834|  2.13k|    }
  835|       |
  836|  1.77k|    int startindex = 0;
  837|  1.77k|    jsmntok_info_t ti = { tokens, parser.toknext };
  838|  1.77k|    switch (tokens[startindex].type) {
  839|    699|        case JSMN_PRIMITIVE:
  ------------------
  |  Branch (839:9): [True: 699, False: 1.07k]
  ------------------
  840|    699|            *plist = parse_primitive(json, &ti, &startindex);
  841|    699|            break;
  842|    187|        case JSMN_STRING:
  ------------------
  |  Branch (842:9): [True: 187, False: 1.59k]
  ------------------
  843|    187|            *plist = parse_string(json, &ti, &startindex);
  844|    187|            break;
  845|    348|        case JSMN_ARRAY:
  ------------------
  |  Branch (845:9): [True: 348, False: 1.43k]
  ------------------
  846|    348|            *plist = parse_array(json, &ti, &startindex);
  847|    348|            break;
  848|    544|        case JSMN_OBJECT:
  ------------------
  |  Branch (848:9): [True: 544, False: 1.23k]
  ------------------
  849|    544|            *plist = parse_object(json, &ti, &startindex);
  850|    544|            break;
  851|      0|        default:
  ------------------
  |  Branch (851:9): [True: 0, False: 1.77k]
  ------------------
  852|      0|            break;
  853|  1.77k|    }
  854|  1.77k|    free(tokens);
  855|  1.77k|    return PLIST_ERR_SUCCESS;
  856|  1.77k|}
jplist.c:parse_primitive:
  497|  21.0k|{
  498|  21.0k|    if (ti->tokens[*index].type != JSMN_PRIMITIVE) {
  ------------------
  |  Branch (498:9): [True: 0, False: 21.0k]
  ------------------
  499|      0|        PLIST_JSON_ERR("%s: token type != JSMN_PRIMITIVE\n", __func__);
  ------------------
  |  |   44|      0|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  500|      0|        return NULL;
  501|      0|    }
  502|  21.0k|    plist_t val = NULL;
  503|  21.0k|    const char* str_val = js + ti->tokens[*index].start;
  504|  21.0k|    const char* str_end = js + ti->tokens[*index].end;
  505|  21.0k|    size_t str_len = ti->tokens[*index].end - ti->tokens[*index].start;
  506|  21.0k|    if (!strncmp("false", str_val, str_len)) {
  ------------------
  |  Branch (506:9): [True: 7.45k, False: 13.6k]
  ------------------
  507|  7.45k|        val = plist_new_bool(0);
  508|  13.6k|    } else if (!strncmp("true", str_val, str_len)) {
  ------------------
  |  Branch (508:16): [True: 2.44k, False: 11.1k]
  ------------------
  509|  2.44k|        val = plist_new_bool(1);
  510|  11.1k|    } else if (!strncmp("null", str_val, str_len)) {
  ------------------
  |  Branch (510:16): [True: 6.41k, False: 4.76k]
  ------------------
  511|  6.41k|        plist_data_t data = plist_new_plist_data();
  512|  6.41k|        data->type = PLIST_NULL;
  513|  6.41k|        val = plist_new_node(data);
  514|  6.41k|    } else if (isdigit(str_val[0]) || (str_val[0] == '-' && str_val+1 < str_end && isdigit(str_val[1]))) {
  ------------------
  |  Branch (514:40): [True: 728, False: 136]
  |  Branch (514:61): [True: 722, False: 6]
  ------------------
  515|  4.62k|        char* endp = (char*)str_val;
  516|  4.62k|        int is_neg = (str_val[0] == '-');
  517|  4.62k|        int64_t intpart = parse_decimal(str_val, str_end, &endp);
  518|  4.62k|        if (endp >= str_end) {
  ------------------
  |  Branch (518:13): [True: 2.74k, False: 1.87k]
  ------------------
  519|       |            /* integer */
  520|  2.74k|            if (is_neg || intpart <= INT64_MAX) {
  ------------------
  |  Branch (520:17): [True: 481, False: 2.26k]
  |  Branch (520:27): [True: 2.26k, False: 0]
  ------------------
  521|  2.74k|                val = plist_new_int(intpart);
  522|  2.74k|            } else {
  523|      0|                val = plist_new_uint((uint64_t)intpart);
  524|      0|            }
  525|  2.74k|        } else if ((*endp == '.' && endp+1 < str_end && isdigit(*(endp+1))) || ((*endp == 'e' || *endp == 'E') && endp+1 < str_end && (isdigit(*(endp+1)) || ((*(endp+1) == '-') && endp+2 < str_end && isdigit(*(endp+2)))))) {
  ------------------
  |  Branch (525:21): [True: 466, False: 1.40k]
  |  Branch (525:37): [True: 465, False: 1]
  |  Branch (525:82): [True: 1.02k, False: 385]
  |  Branch (525:98): [True: 363, False: 22]
  |  Branch (525:115): [True: 1.37k, False: 15]
  |  Branch (525:159): [True: 708, False: 9]
  |  Branch (525:181): [True: 707, False: 1]
  ------------------
  526|       |            /* floating point */
  527|  1.82k|            double dval = (double)intpart;
  528|  1.82k|            char* fendp = endp;
  529|  1.82k|            int err = 0;
  530|  1.82k|            do {
  531|  1.82k|                if (*endp == '.') {
  ------------------
  |  Branch (531:21): [True: 464, False: 1.36k]
  ------------------
  532|    464|                    fendp++;
  533|    464|                    double frac = 0;
  534|    464|                    double p = 0.1;
  535|  1.22k|                    while (fendp < str_end && isdigit(*fendp)) {
  ------------------
  |  Branch (535:28): [True: 788, False: 441]
  ------------------
  536|    765|                        frac = frac + (*fendp - '0') * p;
  537|    765|                        p *= 0.1;
  538|    765|                        fendp++;
  539|    765|                    }
  540|    464|                    if (is_neg) {
  ------------------
  |  Branch (540:25): [True: 240, False: 224]
  ------------------
  541|    240|                        dval -= frac;
  542|    240|                    } else {
  543|    224|                        dval += frac;
  544|    224|                    }
  545|    464|                }
  546|  1.82k|                if (fendp >= str_end) {
  ------------------
  |  Branch (546:21): [True: 441, False: 1.38k]
  ------------------
  547|    441|                    break;
  548|    441|                }
  549|  1.38k|                if (fendp+1 < str_end && (*fendp == 'e' || *fendp == 'E') && (isdigit(*(fendp+1)) || ((*(fendp+1) == '-') && fendp+2 < str_end && isdigit(*(fendp+2))))) {
  ------------------
  |  Branch (549:21): [True: 1.38k, False: 1]
  |  Branch (549:43): [True: 1.01k, False: 366]
  |  Branch (549:60): [True: 354, False: 12]
  |  Branch (549:103): [True: 708, False: 8]
  |  Branch (549:126): [True: 707, False: 1]
  ------------------
  550|  1.36k|                    int64_t exp = parse_decimal(fendp+1, str_end, &fendp);
  551|  1.36k|                    dval = dval * pow(10, (double)exp);
  552|  1.36k|                } else {
  553|     23|                    PLIST_JSON_ERR("%s: invalid character at offset %d when parsing floating point value\n", __func__, (int)(fendp - js));
  ------------------
  |  |   44|     23|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 23]
  |  |  ------------------
  ------------------
  554|     23|                    err++;
  555|     23|                }
  556|  1.38k|            } while (0);
  ------------------
  |  Branch (556:22): [Folded - Ignored]
  ------------------
  557|  1.82k|            if (!err) {
  ------------------
  |  Branch (557:17): [True: 1.80k, False: 23]
  ------------------
  558|  1.80k|                if (isinf(dval) || isnan(dval)) {
  559|    162|                   PLIST_JSON_ERR("%s: unrepresentable floating point value at offset %d when parsing numerical value\n", __func__, (int)(str_val - js));
  ------------------
  |  |   44|    162|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 162]
  |  |  ------------------
  ------------------
  560|  1.64k|                } else {
  561|  1.64k|                    val = plist_new_real(dval);
  562|  1.64k|                }
  563|  1.80k|            }
  564|  1.82k|        } else {
  565|     48|            PLIST_JSON_ERR("%s: invalid character at offset %d when parsing numerical value\n", __func__, (int)(endp - js));
  ------------------
  |  |   44|     48|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 48]
  |  |  ------------------
  ------------------
  566|     48|        }
  567|  4.62k|    } else {
  568|    143|        PLIST_JSON_ERR("%s: invalid primitive value '%.*s' encountered\n", __func__, (int)str_len, str_val);
  ------------------
  |  |   44|    143|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 143]
  |  |  ------------------
  ------------------
  569|    143|    }
  570|      0|    (*index)++;
  571|  21.0k|    return val;
  572|  21.0k|}
jplist.c:parse_decimal:
  454|  5.98k|{
  455|  5.98k|    uint64_t MAX = INT64_MAX;
  456|  5.98k|    uint64_t x = 0;
  457|  5.98k|    int is_neg = 0;
  458|  5.98k|    *endp = (char*)str;
  459|       |
  460|  5.98k|    if (str[0] == '-') {
  ------------------
  |  Branch (460:9): [True: 1.42k, False: 4.55k]
  ------------------
  461|  1.42k|        is_neg = 1;
  462|  1.42k|        (*endp)++;
  463|  1.42k|    }
  464|  5.98k|    if (is_neg) {
  ------------------
  |  Branch (464:9): [True: 1.42k, False: 4.55k]
  ------------------
  465|  1.42k|        MAX++;
  466|  1.42k|    }
  467|  35.1k|    while (*endp < str_end && isdigit(**endp)) {
  ------------------
  |  Branch (467:12): [True: 32.1k, False: 3.03k]
  ------------------
  468|  30.2k|        if (x > PO10i_LIMIT) {
  ------------------
  |  |  276|  30.2k|#define PO10i_LIMIT (INT64_MAX/10)
  ------------------
  |  Branch (468:13): [True: 667, False: 29.6k]
  ------------------
  469|    667|            x = MAX;
  470|    667|            break;
  471|    667|        }
  472|  29.6k|        x = x * 10;
  473|  29.6k|        unsigned int add = (**endp - '0');
  474|  29.6k|        if (x + add > MAX) {
  ------------------
  |  Branch (474:13): [True: 398, False: 29.2k]
  ------------------
  475|    398|            x = MAX;
  476|    398|            break;
  477|    398|        }
  478|  29.2k|        x += add;
  479|  29.2k|        (*endp)++;
  480|  29.2k|    }
  481|       |
  482|       |    // swallow the rest of the digits in case we dropped out early
  483|  7.59k|    while (*endp < str_end && isdigit(**endp)) (*endp)++;
  ------------------
  |  Branch (483:12): [True: 3.49k, False: 4.09k]
  ------------------
  484|       |
  485|  5.98k|    int64_t result = x;
  486|  5.98k|    if (is_neg) {
  ------------------
  |  Branch (486:9): [True: 1.42k, False: 4.55k]
  ------------------
  487|  1.42k|        if (x == MAX) {
  ------------------
  |  Branch (487:13): [True: 640, False: 787]
  ------------------
  488|    640|            result = INT64_MIN;
  489|    787|        } else {
  490|    787|            result = -(int64_t)x;
  491|    787|        }
  492|  1.42k|    }
  493|  5.98k|    return result;
  494|  5.98k|}
jplist.c:parse_string:
  653|  33.8k|{
  654|  33.8k|    if (ti->tokens[*index].type != JSMN_STRING) {
  ------------------
  |  Branch (654:9): [True: 0, False: 33.8k]
  ------------------
  655|      0|        PLIST_JSON_ERR("%s: token type != JSMN_STRING\n", __func__);
  ------------------
  |  |   44|      0|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  656|      0|        return NULL;
  657|      0|    }
  658|       |
  659|  33.8k|    size_t str_len = 0; ;
  660|  33.8k|    char* strval = unescape_string(js + ti->tokens[*index].start, ti->tokens[*index].end - ti->tokens[*index].start, &str_len);
  661|  33.8k|    if (!strval) {
  ------------------
  |  Branch (661:9): [True: 18, False: 33.8k]
  ------------------
  662|     18|        return NULL;
  663|     18|    }
  664|  33.8k|    plist_t node;
  665|       |
  666|  33.8k|    plist_data_t data = plist_new_plist_data();
  667|  33.8k|    data->type = PLIST_STRING;
  668|  33.8k|    data->strval = strval;
  669|  33.8k|    data->length = str_len;
  670|  33.8k|    node = plist_new_node(data);
  671|       |
  672|  33.8k|    (*index)++;
  673|  33.8k|    return node;
  674|  33.8k|}
jplist.c:unescape_string:
  575|   101k|{
  576|   101k|    char* strval = strndup(str_val, str_len);
  577|   101k|    size_t i = 0;
  578|   230k|    while (i < str_len) {
  ------------------
  |  Branch (578:12): [True: 128k, False: 101k]
  ------------------
  579|   128k|        if (strval[i] == '\\' && i < str_len-1) {
  ------------------
  |  Branch (579:13): [True: 2.91k, False: 125k]
  |  Branch (579:34): [True: 2.91k, False: 0]
  ------------------
  580|  2.91k|            switch (strval[i+1]) {
  581|  1.11k|                case '\"': case '/' : case '\\' : case 'b' :
  ------------------
  |  Branch (581:17): [True: 199, False: 2.71k]
  |  Branch (581:28): [True: 306, False: 2.61k]
  |  Branch (581:39): [True: 206, False: 2.71k]
  |  Branch (581:51): [True: 401, False: 2.51k]
  ------------------
  582|  2.11k|                case 'f' : case 'r' : case 'n'  : case 't' :
  ------------------
  |  Branch (582:17): [True: 235, False: 2.68k]
  |  Branch (582:28): [True: 293, False: 2.62k]
  |  Branch (582:39): [True: 231, False: 2.68k]
  |  Branch (582:51): [True: 240, False: 2.67k]
  ------------------
  583|  2.11k|                    memmove(strval+i, strval+i+1, str_len - (i+1));
  584|  2.11k|                    str_len--;
  585|  2.11k|                    switch (strval[i]) {
  586|    401|                        case 'b':
  ------------------
  |  Branch (586:25): [True: 401, False: 1.71k]
  ------------------
  587|    401|                            strval[i] = '\b';
  588|    401|                            break;
  589|    235|                        case 'f':
  ------------------
  |  Branch (589:25): [True: 235, False: 1.87k]
  ------------------
  590|    235|                            strval[i] = '\f';
  591|    235|                            break;
  592|    293|                        case 'r':
  ------------------
  |  Branch (592:25): [True: 293, False: 1.81k]
  ------------------
  593|    293|                            strval[i] = '\r';
  594|    293|                            break;
  595|    231|                        case 'n':
  ------------------
  |  Branch (595:25): [True: 231, False: 1.88k]
  ------------------
  596|    231|                            strval[i] = '\n';
  597|    231|                            break;
  598|    240|                        case 't':
  ------------------
  |  Branch (598:25): [True: 240, False: 1.87k]
  ------------------
  599|    240|                            strval[i] = '\t';
  600|    240|                            break;
  601|    711|                        default:
  ------------------
  |  Branch (601:25): [True: 711, False: 1.40k]
  ------------------
  602|    711|                            break;
  603|  2.11k|                    }
  604|  2.11k|                    break;
  605|  2.11k|                case 'u': {
  ------------------
  |  Branch (605:17): [True: 805, False: 2.11k]
  ------------------
  606|    805|                    unsigned int val = 0;
  607|    805|                    if (str_len-(i+2) < 4) {
  ------------------
  |  Branch (607:25): [True: 4, False: 801]
  ------------------
  608|      4|                        PLIST_JSON_ERR("%s: invalid escape sequence '%s' (too short)\n", __func__, strval+i);
  ------------------
  |  |   44|      4|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 4]
  |  |  ------------------
  ------------------
  609|      4|                        free(strval);
  610|      4|                        return NULL;
  611|      4|                    }
  612|    801|                    if (!(isxdigit(strval[i+2]) && isxdigit(strval[i+3]) && isxdigit(strval[i+4]) && isxdigit(strval[i+5])) || sscanf(strval+i+2, "%04x", &val) != 1) {
  ------------------
  |  Branch (612:128): [True: 0, False: 786]
  ------------------
  613|     15|                        PLIST_JSON_ERR("%s: invalid escape sequence '%.*s'\n", __func__, 6, strval+i);
  ------------------
  |  |   44|     15|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 15]
  |  |  ------------------
  ------------------
  614|     15|                        free(strval);
  615|     15|                        return NULL;
  616|     15|                    }
  617|    786|                    int bytelen = 0;
  618|    786|                    if (val >= 0x800) {
  ------------------
  |  Branch (618:25): [True: 270, False: 516]
  ------------------
  619|       |                        /* three bytes */
  620|    270|                        strval[i]   = (char)(0xE0 + ((val >> 12) & 0xF));
  621|    270|                        strval[i+1] = (char)(0x80 + ((val >> 6) & 0x3F));
  622|    270|                        strval[i+2] = (char)(0x80 + (val & 0x3F));
  623|    270|                        bytelen = 3;
  624|    516|                    } else if (val >= 0x80) {
  ------------------
  |  Branch (624:32): [True: 269, False: 247]
  ------------------
  625|       |                        /* two bytes */
  626|    269|                        strval[i]   = (char)(0xC0 + ((val >> 6) & 0x1F));
  627|    269|                        strval[i+1] = (char)(0x80 + (val & 0x3F));
  628|    269|                        bytelen = 2;
  629|    269|                    } else {
  630|       |                        /* one byte */
  631|    247|                        strval[i] = (char)(val & 0x7F);
  632|    247|                        bytelen = 1;
  633|    247|                    }
  634|    786|                    memmove(strval+i+bytelen, strval+i+6, str_len - (i+5));
  635|    786|                    str_len -= (6-bytelen);
  636|    786|                }   break;
  637|      0|                default:
  ------------------
  |  Branch (637:17): [True: 0, False: 2.91k]
  ------------------
  638|      0|                    PLIST_JSON_ERR("%s: invalid escape sequence '%.*s'\n", __func__, 2, strval+i);
  ------------------
  |  |   44|      0|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  639|      0|                    free(strval);
  640|      0|                    return NULL;
  641|  2.91k|            }
  642|  2.91k|        }
  643|   128k|        i++;
  644|   128k|    }
  645|   101k|    strval[str_len] = '\0';
  646|   101k|    if (new_len) {
  ------------------
  |  Branch (646:9): [True: 33.8k, False: 67.4k]
  ------------------
  647|  33.8k|        *new_len = str_len;
  648|  33.8k|    }
  649|   101k|    return strval;
  650|   101k|}
jplist.c:parse_array:
  679|  58.2k|{
  680|  58.2k|    if (ti->tokens[*index].type != JSMN_ARRAY) {
  ------------------
  |  Branch (680:9): [True: 0, False: 58.2k]
  ------------------
  681|      0|        PLIST_JSON_ERR("%s: token type != JSMN_ARRAY\n", __func__);
  ------------------
  |  |   44|      0|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  682|      0|        return NULL;
  683|      0|    }
  684|  58.2k|    plist_t arr = plist_new_array();
  685|  58.2k|    int num_tokens = ti->tokens[*index].size;
  686|  58.2k|    int num;
  687|  58.2k|    int j = (*index)+1;
  688|   110k|    for (num = 0; num < num_tokens; num++) {
  ------------------
  |  Branch (688:19): [True: 56.1k, False: 54.7k]
  ------------------
  689|  56.1k|        if (j >= ti->count) {
  ------------------
  |  Branch (689:13): [True: 0, False: 56.1k]
  ------------------
  690|      0|            PLIST_JSON_ERR("%s: token index out of valid range\n", __func__);
  ------------------
  |  |   44|      0|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  691|      0|            plist_free(arr);
  692|      0|            return NULL;
  693|      0|        }
  694|  56.1k|        plist_t val = NULL;
  695|  56.1k|        switch (ti->tokens[j].type) {
  696|    482|            case JSMN_OBJECT:
  ------------------
  |  Branch (696:13): [True: 482, False: 55.6k]
  ------------------
  697|    482|                val = parse_object(js, ti, &j);
  698|    482|                break;
  699|  36.7k|            case JSMN_ARRAY:
  ------------------
  |  Branch (699:13): [True: 36.7k, False: 19.3k]
  ------------------
  700|  36.7k|                val = parse_array(js, ti, &j);
  701|  36.7k|                break;
  702|    211|            case JSMN_STRING:
  ------------------
  |  Branch (702:13): [True: 211, False: 55.9k]
  ------------------
  703|    211|                val = parse_string(js, ti, &j);
  704|    211|                break;
  705|  18.6k|            case JSMN_PRIMITIVE:
  ------------------
  |  Branch (705:13): [True: 18.6k, False: 37.4k]
  ------------------
  706|  18.6k|                val = parse_primitive(js, ti, &j);
  707|  18.6k|                break;
  708|      0|            default:
  ------------------
  |  Branch (708:13): [True: 0, False: 56.1k]
  ------------------
  709|      0|                break;
  710|  56.1k|        }
  711|  56.1k|        if (val) {
  ------------------
  |  Branch (711:13): [True: 52.6k, False: 3.51k]
  ------------------
  712|  52.6k|            plist_array_append_item(arr, val);
  713|  52.6k|        } else {
  714|  3.51k|            plist_free(arr);
  715|  3.51k|            return NULL;
  716|  3.51k|        }
  717|  56.1k|    }
  718|  54.7k|    *(index) = j;
  719|  54.7k|    return arr;
  720|  58.2k|}
jplist.c:parse_object:
  723|  12.1k|{
  724|  12.1k|    if (ti->tokens[*index].type != JSMN_OBJECT) {
  ------------------
  |  Branch (724:9): [True: 0, False: 12.1k]
  ------------------
  725|      0|        PLIST_JSON_ERR("%s: token type != JSMN_OBJECT\n", __func__);
  ------------------
  |  |   44|      0|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  726|      0|        return NULL;
  727|      0|    }
  728|  12.1k|    int num_tokens = ti->tokens[*index].size;
  729|  12.1k|    int num;
  730|  12.1k|    int j = (*index)+1;
  731|  12.1k|    if (num_tokens % 2 != 0) {
  ------------------
  |  Branch (731:9): [True: 10, False: 12.1k]
  ------------------
  732|     10|        PLIST_JSON_ERR("%s: number of children must be even\n", __func__);
  ------------------
  |  |   44|     10|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 10]
  |  |  ------------------
  ------------------
  733|     10|        return NULL;
  734|     10|    }
  735|  12.1k|    plist_t obj = plist_new_dict();
  736|  79.4k|    for (num = 0; num < num_tokens; num++) {
  ------------------
  |  Branch (736:19): [True: 67.4k, False: 11.9k]
  ------------------
  737|  67.4k|        if (j+1 >= ti->count) {
  ------------------
  |  Branch (737:13): [True: 0, False: 67.4k]
  ------------------
  738|      0|            PLIST_JSON_ERR("%s: token index out of valid range\n", __func__);
  ------------------
  |  |   44|      0|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  739|      0|            plist_free(obj);
  740|      0|            return NULL;
  741|      0|        }
  742|  67.4k|        if (ti->tokens[j].type == JSMN_STRING) {
  ------------------
  |  Branch (742:13): [True: 67.4k, False: 4]
  ------------------
  743|  67.4k|            char* key = unescape_string(js + ti->tokens[j].start, ti->tokens[j].end - ti->tokens[j].start, NULL);
  744|  67.4k|            if (!key) {
  ------------------
  |  Branch (744:17): [True: 1, False: 67.4k]
  ------------------
  745|      1|                plist_free(obj);
  746|      1|                return NULL;
  747|      1|            }
  748|  67.4k|            plist_t val = NULL;
  749|  67.4k|            j++;
  750|  67.4k|            num++;
  751|  67.4k|            switch (ti->tokens[j].type) {
  752|  11.1k|                case JSMN_OBJECT:
  ------------------
  |  Branch (752:17): [True: 11.1k, False: 56.2k]
  ------------------
  753|  11.1k|                    val = parse_object(js, ti, &j);
  754|  11.1k|                    break;
  755|  21.0k|                case JSMN_ARRAY:
  ------------------
  |  Branch (755:17): [True: 21.0k, False: 46.3k]
  ------------------
  756|  21.0k|                    val = parse_array(js, ti, &j);
  757|  21.0k|                    break;
  758|  33.4k|                case JSMN_STRING:
  ------------------
  |  Branch (758:17): [True: 33.4k, False: 33.9k]
  ------------------
  759|  33.4k|                    val = parse_string(js, ti, &j);
  760|  33.4k|                    break;
  761|  1.70k|                case JSMN_PRIMITIVE:
  ------------------
  |  Branch (761:17): [True: 1.70k, False: 65.7k]
  ------------------
  762|  1.70k|                    val = parse_primitive(js, ti, &j);
  763|  1.70k|                    break;
  764|      0|                default:
  ------------------
  |  Branch (764:17): [True: 0, False: 67.4k]
  ------------------
  765|      0|                    break;
  766|  67.4k|            }
  767|  67.4k|            if (val) {
  ------------------
  |  Branch (767:17): [True: 67.2k, False: 201]
  ------------------
  768|  67.2k|                plist_dict_set_item(obj, key, val);
  769|  67.2k|            } else {
  770|    201|                free(key);
  771|    201|                plist_free(obj);
  772|    201|                return NULL;
  773|    201|            }
  774|  67.2k|            free(key);
  775|  67.2k|        } else {
  776|      4|            PLIST_JSON_ERR("%s: keys must be of type STRING\n", __func__);
  ------------------
  |  |   44|      4|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 4]
  |  |  ------------------
  ------------------
  777|      4|            plist_free(obj);
  778|      4|            return NULL;
  779|      4|        }
  780|  67.4k|    }
  781|  11.9k|    (*index) = j;
  782|  11.9k|    return obj;
  783|  12.1k|}

jsmn_parse:
  166|  12.8k|		unsigned int num_tokens) {
  167|  12.8k|	jsmnerr_t r;
  168|  12.8k|	int i;
  169|  12.8k|	jsmntok_t *token;
  170|       |
  171|  12.8k|	parser->end = length;
  172|       |
  173|   406k|	for (; (parser->end > 0 && parser->pos < parser->end) && js[parser->pos] != '\0'; parser->pos++) {
  ------------------
  |  Branch (173:10): [True: 406k, False: 0]
  |  Branch (173:29): [True: 404k, False: 1.94k]
  |  Branch (173:59): [True: 404k, False: 4]
  ------------------
  174|   404k|		char c;
  175|   404k|		jsmntype_t type;
  176|       |
  177|   404k|		c = js[parser->pos];
  178|   404k|		switch (c) {
  179|   166k|			case '{': case '[':
  ------------------
  |  Branch (179:4): [True: 45.2k, False: 359k]
  |  Branch (179:14): [True: 121k, False: 283k]
  ------------------
  180|   166k|				token = jsmn_alloc_token(parser, tokens, num_tokens);
  181|   166k|				if (token == NULL)
  ------------------
  |  Branch (181:9): [True: 7.02k, False: 159k]
  ------------------
  182|  7.02k|					return JSMN_ERROR_NOMEM;
  183|   159k|				if (parser->toksuper != -1) {
  ------------------
  |  Branch (183:9): [True: 153k, False: 6.01k]
  ------------------
  184|   153k|					tokens[parser->toksuper].size++;
  185|       |#ifdef JSMN_PARENT_LINKS
  186|       |					token->parent = parser->toksuper;
  187|       |#endif
  188|   153k|				}
  189|   159k|				token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
  ------------------
  |  Branch (189:20): [True: 42.7k, False: 116k]
  ------------------
  190|   159k|				token->start = parser->pos;
  191|   159k|				parser->toksuper = parser->toknext - 1;
  192|   159k|				break;
  193|  79.1k|			case '}': case ']':
  ------------------
  |  Branch (193:4): [True: 17.3k, False: 387k]
  |  Branch (193:14): [True: 61.8k, False: 342k]
  ------------------
  194|  79.1k|				type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
  ------------------
  |  Branch (194:13): [True: 17.3k, False: 61.8k]
  ------------------
  195|       |#ifdef JSMN_PARENT_LINKS
  196|       |				if (parser->toknext < 1) {
  197|       |					return JSMN_ERROR_INVAL;
  198|       |				}
  199|       |				token = &tokens[parser->toknext - 1];
  200|       |				for (;;) {
  201|       |					if (token->start != -1 && token->end == -1) {
  202|       |						if (token->type != type) {
  203|       |							return JSMN_ERROR_INVAL;
  204|       |						}
  205|       |						token->end = parser->pos + 1;
  206|       |						parser->toksuper = token->parent;
  207|       |						break;
  208|       |					}
  209|       |					if (token->parent == -1) {
  210|       |						break;
  211|       |					}
  212|       |					token = &tokens[token->parent];
  213|       |				}
  214|       |#else
  215|  16.2M|				for (i = parser->toknext - 1; i >= 0; i--) {
  ------------------
  |  Branch (215:35): [True: 16.2M, False: 39]
  ------------------
  216|  16.2M|					token = &tokens[i];
  217|  16.2M|					if (token->start != -1 && token->end == -1) {
  ------------------
  |  Branch (217:10): [True: 16.2M, False: 0]
  |  Branch (217:32): [True: 79.1k, False: 16.2M]
  ------------------
  218|  79.1k|						if (token->type != type) {
  ------------------
  |  Branch (218:11): [True: 10, False: 79.1k]
  ------------------
  219|     10|							return JSMN_ERROR_INVAL;
  220|     10|						}
  221|  79.1k|						parser->toksuper = -1;
  222|  79.1k|						token->end = parser->pos + 1;
  223|  79.1k|						break;
  224|  79.1k|					}
  225|  16.2M|				}
  226|       |				/* Error if unmatched closing bracket */
  227|  79.1k|				if (i == -1) return JSMN_ERROR_INVAL;
  ------------------
  |  Branch (227:9): [True: 39, False: 79.1k]
  ------------------
  228|  27.1M|				for (; i >= 0; i--) {
  ------------------
  |  Branch (228:12): [True: 27.1M, False: 5.81k]
  ------------------
  229|  27.1M|					token = &tokens[i];
  230|  27.1M|					if (token->start != -1 && token->end == -1) {
  ------------------
  |  Branch (230:10): [True: 27.1M, False: 0]
  |  Branch (230:32): [True: 73.3k, False: 27.0M]
  ------------------
  231|  73.3k|						parser->toksuper = i;
  232|  73.3k|						break;
  233|  73.3k|					}
  234|  27.1M|				}
  235|  79.1k|#endif
  236|  79.1k|				break;
  237|   112k|			case '\"':
  ------------------
  |  Branch (237:4): [True: 112k, False: 291k]
  ------------------
  238|   112k|				r = jsmn_parse_string(parser, js, tokens, num_tokens);
  239|   112k|				if (r < 0) return r;
  ------------------
  |  Branch (239:9): [True: 2.83k, False: 110k]
  ------------------
  240|   110k|				if (parser->toksuper != -1)
  ------------------
  |  Branch (240:9): [True: 109k, False: 559]
  ------------------
  241|   109k|					tokens[parser->toksuper].size++;
  242|   110k|				break;
  243|  19.8k|			case '\t' : case '\r' : case '\n' : case ':' : case ',': case ' ':
  ------------------
  |  Branch (243:4): [True: 439, False: 404k]
  |  Branch (243:16): [True: 1.14k, False: 403k]
  |  Branch (243:28): [True: 6.92k, False: 397k]
  |  Branch (243:40): [True: 8.88k, False: 395k]
  |  Branch (243:51): [True: 2.04k, False: 402k]
  |  Branch (243:61): [True: 441, False: 404k]
  ------------------
  244|  19.8k|				break;
  245|       |#ifdef JSMN_STRICT
  246|       |			/* In strict mode primitives are: numbers and booleans */
  247|       |			case '-': case '0': case '1' : case '2': case '3' : case '4':
  248|       |			case '5': case '6': case '7' : case '8': case '9':
  249|       |			case 't': case 'f': case 'n' :
  250|       |#else
  251|       |			/* In non-strict mode every unquoted value is a primitive */
  252|  26.2k|			default:
  ------------------
  |  Branch (252:4): [True: 26.2k, False: 378k]
  ------------------
  253|  26.2k|#endif
  254|  26.2k|				r = jsmn_parse_primitive(parser, js, tokens, num_tokens);
  255|  26.2k|				if (r < 0) return r;
  ------------------
  |  Branch (255:9): [True: 1.01k, False: 25.2k]
  ------------------
  256|  25.2k|				if (parser->toksuper != -1)
  ------------------
  |  Branch (256:9): [True: 23.2k, False: 1.99k]
  ------------------
  257|  23.2k|					tokens[parser->toksuper].size++;
  258|  25.2k|				break;
  259|       |
  260|       |#ifdef JSMN_STRICT
  261|       |			/* Unexpected char in strict mode */
  262|       |			default:
  263|       |				return JSMN_ERROR_INVAL;
  264|       |#endif
  265|       |
  266|   404k|		}
  267|   404k|	}
  268|       |
  269|   209k|	for (i = parser->toknext - 1; i >= 0; i--) {
  ------------------
  |  Branch (269:32): [True: 208k, False: 1.77k]
  ------------------
  270|       |		/* Unmatched opened object or array */
  271|   208k|		if (tokens[i].start != -1 && tokens[i].end == -1) {
  ------------------
  |  Branch (271:7): [True: 208k, False: 0]
  |  Branch (271:32): [True: 169, False: 207k]
  ------------------
  272|    169|			return JSMN_ERROR_PART;
  273|    169|		}
  274|   208k|	}
  275|       |
  276|  1.77k|	return JSMN_SUCCESS;
  277|  1.94k|}
jsmn_init:
  283|  2.13k|void jsmn_init(jsmn_parser *parser) {
  284|  2.13k|	parser->pos = 0;
  285|  2.13k|	parser->end = 0;
  286|  2.13k|	parser->toknext = 0;
  287|  2.13k|	parser->toksuper = -1;
  288|  2.13k|}
jsmn.c:jsmn_alloc_token:
   34|   305k|		jsmntok_t *tokens, int num_tokens) {
   35|   305k|	jsmntok_t *tok;
   36|   305k|	if (parser->toknext >= num_tokens) {
  ------------------
  |  Branch (36:6): [True: 10.7k, False: 294k]
  ------------------
   37|  10.7k|		return NULL;
   38|  10.7k|	}
   39|   294k|	tok = &tokens[parser->toknext++];
   40|   294k|	tok->start = tok->end = -1;
   41|   294k|	tok->size = 0;
   42|       |#ifdef JSMN_PARENT_LINKS
   43|       |	tok->parent = -1;
   44|       |#endif
   45|   294k|	return tok;
   46|   305k|}
jsmn.c:jsmn_parse_string:
  110|   112k|		jsmntok_t *tokens, int num_tokens) {
  111|   112k|	jsmntok_t *token;
  112|       |
  113|   112k|	int start = parser->pos;
  114|       |
  115|   112k|	parser->pos++;
  116|       |
  117|       |	/* Skip starting quote */
  118|   301k|	for (; (parser->end > 0 && parser->pos < parser->end) && js[parser->pos] != '\0'; parser->pos++) {
  ------------------
  |  Branch (118:10): [True: 301k, False: 0]
  |  Branch (118:29): [True: 301k, False: 115]
  |  Branch (118:59): [True: 301k, False: 1]
  ------------------
  119|   301k|		char c = js[parser->pos];
  120|       |
  121|       |		/* Quote: end of string */
  122|   301k|		if (c == '\"') {
  ------------------
  |  Branch (122:7): [True: 112k, False: 188k]
  ------------------
  123|   112k|			token = jsmn_alloc_token(parser, tokens, num_tokens);
  124|   112k|			if (token == NULL) {
  ------------------
  |  Branch (124:8): [True: 2.71k, False: 110k]
  ------------------
  125|  2.71k|				parser->pos = start;
  126|  2.71k|				return JSMN_ERROR_NOMEM;
  127|  2.71k|			}
  128|   110k|			jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
  129|       |#ifdef JSMN_PARENT_LINKS
  130|       |			token->parent = parser->toksuper;
  131|       |#endif
  132|   110k|			return JSMN_SUCCESS;
  133|   112k|		}
  134|       |
  135|       |		/* Backslash: Quoted symbol expected */
  136|   188k|		if (c == '\\') {
  ------------------
  |  Branch (136:7): [True: 23.2k, False: 165k]
  ------------------
  137|  23.2k|			parser->pos++;
  138|  23.2k|			if (parser->end > 0 && parser->pos >= parser->end) {
  ------------------
  |  Branch (138:8): [True: 23.2k, False: 0]
  |  Branch (138:27): [True: 1, False: 23.2k]
  ------------------
  139|      1|				parser->pos = start;
  140|      1|				return JSMN_ERROR_INVAL;
  141|      1|			}
  142|  23.2k|			switch (js[parser->pos]) {
  143|       |				/* Allowed escaped symbols */
  144|  7.14k|				case '\"': case '/' : case '\\' : case 'b' :
  ------------------
  |  Branch (144:5): [True: 590, False: 22.6k]
  |  Branch (144:16): [True: 612, False: 22.6k]
  |  Branch (144:27): [True: 4.69k, False: 18.5k]
  |  Branch (144:39): [True: 1.24k, False: 21.9k]
  ------------------
  145|  21.7k|				case 'f' : case 'r' : case 'n'  : case 't' :
  ------------------
  |  Branch (145:5): [True: 473, False: 22.7k]
  |  Branch (145:16): [True: 492, False: 22.7k]
  |  Branch (145:27): [True: 13.1k, False: 10.0k]
  |  Branch (145:39): [True: 504, False: 22.7k]
  ------------------
  146|  21.7k|					break;
  147|       |				/* Allows escaped symbol \uXXXX */
  148|  1.41k|				case 'u':
  ------------------
  |  Branch (148:5): [True: 1.41k, False: 21.8k]
  ------------------
  149|       |					/* TODO */
  150|  1.41k|					break;
  151|       |				/* Unexpected symbol */
  152|      3|				default:
  ------------------
  |  Branch (152:5): [True: 3, False: 23.2k]
  ------------------
  153|      3|					parser->pos = start;
  154|      3|					return JSMN_ERROR_INVAL;
  155|  23.2k|			}
  156|  23.2k|		}
  157|   188k|	}
  158|    116|	parser->pos = start;
  159|    116|	return JSMN_ERROR_PART;
  160|   112k|}
jsmn.c:jsmn_fill_token:
   52|   135k|                            int start, int end) {
   53|   135k|	token->type = type;
   54|   135k|	token->start = start;
   55|   135k|	token->end = end;
   56|   135k|	token->size = 0;
   57|   135k|}
jsmn.c:jsmn_parse_primitive:
   63|  26.2k|		jsmntok_t *tokens, int num_tokens) {
   64|  26.2k|	jsmntok_t *token;
   65|  26.2k|	int start;
   66|       |
   67|  26.2k|	start = parser->pos;
   68|       |
   69|  83.4k|	for (; (parser->end > 0 && parser->pos < parser->end) && js[parser->pos] != '\0'; parser->pos++) {
  ------------------
  |  Branch (69:10): [True: 83.4k, False: 0]
  |  Branch (69:29): [True: 82.7k, False: 654]
  |  Branch (69:59): [True: 82.7k, False: 1]
  ------------------
   70|  82.7k|		switch (js[parser->pos]) {
   71|      0|#ifndef JSMN_STRICT
   72|       |			/* In strict mode primitive must be followed by "," or "}" or "]" */
   73|  8.17k|			case ':':
  ------------------
  |  Branch (73:4): [True: 8.17k, False: 74.5k]
  ------------------
   74|  8.17k|#endif
   75|  16.4k|			case '\t' : case '\r' : case '\n' : case ' ' :
  ------------------
  |  Branch (75:4): [True: 246, False: 82.5k]
  |  Branch (75:16): [True: 946, False: 81.8k]
  |  Branch (75:28): [True: 6.85k, False: 75.8k]
  |  Branch (75:40): [True: 243, False: 82.5k]
  ------------------
   76|  25.6k|			case ','  : case ']'  : case '}' :
  ------------------
  |  Branch (76:4): [True: 1.80k, False: 80.9k]
  |  Branch (76:16): [True: 6.23k, False: 76.5k]
  |  Branch (76:28): [True: 1.10k, False: 81.6k]
  ------------------
   77|  25.6k|				goto found;
   78|  57.1k|			default:
  ------------------
  |  Branch (78:4): [True: 57.1k, False: 25.6k]
  ------------------
   79|  57.1k|				break;
   80|  82.7k|		}
   81|  57.1k|		if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
  ------------------
  |  Branch (81:7): [True: 17, False: 57.1k]
  |  Branch (81:31): [True: 1, False: 57.1k]
  ------------------
   82|     18|			parser->pos = start;
   83|     18|			return JSMN_ERROR_INVAL;
   84|     18|		}
   85|  57.1k|	}
   86|       |#ifdef JSMN_STRICT
   87|       |	/* In strict mode primitive must be followed by a comma/object/array */
   88|       |	parser->pos = start;
   89|       |	return JSMN_ERROR_PART;
   90|       |#endif
   91|       |
   92|  26.2k|found:
   93|  26.2k|	token = jsmn_alloc_token(parser, tokens, num_tokens);
   94|  26.2k|	if (token == NULL) {
  ------------------
  |  Branch (94:6): [True: 997, False: 25.2k]
  ------------------
   95|    997|		parser->pos = start;
   96|    997|		return JSMN_ERROR_NOMEM;
   97|    997|	}
   98|  25.2k|	jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
   99|       |#ifdef JSMN_PARENT_LINKS
  100|       |	token->parent = parser->toksuper;
  101|       |#endif
  102|  25.2k|	parser->pos--;
  103|  25.2k|	return JSMN_SUCCESS;
  104|  26.2k|}

plist_ostep_init:
   51|      2|{
   52|       |    /* init OpenStep stuff */
   53|      2|#ifdef DEBUG
   54|      2|    char *env_debug = getenv("PLIST_OSTEP_DEBUG");
   55|      2|    if (env_debug && !strcmp(env_debug, "1")) {
  ------------------
  |  Branch (55:9): [True: 0, False: 2]
  |  Branch (55:22): [True: 0, False: 0]
  ------------------
   56|      0|        plist_ostep_debug = 1;
   57|      0|    }
   58|      2|#endif
   59|      2|}

plist.c:libplist_initialize:
  113|      2|{
  114|      2|    thread_once(&init_once, internal_plist_init);
  ------------------
  |  |  102|      2|#define thread_once pthread_once
  ------------------
  115|      2|}
plist_new_node:
  315|   188k|{
  316|   188k|    return (plist_t) node_create(NULL, data);
  317|   188k|}
plist_get_data:
  320|  15.5M|{
  321|  15.5M|    if (!node)
  ------------------
  |  Branch (321:9): [True: 0, False: 15.5M]
  ------------------
  322|      0|        return NULL;
  323|  15.5M|    return (plist_data_t)((node_t)node)->data;
  324|  15.5M|}
plist_new_plist_data:
  327|   188k|{
  328|   188k|    plist_data_t data = (plist_data_t) calloc(sizeof(struct plist_data_s), 1);
  329|   188k|    return data;
  330|   188k|}
plist_free_data:
  358|   188k|{
  359|   188k|    if (data)
  ------------------
  |  Branch (359:9): [True: 188k, False: 0]
  ------------------
  360|   188k|    {
  361|   188k|        switch (data->type)
  362|   188k|        {
  363|  63.1k|        case PLIST_KEY:
  ------------------
  |  Branch (363:9): [True: 63.1k, False: 124k]
  ------------------
  364|  97.0k|        case PLIST_STRING:
  ------------------
  |  Branch (364:9): [True: 33.8k, False: 154k]
  ------------------
  365|  97.0k|            free(data->strval);
  366|  97.0k|            break;
  367|      0|        case PLIST_DATA:
  ------------------
  |  Branch (367:9): [True: 0, False: 188k]
  ------------------
  368|      0|            free(data->buff);
  369|      0|            break;
  370|  58.2k|        case PLIST_ARRAY:
  ------------------
  |  Branch (370:9): [True: 58.2k, False: 129k]
  ------------------
  371|  58.2k|            ptr_array_free((ptrarray_t*)data->hashtable);
  372|  58.2k|            break;
  373|  12.1k|        case PLIST_DICT:
  ------------------
  |  Branch (373:9): [True: 12.1k, False: 175k]
  ------------------
  374|  12.1k|            hash_table_destroy((hashtable_t*)data->hashtable);
  375|  12.1k|            break;
  376|  20.7k|        default:
  ------------------
  |  Branch (376:9): [True: 20.7k, False: 167k]
  ------------------
  377|  20.7k|            break;
  378|   188k|        }
  379|   188k|        free(data);
  380|   188k|    }
  381|   188k|}
plist_new_dict:
  404|  12.1k|{
  405|  12.1k|    plist_data_t data = plist_new_plist_data();
  406|  12.1k|    data->type = PLIST_DICT;
  407|  12.1k|    return plist_new_node(data);
  408|  12.1k|}
plist_new_array:
  411|  58.2k|{
  412|  58.2k|    plist_data_t data = plist_new_plist_data();
  413|  58.2k|    data->type = PLIST_ARRAY;
  414|  58.2k|    return plist_new_node(data);
  415|  58.2k|}
plist_new_bool:
  437|  9.89k|{
  438|  9.89k|    plist_data_t data = plist_new_plist_data();
  439|  9.89k|    data->type = PLIST_BOOLEAN;
  440|  9.89k|    data->boolval = val;
  441|  9.89k|    data->length = sizeof(uint8_t);
  442|  9.89k|    return plist_new_node(data);
  443|  9.89k|}
plist_new_int:
  455|  2.74k|{
  456|  2.74k|    plist_data_t data = plist_new_plist_data();
  457|  2.74k|    data->type = PLIST_INT;
  458|  2.74k|    data->intval = val;
  459|  2.74k|    data->length = sizeof(uint64_t);
  460|  2.74k|    return plist_new_node(data);
  461|  2.74k|}
plist_new_real:
  473|  1.64k|{
  474|  1.64k|    plist_data_t data = plist_new_plist_data();
  475|  1.64k|    data->type = PLIST_REAL;
  476|  1.64k|    data->realval = val;
  477|  1.64k|    data->length = sizeof(double);
  478|  1.64k|    return plist_new_node(data);
  479|  1.64k|}
plist_free:
  510|  5.85k|{
  511|  5.85k|    if (plist)
  ------------------
  |  Branch (511:9): [True: 5.09k, False: 765]
  ------------------
  512|  5.09k|    {
  513|  5.09k|        plist_free_node((node_t)plist);
  514|  5.09k|    }
  515|  5.85k|}
plist_array_append_item:
  677|  52.6k|{
  678|  52.6k|    if (node && PLIST_ARRAY == plist_get_node_type(node))
  ------------------
  |  Branch (678:9): [True: 52.6k, False: 0]
  |  Branch (678:17): [True: 52.6k, False: 0]
  ------------------
  679|  52.6k|    {
  680|  52.6k|        node_attach((node_t)node, (node_t)item);
  681|  52.6k|        _plist_array_post_insert(node, item, -1);
  682|  52.6k|    }
  683|  52.6k|}
plist_dict_get_item:
  821|  67.2k|{
  822|  67.2k|    plist_t ret = NULL;
  823|       |
  824|  67.2k|    if (node && PLIST_DICT == plist_get_node_type(node))
  ------------------
  |  Branch (824:9): [True: 67.2k, False: 0]
  |  Branch (824:17): [True: 67.2k, False: 0]
  ------------------
  825|  67.2k|    {
  826|  67.2k|        plist_data_t data = plist_get_data(node);
  827|  67.2k|        hashtable_t *ht = (hashtable_t*)data->hashtable;
  828|  67.2k|        if (ht) {
  ------------------
  |  Branch (828:13): [True: 974, False: 66.2k]
  ------------------
  829|    974|            struct plist_data_s sdata;
  830|    974|            sdata.strval = (char*)key;
  831|    974|            sdata.length = strlen(key);
  832|    974|            ret = (plist_t)hash_table_lookup(ht, &sdata);
  833|  66.2k|        } else {
  834|  66.2k|            plist_t current = NULL;
  835|  66.2k|            for (current = (plist_t)node_first_child((node_t)node);
  836|  7.62M|                current;
  ------------------
  |  Branch (836:17): [True: 7.56M, False: 62.7k]
  ------------------
  837|  7.55M|                current = (plist_t)node_next_sibling(node_next_sibling((node_t)current)))
  838|  7.56M|            {
  839|  7.56M|                data = plist_get_data(current);
  840|  7.56M|                assert( PLIST_KEY == plist_get_node_type(current) );
  841|       |
  842|  7.56M|                if (data && !strcmp(key, data->strval))
  ------------------
  |  Branch (842:21): [True: 7.56M, False: 0]
  |  Branch (842:29): [True: 3.48k, False: 7.55M]
  ------------------
  843|  3.48k|                {
  844|  3.48k|                    ret = (plist_t)node_next_sibling((node_t)current);
  845|  3.48k|                    break;
  846|  3.48k|                }
  847|  7.56M|            }
  848|  66.2k|        }
  849|  67.2k|    }
  850|  67.2k|    return ret;
  851|  67.2k|}
plist_dict_set_item:
  854|  67.2k|{
  855|  67.2k|    if (node && PLIST_DICT == plist_get_node_type(node)) {
  ------------------
  |  Branch (855:9): [True: 67.2k, False: 0]
  |  Branch (855:17): [True: 67.2k, False: 0]
  ------------------
  856|  67.2k|        plist_t old_item = plist_dict_get_item(node, key);
  857|  67.2k|        plist_t key_node = NULL;
  858|  67.2k|        if (old_item) {
  ------------------
  |  Branch (858:13): [True: 4.03k, False: 63.1k]
  ------------------
  859|  4.03k|            int idx = plist_free_node((node_t)old_item);
  860|  4.03k|            assert(idx >= 0);
  861|  4.03k|            if (idx < 0) {
  ------------------
  |  Branch (861:17): [True: 0, False: 4.03k]
  ------------------
  862|      0|                return;
  863|      0|            }
  864|  4.03k|            node_insert((node_t)node, idx, (node_t)item);
  865|  4.03k|            key_node = node_prev_sibling((node_t)item);
  866|  63.1k|        } else {
  867|  63.1k|            key_node = plist_new_key(key);
  868|  63.1k|            node_attach((node_t)node, (node_t)key_node);
  869|  63.1k|            node_attach((node_t)node, (node_t)item);
  870|  63.1k|        }
  871|       |
  872|  67.2k|        hashtable_t *ht = (hashtable_t*)((plist_data_t)((node_t)node)->data)->hashtable;
  873|  67.2k|        if (ht) {
  ------------------
  |  Branch (873:13): [True: 974, False: 66.2k]
  ------------------
  874|       |            /* store pointer to item in hash table */
  875|    974|            hash_table_insert(ht, (plist_data_t)((node_t)key_node)->data, item);
  876|  66.2k|        } else {
  877|  66.2k|            if (((node_t)node)->count > 500) {
  ------------------
  |  Branch (877:17): [True: 233, False: 66.0k]
  ------------------
  878|       |                /* make new hash table */
  879|    233|                ht = hash_table_new(dict_key_hash, dict_key_compare, NULL);
  880|       |                /* calculate the hashes for all entries we have so far */
  881|    233|                plist_t current = NULL;
  882|    233|                for (current = (plist_t)node_first_child((node_t)node);
  883|  58.7k|                     ht && current;
  ------------------
  |  Branch (883:22): [True: 58.7k, False: 0]
  |  Branch (883:28): [True: 58.4k, False: 233]
  ------------------
  884|  58.4k|                     current = (plist_t)node_next_sibling(node_next_sibling((node_t)current)))
  885|  58.4k|                {
  886|  58.4k|                    hash_table_insert(ht, ((node_t)current)->data, node_next_sibling((node_t)current));
  887|  58.4k|                }
  888|    233|                ((plist_data_t)((node_t)node)->data)->hashtable = ht;
  889|    233|            }
  890|  66.2k|        }
  891|  67.2k|    }
  892|  67.2k|}
plist_get_node_type:
 1017|  7.74M|{
 1018|  7.74M|    if (node)
  ------------------
  |  Branch (1018:9): [True: 7.74M, False: 0]
  ------------------
 1019|  7.74M|    {
 1020|  7.74M|        plist_data_t data = plist_get_data(node);
 1021|  7.74M|        if (data)
  ------------------
  |  Branch (1021:13): [True: 7.74M, False: 0]
  ------------------
 1022|  7.74M|            return data->type;
 1023|  7.74M|    }
 1024|      0|    return PLIST_NONE;
 1025|  7.74M|}
plist.c:internal_plist_init:
   64|      2|{
   65|      2|    plist_bin_init();
   66|      2|    plist_xml_init();
   67|      2|    plist_json_init();
   68|      2|    plist_ostep_init();
   69|      2|}
plist.c:plist_free_node:
  384|   188k|{
  385|   188k|    plist_data_t data = NULL;
  386|   188k|    int node_index = node_detach(node->parent, node);
  387|   188k|    data = plist_get_data(node);
  388|   188k|    plist_free_data(data);
  389|   188k|    node->data = NULL;
  390|       |
  391|   188k|    node_t ch;
  392|   367k|    for (ch = node_first_child(node); ch; ) {
  ------------------
  |  Branch (392:39): [True: 179k, False: 188k]
  ------------------
  393|   179k|        node_t next = node_next_sibling(ch);
  394|   179k|        plist_free_node(ch);
  395|   179k|        ch = next;
  396|   179k|    }
  397|       |
  398|   188k|    node_destroy(node);
  399|       |
  400|   188k|    return node_index;
  401|   188k|}
plist.c:_plist_array_post_insert:
  634|  52.6k|{
  635|  52.6k|    ptrarray_t *pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable;
  636|  52.6k|    if (pa) {
  ------------------
  |  Branch (636:9): [True: 8.20k, False: 44.4k]
  ------------------
  637|       |        /* store pointer to item in array */
  638|  8.20k|        ptr_array_insert(pa, item, n);
  639|  44.4k|    } else {
  640|  44.4k|        if (((node_t)node)->count > 100) {
  ------------------
  |  Branch (640:13): [True: 102, False: 44.3k]
  ------------------
  641|       |            /* make new lookup array */
  642|    102|            pa = ptr_array_new(128);
  643|    102|            plist_t current = NULL;
  644|    102|            for (current = (plist_t)node_first_child((node_t)node);
  645|  10.4k|                 pa && current;
  ------------------
  |  Branch (645:18): [True: 10.4k, False: 0]
  |  Branch (645:24): [True: 10.3k, False: 102]
  ------------------
  646|  10.3k|                 current = (plist_t)node_next_sibling((node_t)current))
  647|  10.3k|            {
  648|  10.3k|                ptr_array_add(pa, current);
  649|  10.3k|            }
  650|    102|            ((plist_data_t)((node_t)node)->data)->hashtable = pa;
  651|    102|        }
  652|  44.4k|    }
  653|  52.6k|}
plist.c:plist_new_key:
  419|  63.1k|{
  420|  63.1k|    plist_data_t data = plist_new_plist_data();
  421|  63.1k|    data->type = PLIST_KEY;
  422|  63.1k|    data->strval = strdup(val);
  423|  63.1k|    data->length = strlen(val);
  424|  63.1k|    return plist_new_node(data);
  425|  63.1k|}
plist.c:dict_key_hash:
  333|  60.4k|{
  334|  60.4k|    plist_data_t keydata = (plist_data_t)data;
  335|  60.4k|    unsigned int hash = 5381;
  336|  60.4k|    size_t i;
  337|  60.4k|    char *str = keydata->strval;
  338|   165k|    for (i = 0; i < keydata->length; str++, i++) {
  ------------------
  |  Branch (338:17): [True: 104k, False: 60.4k]
  ------------------
  339|   104k|        hash = ((hash << 5) + hash) + *str;
  340|   104k|    }
  341|  60.4k|    return hash;
  342|  60.4k|}
plist.c:dict_key_compare:
  345|  3.82k|{
  346|  3.82k|    plist_data_t data_a = (plist_data_t)a;
  347|  3.82k|    plist_data_t data_b = (plist_data_t)b;
  348|  3.82k|    if (data_a->strval == NULL || data_b->strval == NULL) {
  ------------------
  |  Branch (348:9): [True: 0, False: 3.82k]
  |  Branch (348:35): [True: 0, False: 3.82k]
  ------------------
  349|      0|        return FALSE;
  ------------------
  |  |   32|      0|#define FALSE 0
  ------------------
  350|      0|    }
  351|  3.82k|    if (data_a->length != data_b->length) {
  ------------------
  |  Branch (351:9): [True: 2.12k, False: 1.70k]
  ------------------
  352|  2.12k|        return FALSE;
  ------------------
  |  |   32|  2.12k|#define FALSE 0
  ------------------
  353|  2.12k|    }
  354|  1.70k|    return (strcmp(data_a->strval, data_b->strval) == 0) ? TRUE : FALSE;
  ------------------
  |  |   28|  1.09k|#define TRUE 1
  ------------------
                  return (strcmp(data_a->strval, data_b->strval) == 0) ? TRUE : FALSE;
  ------------------
  |  |   32|    607|#define FALSE 0
  ------------------
  |  Branch (354:12): [True: 1.09k, False: 607]
  ------------------
  355|  3.82k|}

ptr_array_new:
   25|    102|{
   26|    102|	ptrarray_t *pa = (ptrarray_t*)malloc(sizeof(ptrarray_t));
   27|    102|	pa->pdata = (void**)malloc(sizeof(void*) * capacity);
   28|    102|	pa->capacity = capacity;
   29|    102|	pa->capacity_step = (capacity > 4096) ? 4096 : capacity;
  ------------------
  |  Branch (29:22): [True: 0, False: 102]
  ------------------
   30|    102|	pa->len = 0;
   31|    102|	return pa;
   32|    102|}
ptr_array_free:
   35|  58.2k|{
   36|  58.2k|	if (!pa) return;
  ------------------
  |  Branch (36:6): [True: 58.1k, False: 102]
  ------------------
   37|    102|	if (pa->pdata) {
  ------------------
  |  Branch (37:6): [True: 102, False: 0]
  ------------------
   38|    102|		free(pa->pdata);
   39|    102|	}
   40|    102|	free(pa);
   41|    102|}
ptr_array_insert:
   44|  18.5k|{
   45|  18.5k|	if (!pa || !pa->pdata) return;
  ------------------
  |  Branch (45:6): [True: 0, False: 18.5k]
  |  Branch (45:13): [True: 0, False: 18.5k]
  ------------------
   46|  18.5k|	long remaining = pa->capacity-pa->len;
   47|  18.5k|	if (remaining == 0) {
  ------------------
  |  Branch (47:6): [True: 66, False: 18.4k]
  ------------------
   48|     66|		pa->pdata = (void**)realloc(pa->pdata, sizeof(void*) * (pa->capacity + pa->capacity_step));
   49|     66|		pa->capacity += pa->capacity_step;
   50|     66|	}
   51|  18.5k|	if (array_index < 0 || array_index >= pa->len) {
  ------------------
  |  Branch (51:6): [True: 18.5k, False: 0]
  |  Branch (51:25): [True: 0, False: 0]
  ------------------
   52|  18.5k|		pa->pdata[pa->len] = data;
   53|  18.5k|	} else {
   54|      0|		memmove(&pa->pdata[array_index+1], &pa->pdata[array_index], (pa->len-array_index) * sizeof(void*));
   55|      0|		pa->pdata[array_index] = data;
   56|      0|	}
   57|  18.5k|	pa->len++;
   58|  18.5k|}
ptr_array_add:
   61|  10.3k|{
   62|  10.3k|	ptr_array_insert(pa, data, -1);
   63|  10.3k|}

plist_xml_init:
   90|      2|{
   91|       |    /* init XML stuff */
   92|      2|#ifdef DEBUG
   93|      2|    char *env_debug = getenv("PLIST_XML_DEBUG");
   94|      2|    if (env_debug && !strcmp(env_debug, "1")) {
  ------------------
  |  Branch (94:9): [True: 0, False: 2]
  |  Branch (94:22): [True: 0, False: 0]
  ------------------
   95|      0|        plist_xml_debug = 1;
   96|      0|    }
   97|      2|#endif
   98|      2|}

