-/* Parses a list of sort keys and returns a struct sort_criteria
- based on it. Returns a null pointer on error.
- If SAW_DIRECTION is nonnull, sets *SAW_DIRECTION to true if at
- least one parenthesized sort direction was specified, false
- otherwise. */
-struct sort_criteria *
-sort_parse_criteria (const struct dictionary *dict,
- struct variable ***vars, int *var_cnt,
- bool *saw_direction)
-{
- struct sort_criteria *criteria;
- struct variable **local_vars = NULL;
- size_t local_var_cnt;
-
- assert ((vars == NULL) == (var_cnt == NULL));
- if (vars == NULL)
- {
- vars = &local_vars;
- var_cnt = &local_var_cnt;
- }
-
- criteria = xmalloc (sizeof *criteria);
- criteria->crits = NULL;
- criteria->crit_cnt = 0;
-
- *vars = NULL;
- *var_cnt = 0;
- if (saw_direction != NULL)
- *saw_direction = false;
-
- do
- {
- int prev_var_cnt = *var_cnt;
- enum sort_direction direction;
-
- /* Variables. */
- if (!parse_variables (dict, vars, var_cnt,
- PV_NO_DUPLICATE | PV_APPEND | PV_NO_SCRATCH))
- goto error;
-
- /* Sort direction. */
- if (lex_match ('('))
- {
- if (lex_match_id ("D") || lex_match_id ("DOWN"))
- direction = SRT_DESCEND;
- else if (lex_match_id ("A") || lex_match_id ("UP"))
- direction = SRT_ASCEND;
- else
- {
- msg (SE, _("`A' or `D' expected inside parentheses."));
- goto error;
- }
- if (!lex_match (')'))
- {
- msg (SE, _("`)' expected."));
- goto error;
- }
- *saw_direction = true;
- }
- else
- direction = SRT_ASCEND;
-
- criteria->crits = xrealloc (criteria->crits,
- sizeof *criteria->crits * *var_cnt);
- criteria->crit_cnt = *var_cnt;
- for (; prev_var_cnt < criteria->crit_cnt; prev_var_cnt++)
- {
- struct sort_criterion *c = &criteria->crits[prev_var_cnt];
- c->fv = (*vars)[prev_var_cnt]->fv;
- c->width = (*vars)[prev_var_cnt]->width;
- c->dir = direction;
- }
- }
- while (token != '.' && token != '/');
-
- free (local_vars);
- return criteria;
-
- error:
- free (local_vars);
- sort_destroy_criteria (criteria);
- return NULL;
-}
-
-/* Destroys a SORT CASES program. */
-void
-sort_destroy_criteria (struct sort_criteria *criteria)
-{
- if (criteria != NULL)
- {
- free (criteria->crits);
- free (criteria);
- }
-}