+\f
+struct var_set
+ {
+ size_t (*get_cnt) (struct var_set *);
+ struct variable *(*get_var) (struct var_set *, size_t idx);
+ struct variable *(*lookup_var) (struct var_set *, const char *);
+ void (*destroy) (struct var_set *);
+ void *aux;
+ };
+
+size_t
+var_set_get_cnt (struct var_set *vs)
+{
+ assert (vs != NULL);
+
+ return vs->get_cnt (vs);
+}
+
+struct variable *
+var_set_get_var (struct var_set *vs, size_t idx)
+{
+ assert (vs != NULL);
+ assert (idx < var_set_get_cnt (vs));
+
+ return vs->get_var (vs, idx);
+}
+
+struct variable *
+var_set_lookup_var (struct var_set *vs, const char *name)
+{
+ assert (vs != NULL);
+ assert (name != NULL);
+ assert (strlen (name) < 9);
+
+ return vs->lookup_var (vs, name);
+}
+
+void
+var_set_destroy (struct var_set *vs)
+{
+ if (vs != NULL)
+ vs->destroy (vs);
+}
+\f
+static size_t
+dict_var_set_get_cnt (struct var_set *vs)
+{
+ struct dictionary *d = vs->aux;
+
+ return dict_get_var_cnt (d);
+}
+
+static struct variable *
+dict_var_set_get_var (struct var_set *vs, size_t idx)
+{
+ struct dictionary *d = vs->aux;
+
+ return dict_get_var (d, idx);
+}
+
+static struct variable *
+dict_var_set_lookup_var (struct var_set *vs, const char *name)
+{
+ struct dictionary *d = vs->aux;
+
+ return dict_lookup_var (d, name);
+}
+
+static void
+dict_var_set_destroy (struct var_set *vs)
+{
+ free (vs);
+}
+
+struct var_set *
+var_set_create_from_dict (struct dictionary *d)
+{
+ struct var_set *vs = xmalloc (sizeof *vs);
+ vs->get_cnt = dict_var_set_get_cnt;
+ vs->get_var = dict_var_set_get_var;
+ vs->lookup_var = dict_var_set_lookup_var;
+ vs->destroy = dict_var_set_destroy;
+ vs->aux = d;
+ return vs;
+}
+\f
+struct array_var_set
+ {
+ struct variable **var;
+ size_t var_cnt;
+ struct hsh_table *name_tab;
+ };
+
+static size_t
+array_var_set_get_cnt (struct var_set *vs)
+{
+ struct array_var_set *avs = vs->aux;
+
+ return avs->var_cnt;
+}
+
+static struct variable *
+array_var_set_get_var (struct var_set *vs, size_t idx)
+{
+ struct array_var_set *avs = vs->aux;
+
+ return avs->var[idx];
+}
+
+static struct variable *
+array_var_set_lookup_var (struct var_set *vs, const char *name)
+{
+ struct array_var_set *avs = vs->aux;
+ struct variable v;
+
+ strcpy (v.name, name);
+
+ return hsh_find (avs->name_tab, &v);
+}
+
+static void
+array_var_set_destroy (struct var_set *vs)
+{
+ struct array_var_set *avs = vs->aux;
+
+ hsh_destroy (avs->name_tab);
+ free (avs);
+ free (vs);
+}
+
+struct var_set *
+var_set_create_from_array (struct variable **var, size_t var_cnt)
+{
+ struct var_set *vs;
+ struct array_var_set *avs;
+ size_t i;
+
+ vs = xmalloc (sizeof *vs);
+ vs->get_cnt = array_var_set_get_cnt;
+ vs->get_var = array_var_set_get_var;
+ vs->lookup_var = array_var_set_lookup_var;
+ vs->destroy = array_var_set_destroy;
+ vs->aux = avs = xmalloc (sizeof *avs);
+ avs->var = var;
+ avs->var_cnt = var_cnt;
+ avs->name_tab = hsh_create (2 * var_cnt,
+ compare_variables, hash_variable, NULL,
+ NULL);
+ for (i = 0; i < var_cnt; i++)
+ if (hsh_insert (avs->name_tab, var[i]) != NULL)
+ {
+ var_set_destroy (vs);
+ return NULL;
+ }
+
+ return vs;
+}