X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fdata-io%2Fsave-translate.c;h=a565f4471c3aeef45f34db40c44641b34a620ec9;hb=4210c4336dee5e6f59481dadc645af0422be1acf;hp=4cf5e71eaa18b6c696ed682e925572978f5ec658;hpb=173d1687aea88e0e5e1b1d8615ed68ebefb15d08;p=pspp diff --git a/src/language/data-io/save-translate.c b/src/language/data-io/save-translate.c index 4cf5e71eaa..a565f4471c 100644 --- a/src/language/data-io/save-translate.c +++ b/src/language/data-io/save-translate.c @@ -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 @@ -22,10 +22,10 @@ #include "data/casereader.h" #include "data/casewriter.h" #include "data/csv-file-writer.h" +#include "data/dataset.h" #include "data/dictionary.h" #include "data/file-name.h" #include "data/format.h" -#include "data/procedure.h" #include "data/settings.h" #include "language/command.h" #include "language/data-io/file-handle.h" @@ -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, '/')) + while (lex_token (lexer) != T_ENDCMD) { + if (!lex_force_match (lexer, T_SLASH)) + goto error; + if (lex_match_id (lexer, "OUTFILE")) { if (handle != NULL) @@ -94,9 +97,9 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds) goto error; } - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); - handle = fh_parse (lexer, FH_REF_FILE); + handle = fh_parse (lexer, FH_REF_FILE, NULL); if (handle == NULL) goto error; } @@ -108,14 +111,14 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds) goto error; } - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "CSV")) type = CSV_FILE; else if (lex_match_id (lexer, "TAB")) type = TAB_FILE; else { - lex_error (lexer, _("expecting %s or %s"), "CSV", "TAB"); + lex_error_expecting (lexer, "CSV", "TAB"); goto error; } } @@ -125,88 +128,88 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds) include_var_names = true; else if (lex_match_id (lexer, "MISSING")) { - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "IGNORE")) recode_user_missing = false; else if (lex_match_id (lexer, "RECODE")) recode_user_missing = true; else { - lex_error (lexer, _("expecting %s or %s"), "IGNORE", "RECODE"); + lex_error_expecting (lexer, "IGNORE", "RECODE"); goto error; } } else if (lex_match_id (lexer, "CELLS")) { - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "VALUES")) use_value_labels = false; else if (lex_match_id (lexer, "LABELS")) use_value_labels = true; else { - lex_error (lexer, _("expecting %s or %s"), "VALUES", "LABELS"); + lex_error_expecting (lexer, "VALUES", "LABELS"); goto error; } } else if (lex_match_id (lexer, "TEXTOPTIONS")) { - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); for (;;) { if (lex_match_id (lexer, "DELIMITER")) { - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); if (!lex_force_string (lexer)) goto error; - if (ds_length (lex_tokstr (lexer)) != 1) + /* XXX should support multibyte UTF-8 delimiters */ + if (ss_length (lex_tokss (lexer)) != 1) { msg (SE, _("The %s string must contain exactly one " "character."), "DELIMITER"); goto error; } - delimiter = ds_first (lex_tokstr (lexer)); + delimiter = ss_first (lex_tokss (lexer)); lex_get (lexer); } else if (lex_match_id (lexer, "QUALIFIER")) { - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); if (!lex_force_string (lexer)) goto error; - if (ds_length (lex_tokstr (lexer)) != 1) + /* XXX should support multibyte UTF-8 qualifiers */ + if (ss_length (lex_tokss (lexer)) != 1) { msg (SE, _("The %s string must contain exactly one " "character."), "QUALIFIER"); goto error; } - qualifier = ds_first (lex_tokstr (lexer)); + qualifier = ss_first (lex_tokss (lexer)); lex_get (lexer); } else if (lex_match_id (lexer, "DECIMAL")) { - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "DOT")) decimal = '.'; else if (lex_match_id (lexer, "COMMA")) decimal = ','; else { - lex_error (lexer, _("expecting %s or %s"), - "DOT", "COMMA"); + lex_error_expecting (lexer, "DOT", "COMMA"); goto error; } } else if (lex_match_id (lexer, "FORMAT")) { - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "PLAIN")) use_print_formats = false; else if (lex_match_id (lexer, "VARIABLE")) use_print_formats = true; else { - lex_error (lexer, _("expecting %s or %s"), - "PLAIN", "VARIABLE"); + lex_error_expecting (lexer, "PLAIN", "VARIABLE"); goto error; } } @@ -216,63 +219,63 @@ cmd_save_translate (struct lexer *lexer, struct dataset *ds) } else if (lex_match_id (lexer, "UNSELECTED")) { - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "RETAIN")) retain_unselected = true; else if (lex_match_id (lexer, "DELETE")) 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); @@ -281,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; }