+ if (!dictionary->size)
+ dictionary->dict = nmem_malloc(nmem, (dictionary->size = 50) * sizeof(char*));
+ else if (dictionary->num + 1 > dictionary->size)
+ {
+ char **tmp = nmem_malloc(nmem, dictionary->size * 2 * sizeof(char*));
+ memcpy(tmp, dictionary->dict, dictionary->size * sizeof(char*));
+ dictionary->dict = tmp;
+ dictionary->size *= 2;
+ }
+ dictionary->dict[dictionary->num++] = nmem_strdup(nmem, set->name);
+}
+
+// This is called from grep_databases -- adds/overrides setting for a target
+// This is also where the rules for precedence of settings are implemented
+static void update_database(void *context, struct database *db)
+{
+ struct setting *set = (struct setting *) context;
+ struct setting *s, **sp;
+ int offset;
+
+ // Is this the right database?
+ if (!match_zurl(db->url, set->target))
+ return;
+
+ if ((offset = settings_offset_cprefix(set->name)) < 0)
+ abort(); // Should never get here
+
+ // First we determine if this setting is overriding any existing settings
+ // with the same name.
+ for (s = db->settings[offset], sp = &db->settings[offset]; s;
+ sp = &s->next, s = s->next)
+ if (!strcmp(s->name, set->name))
+ {
+ if (s->precedence < set->precedence)
+ // We discard the value (nmem keeps track of the space)
+ *sp = (*sp)->next; // unlink value from existing setting
+ else if (s->precedence > set->precedence)
+ // Db contains a higher-priority setting. Abort search
+ break;
+ if (zurl_wildcard(s->target) > zurl_wildcard(set->target))
+ // target-specific value trumps wildcard. Delete.
+ *sp = (*sp)->next; // unlink.....
+ else if (!zurl_wildcard(s->target))
+ // Db already contains higher-priority setting. Abort search
+ break;
+ }
+ if (!s) // s will be null when there are no higher-priority settings -- we add one