+ /* string not found, add it */
+ off = add_new_string(rules, str, len + 1);
+
+ /* grow trie nodes if needed */
+ if (rules->trie_nodes_cur >= rules->trie_nodes_max) {
+ struct trie_node *nodes;
+ unsigned int add;
+
+ /* double the buffer size */
+ add = rules->trie_nodes_max;
+ if (add < 8)
+ add = 8;
+
+ nodes = realloc(rules->trie_nodes, (rules->trie_nodes_max + add) * sizeof(struct trie_node));
+ if (nodes == NULL)
+ return -1;
+ dbg(rules->udev, "extend trie nodes from %u to %u\n",
+ rules->trie_nodes_max, rules->trie_nodes_max + add);
+ rules->trie_nodes = nodes;
+ rules->trie_nodes_max += add;
+ }
+
+ /* get a new node */
+ new_node_idx = rules->trie_nodes_cur;
+ rules->trie_nodes_cur++;
+ new_node = &rules->trie_nodes[new_node_idx];
+ memset(new_node, 0x00, sizeof(struct trie_node));
+ new_node->value_off = off;
+ new_node->value_len = len;
+ new_node->key = key;
+
+ /* join the parent's child list */
+ parent = &rules->trie_nodes[node_idx];
+ if (parent->child_idx == 0) {
+ parent->child_idx = new_node_idx;
+ } else {
+ struct trie_node *last_child;
+
+ last_child = &rules->trie_nodes[parent->last_child_idx];
+ last_child->next_child_idx = new_node_idx;
+ }
+ parent->last_child_idx = new_node_idx;
+ return off;
+}
+
+static int add_token(struct udev_rules *rules, struct token *token)
+{