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

node_destroy:
   31|   195k|{
   32|   195k|	if(!node) return;
  ------------------
  |  Branch (32:5): [True: 0, False: 195k]
  ------------------
   33|       |
   34|   195k|	if (node->children && node->children->count > 0) {
  ------------------
  |  Branch (34:6): [True: 30.5k, False: 164k]
  |  Branch (34:24): [True: 0, False: 30.5k]
  ------------------
   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|   195k|	node_list_destroy(node->children);
   42|   195k|	node->children = NULL;
   43|       |
   44|   195k|	free(node);
   45|   195k|}
node_create:
   48|   195k|{
   49|   195k|	int error = 0;
   50|       |
   51|   195k|	node_t node = (node_t)calloc(1, sizeof(struct node));
   52|   195k|	if (node == NULL) {
  ------------------
  |  Branch (52:6): [True: 0, False: 195k]
  ------------------
   53|      0|		return NULL;
   54|      0|	}
   55|       |
   56|   195k|	node->data = data;
   57|   195k|	node->next = NULL;
   58|   195k|	node->prev = NULL;
   59|   195k|	node->count = 0;
   60|   195k|	node->parent = NULL;
   61|   195k|	node->children = NULL;
   62|       |
   63|       |	// Pass NULL to create a root node
   64|   195k|	if(parent != NULL) {
  ------------------
  |  Branch (64:5): [True: 0, False: 195k]
  ------------------
   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|   195k|	return node;
   76|   195k|}
node_attach:
   79|   186k|{
   80|   186k|	if (!parent || !child) return -1;
  ------------------
  |  Branch (80:6): [True: 0, False: 186k]
  |  Branch (80:17): [True: 0, False: 186k]
  ------------------
   81|   186k|	child->parent = parent;
   82|   186k|	if(!parent->children) {
  ------------------
  |  Branch (82:5): [True: 30.5k, False: 155k]
  ------------------
   83|  30.5k|		parent->children = node_list_create();
   84|  30.5k|	}
   85|   186k|	int res = node_list_add(parent->children, child);
   86|   186k|	if (res == 0) {
  ------------------
  |  Branch (86:6): [True: 186k, False: 0]
  ------------------
   87|   186k|		parent->count++;
   88|   186k|	}
   89|   186k|	return res;
   90|   186k|}
node_detach:
   93|   195k|{
   94|   195k|	if (!parent || !child) return -1;
  ------------------
  |  Branch (94:6): [True: 4.74k, False: 190k]
  |  Branch (94:17): [True: 0, False: 190k]
  ------------------
   95|   190k|	int node_index = node_list_remove(parent->children, child);
   96|   190k|	if (node_index >= 0) {
  ------------------
  |  Branch (96:6): [True: 190k, False: 0]
  ------------------
   97|   190k|		parent->count--;
   98|   190k|	}
   99|   190k|	return node_index;
  100|   195k|}
node_insert:
  103|  3.85k|{
  104|  3.85k|	if (!parent || !child) return -1;
  ------------------
  |  Branch (104:6): [True: 0, False: 3.85k]
  |  Branch (104:17): [True: 0, False: 3.85k]
  ------------------
  105|  3.85k|	child->parent = parent;
  106|  3.85k|	if(!parent->children) {
  ------------------
  |  Branch (106:5): [True: 0, False: 3.85k]
  ------------------
  107|      0|		parent->children = node_list_create();
  108|      0|	}
  109|  3.85k|	int res = node_list_insert(parent->children, node_index, child);
  110|  3.85k|	if (res == 0) {
  ------------------
  |  Branch (110:6): [True: 3.85k, False: 0]
  ------------------
  111|  3.85k|		parent->count++;
  112|  3.85k|	}
  113|  3.85k|	return res;
  114|  3.85k|}
node_first_child:
  170|   264k|{
  171|   264k|	if (!node || !node->children) return NULL;
  ------------------
  |  Branch (171:6): [True: 0, False: 264k]
  |  Branch (171:15): [True: 165k, False: 98.7k]
  ------------------
  172|  98.7k|	return node->children->begin;
  173|   264k|}
node_prev_sibling:
  176|  3.85k|{
  177|  3.85k|	if (!node) return NULL;
  ------------------
  |  Branch (177:6): [True: 0, False: 3.85k]
  ------------------
  178|  3.85k|	return node->prev;
  179|  3.85k|}
node_next_sibling:
  182|  16.2M|{
  183|  16.2M|	if (!node) return NULL;
  ------------------
  |  Branch (183:6): [True: 0, False: 16.2M]
  ------------------
  184|  16.2M|	return node->next;
  185|  16.2M|}

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

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|    245|{
   25|    245|	hashtable_t* ht = (hashtable_t*)malloc(sizeof(hashtable_t));
   26|    245|	int i;
   27|  1.00M|	for (i = 0; i < 4096; i++) {
  ------------------
  |  Branch (27:14): [True: 1.00M, False: 245]
  ------------------
   28|  1.00M|		ht->entries[i] = NULL;
   29|  1.00M|	}
   30|    245|	ht->count = 0;
   31|    245|	ht->hash_func = hash_func;
   32|    245|	ht->compare_func = compare_func;
   33|    245|	ht->free_func = free_func;
   34|    245|	return ht;
   35|    245|}
hash_table_destroy:
   38|  12.8k|{
   39|  12.8k|	if (!ht) return;
  ------------------
  |  Branch (39:6): [True: 12.5k, False: 245]
  ------------------
   40|       |
   41|    245|	int i = 0;
   42|  1.00M|	for (i = 0; i < 4096; i++) {
  ------------------
  |  Branch (42:14): [True: 1.00M, False: 245]
  ------------------
   43|  1.00M|		if (ht->entries[i]) {
  ------------------
  |  Branch (43:7): [True: 60.5k, False: 943k]
  ------------------
   44|  60.5k|			hashentry_t* e = ht->entries[i];
   45|   122k|			while (e) {
  ------------------
  |  Branch (45:11): [True: 61.9k, False: 60.5k]
  ------------------
   46|  61.9k|				if (ht->free_func) {
  ------------------
  |  Branch (46:9): [True: 0, False: 61.9k]
  ------------------
   47|      0|					ht->free_func(e->value);
   48|      0|				}
   49|  61.9k|				hashentry_t* old = e;
   50|  61.9k|				e = (hashentry_t*)e->next;
   51|  61.9k|				free(old);
   52|  61.9k|			}
   53|  60.5k|		}
   54|  1.00M|	}
   55|    245|	free(ht);
   56|    245|}
hash_table_insert:
   59|  62.5k|{
   60|  62.5k|	if (!ht || !key) return;
  ------------------
  |  Branch (60:6): [True: 0, False: 62.5k]
  |  Branch (60:13): [True: 0, False: 62.5k]
  ------------------
   61|       |
   62|  62.5k|	unsigned int hash = ht->hash_func(key);
   63|       |
   64|  62.5k|	int idx0 = hash & 0xFFF;
   65|       |
   66|       |	// get the idx0 list
   67|  62.5k|	hashentry_t* e = ht->entries[idx0];
   68|  64.6k|	while (e) {
  ------------------
  |  Branch (68:9): [True: 2.62k, False: 61.9k]
  ------------------
   69|  2.62k|		if (ht->compare_func(e->key, key)) {
  ------------------
  |  Branch (69:7): [True: 596, False: 2.03k]
  ------------------
   70|       |			// element already present. replace value.
   71|    596|			e->value = value;
   72|    596|			return;
   73|    596|		}
   74|  2.03k|		e = (hashentry_t*)e->next;
   75|  2.03k|	}
   76|       |
   77|       |	// if we get here, the element is not yet in the list.
   78|       |
   79|       |	// make a new entry.
   80|  61.9k|	hashentry_t* entry = (hashentry_t*)malloc(sizeof(hashentry_t));
   81|  61.9k|	entry->key = key;
   82|  61.9k|	entry->value = value;
   83|  61.9k|	if (!ht->entries[idx0]) {
  ------------------
  |  Branch (83:6): [True: 60.5k, False: 1.47k]
  ------------------
   84|       |		// first entry
   85|  60.5k|		entry->next = NULL;
   86|  60.5k|	} else {
   87|       |		// add to list
   88|  1.47k|		entry->next = ht->entries[idx0];
   89|  1.47k|	}
   90|  61.9k|	ht->entries[idx0] = entry;
   91|  61.9k|	ht->count++;
   92|  61.9k|}
hash_table_lookup:
   95|  1.08k|{
   96|  1.08k|	if (!ht || !key) return NULL;
  ------------------
  |  Branch (96:6): [True: 0, False: 1.08k]
  |  Branch (96:13): [True: 0, False: 1.08k]
  ------------------
   97|  1.08k|	unsigned int hash = ht->hash_func(key);
   98|       |
   99|  1.08k|	int idx0 = hash & 0xFFF;
  100|       |
  101|  1.08k|	hashentry_t* e = ht->entries[idx0];
  102|  1.54k|	while (e) {
  ------------------
  |  Branch (102:9): [True: 1.05k, False: 487]
  ------------------
  103|  1.05k|		if (ht->compare_func(e->key, key)) {
  ------------------
  |  Branch (103:7): [True: 596, False: 462]
  ------------------
  104|    596|			return e->value;
  105|    596|		}
  106|    462|		e = (hashentry_t*)e->next;
  107|    462|	}
  108|    487|	return NULL;
  109|  1.08k|}

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.16k|{
  787|  2.16k|    if (!plist) {
  ------------------
  |  Branch (787:9): [True: 0, False: 2.16k]
  ------------------
  788|      0|        return PLIST_ERR_INVALID_ARG;
  789|      0|    }
  790|  2.16k|    *plist = NULL;
  791|  2.16k|    if (!json || (length == 0)) {
  ------------------
  |  Branch (791:9): [True: 0, False: 2.16k]
  |  Branch (791:18): [True: 0, False: 2.16k]
  ------------------
  792|      0|        return PLIST_ERR_INVALID_ARG;
  793|      0|    }
  794|       |
  795|  2.16k|    jsmn_parser parser;
  796|  2.16k|    jsmn_init(&parser);
  797|  2.16k|    int maxtoks = 256;
  798|  2.16k|    int curtoks = 0;
  799|  2.16k|    int r = 0;
  800|  2.16k|    jsmntok_t *tokens = NULL;
  801|       |
  802|  13.0k|    do {
  803|  13.0k|        jsmntok_t* newtokens = (jsmntok_t*)realloc(tokens, sizeof(jsmntok_t)*maxtoks);
  804|  13.0k|        if (!newtokens) {
  ------------------
  |  Branch (804:13): [True: 0, False: 13.0k]
  ------------------
  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|  13.0k|        memset((unsigned char*)newtokens + sizeof(jsmntok_t)*curtoks, '\0', sizeof(jsmntok_t)*(maxtoks-curtoks));
  809|  13.0k|        tokens = newtokens;
  810|  13.0k|        curtoks = maxtoks;
  811|       |
  812|  13.0k|        r = jsmn_parse(&parser, json, length, tokens, maxtoks);
  813|  13.0k|        if (r == JSMN_ERROR_NOMEM) {
  ------------------
  |  Branch (813:13): [True: 10.8k, False: 2.16k]
  ------------------
  814|  10.8k|            maxtoks+=16;
  815|  10.8k|            continue;
  816|  10.8k|        }
  817|  13.0k|    } while (r == JSMN_ERROR_NOMEM);
  ------------------
  |  Branch (817:14): [True: 10.8k, False: 2.16k]
  ------------------
  818|       |
  819|  2.16k|    switch(r) {
  820|      0|        case JSMN_ERROR_NOMEM:
  ------------------
  |  Branch (820:9): [True: 0, False: 2.16k]
  ------------------
  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|     67|        case JSMN_ERROR_INVAL:
  ------------------
  |  Branch (824:9): [True: 67, False: 2.09k]
  ------------------
  825|     67|            PLIST_JSON_ERR("%s: Invalid character inside JSON string\n", __func__);
  ------------------
  |  |   44|     67|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 67]
  |  |  ------------------
  ------------------
  826|     67|            free(tokens);
  827|     67|            return PLIST_ERR_PARSE;
  828|    291|        case JSMN_ERROR_PART:
  ------------------
  |  Branch (828:9): [True: 291, False: 1.87k]
  ------------------
  829|    291|            PLIST_JSON_ERR("%s: Incomplete JSON, more bytes expected\n", __func__);
  ------------------
  |  |   44|    291|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 291]
  |  |  ------------------
  ------------------
  830|    291|            free(tokens);
  831|    291|            return PLIST_ERR_PARSE;
  832|  1.80k|        default:
  ------------------
  |  Branch (832:9): [True: 1.80k, False: 358]
  ------------------
  833|  1.80k|            break;
  834|  2.16k|    }
  835|       |
  836|  1.80k|    int startindex = 0;
  837|  1.80k|    jsmntok_info_t ti = { tokens, parser.toknext };
  838|  1.80k|    switch (tokens[startindex].type) {
  839|    699|        case JSMN_PRIMITIVE:
  ------------------
  |  Branch (839:9): [True: 699, False: 1.10k]
  ------------------
  840|    699|            *plist = parse_primitive(json, &ti, &startindex);
  841|    699|            break;
  842|    196|        case JSMN_STRING:
  ------------------
  |  Branch (842:9): [True: 196, False: 1.61k]
  ------------------
  843|    196|            *plist = parse_string(json, &ti, &startindex);
  844|    196|            break;
  845|    343|        case JSMN_ARRAY:
  ------------------
  |  Branch (845:9): [True: 343, False: 1.46k]
  ------------------
  846|    343|            *plist = parse_array(json, &ti, &startindex);
  847|    343|            break;
  848|    569|        case JSMN_OBJECT:
  ------------------
  |  Branch (848:9): [True: 569, False: 1.23k]
  ------------------
  849|    569|            *plist = parse_object(json, &ti, &startindex);
  850|    569|            break;
  851|      0|        default:
  ------------------
  |  Branch (851:9): [True: 0, False: 1.80k]
  ------------------
  852|      0|            break;
  853|  1.80k|    }
  854|  1.80k|    free(tokens);
  855|  1.80k|    return PLIST_ERR_SUCCESS;
  856|  1.80k|}
jplist.c:parse_primitive:
  497|  23.0k|{
  498|  23.0k|    if (ti->tokens[*index].type != JSMN_PRIMITIVE) {
  ------------------
  |  Branch (498:9): [True: 0, False: 23.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|  23.0k|    plist_t val = NULL;
  503|  23.0k|    const char* str_val = js + ti->tokens[*index].start;
  504|  23.0k|    const char* str_end = js + ti->tokens[*index].end;
  505|  23.0k|    size_t str_len = ti->tokens[*index].end - ti->tokens[*index].start;
  506|  23.0k|    if (!strncmp("false", str_val, str_len)) {
  ------------------
  |  Branch (506:9): [True: 5.63k, False: 17.4k]
  ------------------
  507|  5.63k|        val = plist_new_bool(0);
  508|  17.4k|    } else if (!strncmp("true", str_val, str_len)) {
  ------------------
  |  Branch (508:16): [True: 4.45k, False: 12.9k]
  ------------------
  509|  4.45k|        val = plist_new_bool(1);
  510|  12.9k|    } else if (!strncmp("null", str_val, str_len)) {
  ------------------
  |  Branch (510:16): [True: 7.15k, False: 5.84k]
  ------------------
  511|  7.15k|        plist_data_t data = plist_new_plist_data();
  512|  7.15k|        data->type = PLIST_NULL;
  513|  7.15k|        val = plist_new_node(data);
  514|  7.15k|    } else if (isdigit(str_val[0]) || (str_val[0] == '-' && str_val+1 < str_end && isdigit(str_val[1]))) {
  ------------------
  |  Branch (514:40): [True: 748, False: 147]
  |  Branch (514:61): [True: 744, False: 4]
  ------------------
  515|  5.69k|        char* endp = (char*)str_val;
  516|  5.69k|        int is_neg = (str_val[0] == '-');
  517|  5.69k|        int64_t intpart = parse_decimal(str_val, str_end, &endp);
  518|  5.69k|        if (endp >= str_end) {
  ------------------
  |  Branch (518:13): [True: 3.47k, False: 2.22k]
  ------------------
  519|       |            /* integer */
  520|  3.47k|            if (is_neg || intpart <= INT64_MAX) {
  ------------------
  |  Branch (520:17): [True: 501, False: 2.97k]
  |  Branch (520:27): [True: 2.97k, False: 0]
  ------------------
  521|  3.47k|                val = plist_new_int(intpart);
  522|  3.47k|            } else {
  523|      0|                val = plist_new_uint((uint64_t)intpart);
  524|      0|            }
  525|  3.47k|        } 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: 468, False: 1.75k]
  |  Branch (525:37): [True: 467, False: 1]
  |  Branch (525:82): [True: 1.28k, False: 469]
  |  Branch (525:98): [True: 445, False: 24]
  |  Branch (525:115): [True: 1.71k, False: 15]
  |  Branch (525:159): [True: 956, False: 8]
  |  Branch (525:181): [True: 955, False: 1]
  ------------------
  526|       |            /* floating point */
  527|  2.17k|            double dval = (double)intpart;
  528|  2.17k|            char* fendp = endp;
  529|  2.17k|            int err = 0;
  530|  2.17k|            do {
  531|  2.17k|                if (*endp == '.') {
  ------------------
  |  Branch (531:21): [True: 466, False: 1.70k]
  ------------------
  532|    466|                    fendp++;
  533|    466|                    double frac = 0;
  534|    466|                    double p = 0.1;
  535|  1.23k|                    while (fendp < str_end && isdigit(*fendp)) {
  ------------------
  |  Branch (535:28): [True: 792, False: 441]
  ------------------
  536|    767|                        frac = frac + (*fendp - '0') * p;
  537|    767|                        p *= 0.1;
  538|    767|                        fendp++;
  539|    767|                    }
  540|    466|                    if (is_neg) {
  ------------------
  |  Branch (540:25): [True: 240, False: 226]
  ------------------
  541|    240|                        dval -= frac;
  542|    240|                    } else {
  543|    226|                        dval += frac;
  544|    226|                    }
  545|    466|                }
  546|  2.17k|                if (fendp >= str_end) {
  ------------------
  |  Branch (546:21): [True: 441, False: 1.73k]
  ------------------
  547|    441|                    break;
  548|    441|                }
  549|  1.73k|                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.73k, False: 1]
  |  Branch (549:43): [True: 1.28k, False: 451]
  |  Branch (549:60): [True: 437, False: 14]
  |  Branch (549:103): [True: 955, False: 8]
  |  Branch (549:126): [True: 954, False: 1]
  ------------------
  550|  1.70k|                    int64_t exp = parse_decimal(fendp+1, str_end, &fendp);
  551|  1.70k|                    dval = dval * pow(10, (double)exp);
  552|  1.70k|                } else {
  553|     25|                    PLIST_JSON_ERR("%s: invalid character at offset %d when parsing floating point value\n", __func__, (int)(fendp - js));
  ------------------
  |  |   44|     25|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 25]
  |  |  ------------------
  ------------------
  554|     25|                    err++;
  555|     25|                }
  556|  1.73k|            } while (0);
  ------------------
  |  Branch (556:22): [Folded - Ignored]
  ------------------
  557|  2.17k|            if (!err) {
  ------------------
  |  Branch (557:17): [True: 2.14k, False: 25]
  ------------------
  558|  2.14k|                if (isinf(dval) || isnan(dval)) {
  559|    157|                   PLIST_JSON_ERR("%s: unrepresentable floating point value at offset %d when parsing numerical value\n", __func__, (int)(str_val - js));
  ------------------
  |  |   44|    157|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 157]
  |  |  ------------------
  ------------------
  560|  1.99k|                } else {
  561|  1.99k|                    val = plist_new_real(dval);
  562|  1.99k|                }
  563|  2.14k|            }
  564|  2.17k|        } else {
  565|     50|            PLIST_JSON_ERR("%s: invalid character at offset %d when parsing numerical value\n", __func__, (int)(endp - js));
  ------------------
  |  |   44|     50|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 50]
  |  |  ------------------
  ------------------
  566|     50|        }
  567|  5.69k|    } else {
  568|    152|        PLIST_JSON_ERR("%s: invalid primitive value '%.*s' encountered\n", __func__, (int)str_len, str_val);
  ------------------
  |  |   44|    152|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 152]
  |  |  ------------------
  ------------------
  569|    152|    }
  570|      0|    (*index)++;
  571|  23.0k|    return val;
  572|  23.0k|}
jplist.c:parse_decimal:
  454|  7.40k|{
  455|  7.40k|    uint64_t MAX = INT64_MAX;
  456|  7.40k|    uint64_t x = 0;
  457|  7.40k|    int is_neg = 0;
  458|  7.40k|    *endp = (char*)str;
  459|       |
  460|  7.40k|    if (str[0] == '-') {
  ------------------
  |  Branch (460:9): [True: 1.69k, False: 5.70k]
  ------------------
  461|  1.69k|        is_neg = 1;
  462|  1.69k|        (*endp)++;
  463|  1.69k|    }
  464|  7.40k|    if (is_neg) {
  ------------------
  |  Branch (464:9): [True: 1.69k, False: 5.70k]
  ------------------
  465|  1.69k|        MAX++;
  466|  1.69k|    }
  467|  41.7k|    while (*endp < str_end && isdigit(**endp)) {
  ------------------
  |  Branch (467:12): [True: 37.8k, False: 3.87k]
  ------------------
  468|  35.5k|        if (x > PO10i_LIMIT) {
  ------------------
  |  |  276|  35.5k|#define PO10i_LIMIT (INT64_MAX/10)
  ------------------
  |  Branch (468:13): [True: 701, False: 34.8k]
  ------------------
  469|    701|            x = MAX;
  470|    701|            break;
  471|    701|        }
  472|  34.8k|        x = x * 10;
  473|  34.8k|        unsigned int add = (**endp - '0');
  474|  34.8k|        if (x + add > MAX) {
  ------------------
  |  Branch (474:13): [True: 553, False: 34.2k]
  ------------------
  475|    553|            x = MAX;
  476|    553|            break;
  477|    553|        }
  478|  34.2k|        x += add;
  479|  34.2k|        (*endp)++;
  480|  34.2k|    }
  481|       |
  482|       |    // swallow the rest of the digits in case we dropped out early
  483|  9.52k|    while (*endp < str_end && isdigit(**endp)) (*endp)++;
  ------------------
  |  Branch (483:12): [True: 4.40k, False: 5.11k]
  ------------------
  484|       |
  485|  7.40k|    int64_t result = x;
  486|  7.40k|    if (is_neg) {
  ------------------
  |  Branch (486:9): [True: 1.69k, False: 5.70k]
  ------------------
  487|  1.69k|        if (x == MAX) {
  ------------------
  |  Branch (487:13): [True: 827, False: 869]
  ------------------
  488|    827|            result = INT64_MIN;
  489|    869|        } else {
  490|    869|            result = -(int64_t)x;
  491|    869|        }
  492|  1.69k|    }
  493|  7.40k|    return result;
  494|  7.40k|}
jplist.c:parse_string:
  653|  35.1k|{
  654|  35.1k|    if (ti->tokens[*index].type != JSMN_STRING) {
  ------------------
  |  Branch (654:9): [True: 0, False: 35.1k]
  ------------------
  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|  35.1k|    size_t str_len = 0; ;
  660|  35.1k|    char* strval = unescape_string(js + ti->tokens[*index].start, ti->tokens[*index].end - ti->tokens[*index].start, &str_len);
  661|  35.1k|    if (!strval) {
  ------------------
  |  Branch (661:9): [True: 24, False: 35.1k]
  ------------------
  662|     24|        return NULL;
  663|     24|    }
  664|  35.1k|    plist_t node;
  665|       |
  666|  35.1k|    plist_data_t data = plist_new_plist_data();
  667|  35.1k|    data->type = PLIST_STRING;
  668|  35.1k|    data->strval = strval;
  669|  35.1k|    data->length = str_len;
  670|  35.1k|    node = plist_new_node(data);
  671|       |
  672|  35.1k|    (*index)++;
  673|  35.1k|    return node;
  674|  35.1k|}
jplist.c:unescape_string:
  575|   105k|{
  576|   105k|    char* strval = strndup(str_val, str_len);
  577|   105k|    size_t i = 0;
  578|   238k|    while (i < str_len) {
  ------------------
  |  Branch (578:12): [True: 132k, False: 105k]
  ------------------
  579|   132k|        if (strval[i] == '\\' && i < str_len-1) {
  ------------------
  |  Branch (579:13): [True: 2.49k, False: 130k]
  |  Branch (579:34): [True: 2.49k, False: 0]
  ------------------
  580|  2.49k|            switch (strval[i+1]) {
  581|    872|                case '\"': case '/' : case '\\' : case 'b' :
  ------------------
  |  Branch (581:17): [True: 199, False: 2.29k]
  |  Branch (581:28): [True: 226, False: 2.26k]
  |  Branch (581:39): [True: 200, False: 2.29k]
  |  Branch (581:51): [True: 247, False: 2.24k]
  ------------------
  582|  1.78k|                case 'f' : case 'r' : case 'n'  : case 't' :
  ------------------
  |  Branch (582:17): [True: 205, False: 2.28k]
  |  Branch (582:28): [True: 251, False: 2.24k]
  |  Branch (582:39): [True: 213, False: 2.27k]
  |  Branch (582:51): [True: 242, False: 2.24k]
  ------------------
  583|  1.78k|                    memmove(strval+i, strval+i+1, str_len - (i+1));
  584|  1.78k|                    str_len--;
  585|  1.78k|                    switch (strval[i]) {
  586|    247|                        case 'b':
  ------------------
  |  Branch (586:25): [True: 247, False: 1.53k]
  ------------------
  587|    247|                            strval[i] = '\b';
  588|    247|                            break;
  589|    205|                        case 'f':
  ------------------
  |  Branch (589:25): [True: 205, False: 1.57k]
  ------------------
  590|    205|                            strval[i] = '\f';
  591|    205|                            break;
  592|    251|                        case 'r':
  ------------------
  |  Branch (592:25): [True: 251, False: 1.53k]
  ------------------
  593|    251|                            strval[i] = '\r';
  594|    251|                            break;
  595|    213|                        case 'n':
  ------------------
  |  Branch (595:25): [True: 213, False: 1.57k]
  ------------------
  596|    213|                            strval[i] = '\n';
  597|    213|                            break;
  598|    242|                        case 't':
  ------------------
  |  Branch (598:25): [True: 242, False: 1.54k]
  ------------------
  599|    242|                            strval[i] = '\t';
  600|    242|                            break;
  601|    625|                        default:
  ------------------
  |  Branch (601:25): [True: 625, False: 1.15k]
  ------------------
  602|    625|                            break;
  603|  1.78k|                    }
  604|  1.78k|                    break;
  605|  1.78k|                case 'u': {
  ------------------
  |  Branch (605:17): [True: 708, False: 1.78k]
  ------------------
  606|    708|                    unsigned int val = 0;
  607|    708|                    if (str_len-(i+2) < 4) {
  ------------------
  |  Branch (607:25): [True: 5, False: 703]
  ------------------
  608|      5|                        PLIST_JSON_ERR("%s: invalid escape sequence '%s' (too short)\n", __func__, strval+i);
  ------------------
  |  |   44|      5|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 5]
  |  |  ------------------
  ------------------
  609|      5|                        free(strval);
  610|      5|                        return NULL;
  611|      5|                    }
  612|    703|                    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: 683]
  ------------------
  613|     20|                        PLIST_JSON_ERR("%s: invalid escape sequence '%.*s'\n", __func__, 6, strval+i);
  ------------------
  |  |   44|     20|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 20]
  |  |  ------------------
  ------------------
  614|     20|                        free(strval);
  615|     20|                        return NULL;
  616|     20|                    }
  617|    683|                    int bytelen = 0;
  618|    683|                    if (val >= 0x800) {
  ------------------
  |  Branch (618:25): [True: 206, False: 477]
  ------------------
  619|       |                        /* three bytes */
  620|    206|                        strval[i]   = (char)(0xE0 + ((val >> 12) & 0xF));
  621|    206|                        strval[i+1] = (char)(0x80 + ((val >> 6) & 0x3F));
  622|    206|                        strval[i+2] = (char)(0x80 + (val & 0x3F));
  623|    206|                        bytelen = 3;
  624|    477|                    } else if (val >= 0x80) {
  ------------------
  |  Branch (624:32): [True: 234, False: 243]
  ------------------
  625|       |                        /* two bytes */
  626|    234|                        strval[i]   = (char)(0xC0 + ((val >> 6) & 0x1F));
  627|    234|                        strval[i+1] = (char)(0x80 + (val & 0x3F));
  628|    234|                        bytelen = 2;
  629|    243|                    } else {
  630|       |                        /* one byte */
  631|    243|                        strval[i] = (char)(val & 0x7F);
  632|    243|                        bytelen = 1;
  633|    243|                    }
  634|    683|                    memmove(strval+i+bytelen, strval+i+6, str_len - (i+5));
  635|    683|                    str_len -= (6-bytelen);
  636|    683|                }   break;
  637|      0|                default:
  ------------------
  |  Branch (637:17): [True: 0, False: 2.49k]
  ------------------
  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.49k|            }
  642|  2.49k|        }
  643|   132k|        i++;
  644|   132k|    }
  645|   105k|    strval[str_len] = '\0';
  646|   105k|    if (new_len) {
  ------------------
  |  Branch (646:9): [True: 35.1k, False: 70.3k]
  ------------------
  647|  35.1k|        *new_len = str_len;
  648|  35.1k|    }
  649|   105k|    return strval;
  650|   105k|}
jplist.c:parse_array:
  679|  58.1k|{
  680|  58.1k|    if (ti->tokens[*index].type != JSMN_ARRAY) {
  ------------------
  |  Branch (680:9): [True: 0, False: 58.1k]
  ------------------
  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.1k|    plist_t arr = plist_new_array();
  685|  58.1k|    int num_tokens = ti->tokens[*index].size;
  686|  58.1k|    int num;
  687|  58.1k|    int j = (*index)+1;
  688|   112k|    for (num = 0; num < num_tokens; num++) {
  ------------------
  |  Branch (688:19): [True: 57.1k, False: 54.9k]
  ------------------
  689|  57.1k|        if (j >= ti->count) {
  ------------------
  |  Branch (689:13): [True: 0, False: 57.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|  57.1k|        plist_t val = NULL;
  695|  57.1k|        switch (ti->tokens[j].type) {
  696|    485|            case JSMN_OBJECT:
  ------------------
  |  Branch (696:13): [True: 485, False: 56.6k]
  ------------------
  697|    485|                val = parse_object(js, ti, &j);
  698|    485|                break;
  699|  35.7k|            case JSMN_ARRAY:
  ------------------
  |  Branch (699:13): [True: 35.7k, False: 21.4k]
  ------------------
  700|  35.7k|                val = parse_array(js, ti, &j);
  701|  35.7k|                break;
  702|    237|            case JSMN_STRING:
  ------------------
  |  Branch (702:13): [True: 237, False: 56.8k]
  ------------------
  703|    237|                val = parse_string(js, ti, &j);
  704|    237|                break;
  705|  20.6k|            case JSMN_PRIMITIVE:
  ------------------
  |  Branch (705:13): [True: 20.6k, False: 36.4k]
  ------------------
  706|  20.6k|                val = parse_primitive(js, ti, &j);
  707|  20.6k|                break;
  708|      0|            default:
  ------------------
  |  Branch (708:13): [True: 0, False: 57.1k]
  ------------------
  709|      0|                break;
  710|  57.1k|        }
  711|  57.1k|        if (val) {
  ------------------
  |  Branch (711:13): [True: 53.9k, False: 3.15k]
  ------------------
  712|  53.9k|            plist_array_append_item(arr, val);
  713|  53.9k|        } else {
  714|  3.15k|            plist_free(arr);
  715|  3.15k|            return NULL;
  716|  3.15k|        }
  717|  57.1k|    }
  718|  54.9k|    *(index) = j;
  719|  54.9k|    return arr;
  720|  58.1k|}
jplist.c:parse_object:
  723|  12.8k|{
  724|  12.8k|    if (ti->tokens[*index].type != JSMN_OBJECT) {
  ------------------
  |  Branch (724:9): [True: 0, False: 12.8k]
  ------------------
  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.8k|    int num_tokens = ti->tokens[*index].size;
  729|  12.8k|    int num;
  730|  12.8k|    int j = (*index)+1;
  731|  12.8k|    if (num_tokens % 2 != 0) {
  ------------------
  |  Branch (731:9): [True: 13, False: 12.8k]
  ------------------
  732|     13|        PLIST_JSON_ERR("%s: number of children must be even\n", __func__);
  ------------------
  |  |   44|     13|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 13]
  |  |  ------------------
  ------------------
  733|     13|        return NULL;
  734|     13|    }
  735|  12.8k|    plist_t obj = plist_new_dict();
  736|  82.9k|    for (num = 0; num < num_tokens; num++) {
  ------------------
  |  Branch (736:19): [True: 70.3k, False: 12.6k]
  ------------------
  737|  70.3k|        if (j+1 >= ti->count) {
  ------------------
  |  Branch (737:13): [True: 0, False: 70.3k]
  ------------------
  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|  70.3k|        if (ti->tokens[j].type == JSMN_STRING) {
  ------------------
  |  Branch (742:13): [True: 70.3k, False: 8]
  ------------------
  743|  70.3k|            char* key = unescape_string(js + ti->tokens[j].start, ti->tokens[j].end - ti->tokens[j].start, NULL);
  744|  70.3k|            if (!key) {
  ------------------
  |  Branch (744:17): [True: 1, False: 70.3k]
  ------------------
  745|      1|                plist_free(obj);
  746|      1|                return NULL;
  747|      1|            }
  748|  70.3k|            plist_t val = NULL;
  749|  70.3k|            j++;
  750|  70.3k|            num++;
  751|  70.3k|            switch (ti->tokens[j].type) {
  752|  11.7k|                case JSMN_OBJECT:
  ------------------
  |  Branch (752:17): [True: 11.7k, False: 58.5k]
  ------------------
  753|  11.7k|                    val = parse_object(js, ti, &j);
  754|  11.7k|                    break;
  755|  22.0k|                case JSMN_ARRAY:
  ------------------
  |  Branch (755:17): [True: 22.0k, False: 48.2k]
  ------------------
  756|  22.0k|                    val = parse_array(js, ti, &j);
  757|  22.0k|                    break;
  758|  34.7k|                case JSMN_STRING:
  ------------------
  |  Branch (758:17): [True: 34.7k, False: 35.5k]
  ------------------
  759|  34.7k|                    val = parse_string(js, ti, &j);
  760|  34.7k|                    break;
  761|  1.71k|                case JSMN_PRIMITIVE:
  ------------------
  |  Branch (761:17): [True: 1.71k, False: 68.6k]
  ------------------
  762|  1.71k|                    val = parse_primitive(js, ti, &j);
  763|  1.71k|                    break;
  764|      0|                default:
  ------------------
  |  Branch (764:17): [True: 0, False: 70.3k]
  ------------------
  765|      0|                    break;
  766|  70.3k|            }
  767|  70.3k|            if (val) {
  ------------------
  |  Branch (767:17): [True: 70.1k, False: 203]
  ------------------
  768|  70.1k|                plist_dict_set_item(obj, key, val);
  769|  70.1k|            } else {
  770|    203|                free(key);
  771|    203|                plist_free(obj);
  772|    203|                return NULL;
  773|    203|            }
  774|  70.1k|            free(key);
  775|  70.1k|        } else {
  776|      8|            PLIST_JSON_ERR("%s: keys must be of type STRING\n", __func__);
  ------------------
  |  |   44|      8|#define PLIST_JSON_ERR(...) if (plist_json_debug) { fprintf(stderr, "libplist[jsonparser] ERROR: " __VA_ARGS__); }
  |  |  ------------------
  |  |  |  Branch (44:33): [True: 0, False: 8]
  |  |  ------------------
  ------------------
  777|      8|            plist_free(obj);
  778|      8|            return NULL;
  779|      8|        }
  780|  70.3k|    }
  781|  12.6k|    (*index) = j;
  782|  12.6k|    return obj;
  783|  12.8k|}

jsmn_parse:
  166|  13.0k|		unsigned int num_tokens) {
  167|  13.0k|	jsmnerr_t r;
  168|  13.0k|	int i;
  169|  13.0k|	jsmntok_t *token;
  170|       |
  171|  13.0k|	parser->end = length;
  172|       |
  173|   412k|	for (; (parser->end > 0 && parser->pos < parser->end) && js[parser->pos] != '\0'; parser->pos++) {
  ------------------
  |  Branch (173:10): [True: 412k, False: 0]
  |  Branch (173:29): [True: 411k, False: 1.97k]
  |  Branch (173:59): [True: 411k, False: 4]
  ------------------
  174|   411k|		char c;
  175|   411k|		jsmntype_t type;
  176|       |
  177|   411k|		c = js[parser->pos];
  178|   411k|		switch (c) {
  179|   164k|			case '{': case '[':
  ------------------
  |  Branch (179:4): [True: 42.3k, False: 368k]
  |  Branch (179:14): [True: 122k, False: 288k]
  ------------------
  180|   164k|				token = jsmn_alloc_token(parser, tokens, num_tokens);
  181|   164k|				if (token == NULL)
  ------------------
  |  Branch (181:9): [True: 6.96k, False: 157k]
  ------------------
  182|  6.96k|					return JSMN_ERROR_NOMEM;
  183|   157k|				if (parser->toksuper != -1) {
  ------------------
  |  Branch (183:9): [True: 151k, False: 6.04k]
  ------------------
  184|   151k|					tokens[parser->toksuper].size++;
  185|       |#ifdef JSMN_PARENT_LINKS
  186|       |					token->parent = parser->toksuper;
  187|       |#endif
  188|   151k|				}
  189|   157k|				token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
  ------------------
  |  Branch (189:20): [True: 39.9k, False: 117k]
  ------------------
  190|   157k|				token->start = parser->pos;
  191|   157k|				parser->toksuper = parser->toknext - 1;
  192|   157k|				break;
  193|  78.4k|			case '}': case ']':
  ------------------
  |  Branch (193:4): [True: 18.1k, False: 392k]
  |  Branch (193:14): [True: 60.2k, False: 350k]
  ------------------
  194|  78.4k|				type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
  ------------------
  |  Branch (194:13): [True: 18.1k, False: 60.2k]
  ------------------
  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.6M|				for (i = parser->toknext - 1; i >= 0; i--) {
  ------------------
  |  Branch (215:35): [True: 16.6M, False: 39]
  ------------------
  216|  16.6M|					token = &tokens[i];
  217|  16.6M|					if (token->start != -1 && token->end == -1) {
  ------------------
  |  Branch (217:10): [True: 16.6M, False: 0]
  |  Branch (217:32): [True: 78.4k, False: 16.5M]
  ------------------
  218|  78.4k|						if (token->type != type) {
  ------------------
  |  Branch (218:11): [True: 5, False: 78.3k]
  ------------------
  219|      5|							return JSMN_ERROR_INVAL;
  220|      5|						}
  221|  78.3k|						parser->toksuper = -1;
  222|  78.3k|						token->end = parser->pos + 1;
  223|  78.3k|						break;
  224|  78.4k|					}
  225|  16.6M|				}
  226|       |				/* Error if unmatched closing bracket */
  227|  78.4k|				if (i == -1) return JSMN_ERROR_INVAL;
  ------------------
  |  Branch (227:9): [True: 39, False: 78.3k]
  ------------------
  228|  27.3M|				for (; i >= 0; i--) {
  ------------------
  |  Branch (228:12): [True: 27.3M, False: 5.84k]
  ------------------
  229|  27.3M|					token = &tokens[i];
  230|  27.3M|					if (token->start != -1 && token->end == -1) {
  ------------------
  |  Branch (230:10): [True: 27.3M, False: 0]
  |  Branch (230:32): [True: 72.5k, False: 27.3M]
  ------------------
  231|  72.5k|						parser->toksuper = i;
  232|  72.5k|						break;
  233|  72.5k|					}
  234|  27.3M|				}
  235|  78.3k|#endif
  236|  78.3k|				break;
  237|   117k|			case '\"':
  ------------------
  |  Branch (237:4): [True: 117k, False: 293k]
  ------------------
  238|   117k|				r = jsmn_parse_string(parser, js, tokens, num_tokens);
  239|   117k|				if (r < 0) return r;
  ------------------
  |  Branch (239:9): [True: 2.92k, False: 114k]
  ------------------
  240|   114k|				if (parser->toksuper != -1)
  ------------------
  |  Branch (240:9): [True: 114k, False: 456]
  ------------------
  241|   114k|					tokens[parser->toksuper].size++;
  242|   114k|				break;
  243|  21.9k|			case '\t' : case '\r' : case '\n' : case ':' : case ',': case ' ':
  ------------------
  |  Branch (243:4): [True: 430, False: 410k]
  |  Branch (243:16): [True: 2.68k, False: 408k]
  |  Branch (243:28): [True: 7.19k, False: 403k]
  |  Branch (243:40): [True: 8.79k, False: 402k]
  |  Branch (243:51): [True: 2.37k, False: 408k]
  |  Branch (243:61): [True: 510, False: 410k]
  ------------------
  244|  21.9k|				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|  28.3k|			default:
  ------------------
  |  Branch (252:4): [True: 28.3k, False: 382k]
  ------------------
  253|  28.3k|#endif
  254|  28.3k|				r = jsmn_parse_primitive(parser, js, tokens, num_tokens);
  255|  28.3k|				if (r < 0) return r;
  ------------------
  |  Branch (255:9): [True: 1.10k, False: 27.2k]
  ------------------
  256|  27.2k|				if (parser->toksuper != -1)
  ------------------
  |  Branch (256:9): [True: 25.2k, False: 1.97k]
  ------------------
  257|  25.2k|					tokens[parser->toksuper].size++;
  258|  27.2k|				break;
  259|       |
  260|       |#ifdef JSMN_STRICT
  261|       |			/* Unexpected char in strict mode */
  262|       |			default:
  263|       |				return JSMN_ERROR_INVAL;
  264|       |#endif
  265|       |
  266|   411k|		}
  267|   411k|	}
  268|       |
  269|   217k|	for (i = parser->toknext - 1; i >= 0; i--) {
  ------------------
  |  Branch (269:32): [True: 215k, False: 1.80k]
  ------------------
  270|       |		/* Unmatched opened object or array */
  271|   215k|		if (tokens[i].start != -1 && tokens[i].end == -1) {
  ------------------
  |  Branch (271:7): [True: 215k, False: 0]
  |  Branch (271:32): [True: 168, False: 215k]
  ------------------
  272|    168|			return JSMN_ERROR_PART;
  273|    168|		}
  274|   215k|	}
  275|       |
  276|  1.80k|	return JSMN_SUCCESS;
  277|  1.97k|}
jsmn_init:
  283|  2.16k|void jsmn_init(jsmn_parser *parser) {
  284|  2.16k|	parser->pos = 0;
  285|  2.16k|	parser->end = 0;
  286|  2.16k|	parser->toknext = 0;
  287|  2.16k|	parser->toksuper = -1;
  288|  2.16k|}
jsmn.c:jsmn_alloc_token:
   34|   310k|		jsmntok_t *tokens, int num_tokens) {
   35|   310k|	jsmntok_t *tok;
   36|   310k|	if (parser->toknext >= num_tokens) {
  ------------------
  |  Branch (36:6): [True: 10.8k, False: 299k]
  ------------------
   37|  10.8k|		return NULL;
   38|  10.8k|	}
   39|   299k|	tok = &tokens[parser->toknext++];
   40|   299k|	tok->start = tok->end = -1;
   41|   299k|	tok->size = 0;
   42|       |#ifdef JSMN_PARENT_LINKS
   43|       |	tok->parent = -1;
   44|       |#endif
   45|   299k|	return tok;
   46|   310k|}
jsmn.c:jsmn_parse_string:
  110|   117k|		jsmntok_t *tokens, int num_tokens) {
  111|   117k|	jsmntok_t *token;
  112|       |
  113|   117k|	int start = parser->pos;
  114|       |
  115|   117k|	parser->pos++;
  116|       |
  117|       |	/* Skip starting quote */
  118|   316k|	for (; (parser->end > 0 && parser->pos < parser->end) && js[parser->pos] != '\0'; parser->pos++) {
  ------------------
  |  Branch (118:10): [True: 316k, False: 0]
  |  Branch (118:29): [True: 316k, False: 122]
  |  Branch (118:59): [True: 316k, False: 1]
  ------------------
  119|   316k|		char c = js[parser->pos];
  120|       |
  121|       |		/* Quote: end of string */
  122|   316k|		if (c == '\"') {
  ------------------
  |  Branch (122:7): [True: 117k, False: 199k]
  ------------------
  123|   117k|			token = jsmn_alloc_token(parser, tokens, num_tokens);
  124|   117k|			if (token == NULL) {
  ------------------
  |  Branch (124:8): [True: 2.80k, False: 114k]
  ------------------
  125|  2.80k|				parser->pos = start;
  126|  2.80k|				return JSMN_ERROR_NOMEM;
  127|  2.80k|			}
  128|   114k|			jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
  129|       |#ifdef JSMN_PARENT_LINKS
  130|       |			token->parent = parser->toksuper;
  131|       |#endif
  132|   114k|			return JSMN_SUCCESS;
  133|   117k|		}
  134|       |
  135|       |		/* Backslash: Quoted symbol expected */
  136|   199k|		if (c == '\\') {
  ------------------
  |  Branch (136:7): [True: 24.0k, False: 175k]
  ------------------
  137|  24.0k|			parser->pos++;
  138|  24.0k|			if (parser->end > 0 && parser->pos >= parser->end) {
  ------------------
  |  Branch (138:8): [True: 24.0k, False: 0]
  |  Branch (138:27): [True: 4, False: 24.0k]
  ------------------
  139|      4|				parser->pos = start;
  140|      4|				return JSMN_ERROR_INVAL;
  141|      4|			}
  142|  24.0k|			switch (js[parser->pos]) {
  143|       |				/* Allowed escaped symbols */
  144|  6.39k|				case '\"': case '/' : case '\\' : case 'b' :
  ------------------
  |  Branch (144:5): [True: 578, False: 23.4k]
  |  Branch (144:16): [True: 546, False: 23.4k]
  |  Branch (144:27): [True: 4.81k, False: 19.1k]
  |  Branch (144:39): [True: 456, False: 23.5k]
  ------------------
  145|  22.6k|				case 'f' : case 'r' : case 'n'  : case 't' :
  ------------------
  |  Branch (145:5): [True: 588, False: 23.4k]
  |  Branch (145:16): [True: 2.00k, False: 21.9k]
  |  Branch (145:27): [True: 13.2k, False: 10.7k]
  |  Branch (145:39): [True: 447, False: 23.5k]
  ------------------
  146|  22.6k|					break;
  147|       |				/* Allows escaped symbol \uXXXX */
  148|  1.30k|				case 'u':
  ------------------
  |  Branch (148:5): [True: 1.30k, False: 22.6k]
  ------------------
  149|       |					/* TODO */
  150|  1.30k|					break;
  151|       |				/* Unexpected symbol */
  152|      1|				default:
  ------------------
  |  Branch (152:5): [True: 1, False: 24.0k]
  ------------------
  153|      1|					parser->pos = start;
  154|      1|					return JSMN_ERROR_INVAL;
  155|  24.0k|			}
  156|  24.0k|		}
  157|   199k|	}
  158|    123|	parser->pos = start;
  159|    123|	return JSMN_ERROR_PART;
  160|   117k|}
jsmn.c:jsmn_fill_token:
   52|   141k|                            int start, int end) {
   53|   141k|	token->type = type;
   54|   141k|	token->start = start;
   55|   141k|	token->end = end;
   56|   141k|	token->size = 0;
   57|   141k|}
jsmn.c:jsmn_parse_primitive:
   63|  28.3k|		jsmntok_t *tokens, int num_tokens) {
   64|  28.3k|	jsmntok_t *token;
   65|  28.3k|	int start;
   66|       |
   67|  28.3k|	start = parser->pos;
   68|       |
   69|  93.5k|	for (; (parser->end > 0 && parser->pos < parser->end) && js[parser->pos] != '\0'; parser->pos++) {
  ------------------
  |  Branch (69:10): [True: 93.5k, False: 0]
  |  Branch (69:29): [True: 92.8k, False: 657]
  |  Branch (69:59): [True: 92.8k, False: 1]
  ------------------
   70|  92.8k|		switch (js[parser->pos]) {
   71|      0|#ifndef JSMN_STRICT
   72|       |			/* In strict mode primitive must be followed by "," or "}" or "]" */
   73|  8.35k|			case ':':
  ------------------
  |  Branch (73:4): [True: 8.35k, False: 84.5k]
  ------------------
   74|  8.35k|#endif
   75|  18.5k|			case '\t' : case '\r' : case '\n' : case ' ' :
  ------------------
  |  Branch (75:4): [True: 234, False: 92.6k]
  |  Branch (75:16): [True: 2.53k, False: 90.3k]
  |  Branch (75:28): [True: 7.11k, False: 85.7k]
  |  Branch (75:40): [True: 323, False: 92.5k]
  ------------------
   76|  27.6k|			case ','  : case ']'  : case '}' :
  ------------------
  |  Branch (76:4): [True: 2.16k, False: 90.7k]
  |  Branch (76:16): [True: 5.76k, False: 87.1k]
  |  Branch (76:28): [True: 1.15k, False: 91.7k]
  ------------------
   77|  27.6k|				goto found;
   78|  65.2k|			default:
  ------------------
  |  Branch (78:4): [True: 65.2k, False: 27.6k]
  ------------------
   79|  65.2k|				break;
   80|  92.8k|		}
   81|  65.2k|		if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
  ------------------
  |  Branch (81:7): [True: 17, False: 65.2k]
  |  Branch (81:31): [True: 1, False: 65.2k]
  ------------------
   82|     18|			parser->pos = start;
   83|     18|			return JSMN_ERROR_INVAL;
   84|     18|		}
   85|  65.2k|	}
   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|  28.3k|found:
   93|  28.3k|	token = jsmn_alloc_token(parser, tokens, num_tokens);
   94|  28.3k|	if (token == NULL) {
  ------------------
  |  Branch (94:6): [True: 1.08k, False: 27.2k]
  ------------------
   95|  1.08k|		parser->pos = start;
   96|  1.08k|		return JSMN_ERROR_NOMEM;
   97|  1.08k|	}
   98|  27.2k|	jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
   99|       |#ifdef JSMN_PARENT_LINKS
  100|       |	token->parent = parser->toksuper;
  101|       |#endif
  102|  27.2k|	parser->pos--;
  103|  27.2k|	return JSMN_SUCCESS;
  104|  28.3k|}

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|   195k|{
  316|   195k|    return (plist_t) node_create(NULL, data);
  317|   195k|}
plist_get_data:
  320|  16.3M|{
  321|  16.3M|    if (!node)
  ------------------
  |  Branch (321:9): [True: 0, False: 16.3M]
  ------------------
  322|      0|        return NULL;
  323|  16.3M|    return (plist_data_t)((node_t)node)->data;
  324|  16.3M|}
plist_new_plist_data:
  327|   195k|{
  328|   195k|    plist_data_t data = (plist_data_t) calloc(sizeof(struct plist_data_s), 1);
  329|   195k|    return data;
  330|   195k|}
plist_free_data:
  358|   195k|{
  359|   195k|    if (data)
  ------------------
  |  Branch (359:9): [True: 195k, False: 0]
  ------------------
  360|   195k|    {
  361|   195k|        switch (data->type)
  362|   195k|        {
  363|  66.2k|        case PLIST_KEY:
  ------------------
  |  Branch (363:9): [True: 66.2k, False: 128k]
  ------------------
  364|   101k|        case PLIST_STRING:
  ------------------
  |  Branch (364:9): [True: 35.1k, False: 159k]
  ------------------
  365|   101k|            free(data->strval);
  366|   101k|            break;
  367|      0|        case PLIST_DATA:
  ------------------
  |  Branch (367:9): [True: 0, False: 195k]
  ------------------
  368|      0|            free(data->buff);
  369|      0|            break;
  370|  58.1k|        case PLIST_ARRAY:
  ------------------
  |  Branch (370:9): [True: 58.1k, False: 136k]
  ------------------
  371|  58.1k|            ptr_array_free((ptrarray_t*)data->hashtable);
  372|  58.1k|            break;
  373|  12.8k|        case PLIST_DICT:
  ------------------
  |  Branch (373:9): [True: 12.8k, False: 182k]
  ------------------
  374|  12.8k|            hash_table_destroy((hashtable_t*)data->hashtable);
  375|  12.8k|            break;
  376|  22.7k|        default:
  ------------------
  |  Branch (376:9): [True: 22.7k, False: 172k]
  ------------------
  377|  22.7k|            break;
  378|   195k|        }
  379|   195k|        free(data);
  380|   195k|    }
  381|   195k|}
plist_new_dict:
  404|  12.8k|{
  405|  12.8k|    plist_data_t data = plist_new_plist_data();
  406|  12.8k|    data->type = PLIST_DICT;
  407|  12.8k|    return plist_new_node(data);
  408|  12.8k|}
plist_new_array:
  411|  58.1k|{
  412|  58.1k|    plist_data_t data = plist_new_plist_data();
  413|  58.1k|    data->type = PLIST_ARRAY;
  414|  58.1k|    return plist_new_node(data);
  415|  58.1k|}
plist_new_bool:
  437|  10.0k|{
  438|  10.0k|    plist_data_t data = plist_new_plist_data();
  439|  10.0k|    data->type = PLIST_BOOLEAN;
  440|  10.0k|    data->boolval = val;
  441|  10.0k|    data->length = sizeof(uint8_t);
  442|  10.0k|    return plist_new_node(data);
  443|  10.0k|}
plist_new_int:
  455|  3.47k|{
  456|  3.47k|    plist_data_t data = plist_new_plist_data();
  457|  3.47k|    data->type = PLIST_INT;
  458|  3.47k|    data->intval = val;
  459|  3.47k|    data->length = sizeof(uint64_t);
  460|  3.47k|    return plist_new_node(data);
  461|  3.47k|}
plist_new_real:
  473|  1.99k|{
  474|  1.99k|    plist_data_t data = plist_new_plist_data();
  475|  1.99k|    data->type = PLIST_REAL;
  476|  1.99k|    data->realval = val;
  477|  1.99k|    data->length = sizeof(double);
  478|  1.99k|    return plist_new_node(data);
  479|  1.99k|}
plist_free:
  510|  5.52k|{
  511|  5.52k|    if (plist)
  ------------------
  |  Branch (511:9): [True: 4.74k, False: 788]
  ------------------
  512|  4.74k|    {
  513|  4.74k|        plist_free_node((node_t)plist);
  514|  4.74k|    }
  515|  5.52k|}
plist_array_append_item:
  680|  53.9k|{
  681|  53.9k|    if (!item) {
  ------------------
  |  Branch (681:9): [True: 0, False: 53.9k]
  ------------------
  682|      0|        return;
  683|      0|    }
  684|  53.9k|    if (node && PLIST_ARRAY == plist_get_node_type(node))
  ------------------
  |  Branch (684:9): [True: 53.9k, False: 0]
  |  Branch (684:17): [True: 53.9k, False: 0]
  ------------------
  685|  53.9k|    {
  686|  53.9k|        node_attach((node_t)node, (node_t)item);
  687|  53.9k|        _plist_array_post_insert(node, item, -1);
  688|  53.9k|    }
  689|  53.9k|}
plist_dict_get_item:
  830|  70.1k|{
  831|  70.1k|    plist_t ret = NULL;
  832|       |
  833|  70.1k|    if (node && PLIST_DICT == plist_get_node_type(node))
  ------------------
  |  Branch (833:9): [True: 70.1k, False: 0]
  |  Branch (833:17): [True: 70.1k, False: 0]
  ------------------
  834|  70.1k|    {
  835|  70.1k|        plist_data_t data = plist_get_data(node);
  836|  70.1k|        hashtable_t *ht = (hashtable_t*)data->hashtable;
  837|  70.1k|        if (ht) {
  ------------------
  |  Branch (837:13): [True: 1.08k, False: 69.0k]
  ------------------
  838|  1.08k|            struct plist_data_s sdata;
  839|  1.08k|            sdata.strval = (char*)key;
  840|  1.08k|            sdata.length = strlen(key);
  841|  1.08k|            ret = (plist_t)hash_table_lookup(ht, &sdata);
  842|  69.0k|        } else {
  843|  69.0k|            plist_t current = NULL;
  844|  69.0k|            for (current = (plist_t)node_first_child((node_t)node);
  845|  7.99M|                current;
  ------------------
  |  Branch (845:17): [True: 7.93M, False: 65.7k]
  ------------------
  846|  7.92M|                current = (plist_t)node_next_sibling(node_next_sibling((node_t)current)))
  847|  7.93M|            {
  848|  7.93M|                data = plist_get_data(current);
  849|  7.93M|                assert( PLIST_KEY == plist_get_node_type(current) );
  850|       |
  851|  7.93M|                if (data && !strcmp(key, data->strval))
  ------------------
  |  Branch (851:21): [True: 7.93M, False: 0]
  |  Branch (851:29): [True: 3.25k, False: 7.92M]
  ------------------
  852|  3.25k|                {
  853|  3.25k|                    ret = (plist_t)node_next_sibling((node_t)current);
  854|  3.25k|                    break;
  855|  3.25k|                }
  856|  7.93M|            }
  857|  69.0k|        }
  858|  70.1k|    }
  859|  70.1k|    return ret;
  860|  70.1k|}
plist_dict_set_item:
  863|  70.1k|{
  864|  70.1k|    if (!item) {
  ------------------
  |  Branch (864:9): [True: 0, False: 70.1k]
  ------------------
  865|      0|        return;
  866|      0|    }
  867|  70.1k|    if (node && PLIST_DICT == plist_get_node_type(node)) {
  ------------------
  |  Branch (867:9): [True: 70.1k, False: 0]
  |  Branch (867:17): [True: 70.1k, False: 0]
  ------------------
  868|  70.1k|        plist_t old_item = plist_dict_get_item(node, key);
  869|  70.1k|        plist_t key_node = NULL;
  870|  70.1k|        if (old_item) {
  ------------------
  |  Branch (870:13): [True: 3.85k, False: 66.2k]
  ------------------
  871|  3.85k|            int idx = plist_free_node((node_t)old_item);
  872|  3.85k|            assert(idx >= 0);
  873|  3.85k|            if (idx < 0) {
  ------------------
  |  Branch (873:17): [True: 0, False: 3.85k]
  ------------------
  874|      0|                return;
  875|      0|            }
  876|  3.85k|            node_insert((node_t)node, idx, (node_t)item);
  877|  3.85k|            key_node = node_prev_sibling((node_t)item);
  878|  66.2k|        } else {
  879|  66.2k|            key_node = plist_new_key(key);
  880|  66.2k|            node_attach((node_t)node, (node_t)key_node);
  881|  66.2k|            node_attach((node_t)node, (node_t)item);
  882|  66.2k|        }
  883|       |
  884|  70.1k|        hashtable_t *ht = (hashtable_t*)((plist_data_t)((node_t)node)->data)->hashtable;
  885|  70.1k|        if (ht) {
  ------------------
  |  Branch (885:13): [True: 1.08k, False: 69.0k]
  ------------------
  886|       |            /* store pointer to item in hash table */
  887|  1.08k|            hash_table_insert(ht, (plist_data_t)((node_t)key_node)->data, item);
  888|  69.0k|        } else {
  889|  69.0k|            if (((node_t)node)->count > 500) {
  ------------------
  |  Branch (889:17): [True: 245, False: 68.7k]
  ------------------
  890|       |                /* make new hash table */
  891|    245|                ht = hash_table_new(dict_key_hash, dict_key_compare, NULL);
  892|       |                /* calculate the hashes for all entries we have so far */
  893|    245|                plist_t current = NULL;
  894|    245|                for (current = (plist_t)node_first_child((node_t)node);
  895|  61.7k|                     ht && current;
  ------------------
  |  Branch (895:22): [True: 61.7k, False: 0]
  |  Branch (895:28): [True: 61.4k, False: 245]
  ------------------
  896|  61.4k|                     current = (plist_t)node_next_sibling(node_next_sibling((node_t)current)))
  897|  61.4k|                {
  898|  61.4k|                    hash_table_insert(ht, ((node_t)current)->data, node_next_sibling((node_t)current));
  899|  61.4k|                }
  900|    245|                ((plist_data_t)((node_t)node)->data)->hashtable = ht;
  901|    245|            }
  902|  69.0k|        }
  903|  70.1k|    }
  904|  70.1k|}
plist_get_node_type:
 1029|  8.12M|{
 1030|  8.12M|    if (node)
  ------------------
  |  Branch (1030:9): [True: 8.12M, False: 0]
  ------------------
 1031|  8.12M|    {
 1032|  8.12M|        plist_data_t data = plist_get_data(node);
 1033|  8.12M|        if (data)
  ------------------
  |  Branch (1033:13): [True: 8.12M, False: 0]
  ------------------
 1034|  8.12M|            return data->type;
 1035|  8.12M|    }
 1036|      0|    return PLIST_NONE;
 1037|  8.12M|}
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|   195k|{
  385|   195k|    plist_data_t data = NULL;
  386|   195k|    int node_index = node_detach(node->parent, node);
  387|   195k|    data = plist_get_data(node);
  388|   195k|    plist_free_data(data);
  389|   195k|    node->data = NULL;
  390|       |
  391|   195k|    node_t ch;
  392|   381k|    for (ch = node_first_child(node); ch; ) {
  ------------------
  |  Branch (392:39): [True: 186k, False: 195k]
  ------------------
  393|   186k|        node_t next = node_next_sibling(ch);
  394|   186k|        plist_free_node(ch);
  395|   186k|        ch = next;
  396|   186k|    }
  397|       |
  398|   195k|    node_destroy(node);
  399|       |
  400|   195k|    return node_index;
  401|   195k|}
plist.c:_plist_array_post_insert:
  634|  53.9k|{
  635|  53.9k|    ptrarray_t *pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable;
  636|  53.9k|    if (pa) {
  ------------------
  |  Branch (636:9): [True: 8.11k, False: 45.8k]
  ------------------
  637|       |        /* store pointer to item in array */
  638|  8.11k|        ptr_array_insert(pa, item, n);
  639|  45.8k|    } else {
  640|  45.8k|        if (((node_t)node)->count > 100) {
  ------------------
  |  Branch (640:13): [True: 103, False: 45.7k]
  ------------------
  641|       |            /* make new lookup array */
  642|    103|            pa = ptr_array_new(128);
  643|    103|            plist_t current = NULL;
  644|    103|            for (current = (plist_t)node_first_child((node_t)node);
  645|  10.5k|                 pa && current;
  ------------------
  |  Branch (645:18): [True: 10.5k, False: 0]
  |  Branch (645:24): [True: 10.4k, False: 103]
  ------------------
  646|  10.4k|                 current = (plist_t)node_next_sibling((node_t)current))
  647|  10.4k|            {
  648|  10.4k|                ptr_array_add(pa, current);
  649|  10.4k|            }
  650|    103|            ((plist_data_t)((node_t)node)->data)->hashtable = pa;
  651|    103|        }
  652|  45.8k|    }
  653|  53.9k|}
plist.c:plist_new_key:
  419|  66.2k|{
  420|  66.2k|    plist_data_t data = plist_new_plist_data();
  421|  66.2k|    data->type = PLIST_KEY;
  422|  66.2k|    data->strval = strdup(val);
  423|  66.2k|    data->length = strlen(val);
  424|  66.2k|    return plist_new_node(data);
  425|  66.2k|}
plist.c:dict_key_hash:
  333|  63.6k|{
  334|  63.6k|    plist_data_t keydata = (plist_data_t)data;
  335|  63.6k|    unsigned int hash = 5381;
  336|  63.6k|    size_t i;
  337|  63.6k|    char *str = keydata->strval;
  338|   175k|    for (i = 0; i < keydata->length; str++, i++) {
  ------------------
  |  Branch (338:17): [True: 112k, False: 63.6k]
  ------------------
  339|   112k|        hash = ((hash << 5) + hash) + *str;
  340|   112k|    }
  341|  63.6k|    return hash;
  342|  63.6k|}
plist.c:dict_key_compare:
  345|  3.68k|{
  346|  3.68k|    plist_data_t data_a = (plist_data_t)a;
  347|  3.68k|    plist_data_t data_b = (plist_data_t)b;
  348|  3.68k|    if (data_a->strval == NULL || data_b->strval == NULL) {
  ------------------
  |  Branch (348:9): [True: 0, False: 3.68k]
  |  Branch (348:35): [True: 0, False: 3.68k]
  ------------------
  349|      0|        return FALSE;
  ------------------
  |  |   32|      0|#define FALSE 0
  ------------------
  350|      0|    }
  351|  3.68k|    if (data_a->length != data_b->length) {
  ------------------
  |  Branch (351:9): [True: 1.85k, False: 1.83k]
  ------------------
  352|  1.85k|        return FALSE;
  ------------------
  |  |   32|  1.85k|#define FALSE 0
  ------------------
  353|  1.85k|    }
  354|  1.83k|    return (strcmp(data_a->strval, data_b->strval) == 0) ? TRUE : FALSE;
  ------------------
  |  |   28|  1.19k|#define TRUE 1
  ------------------
                  return (strcmp(data_a->strval, data_b->strval) == 0) ? TRUE : FALSE;
  ------------------
  |  |   32|    640|#define FALSE 0
  ------------------
  |  Branch (354:12): [True: 1.19k, False: 640]
  ------------------
  355|  3.68k|}

ptr_array_new:
   25|    103|{
   26|    103|	ptrarray_t *pa = (ptrarray_t*)malloc(sizeof(ptrarray_t));
   27|    103|	pa->pdata = (void**)malloc(sizeof(void*) * capacity);
   28|    103|	pa->capacity = capacity;
   29|    103|	pa->capacity_step = (capacity > 4096) ? 4096 : capacity;
  ------------------
  |  Branch (29:22): [True: 0, False: 103]
  ------------------
   30|    103|	pa->len = 0;
   31|    103|	return pa;
   32|    103|}
ptr_array_free:
   35|  58.1k|{
   36|  58.1k|	if (!pa) return;
  ------------------
  |  Branch (36:6): [True: 58.0k, False: 103]
  ------------------
   37|    103|	if (pa->pdata) {
  ------------------
  |  Branch (37:6): [True: 103, False: 0]
  ------------------
   38|    103|		free(pa->pdata);
   39|    103|	}
   40|    103|	free(pa);
   41|    103|}
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.4k|{
   62|  10.4k|	ptr_array_insert(pa, data, -1);
   63|  10.4k|}

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|}

