X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fdata-io%2Fdata-list.c;h=f68b2e1b4d058e2f71585b5742d8ad98e1baa8dc;hb=eb06da6a334bc37108cdce9bfc7f26cfcb2003ee;hp=043b424db77a6e3303fd845438ef8ff2911f164c;hpb=81579d9e9f994fb2908f50af41c3eb033d216e58;p=pspp diff --git a/src/language/data-io/data-list.c b/src/language/data-io/data-list.c index 043b424db7..f68b2e1b4d 100644 --- a/src/language/data-io/data-list.c +++ b/src/language/data-io/data-list.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011, 2012, 2013 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 @@ -25,9 +25,9 @@ #include "data/case.h" #include "data/casereader.h" #include "data/data-in.h" +#include "data/dataset.h" #include "data/dictionary.h" #include "data/format.h" -#include "data/procedure.h" #include "data/settings.h" #include "data/transformations.h" #include "data/variable.h" @@ -42,6 +42,7 @@ #include "language/lexer/variable-parser.h" #include "libpspp/assertion.h" #include "libpspp/compiler.h" +#include "libpspp/i18n.h" #include "libpspp/message.h" #include "libpspp/misc.h" #include "libpspp/pool.h" @@ -77,7 +78,7 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) struct dfm_reader *reader; struct variable *end = NULL; struct file_handle *fh = NULL; - struct string encoding = DS_EMPTY_INITIALIZER; + char *encoding = NULL; int table; enum data_parser_type type; @@ -85,7 +86,9 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) struct pool *tmp_pool; bool ok; - dict = in_input_program () ? dataset_dict (ds) : dict_create (); + dict = (in_input_program () + ? dataset_dict (ds) + : dict_create (get_default_encoding ())); parser = data_parser_create (dict); reader = NULL; @@ -98,7 +101,7 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) { lex_match (lexer, T_EQUALS); fh_unref (fh); - fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE); + fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE, NULL); if (fh == NULL) goto error; } @@ -108,7 +111,8 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) if (!lex_force_string (lexer)) goto error; - ds_init_substring (&encoding, lex_tokss (lexer)); + free (encoding); + encoding = ss_xstrdup (lex_tokss (lexer)); lex_get (lexer); } @@ -134,13 +138,12 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) { if (!in_input_program ()) { - msg (SE, _("The END subcommand may only be used within " - "INPUT PROGRAM.")); + msg (SE, _("The %s subcommand may only be used within %s."), "END", "INPUT PROGRAM"); goto error; } if (end) { - msg (SE, _("The END subcommand may only be specified once.")); + msg (SE, _("The %s subcommand may only be specified once."), "END"); goto error; } @@ -204,6 +207,7 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) } else { + /* XXX should support multibyte UTF-8 characters */ lex_error (lexer, NULL); ds_destroy (&delims); goto error; @@ -237,13 +241,9 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) } type = data_parser_get_type (parser); - if (! ds_is_empty (&encoding)) - { - if ( NULL == fh) - msg (MW, _("Encoding should not be specified for inline data. It will be ignored.")); - else - dict_set_encoding (dict, ds_cstr (&encoding)); - } + if (encoding && NULL == fh) + msg (MW, _("Encoding should not be specified for inline data. It will be " + "ignored.")); if (fh == NULL) fh = fh_inline_file (); @@ -251,7 +251,7 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) if (type != DP_FIXED && end != NULL) { - msg (SE, _("The END subcommand may be used only with DATA LIST FIXED.")); + msg (SE, _("The %s subcommand may be used only with %s."), "END", "DATA LIST FIXED"); goto error; } @@ -278,7 +278,7 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) if (table) data_parser_output_description (parser, fh); - reader = dfm_open_reader (fh, lexer); + reader = dfm_open_reader (fh, lexer, encoding); if (reader == NULL) goto error; @@ -294,16 +294,16 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) data_parser_make_active_file (parser, ds, reader, dict); fh_unref (fh); - ds_destroy (&encoding); + free (encoding); - return CMD_SUCCESS; + return CMD_DATA_LIST; error: data_parser_destroy (parser); if (!in_input_program ()) dict_destroy (dict); fh_unref (fh); - ds_destroy (&encoding); + free (encoding); return CMD_CASCADING_FAILURE; } @@ -330,9 +330,9 @@ parse_fixed (struct lexer *lexer, struct dictionary *dict, /* Parse everything. */ if (!parse_record_placement (lexer, &record, &column) - || !parse_DATA_LIST_vars_pool (lexer, tmp_pool, + || !parse_DATA_LIST_vars_pool (lexer, dict, tmp_pool, &names, &name_cnt, PV_NONE) - || !parse_var_placements (lexer, tmp_pool, name_cnt, true, + || !parse_var_placements (lexer, tmp_pool, name_cnt, FMT_FOR_INPUT, &formats, &format_cnt)) return false; @@ -422,15 +422,34 @@ parse_free (struct lexer *lexer, struct dictionary *dict, size_t name_cnt; size_t i; - if (!parse_DATA_LIST_vars_pool (lexer, tmp_pool, + if (!parse_DATA_LIST_vars_pool (lexer, dict, tmp_pool, &name, &name_cnt, PV_NONE)) return false; if (lex_match (lexer, T_LPAREN)) { - if (!parse_format_specifier (lexer, &input) - || !fmt_check_input (&input) - || !lex_force_match (lexer, T_RPAREN)) + char type[FMT_TYPE_LEN_MAX + 1]; + + if (!parse_abstract_format_specifier (lexer, type, &input.w, + &input.d)) + return NULL; + if (!fmt_from_name (type, &input.type)) + { + msg (SE, _("Unknown format type `%s'."), type); + return NULL; + } + + /* If no width was included, use the minimum width for the type. + This isn't quite right, because DATETIME by itself seems to become + DATETIME20 (see bug #30690), whereas this will become + DATETIME17. The correct behavior is not documented. */ + if (input.w == 0) + { + input.w = fmt_min_input_width (input.type); + input.d = 0; + } + + if (!fmt_check_input (&input) || !lex_force_match (lexer, T_RPAREN)) return NULL; /* As a special case, N format is treated as F format