static int trie_node_add_value(struct trie *trie, struct trie_node *node, const char *key, const char *value, const char *filename, uint16_t file_priority, uint32_t line_number) { ssize_t k, v, fn; struct trie_value_entry *val; k = strbuf_add_string(trie->strings, key, strlen(key)); if (k < 0) return k; v = strbuf_add_string(trie->strings, value, strlen(value)); if (v < 0) return v; fn = strbuf_add_string(trie->strings, filename, strlen(filename)); if (fn < 0) return fn; if (node->values_count) { struct trie_value_entry search = { .key_off = k, .value_off = v, }; val = xbsearch_r(&search, node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp, trie); if (val) { /* At this point we have 2 identical properties on the same match-string. * Since we process files in order, we just replace the previous value. */ val->value_off = v; val->filename_off = fn; val->file_priority = file_priority; val->line_number = line_number; return 0; } } /* extend array, add new entry, sort for bisection */ val = reallocarray(node->values, node->values_count + 1, sizeof(struct trie_value_entry)); if (!val) return -ENOMEM; trie->values_count++; node->values = val; node->values[node->values_count].key_off = k; node->values[node->values_count].value_off = v; node->values[node->values_count].filename_off = fn; node->values[node->values_count].file_priority = file_priority; node->values[node->values_count].line_number = line_number; node->values_count++; qsort_r(node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp, trie); return 0; }
static int trie_node_add_value(struct trie *trie, struct trie_node *node, const char *key, const char *value) { ssize_t k, v; struct trie_value_entry *val; k = strbuf_add_string(trie->strings, key, strlen(key)); if (k < 0) return k; v = strbuf_add_string(trie->strings, value, strlen(value)); if (v < 0) return v; if (node->values_count) { struct trie_value_entry search = { .key_off = k, .value_off = v, }; val = xbsearch_r(&search, node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp_r, trie); if (val) { /* replace existing earlier key with new value */ val->value_off = v; return 0; } } /* extend array, add new entry, sort for bisection */ val = realloc(node->values, (node->values_count + 1) * sizeof(struct trie_value_entry)); if (!val) return -ENOMEM; trie->values_count++; node->values = val; node->values[node->values_count].key_off = k; node->values[node->values_count].value_off = v; node->values_count++; trie_values_cmp_param = trie; qsort(node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp); return 0; }