FILE HANDLE: Improve error messages and coding style.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 6 Nov 2022 19:52:58 +0000 (11:52 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 6 Nov 2022 19:52:58 +0000 (11:52 -0800)
src/language/data-io/file-handle.c
tests/language/data-io/file-handle.at

index 01d707c0b96b3e7bea6c6c5cbf2f89b5c013540d..66411794fa5f934b4ab9f60bc42ca6c25622a05e 100644 (file)
@@ -56,8 +56,10 @@ cmd_file_handle (struct lexer *lexer, struct dataset *ds UNUSED)
     goto exit;
 
   handle_name = xstrdup (lex_tokcstr (lexer));
-  if (fh_from_id (handle_name))
+  struct file_handle *fh = fh_from_id (handle_name);
+  if (fh)
     {
+      fh_unref (fh);
       lex_error (lexer, _("File handle %s is already defined.  "
                           "Use %s before redefining a file handle."),
                  handle_name, "CLOSE FILE HANDLE");
@@ -68,6 +70,8 @@ cmd_file_handle (struct lexer *lexer, struct dataset *ds UNUSED)
   if (!lex_force_match (lexer, T_SLASH))
     goto exit;
 
+  int mode_start = 0;
+  int mode_end = 0;
   while (lex_token (lexer) != T_ENDCMD)
     {
       if (lex_match_id (lexer, "NAME"))
@@ -120,6 +124,7 @@ cmd_file_handle (struct lexer *lexer, struct dataset *ds UNUSED)
               lex_sbc_only_once (lexer, "MODE");
               goto exit;
             }
+          mode_start = lex_ofs (lexer) - 1;
           lex_match (lexer, T_EQUALS);
 
           if (lex_match_id (lexer, "CHARACTER"))
@@ -132,9 +137,11 @@ cmd_file_handle (struct lexer *lexer, struct dataset *ds UNUSED)
             mode = MODE_360;
           else
             {
-              lex_error (lexer, NULL);
+              lex_error_expecting (lexer, "CHARACTER", "BINARY",
+                                   "IMAGE", "360");
               goto exit;
             }
+          mode_end = lex_ofs (lexer) - 1;
         }
       else if (lex_match_id (lexer, "ENDS"))
         {
@@ -151,7 +158,7 @@ cmd_file_handle (struct lexer *lexer, struct dataset *ds UNUSED)
             ends = FH_END_CRLF;
           else
             {
-              lex_error (lexer, NULL);
+              lex_error_expecting (lexer, "LF", "CRLF");
               goto exit;
             }
         }
@@ -173,7 +180,7 @@ cmd_file_handle (struct lexer *lexer, struct dataset *ds UNUSED)
             recform = RECFORM_SPANNED;
           else
             {
-              lex_error (lexer, NULL);
+              lex_error_expecting (lexer, "FIXED", "VARIABLE", "SPANNED");
               goto exit;
             }
         }
@@ -238,7 +245,9 @@ cmd_file_handle (struct lexer *lexer, struct dataset *ds UNUSED)
         }
       else
         {
-          msg (SE, _("%s must be specified with %s."), "RECFORM", "MODE=360");
+          lex_ofs_error (lexer, mode_start, mode_end,
+                         _("%s must be specified with %s."),
+                         "RECFORM", "MODE=360");
           goto exit;
         }
       break;
index cd5e10835863ba52922549c5333f12d6ecdd8fe5..74989ba490e6cc7b4b95ccd5ee26c52dc0427d83 100644 (file)
@@ -42,3 +42,107 @@ x
 ])
 AT_CLEANUP
 
+AT_SETUP([FILE HANDLE syntax errors])
+AT_DATA([file-handle.sps], [dnl
+FILE HANDLE **.
+FILE HANDLE x/NAME='x.txt'.
+FILE HANDLE x/NAME='x.txt'.
+FILE HANDLE y **.
+FILE HANDLE y/NAME=**.
+FILE HANDLE y/LRECL=8/LRECL=8.
+FILE HANDLE y/LRECL=**.
+FILE HANDLE y/TABWIDTH=8/TABWIDTH=8.
+FILE HANDLE y/TABWIDTH=**.
+FILE HANDLE y/MODE=CHARACTER/MODE=CHARACTER.
+FILE HANDLE y/MODE=**.
+FILE HANDLE y/ENDS=LF/ENDS=LF.
+FILE HANDLE y/ENDS=**.
+FILE HANDLE y/RECFORM=FIXED/RECFORM=FIXED.
+FILE HANDLE y/RECFORM=**.
+FILE HANDLE y/ENCODING='UTF-8'/ENCODING='UTF-8'.
+FILE HANDLE y/ENCODING=**.
+FILE HANDLE y/TABWIDTH=8.
+FILE HANDLE y/NAME='x.txt'/MODE=360.
+FILE HANDLE y/NAME='x.txt'/MODE=FIXED.
+])
+AT_DATA([insert.sps], [dnl
+INSERT FILE='file-handle.sps' ERROR=IGNORE.
+])
+AT_CHECK([pspp --testing-mode -O format=csv insert.sps], [1], [dnl
+"file-handle.sps:1.13-1.14: error: FILE HANDLE: Syntax error expecting identifier.
+    1 | FILE HANDLE **.
+      |             ^~"
+
+"file-handle.sps:3.13: error: FILE HANDLE: File handle x is already defined.  Use CLOSE FILE HANDLE before redefining a file handle.
+    3 | FILE HANDLE x/NAME='x.txt'.
+      |             ^"
+
+"file-handle.sps:4.15-4.16: error: FILE HANDLE: Syntax error expecting `/'.
+    4 | FILE HANDLE y **.
+      |               ^~"
+
+"file-handle.sps:5.20-5.21: error: FILE HANDLE: Syntax error expecting string.
+    5 | FILE HANDLE y/NAME=**.
+      |                    ^~"
+
+"file-handle.sps:6.23-6.27: error: FILE HANDLE: Subcommand LRECL may only be specified once.
+    6 | FILE HANDLE y/LRECL=8/LRECL=8.
+      |                       ^~~~~"
+
+"file-handle.sps:7.21-7.22: error: FILE HANDLE: Syntax error expecting positive integer for LRECL.
+    7 | FILE HANDLE y/LRECL=**.
+      |                     ^~"
+
+"file-handle.sps:8.26-8.33: error: FILE HANDLE: Subcommand TABWIDTH may only be specified once.
+    8 | FILE HANDLE y/TABWIDTH=8/TABWIDTH=8.
+      |                          ^~~~~~~~"
+
+"file-handle.sps:9.24-9.25: error: FILE HANDLE: Syntax error expecting positive integer for TABWIDTH.
+    9 | FILE HANDLE y/TABWIDTH=**.
+      |                        ^~"
+
+"file-handle.sps:10.30-10.33: error: FILE HANDLE: Subcommand MODE may only be specified once.
+   10 | FILE HANDLE y/MODE=CHARACTER/MODE=CHARACTER.
+      |                              ^~~~"
+
+"file-handle.sps:11.20-11.21: error: FILE HANDLE: Syntax error expecting CHARACTER, BINARY, IMAGE, or 360.
+   11 | FILE HANDLE y/MODE=**.
+      |                    ^~"
+
+"file-handle.sps:12.23-12.26: error: FILE HANDLE: Subcommand ENDS may only be specified once.
+   12 | FILE HANDLE y/ENDS=LF/ENDS=LF.
+      |                       ^~~~"
+
+"file-handle.sps:13.20-13.21: error: FILE HANDLE: Syntax error expecting LF or CRLF.
+   13 | FILE HANDLE y/ENDS=**.
+      |                    ^~"
+
+"file-handle.sps:14.29-14.35: error: FILE HANDLE: Subcommand RECFORM may only be specified once.
+   14 | FILE HANDLE y/RECFORM=FIXED/RECFORM=FIXED.
+      |                             ^~~~~~~"
+
+"file-handle.sps:15.23-15.24: error: FILE HANDLE: Syntax error expecting FIXED, VARIABLE, or SPANNED.
+   15 | FILE HANDLE y/RECFORM=**.
+      |                       ^~"
+
+"file-handle.sps:16.32-16.39: error: FILE HANDLE: Subcommand ENCODING may only be specified once.
+   16 | FILE HANDLE y/ENCODING='UTF-8'/ENCODING='UTF-8'.
+      |                                ^~~~~~~~"
+
+"file-handle.sps:17.24-17.25: error: FILE HANDLE: Syntax error expecting string.
+   17 | FILE HANDLE y/ENCODING=**.
+      |                        ^~"
+
+"file-handle.sps:18.1-18.25: error: FILE HANDLE: Required subcommand NAME was not specified.
+   18 | FILE HANDLE y/TABWIDTH=8.
+      | ^~~~~~~~~~~~~~~~~~~~~~~~~"
+
+"file-handle.sps:19.28-19.35: error: FILE HANDLE: RECFORM must be specified with MODE=360.
+   19 | FILE HANDLE y/NAME='x.txt'/MODE=360.
+      |                            ^~~~~~~~"
+
+"file-handle.sps:20.33-20.37: error: FILE HANDLE: Syntax error expecting CHARACTER, BINARY, IMAGE, or 360.
+   20 | FILE HANDLE y/NAME='x.txt'/MODE=FIXED.
+      |                                 ^~~~~"
+])
+AT_CLEANUP
\ No newline at end of file