X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata-list.c;h=a0036d6aa51c9b951027bb3dabf444d032898c04;hb=60d7d619ee7885ad065f178eb0cf1e5d432b1921;hp=b2d12893f0a3cdcf2d999b3a505535c83a2eeef6;hpb=6bc566408707e018674d1776d835c78368b6b5a3;p=pspp diff --git a/src/data-list.c b/src/data-list.c index b2d12893f0..a0036d6aa5 100644 --- a/src/data-list.c +++ b/src/data-list.c @@ -18,6 +18,7 @@ 02111-1307, USA. */ #include +#include "data-list.h" #include #include #include @@ -162,10 +163,7 @@ cmd_data_list (void) return CMD_FAILURE; dls.end = dict_lookup_var (default_dict, tokid); if (!dls.end) - { - dls.end = dict_create_var (default_dict, tokid, 0); - assert (dls.end != NULL); - } + dls.end = dict_create_var_assert (default_dict, tokid, 0); lex_get (); } else if (token == T_ID) @@ -518,11 +516,13 @@ fixed_parse_compatible (void) { convert_fmt_ItoO (&fx.spec.input, &v->print); v->write = v->print; + if (vfm_source != &input_program_source + && vfm_source != &file_type_source) + v->init = 0; } else { - v = dict_lookup_var (default_dict, fx.name[i]); - assert (v != NULL); + v = dict_lookup_var_assert (default_dict, fx.name[i]); if (!vfm_source) { msg (SE, _("%s is a duplicate variable name."), fx.name[i]); @@ -626,6 +626,10 @@ dump_fmt_list (struct fmt_list *f) return 0; } + if (vfm_source != &input_program_source + && vfm_source != &file_type_source) + v->init = 0; + fx.spec.input = f->f; convert_fmt_ItoO (&fx.spec.input, &v->print); v->write = v->print; @@ -828,6 +832,10 @@ parse_free (void) v->print = v->write = out; + if (vfm_source != &input_program_source + && vfm_source != &file_type_source) + v->init = 0; + strcpy (spec.name, name[i]); spec.fv = v->fv; spec.width = width; @@ -967,14 +975,13 @@ cut_field (char **ret_cp, int *ret_len) static int read_from_data_list_fixed (void); static int read_from_data_list_free (void); static int read_from_data_list_list (void); -static int do_reading (int flag); /* FLAG==0: reads any number of cases into temp_case and calls write_case() for each one, returns garbage. FLAG!=0: reads one case into temp_case and returns -2 on eof, -1 otherwise. Uses dlsp as the relevant parsing description. */ static int -do_reading (int flag) +do_reading (int flag, write_case_func *write_case, write_case_data wc_data) { int (*func) (void); @@ -1030,7 +1037,7 @@ do_reading (int flag) else { while (func () != -2) - if (!write_case ()) + if (!write_case (wc_data)) { debug_printf ((_("abort in write_case()\n"))); break; @@ -1179,46 +1186,52 @@ read_from_data_list_list (void) return -1; } -/* Destroys DATA LIST transformation or input program PGM. */ +/* Destroys SPEC. */ static void -destroy_dls (struct trns_header *pgm) +destroy_dls_var_spec (struct dls_var_spec *spec) { - struct data_list_pgm *dls = (struct data_list_pgm *) pgm; - struct dls_var_spec *iter, *next; + struct dls_var_spec *next; - iter = dls->spec; - while (iter) + while (spec != NULL) { - next = iter->next; - free (iter); - iter = next; + next = spec->next; + free (spec); + spec = next; } +} + +/* Destroys DATA LIST transformation PGM. */ +static void +destroy_dls (struct trns_header *pgm) +{ + struct data_list_pgm *dls = (struct data_list_pgm *) pgm; + destroy_dls_var_spec (dls->spec); fh_close_handle (dls->handle); } /* Note that since this is exclusively an input program, C is guaranteed to be temp_case. */ static int -read_one_case (struct trns_header *t, struct ccase *c unused) +read_one_case (struct trns_header *t, struct ccase *c UNUSED) { dlsp = (struct data_list_pgm *) t; - return do_reading (1); + return do_reading (1, NULL, NULL); } /* Reads all the records from the data file and passes them to write_case(). */ static void -data_list_source_read (void) +data_list_source_read (write_case_func *write_case, write_case_data wc_data) { dlsp = &dls; - do_reading (0); + do_reading (0, write_case, wc_data); } /* Destroys the source's internal data. */ static void data_list_source_destroy_source (void) { - destroy_dls ((struct trns_header *) & dls); + destroy_dls (&dls.h); } struct case_stream data_list_source = @@ -1247,7 +1260,6 @@ struct repeating_data_trns struct trns_header h; struct dls_var_spec *spec; /* Variable parsing specifications. */ struct file_handle *handle; /* Input file, never NULL. */ - /* Do not reorder preceding fields. */ struct rpd_num_or_var starts_beg; /* STARTS=, before the dash. */ struct rpd_num_or_var starts_end; /* STARTS=, after the dash. */ @@ -1255,15 +1267,22 @@ struct repeating_data_trns struct rpd_num_or_var length; /* LENGTH= subcommand. */ struct rpd_num_or_var cont_beg; /* CONTINUED=, before the dash. */ struct rpd_num_or_var cont_end; /* CONTINUED=, after the dash. */ - int id_beg, id_end; /* ID subcommand, beginning & end columns. */ - struct variable *id_var; /* ID subcommand, DATA LIST variable. */ - struct fmt_spec id_spec; /* ID subcommand, input format spec. */ + + /* ID subcommand. */ + int id_beg, id_end; /* Beginning & end columns. */ + struct variable *id_var; /* DATA LIST variable. */ + struct fmt_spec id_spec; /* Input format spec. */ + union value *id_value; /* ID value. */ + + write_case_func *write_case; + write_case_data wc_data; }; /* Information about the transformation being parsed. */ static struct repeating_data_trns rpd; -static int read_one_set_of_repetitions (struct trns_header *, struct ccase *); +int repeating_data_trns_proc (struct trns_header *, struct ccase *); +void repeating_data_trns_free (struct trns_header *); static int parse_num_or_var (struct rpd_num_or_var *, const char *); static int parse_repeating_data (void); static void find_variable_input_spec (struct variable *v, @@ -1292,6 +1311,7 @@ cmd_repeating_data (void) = rpd.cont_end = rpd.starts_beg; rpd.id_beg = rpd.id_end = 0; rpd.id_var = NULL; + rpd.id_value = NULL; rpd.spec = NULL; first = &rpd.spec; next = NULL; @@ -1318,7 +1338,7 @@ cmd_repeating_data (void) lex_match ('='); if (seen & 1) { - msg (SE, _("STARTS subcommand given multiple times.")); + msg (SE, _("%s subcommand given multiple times."),"STARTS"); return CMD_FAILURE; } seen |= 1; @@ -1353,7 +1373,7 @@ cmd_repeating_data (void) lex_match ('='); if (seen & 2) { - msg (SE, _("OCCURS subcommand given multiple times.")); + msg (SE, _("%s subcommand given multiple times."),"OCCURS"); return CMD_FAILURE; } seen |= 2; @@ -1366,7 +1386,7 @@ cmd_repeating_data (void) lex_match ('='); if (seen & 4) { - msg (SE, _("LENGTH subcommand given multiple times.")); + msg (SE, _("%s subcommand given multiple times."),"LENGTH"); return CMD_FAILURE; } seen |= 4; @@ -1379,7 +1399,7 @@ cmd_repeating_data (void) lex_match ('='); if (seen & 8) { - msg (SE, _("CONTINUED subcommand given multiple times.")); + msg (SE, _("%s subcommand given multiple times."),"CONTINUED"); return CMD_FAILURE; } seen |= 8; @@ -1412,7 +1432,7 @@ cmd_repeating_data (void) lex_match ('='); if (seen & 16) { - msg (SE, _("ID subcommand given multiple times.")); + msg (SE, _("%s subcommand given multiple times."),"ID"); return CMD_FAILURE; } seen |= 16; @@ -1460,6 +1480,7 @@ cmd_repeating_data (void) return CMD_FAILURE; find_variable_input_spec (rpd.id_var, &rpd.id_spec); + rpd.id_value = xmalloc (sizeof *rpd.id_value * rpd.id_var->nv); } else if (lex_match_id ("TABLE")) table = 1; @@ -1523,8 +1544,8 @@ cmd_repeating_data (void) { struct repeating_data_trns *new_trns; - rpd.h.proc = read_one_set_of_repetitions; - rpd.h.free = destroy_dls; + rpd.h.proc = repeating_data_trns_proc; + rpd.h.free = repeating_data_trns_free; new_trns = xmalloc (sizeof *new_trns); memcpy (new_trns, &rpd, sizeof *new_trns); @@ -1700,14 +1721,14 @@ rpd_parse_record (int beg, int end, int ofs, struct ccase *c, /* Handle record ID values. */ if (t->id_beg != 0) { - static union value comparator; - union value v; + union value id_temp[MAX_ELEMS_PER_VALUE]; + /* Parse record ID into V. */ { struct data_in di; data_in_finite_line (&di, line, len, t->id_beg, t->id_end); - di.v = &v; + di.v = compare_id ? id_temp : t->id_value; di.flags = 0; di.f1 = t->id_beg; di.format = t->id_spec; @@ -1716,25 +1737,21 @@ rpd_parse_record (int beg, int end, int ofs, struct ccase *c, return 0; } - if (compare_id == 0) - comparator = v; - else if ((t->id_var->type == NUMERIC && comparator.f != v.f) - || (t->id_var->type == ALPHA - && strncmp (comparator.s, v.s, t->id_var->width))) + if (compare_id + && compare_values (id_temp, t->id_value, t->id_var->width) != 0) { - char comp_str [64]; - char v_str [64]; + char expected_str [MAX_FORMATTED_LEN + 1]; + char actual_str [MAX_FORMATTED_LEN + 1]; - if (!data_out (comp_str, &t->id_var->print, &comparator)) - comp_str[0] = 0; - if (!data_out (v_str, &t->id_var->print, &v)) - v_str[0] = 0; - - comp_str[t->id_var->print.w] = v_str[t->id_var->print.w] = 0; + data_out (expected_str, &t->id_var->print, t->id_value); + expected_str[t->id_var->print.w] = '\0'; + + data_out (actual_str, &t->id_var->print, id_temp); + actual_str[t->id_var->print.w] = '\0'; tmsg (SE, RPD_ERR, - _("Mismatched case ID (%s). Expected value was %s."), - v_str, comp_str); + _("Encountered mismatched record ID \"%s\" expecting \"%s\"."), + actual_str, expected_str); return 0; } @@ -1765,7 +1782,7 @@ rpd_parse_record (int beg, int end, int ofs, struct ccase *c, warned = 1; tmsg (SW, RPD_ERR, - _("Variable %s startging in column %d extends " + _("Variable %s starting in column %d extends " "beyond physical record length of %d."), var_spec->v->name, fc, len); } @@ -1787,7 +1804,7 @@ rpd_parse_record (int beg, int end, int ofs, struct ccase *c, cur += ofs; - if (!write_case ()) + if (!t->write_case (t->wc_data)) return 0; } } @@ -1798,8 +1815,8 @@ rpd_parse_record (int beg, int end, int ofs, struct ccase *c, /* Analogous to read_one_case; reads one set of repetitions of the elements in the REPEATING DATA structure. Returns -1 on success, -2 on end of file or on failure. */ -static int -read_one_set_of_repetitions (struct trns_header *trns, struct ccase *c) +int +repeating_data_trns_proc (struct trns_header *trns, struct ccase *c) { dfm_push (dlsp->handle); @@ -1932,3 +1949,29 @@ read_one_set_of_repetitions (struct trns_header *trns, struct ccase *c) transformations. */ return -3; } + +void +repeating_data_trns_free (struct trns_header *rpd_) +{ + struct repeating_data_trns *rpd = (struct repeating_data_trns *) rpd_; + + destroy_dls_var_spec (rpd->spec); + fh_close_handle (rpd->handle); + free (rpd->id_value); +} + +/* This is a kluge. It is only here until I have more time + tocome up with something better. It lets + repeating_data_trns_proc() know how to write the cases that it + composes. */ +void +repeating_data_set_write_case (struct trns_header *trns, + write_case_func *write_case, + write_case_data wc_data) +{ + struct repeating_data_trns *t = (struct repeating_data_trns *) trns; + + assert (trns->proc == repeating_data_trns_proc); + t->write_case = write_case; + t->wc_data = wc_data; +}