/* Removes from A all of the strings in B. */ void stringi_set_subtract (struct stringi_set *a, const struct stringi_set *b) { struct stringi_set_node *node, *next; if (stringi_set_count (a) < stringi_set_count (b)) { HMAP_FOR_EACH_SAFE (node, next, struct stringi_set_node, hmap_node, &a->hmap) if (stringi_set_find_node__ (b, node->string, node->hmap_node.hash)) stringi_set_delete_node (a, node); }
/* Initializes SET as a new string set that initially contains the same strings as OLD. */ void stringi_set_clone (struct stringi_set *set, const struct stringi_set *old) { const struct stringi_set_node *node; const char *s; stringi_set_init (set); hmap_reserve (&set->hmap, stringi_set_count (old)); STRINGI_SET_FOR_EACH (s, node, old) stringi_set_insert__ (set, xstrdup (s), node->hmap_node.hash); }
/* Checks that SET contains the CNT strings in DATA, that its structure is correct, and that certain operations on SET produce the expected results. */ static void check_stringi_set (struct stringi_set *set, const int data[], size_t cnt) { size_t i; check (stringi_set_is_empty (set) == (cnt == 0)); check (stringi_set_count (set) == cnt); for (i = 0; i < cnt; i++) { const char *s; char copy[16]; char *p; s = make_string (data[i]); check_set_contains (set, s); strcpy (copy, s); for (p = copy; *p != '\0'; p++) { assert (isupper (*p)); *p = tolower (*p); check_set_contains (set, copy); } } check (!stringi_set_contains (set, "xxx")); check (stringi_set_find_node (set, "") == NULL); if (cnt == 0) { check (stringi_set_first (set) == NULL); free (stringi_set_get_array (set)); } else { const struct stringi_set_node *node; char **array; int *data_copy; int left; array = stringi_set_get_array (set); data_copy = xmemdup (data, cnt * sizeof *data); left = cnt; for (node = stringi_set_first (set), i = 0; i < cnt; node = stringi_set_next (set, node), i++) { const char *s = stringi_set_node_get_string (node); size_t j; check (s == array[i]); for (j = 0; j < left; j++) if (!utf8_strcasecmp (s, make_string (data_copy[j]))) { data_copy[j] = data_copy[--left]; goto next; } check_die (); next: ; } check (node == NULL); free (data_copy); free (array); array = stringi_set_get_sorted_array (set); for (i = 0; i < cnt; i++) { if (i > 0) check (utf8_strcasecmp (array[i - 1], array[i]) < 0); check (stringi_set_contains (set, array[i])); } free (array); } }