PRINT SPACE: Improve error messages.
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 12 Sep 2022 16:34:59 +0000 (09:34 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Mon, 12 Sep 2022 16:34:59 +0000 (09:34 -0700)
src/language/data-io/print-space.c
tests/language/data-io/print-space.at

index 7a16d818cb4f205fd7669365fa10a10b57cba64a..7e2f9b58ae7d66b25bbf535deeabadc12471ffb8 100644 (file)
@@ -39,6 +39,7 @@ struct print_space_trns
   {
     struct dfm_writer *writer;  /* Output data file. */
     struct expression *expr;   /* Number of lines; NULL means 1. */
+    struct msg_location *expr_location;
   };
 
 static const struct trns_class print_space_class;
@@ -46,10 +47,9 @@ static const struct trns_class print_space_class;
 int
 cmd_print_space (struct lexer *lexer, struct dataset *ds)
 {
-  struct print_space_trns *trns;
   struct file_handle *handle = NULL;
   struct expression *expr = NULL;
-  struct dfm_writer *writer;
+  struct msg_location *expr_location = NULL;
   char *encoding = NULL;
 
   if (lex_match_id (lexer, "OUTFILE"))
@@ -76,7 +76,13 @@ cmd_print_space (struct lexer *lexer, struct dataset *ds)
 
   if (lex_token (lexer) != T_ENDCMD)
     {
+      int start_ofs = lex_ofs (lexer);
       expr = expr_parse (lexer, ds, VAL_NUMERIC);
+      int end_ofs = lex_ofs (lexer) - 1;
+      expr_location = lex_ofs_location (lexer, start_ofs, end_ofs);
+      if (!expr)
+        goto error;
+
       if (lex_token (lexer) != T_ENDCMD)
        {
           lex_error (lexer, _("Syntax error expecting end of command."));
@@ -86,26 +92,31 @@ cmd_print_space (struct lexer *lexer, struct dataset *ds)
   else
     expr = NULL;
 
+  struct dfm_writer *writer = NULL;
   if (handle != NULL)
     {
       writer = dfm_open_writer (handle, encoding);
       if (writer == NULL)
         goto error;
     }
-  else
-    writer = NULL;
 
-  trns = xmalloc (sizeof *trns);
-  trns->writer = writer;
-  trns->expr = expr;
+  struct print_space_trns *trns = xmalloc (sizeof *trns);
+  *trns = (struct print_space_trns) {
+    .writer = writer,
+    .expr = expr,
+    .expr_location = expr_location,
+  };
 
   add_transformation (ds, &print_space_class, trns);
   fh_unref (handle);
+  free (encoding);
   return CMD_SUCCESS;
 
 error:
+  msg_location_destroy (expr_location);
   fh_unref (handle);
   expr_free (expr);
+  free (encoding);
   return CMD_FAILURE;
 }
 
@@ -122,10 +133,12 @@ print_space_trns_proc (void *t_, struct ccase **c,
     {
       double f = expr_evaluate_num (trns->expr, *c, case_num);
       if (f == SYSMIS)
-        msg (SW, _("The expression on %s evaluated to the "
-                   "system-missing value."), "PRINT SPACE");
+        msg_at (SW, trns->expr_location,
+                _("The expression on %s evaluated to the "
+                  "system-missing value."), "PRINT SPACE");
       else if (f < 0 || f > INT_MAX)
-        msg (SW, _("The expression on %s evaluated to %g."), "PRINT SPACE", f);
+        msg_at (SW, trns->expr_location,
+                _("The expression on %s evaluated to %g."), "PRINT SPACE", f);
       else
         n = f;
     }
@@ -149,6 +162,7 @@ print_space_trns_free (void *trns_)
   struct print_space_trns *trns = trns_;
   bool ok = dfm_close_writer (trns->writer);
   expr_free (trns->expr);
+  msg_location_destroy (trns->expr_location);
   free (trns);
   return ok;
 }
index 65695f88056a76f2feba3d7eb6de1415ee5cdca0..9cd621cf52592cb11623bba3d5644c979f6c4869 100644 (file)
@@ -99,3 +99,55 @@ AT_CHECK([cat output.txt], [0], [dnl
  @&t@
 ])
 AT_CLEANUP
+
+AT_SETUP([PRINT SPACE syntax errors])
+AT_DATA([print-space.sps], [dnl
+DATA LIST NOTABLE /x 1.
+PRINT SPACE OUTFILE=**.
+PRINT SPACE OUTFILE='out.txt' ENCODING=**.
+PRINT SPACE **.
+PRINT SPACE 1 'xyzzy'.
+])
+AT_CHECK([pspp -O format=csv print-space.sps], [1], [dnl
+"print-space.sps:2.21-2.22: error: PRINT SPACE: Syntax error expecting a file name or handle name.
+    2 | PRINT SPACE OUTFILE=**.
+      |                     ^~"
+
+"print-space.sps:3.40-3.41: error: PRINT SPACE: Syntax error expecting string.
+    3 | PRINT SPACE OUTFILE='out.txt' ENCODING=**.
+      |                                        ^~"
+
+"print-space.sps:4.13-4.14: error: PRINT SPACE: Syntax error.
+    4 | PRINT SPACE **.
+      |             ^~"
+
+"print-space.sps:5.15-5.21: error: PRINT SPACE: Syntax error expecting end of command.
+    5 | PRINT SPACE 1 'xyzzy'.
+      |               ^~~~~~~"
+])
+AT_CLEANUP
+
+AT_SETUP([PRINT SPACE evaluation errors])
+AT_DATA([print-space.sps], [dnl
+DATA LIST NOTABLE /x 1.
+BEGIN DATA.
+1
+END DATA.
+PRINT SPACE $SYSMIS.
+PRINT SPACE -1.
+EXECUTE.
+])
+AT_CHECK([pspp -O format=csv print-space.sps], [0], [dnl
+"print-space.sps:5.13-5.19: warning: EXECUTE: The expression on PRINT SPACE evaluated to the system-missing value.
+    5 | PRINT SPACE $SYSMIS.
+      |             ^~~~~~~"
+
+
+
+"print-space.sps:6.13-6.14: warning: EXECUTE: The expression on PRINT SPACE evaluated to -1.
+    6 | PRINT SPACE -1.
+      |             ^~"
+
+
+])
+AT_CLEANUP