+/* Parses a variable name from VS. If successful, sets *IDX to
+ the variable's index in VS, *CLASS to the variable's
+ dictionary class, and returns nonzero. Returns zero on
+ failure. */
+static int
+parse_var_idx_class (const struct var_set *vs, int *idx,
+ enum dict_class *class)
+{
+ *idx = parse_vs_variable_idx (vs);
+ if (*idx < 0)
+ return 0;
+
+ *class = dict_class_from_id (var_set_get_var (vs, *idx)->name);
+ return 1;
+}
+
+/* Add the variable from VS with index IDX to the list of
+ variables V that has *NV elements and room for *MV.
+ Uses and updates INCLUDED to avoid duplicates if indicated by
+ PV_OPTS, which also affects what variables are allowed in
+ appropriate ways. */
+static void
+add_variable (struct variable ***v, int *nv, int *mv,
+ char *included, int pv_opts,
+ const struct var_set *vs, int idx)
+{
+ struct variable *add = var_set_get_var (vs, idx);
+
+ if ((pv_opts & PV_NUMERIC) && add->type != NUMERIC)
+ msg (SW, _("%s is not a numeric variable. It will not be "
+ "included in the variable list."), add->name);
+ else if ((pv_opts & PV_STRING) && add->type != ALPHA)
+ msg (SE, _("%s is not a string variable. It will not be "
+ "included in the variable list."), add->name);
+ else if ((pv_opts & PV_NO_SCRATCH)
+ && dict_class_from_id (add->name) == DC_SCRATCH)
+ msg (SE, _("Scratch variables (such as %s) are not allowed "
+ "here."), add->name);
+ else if ((pv_opts & PV_SAME_TYPE) && *nv && add->type != (*v)[0]->type)
+ msg (SE, _("%s and %s are not the same type. All variables in "
+ "this variable list must be of the same type. %s "
+ "will be omitted from list."),
+ (*v)[0]->name, add->name, add->name);
+ else if ((pv_opts & PV_NO_DUPLICATE) && included[idx])
+ msg (SE, _("Variable %s appears twice in variable list."), add->name);
+ else
+ {
+ if (*nv >= *mv)
+ {
+ *mv = 2 * (*nv + 1);
+ *v = xrealloc (*v, *mv * sizeof **v);
+ }
+
+ if ((pv_opts & PV_DUPLICATE) || !included[idx])
+ {
+ (*v)[(*nv)++] = add;
+ if (!(pv_opts & PV_DUPLICATE))
+ included[idx] = 1;
+ }
+ }
+}
+
+/* Adds the variables in VS with indexes FIRST_IDX through
+ LAST_IDX, inclusive, to the list of variables V that has *NV
+ elements and room for *MV. Uses and updates INCLUDED to avoid
+ duplicates if indicated by PV_OPTS, which also affects what
+ variables are allowed in appropriate ways. */
+static void
+add_variables (struct variable ***v, int *nv, int *mv, char *included,
+ int pv_opts,
+ const struct var_set *vs, int first_idx, int last_idx,
+ enum dict_class class)
+{
+ int i;
+
+ for (i = first_idx; i <= last_idx; i++)
+ if (dict_class_from_id (var_set_get_var (vs, i)->name) == class)
+ add_variable (v, nv, mv, included, pv_opts, vs, i);
+}
+