+ db->settings = nmem_malloc(nmem, sizeof(struct settings*) * dictionary->num);
+ memset(db->settings, sizeof(struct settings*) * dictionary->num, 0);
+ }
+ if ((offset = settings_offset(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->user, set->user))
+ {
+ if (s->precedence < set->precedence)
+ // We discard the value (nmem keeps track of the space)
+ *sp = (*sp)->next;
+ else if (s->precedence > set->precedence)
+ // Db contains a higher-priority setting. Abort
+ break;
+ if (*s->target == '*' && *set->target != '*')
+ // target-specific value trumps wildcard. Delete.
+ *sp = (*sp)->next;
+ else if (*s->target != '*' && *set->target == '*')
+ // Db already contains higher-priority setting. Abort
+ break;
+ }
+ if (!s) // s will be null when there are no higher-priority settings -- we add one
+ {
+ struct setting *new = nmem_malloc(nmem, sizeof(*new));
+
+ memset(new, sizeof(*new), 0);
+ new->precedence = set->precedence;
+ new->target = nmem_strdup(nmem, set->target);
+ new->name = nmem_strdup(nmem, set->name);
+ new->value = nmem_strdup(nmem, set->value);
+ new->user = nmem_strdup(nmem, set->user);
+ new->next = db->settings[offset];
+ db->settings[offset] = new;