Some basic tests.
[pspp] / src / language / data-io / save-translate.c
index f6487c57932e3faad8a64e45adcf570e9ab7b897..a565f4471c3aeef45f34db40c44641b34a620ec9 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2010 Free Software Foundation, Inc.
+   Copyright (C) 2010, 2011, 2013, 2016 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -33,7 +33,6 @@
 #include "language/lexer/lexer.h"
 #include "libpspp/message.h"
 
-#include "xalloc.h"
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
@@ -45,12 +44,11 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
   enum { CSV_FILE = 1, TAB_FILE } type;
 
   struct dictionary *dict;
+  struct case_map_stage *stage;
   struct case_map *map;
   struct casewriter *writer;
   struct file_handle *handle;
 
-  struct csv_writer_options csv_opts;
-
   bool replace;
 
   bool retain_unselected;
@@ -67,6 +65,8 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
   type = 0;
 
   dict = dict_clone (dataset_dict (ds));
+  dict_set_names_must_be_ids (dict, false);
+  stage = NULL;
   map = NULL;
 
   handle = NULL;
@@ -77,15 +77,18 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
   include_var_names = false;
   use_value_labels = false;
   use_print_formats = false;
-  decimal = settings_get_decimal_char (FMT_F);
+  decimal = settings_get_fmt_settings ()->decimal;
   delimiter = 0;
   qualifier = '"';
 
-  case_map_prepare_dict (dict);
+  stage = case_map_stage_create (dict);
   dict_delete_scratch_vars (dict);
 
-  while (lex_match (lexer, T_SLASH))
+  while (lex_token (lexer) != T_ENDCMD)
     {
+      if (!lex_force_match (lexer, T_SLASH))
+        goto error;
+
       if (lex_match_id (lexer, "OUTFILE"))
        {
           if (handle != NULL)
@@ -115,7 +118,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
             type = TAB_FILE;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "CSV", "TAB");
+              lex_error_expecting (lexer, "CSV", "TAB");
               goto error;
             }
         }
@@ -132,7 +135,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
             recode_user_missing = true;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "IGNORE", "RECODE");
+              lex_error_expecting (lexer, "IGNORE", "RECODE");
               goto error;
             }
         }
@@ -145,7 +148,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
             use_value_labels = true;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "VALUES", "LABELS");
+              lex_error_expecting (lexer, "VALUES", "LABELS");
               goto error;
             }
         }
@@ -193,8 +196,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
                     decimal = ',';
                   else
                     {
-                      lex_error (lexer, _("expecting %s or %s"),
-                                 "DOT", "COMMA");
+                      lex_error_expecting (lexer, "DOT", "COMMA");
                       goto error;
                     }
                 }
@@ -207,8 +209,7 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
                     use_print_formats = true;
                   else
                     {
-                      lex_error (lexer, _("expecting %s or %s"),
-                                 "PLAIN", "VARIABLE");
+                      lex_error_expecting (lexer, "PLAIN", "VARIABLE");
                       goto error;
                     }
                 }
@@ -225,56 +226,56 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
             retain_unselected = false;
           else
             {
-              lex_error (lexer, _("expecting %s or %s"), "RETAIN", "DELETE");
+              lex_error_expecting (lexer, "RETAIN", "DELETE");
               goto error;
             }
         }
-      else if (!parse_dict_trim (lexer, dict))
+      else if (!parse_dict_trim (lexer, dict, true))
         goto error;
     }
-  if (lex_end_of_command (lexer) != CMD_SUCCESS)
-    goto error;
 
   if (type == 0)
     {
-      lex_sbc_missing (lexer, "TYPE");
+      lex_sbc_missing ("TYPE");
       goto error;
     }
   else if (handle == NULL)
     {
-      lex_sbc_missing (lexer, "OUTFILE");
+      lex_sbc_missing ("OUTFILE");
       goto error;
     }
-  else if (!replace && fn_exists (fh_get_file_name (handle)))
+  else if (!replace && fn_exists (handle))
     {
-      msg (SE, _("Output file `%s' exists but REPLACE was not specified."),
-           fh_get_file_name (handle));
+      msg (SE, _("Output file `%s' exists but %s was not specified."),
+           fh_get_file_name (handle), "REPLACE");
       goto error;
     }
 
   dict_delete_scratch_vars (dict);
   dict_compact_values (dict);
 
-  csv_opts.recode_user_missing = recode_user_missing;
-  csv_opts.include_var_names = include_var_names;
-  csv_opts.use_value_labels = use_value_labels;
-  csv_opts.use_print_formats = use_print_formats;
-  csv_opts.decimal = decimal;
-  csv_opts.delimiter = (delimiter ? delimiter
-                        : type == TAB_FILE ? '\t'
-                        : decimal == '.' ? ','
-                        : ';');
-  csv_opts.qualifier = qualifier;
-
+  struct csv_writer_options csv_opts = {
+    .recode_user_missing = recode_user_missing,
+    .include_var_names = include_var_names,
+    .use_value_labels = use_value_labels,
+    .use_print_formats = use_print_formats,
+    .decimal = decimal,
+    .delimiter = (delimiter ? delimiter
+                  : type == TAB_FILE ? '\t'
+                  : decimal == '.' ? ','
+                  : ';'),
+    .qualifier = qualifier,
+  };
   writer = csv_writer_open (handle, dict, &csv_opts);
   if (writer == NULL)
     goto error;
   fh_unref (handle);
 
-  map = case_map_from_dict (dict);
+  map = case_map_stage_get_case_map (stage);
+  case_map_stage_destroy (stage);
   if (map != NULL)
     writer = case_map_create_output_translator (map, writer);
-  dict_destroy (dict);
+  dict_unref (dict);
 
   casereader_transfer (proc_open_filtering (ds, !retain_unselected), writer);
   ok = casewriter_destroy (writer);
@@ -283,8 +284,9 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds)
   return ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE;
 
 error:
+  case_map_stage_destroy (stage);
   fh_unref (handle);
-  dict_destroy (dict);
+  dict_unref (dict);
   case_map_destroy (map);
   return CMD_FAILURE;
 }