+struct feature {
+ struct feature *next;
+ char name[];
+};
+
+static struct feature *enable;
+static struct feature *disable;
+
+static void
+ao_scheme_add_feature(struct feature **list, char *name)
+{
+ struct feature *feature = malloc (sizeof (struct feature) + strlen(name) + 1);
+ strcpy(feature->name, name);
+ feature->next = *list;
+ *list = feature;
+}
+
+static bool
+_ao_scheme_has_feature(struct feature *list, const char *name, bool skip_undef)
+{
+ if (skip_undef && !strcmp(name, "UNDEF"))
+ return false;
+
+ while (list) {
+ if (!strcmp(list->name, name))
+ return true;
+ list = list->next;
+ }
+ return false;
+}
+
+static bool
+ao_scheme_has_undef(struct feature *list)
+{
+ return _ao_scheme_has_feature(list, "UNDEF", false);
+}
+
+static bool
+ao_scheme_has_feature(struct feature *list, const char *name)
+{
+ return _ao_scheme_has_feature(list, name, true);
+}
+
+static void
+ao_scheme_add_features(struct feature **list, const char *names)
+{
+ char *saveptr = NULL;
+ char *name;
+ char *copy = strdup(names);
+ char *save = copy;
+
+ while ((name = strtok_r(copy, ",", &saveptr)) != NULL) {
+ copy = NULL;
+ if (!ao_scheme_has_feature(*list, name))
+ ao_scheme_add_feature(list, name);
+ }
+ free(save);
+}
+