X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fdata-io%2Fdata-list.c;h=e464db1223ce607ad3492736c379eb3b92818efe;hb=3221f4af1d83871f3f5d97fcb836a34b2dd81e66;hp=58224baa2de01b6b3920e7947cb25cd528de9be7;hpb=07da9f454c17fb961cae09f6d7d505f7abb281c0;p=pspp diff --git a/src/language/data-io/data-list.c b/src/language/data-io/data-list.c index 58224baa2d..e464db1223 100644 --- a/src/language/data-io/data-list.c +++ b/src/language/data-io/data-list.c @@ -58,6 +58,7 @@ struct data_list_trns { struct data_parser *parser; /* Parser. */ + struct dictionary *dict; /* Dictionary. */ struct dfm_reader *reader; /* Data file reader. */ struct variable *end; /* Variable specified on END subcommand. */ }; @@ -67,8 +68,7 @@ static bool parse_fixed (struct lexer *, struct dictionary *, static bool parse_free (struct lexer *, struct dictionary *, struct pool *, struct data_parser *); -static trns_free_func data_list_trns_free; -static trns_proc_func data_list_trns_proc; +static const struct trns_class data_list_trns_class; int cmd_data_list (struct lexer *lexer, struct dataset *ds) @@ -89,7 +89,7 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) dict = (in_input_program () ? dataset_dict (ds) : dict_create (get_default_encoding ())); - parser = data_parser_create (dict); + parser = data_parser_create (); reader = NULL; table = -1; /* Print table if nonzero, -1=undecided. */ @@ -118,33 +118,25 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) } else if (lex_match_id (lexer, "RECORDS")) { + if (data_parser_get_records (parser) > 0) + { + lex_sbc_only_once ("RECORDS"); + goto error; + } lex_match (lexer, T_EQUALS); lex_match (lexer, T_LPAREN); - if (!lex_force_int (lexer)) + if (!lex_force_int_range (lexer, "RECORDS", 0, INT_MAX)) goto error; - - int records = lex_integer (lexer); - if (records < 0) - { - msg (SE, _("The %s value must be non-negative."), "RECORDS"); - goto error; - } - data_parser_set_records (parser, records); + data_parser_set_records (parser, lex_integer (lexer)); lex_get (lexer); lex_match (lexer, T_RPAREN); } else if (lex_match_id (lexer, "SKIP")) { lex_match (lexer, T_EQUALS); - if (!lex_force_int (lexer)) + if (!lex_force_int_range (lexer, "SKIP", 0, INT_MAX)) goto error; - int skip = lex_integer (lexer); - if (skip < 0) - { - msg (SE, _("The %s value must be non-negative."), "SKIP"); - goto error; - } - data_parser_set_skip (parser, skip); + data_parser_set_skip (parser, lex_integer (lexer)); lex_get (lexer); } else if (lex_match_id (lexer, "END")) @@ -156,7 +148,7 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) } if (end) { - msg (SE, _("The %s subcommand may only be specified once."), "END"); + lex_sbc_only_once ("END"); goto error; } @@ -301,9 +293,10 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) { struct data_list_trns *trns = xmalloc (sizeof *trns); trns->parser = parser; + trns->dict = dict_ref (dict); trns->reader = reader; trns->end = end; - add_transformation (ds, data_list_trns_proc, data_list_trns_free, trns); + add_transformation (ds, &data_list_trns_class, trns); } else data_parser_make_active_file (parser, ds, reader, dict, NULL, NULL); @@ -311,7 +304,9 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds) fh_unref (fh); free (encoding); - return CMD_DATA_LIST; + data_list_seen (); + + return CMD_SUCCESS; error: data_parser_destroy (parser); @@ -339,21 +334,21 @@ parse_fixed (struct lexer *lexer, struct dictionary *dict, while (lex_token (lexer) != T_ENDCMD) { char **names; - size_t name_cnt, name_idx; + size_t n_names, name_idx; struct fmt_spec *formats, *f; - size_t format_cnt; + size_t n_formats; /* Parse everything. */ 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, FMT_FOR_INPUT, - &formats, &format_cnt)) + &names, &n_names, PV_NONE) + || !parse_var_placements (lexer, tmp_pool, n_names, FMT_FOR_INPUT, + &formats, &n_formats)) return false; /* Create variables and var specs. */ name_idx = 0; - for (f = formats; f < &formats[format_cnt]; f++) + for (f = formats; f < &formats[n_formats]; f++) if (!execute_placement_format (f, &record, &column)) { char *name; @@ -415,7 +410,7 @@ parse_fixed (struct lexer *lexer, struct dictionary *dict, column += f->w; } - assert (name_idx == name_cnt); + assert (name_idx == n_names); } return true; @@ -435,11 +430,11 @@ parse_free (struct lexer *lexer, struct dictionary *dict, { struct fmt_spec input, output; char **name; - size_t name_cnt; + size_t n_names; size_t i; if (!parse_DATA_LIST_vars_pool (lexer, dict, tmp_pool, - &name, &name_cnt, PV_NONE)) + &name, &n_names, PV_NONE)) return false; if (lex_match (lexer, T_LPAREN)) @@ -483,7 +478,7 @@ parse_free (struct lexer *lexer, struct dictionary *dict, output = *settings_get_format (); } - for (i = 0; i < name_cnt; i++) + for (i = 0; i < n_names; i++) { struct variable *v; @@ -514,19 +509,20 @@ data_list_trns_free (void *trns_) struct data_list_trns *trns = trns_; data_parser_destroy (trns->parser); dfm_close_reader (trns->reader); + dict_unref (trns->dict); free (trns); return true; } /* Handle DATA LIST transformation TRNS, parsing data into *C. */ -static int +static enum trns_result data_list_trns_proc (void *trns_, struct ccase **c, casenumber case_num UNUSED) { struct data_list_trns *trns = trns_; - int retval; + enum trns_result retval; *c = case_unshare (*c); - if (data_parser_parse (trns->parser, trns->reader, *c)) + if (data_parser_parse (trns->parser, trns->reader, trns->dict, *c)) retval = TRNS_CONTINUE; else if (dfm_reader_error (trns->reader) || dfm_eof (trns->reader) > 1) { @@ -540,7 +536,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_num_rw (*c, trns->end); if (retval == TRNS_END_FILE) { *end = 1.0; @@ -552,4 +548,9 @@ data_list_trns_proc (void *trns_, struct ccase **c, casenumber case_num UNUSED) return retval; } - + +static const struct trns_class data_list_trns_class = { + .name = "DATA LIST", + .execute = data_list_trns_proc, + .destroy = data_list_trns_free, +};