X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fdata-io%2Fdata-list.c;h=0b98f40a07e2a2e08d6e54ce0a944473f68c1738;hb=5e328ed3392221e6c201a60e6d4e6638fe7f32de;hp=6d21c8439e7cb9e3a7e5c3ebc31744a4dd92c437;hpb=9ade26c8349b4434008c46cf09bc7473ec743972;p=pspp diff --git a/src/language/data-io/data-list.c b/src/language/data-io/data-list.c index 6d21c8439e..0b98f40a07 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); } @@ -118,7 +122,14 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) lex_match (lexer, T_LPAREN); if (!lex_force_int (lexer)) goto error; - data_parser_set_records (parser, lex_integer (lexer)); + + int records = lex_integer (lexer); + if (records < 0) + { + msg (SE, _("The %s value must be nonnegative."), "RECORDS"); + goto error; + } + data_parser_set_records (parser, records); lex_get (lexer); lex_match (lexer, T_RPAREN); } @@ -127,20 +138,25 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) lex_match (lexer, T_EQUALS); if (!lex_force_int (lexer)) goto error; - data_parser_set_skip (parser, lex_integer (lexer)); + int skip = lex_integer (lexer); + if (skip < 0) + { + msg (SE, _("The %s value must be nonnegative."), "SKIP"); + goto error; + } + data_parser_set_skip (parser, skip); lex_get (lexer); } else if (lex_match_id (lexer, "END")) { 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; } @@ -226,7 +242,9 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) data_parser_set_quotes (parser, ss_cstr ("'\"")); data_parser_set_soft_delimiters (parser, ss_cstr (CC_SPACES)); - data_parser_set_hard_delimiters (parser, ss_cstr (",")); + const char decimal = settings_get_decimal_char (FMT_F); + data_parser_set_hard_delimiters (parser, + ss_buffer (",", (decimal == '.') ? 1 : 0)); } } } @@ -238,13 +256,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 (); @@ -252,7 +266,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; } @@ -279,7 +293,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; @@ -292,19 +306,19 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) add_transformation (ds, data_list_trns_proc, data_list_trns_free, trns); } else - data_parser_make_active_file (parser, ds, reader, dict); + data_parser_make_active_file (parser, ds, reader, dict, NULL, NULL); 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; } @@ -333,7 +347,7 @@ parse_fixed (struct lexer *lexer, struct dictionary *dict, if (!parse_record_placement (lexer, &record, &column) || !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; @@ -429,9 +443,28 @@ parse_free (struct lexer *lexer, struct dictionary *dict, 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