X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fdata-io%2Fdata-list.c;h=043b424db77a6e3303fd845438ef8ff2911f164c;hb=81579d9e9f994fb2908f50af41c3eb033d216e58;hp=7a2a074b59e763eebe322780c96e86f057991ed6;hpb=015e221b0f8578afee769528572c76387f26c629;p=pspp-builds.git diff --git a/src/language/data-io/data-list.c b/src/language/data-io/data-list.c index 7a2a074b..043b424d 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 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011 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,33 +22,33 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xsize.h" -#include "xalloc.h" +#include "data/case.h" +#include "data/casereader.h" +#include "data/data-in.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" +#include "language/command.h" +#include "language/data-io/data-parser.h" +#include "language/data-io/data-reader.h" +#include "language/data-io/file-handle.h" +#include "language/data-io/inpt-pgm.h" +#include "language/data-io/placement-parser.h" +#include "language/lexer/format-parser.h" +#include "language/lexer/lexer.h" +#include "language/lexer/variable-parser.h" +#include "libpspp/assertion.h" +#include "libpspp/compiler.h" +#include "libpspp/message.h" +#include "libpspp/misc.h" +#include "libpspp/pool.h" +#include "libpspp/str.h" + +#include "gl/xsize.h" +#include "gl/xalloc.h" #include "gettext.h" #define _(msgid) gettext (msgid) @@ -75,8 +75,9 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) struct dictionary *dict; struct data_parser *parser; struct dfm_reader *reader; - struct variable *end; - struct file_handle *fh; + struct variable *end = NULL; + struct file_handle *fh = NULL; + struct string encoding = DS_EMPTY_INITIALIZER; int table; enum data_parser_type type; @@ -85,37 +86,45 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) bool ok; dict = in_input_program () ? dataset_dict (ds) : dict_create (); - parser = data_parser_create (); + parser = data_parser_create (dict); reader = NULL; - end = NULL; - fh = NULL; table = -1; /* Print table if nonzero, -1=undecided. */ has_type = false; - while (lex_token (lexer) != '/') + while (lex_token (lexer) != T_SLASH) { if (lex_match_id (lexer, "FILE")) { - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); fh_unref (fh); fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE); if (fh == NULL) goto error; } + else if (lex_match_id (lexer, "ENCODING")) + { + lex_match (lexer, T_EQUALS); + if (!lex_force_string (lexer)) + goto error; + + ds_init_substring (&encoding, lex_tokss (lexer)); + + lex_get (lexer); + } else if (lex_match_id (lexer, "RECORDS")) { - lex_match (lexer, '='); - lex_match (lexer, '('); + lex_match (lexer, T_EQUALS); + lex_match (lexer, T_LPAREN); if (!lex_force_int (lexer)) goto error; data_parser_set_records (parser, lex_integer (lexer)); lex_get (lexer); - lex_match (lexer, ')'); + lex_match (lexer, T_RPAREN); } else if (lex_match_id (lexer, "SKIP")) { - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); if (!lex_force_int (lexer)) goto error; data_parser_set_skip (parser, lex_integer (lexer)); @@ -135,12 +144,12 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) goto error; } - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); if (!lex_force_id (lexer)) goto error; - end = dict_lookup_var (dict, lex_tokid (lexer)); + end = dict_lookup_var (dict, lex_tokcstr (lexer)); if (!end) - end = dict_create_var_assert (dict, lex_tokid (lexer), 0); + end = dict_create_var_assert (dict, lex_tokcstr (lexer), 0); lex_get (lexer); } else if (lex_match_id (lexer, "NOTABLE")) @@ -177,20 +186,20 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) if (data_parser_get_type (parser) == DP_DELIMITED) { - if (lex_match (lexer, '(')) + if (lex_match (lexer, T_LPAREN)) { struct string delims = DS_EMPTY_INITIALIZER; - while (!lex_match (lexer, ')')) + while (!lex_match (lexer, T_RPAREN)) { int delim; if (lex_match_id (lexer, "TAB")) delim = '\t'; - else if (lex_token (lexer) == T_STRING - && ds_length (lex_tokstr (lexer)) == 1) + else if (lex_is_string (lexer) + && ss_length (lex_tokss (lexer)) == 1) { - delim = ds_first (lex_tokstr (lexer)); + delim = ss_first (lex_tokss (lexer)); lex_get (lexer); } else @@ -199,9 +208,9 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) ds_destroy (&delims); goto error; } - ds_put_char (&delims, delim); + ds_put_byte (&delims, delim); - lex_match (lexer, ','); + lex_match (lexer, T_COMMA); } data_parser_set_empty_line_has_field (parser, true); @@ -228,6 +237,14 @@ 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 (fh == NULL) fh = fh_inline_file (); fh_set_default_handle (fh); @@ -277,6 +294,7 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) data_parser_make_active_file (parser, ds, reader, dict); fh_unref (fh); + ds_destroy (&encoding); return CMD_SUCCESS; @@ -285,6 +303,7 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) if (!in_input_program ()) dict_destroy (dict); fh_unref (fh); + ds_destroy (&encoding); return CMD_CASCADING_FAILURE; } @@ -302,7 +321,7 @@ parse_fixed (struct lexer *lexer, struct dictionary *dict, int record = 0; int column = 1; - while (lex_token (lexer) != '.') + while (lex_token (lexer) != T_ENDCMD) { char **names; size_t name_cnt, name_idx; @@ -396,7 +415,7 @@ parse_free (struct lexer *lexer, struct dictionary *dict, struct pool *tmp_pool, struct data_parser *parser) { lex_get (lexer); - while (lex_token (lexer) != '.') + while (lex_token (lexer) != T_ENDCMD) { struct fmt_spec input, output; char **name; @@ -407,11 +426,11 @@ parse_free (struct lexer *lexer, struct dictionary *dict, &name, &name_cnt, PV_NONE)) return false; - if (lex_match (lexer, '(')) + if (lex_match (lexer, T_LPAREN)) { if (!parse_format_specifier (lexer, &input) || !fmt_check_input (&input) - || !lex_force_match (lexer, ')')) + || !lex_force_match (lexer, T_RPAREN)) return NULL; /* As a special case, N format is treated as F format @@ -423,7 +442,7 @@ parse_free (struct lexer *lexer, struct dictionary *dict, } else { - lex_match (lexer, '*'); + lex_match (lexer, T_ASTERISK); input = fmt_for_input (FMT_F, 8, 0); output = *settings_get_format (); } @@ -463,14 +482,15 @@ data_list_trns_free (void *trns_) return true; } -/* Handle DATA LIST transformation TRNS, parsing data into C. */ +/* Handle DATA LIST transformation TRNS, parsing data into *C. */ static int -data_list_trns_proc (void *trns_, struct ccase *c, casenumber case_num UNUSED) +data_list_trns_proc (void *trns_, struct ccase **c, casenumber case_num UNUSED) { struct data_list_trns *trns = trns_; int retval; - if (data_parser_parse (trns->parser, trns->reader, c)) + *c = case_unshare (*c); + if (data_parser_parse (trns->parser, trns->reader, *c)) retval = TRNS_CONTINUE; else if (dfm_reader_error (trns->reader) || dfm_eof (trns->reader) > 1) { @@ -484,7 +504,7 @@ data_list_trns_proc (void *trns_, struct ccase *c, casenumber case_num UNUSED) /* If there was an END subcommand handle it. */ if (trns->end != NULL) { - double *end = &case_data_rw (c, trns->end)->f; + double *end = &case_data_rw (*c, trns->end)->f; if (retval == TRNS_END_FILE) { *end = 1.0;