CROSSTABS: Improve error messages and coding style.
[pspp] / src / language / stats / sort-criteria.c
index b8bdbd06f85b658808e7cfd6126a9350b845ab00..92c80640460895a5bdb3dfda143d6240b4ab2f9b 100644 (file)
@@ -42,27 +42,27 @@ parse_sort_criteria (struct lexer *lexer, const struct dictionary *dict,
                      const struct variable ***vars, bool *saw_direction)
 {
   const struct variable **local_vars = NULL;
-  size_t var_cnt = 0;
+  size_t n_vars = 0;
 
-  if (vars == NULL) 
+  if (vars == NULL)
     vars = &local_vars;
   *vars = NULL;
 
   if (saw_direction != NULL)
     *saw_direction = false;
 
+  int start_ofs = lex_ofs (lexer);
   do
     {
-      size_t prev_var_cnt = var_cnt;
-      enum subcase_direction direction;
-      size_t i;
+      size_t prev_n_vars = n_vars;
 
       /* Variables. */
-      if (!parse_variables_const (lexer, dict, vars, &var_cnt,
-                                  PV_APPEND | PV_NO_SCRATCH))
+      if (!parse_variables_const (lexer, dict, vars, &n_vars,
+                                  PV_APPEND | PV_DUPLICATE | PV_NO_SCRATCH))
         goto error;
 
       /* Sort direction. */
+      enum subcase_direction direction;
       if (lex_match (lexer, T_LPAREN))
        {
          if (lex_match_id (lexer, "D") || lex_match_id (lexer, "DOWN"))
@@ -71,26 +71,24 @@ parse_sort_criteria (struct lexer *lexer, const struct dictionary *dict,
             direction = SC_ASCEND;
           else
            {
-             msg (SE, _("`A' or `D' expected inside parentheses."));
-              goto error;
-           }
-         if (!lex_match (lexer, T_RPAREN))
-           {
-             msg (SE, _("`)' expected."));
+              lex_error_expecting (lexer, "A", "D");
               goto error;
            }
+         if (!lex_force_match (lexer, T_RPAREN))
+            goto error;
           if (saw_direction != NULL)
             *saw_direction = true;
        }
       else
         direction = SC_ASCEND;
 
-      for (i = prev_var_cnt; i < var_cnt; i++) 
+      for (size_t i = prev_n_vars; i < n_vars; i++)
         {
           const struct variable *var = (*vars)[i];
           if (!subcase_add_var (ordering, var, direction))
-            msg (SW, _("Variable %s specified twice in sort criteria."),
-                 var_get_name (var)); 
+            lex_ofs_msg (lexer, SW, start_ofs, lex_ofs (lexer) - 1,
+                         _("Variable %s specified twice in sort criteria."),
+                         var_get_name (var));
         }
     }
   while (lex_token (lexer) == T_ID
@@ -100,6 +98,8 @@ parse_sort_criteria (struct lexer *lexer, const struct dictionary *dict,
   return true;
 
 error:
+  subcase_uninit (ordering);
+  subcase_init_empty (ordering);
   free (local_vars);
   if (vars)
     *vars = NULL;