From bd68eeaf9bf3dba6052943d41a907bc3c3dd3b9b Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 12 Jun 2005 21:58:10 +0000 Subject: [PATCH] Did some more work on bug 12859 and then realized that a *good* solution would require some fundamental restructuring. For now, I'm marking REPEATING DATA unimplemented, and then we can revisit it post-0.4.0. --- src/ChangeLog | 19 +++++++++++++ src/command.def | 2 +- src/data-list.c | 71 ++++++++++++++++++++++++++++------------------- src/error.c | 2 +- src/file-handle.q | 5 ++-- src/str.c | 2 +- src/vfm.c | 3 +- 7 files changed, 68 insertions(+), 36 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 08b65137..45b4ce33 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,22 @@ +Sun Jun 12 14:54:40 2005 Ben Pfaff + + Did some more work on bug 12859 and then realized that a *good* + solution would require some fundamental restructuring. For now, + I'm marking REPEATING DATA unimplemented, and then we can revisit + it post-0.4.0. + + * command.def: Make REPEATING DATA unimplemented. + + * data-list.c: (cmd_repeating_data) Assume inline file is 80 + characters wide. + (realize_value) Revert previous changes; no longer needed. + Updated all callers. + + * error.c: (err_hcf) Set nfile_loc, mfile_loc to 0 after freeing + file_loc, to avoid bad references later. + + * str.c: Fix typo. + Tue Jun 7 00:14:09 2005 Ben Pfaff Make some code tolerant of reentry. Should not be needed if other diff --git a/src/command.def b/src/command.def index 495ba669..fea29e93 100644 --- a/src/command.def +++ b/src/command.def @@ -145,7 +145,7 @@ DEFCMD ("RECORD TYPE", ERRO, INPU, ERRO, ERRO, cmd_record_type) UNIMPL ("REFORMAT", ERRO, ERRO, ERRO, ERRO, "Read obsolete files") UNIMPL ("REGRESSION", ERRO, ERRO, ERRO, ERRO, "Compute regression coefficients") DEFCMD ("RENAME VARIABLES", ERRO, INPU, TRAN, PROC, cmd_rename_variables) -DEFCMD ("REPEATING DATA", ERRO, INPU, ERRO, ERRO, cmd_repeating_data) +UNIMPL ("REPEATING DATA", ERRO, INPU, ERRO, ERRO, "Specify multiple cases per input record") UNIMPL ("REPORT", ERRO, ERRO, ERRO, ERRO, "Pretty print working file") DEFCMD ("REREAD", ERRO, INPU, ERRO, ERRO, cmd_reread) UNIMPL ("RESTORE", ERRO, ERRO, ERRO, ERRO, "Restore settings") diff --git a/src/data-list.c b/src/data-list.c index 2ed1f673..bab5d215 100644 --- a/src/data-list.c +++ b/src/data-list.c @@ -1426,11 +1426,10 @@ cmd_repeating_data (void) if (!parse_num_or_var (&rpd->starts_end, "STARTS ending column")) goto error; } else { - /* Otherwise, rpd->starts_end is left uninitialized. - This is okay. We will initialize it later from the - record length of the file. We can't do this now - because we can't be sure that the user has specified - the file handle yet. */ + /* Otherwise, rpd->starts_end is uninitialized. We + will initialize it later from the record length + of the file. We can't do so now because the + file handle may not be specified yet. */ } if (rpd->starts_beg.num != 0 && rpd->starts_end.num != 0 @@ -1480,7 +1479,8 @@ cmd_repeating_data (void) if (!lex_match ('/')) { - if (!parse_num_or_var (&rpd->cont_beg, "CONTINUED beginning column")) + if (!parse_num_or_var (&rpd->cont_beg, + "CONTINUED beginning column")) goto error; lex_negative_to_dash (); @@ -1589,13 +1589,32 @@ cmd_repeating_data (void) goto error; } - /* Calculate starts_end, cont_end if necessary and possible. */ - if (fh != NULL) + /* Calculate and check starts_end, cont_end if necessary. */ + if (rpd->starts_end.num == 0 && rpd->starts_end.var == NULL) { - if (rpd->starts_end.num == 0 && rpd->starts_end.var == NULL) - rpd->starts_end.num = handle_get_record_width (fh); - if (rpd->cont_end.num == 0 && rpd->cont_end.var == NULL) - rpd->cont_end.num = handle_get_record_width (fh); + rpd->starts_end.num = fh != NULL ? handle_get_record_width (fh) : 80; + if (rpd->starts_beg.num != 0 + && rpd->starts_beg.num > rpd->starts_end.num) + { + msg (SE, _("STARTS beginning column (%d) exceeds " + "default STARTS ending column taken from file's " + "record width (%d)."), + rpd->starts_beg.num, rpd->starts_end.num); + goto error; + } + } + if (rpd->cont_end.num == 0 && rpd->cont_end.var == NULL) + { + rpd->cont_end.num = fh != NULL ? handle_get_record_width (fh) : 80; + if (rpd->cont_beg.num != 0 + && rpd->cont_beg.num > rpd->cont_end.num) + { + msg (SE, _("CONTINUED beginning column (%d) exceeds " + "default CONTINUED ending column taken from file's " + "record width (%d)."), + rpd->cont_beg.num, rpd->cont_end.num); + goto error; + } } lex_match ('='); @@ -1744,23 +1763,17 @@ parse_repeating_data (struct dls_var_spec **first, struct dls_var_spec **last) /* Obtains the real value for rpd_num_or_var N in case C and returns it. The valid range is nonnegative numbers, but numbers outside this range can be returned and should be handled by the caller as - invalid. If N does not have a value, returns DEFAULT_VALUE, - which must be nonzero if this is possible. */ + invalid. */ static int -realize_value (struct rpd_num_or_var *n, struct ccase *c, int default_value) +realize_value (struct rpd_num_or_var *n, struct ccase *c) { - if (n->num != 0) - return n->num; - else if (n->var != NULL) + if (n->var != NULL) { double v = case_num (c, n->var->fv); return v != SYSMIS && v >= INT_MIN && v <= INT_MAX ? v : -1; } - else - { - assert (default_value != 0); - return default_value; - } + else + return n->num; } /* Parameter record passed to rpd_parse_record(). */ @@ -1915,13 +1928,13 @@ repeating_data_trns_proc (struct trns_header *trns, struct ccase *c, dfm_forward_record (t->reader); /* Calculate occurs, length. */ - occurs_left = occurs = realize_value (&t->occurs, c, 0); + occurs_left = occurs = realize_value (&t->occurs, c); if (occurs <= 0) { tmsg (SE, RPD_ERR, _("Invalid value %d for OCCURS."), occurs); return -3; } - starts_beg = realize_value (&t->starts_beg, c, 0); + starts_beg = realize_value (&t->starts_beg, c); if (starts_beg <= 0) { tmsg (SE, RPD_ERR, _("Beginning column for STARTS (%d) must be " @@ -1929,7 +1942,7 @@ repeating_data_trns_proc (struct trns_header *trns, struct ccase *c, starts_beg); return -3; } - starts_end = realize_value (&t->starts_end, c, line.length + 1); + starts_end = realize_value (&t->starts_end, c); if (starts_end < starts_beg) { tmsg (SE, RPD_ERR, _("Ending column for STARTS (%d) is less than " @@ -1937,14 +1950,14 @@ repeating_data_trns_proc (struct trns_header *trns, struct ccase *c, starts_end, starts_beg); skip_first_record = 1; } - length = realize_value (&t->length, c, 0); + length = realize_value (&t->length, c); if (length < 0) { tmsg (SE, RPD_ERR, _("Invalid value %d for LENGTH."), length); length = 1; occurs = occurs_left = 1; } - cont_beg = realize_value (&t->cont_beg, c, 0); + cont_beg = realize_value (&t->cont_beg, c); if (cont_beg < 0) { tmsg (SE, RPD_ERR, _("Beginning column for CONTINUED (%d) must be " @@ -1952,7 +1965,7 @@ repeating_data_trns_proc (struct trns_header *trns, struct ccase *c, cont_beg); return -2; } - cont_end = realize_value (&t->cont_end, c, line.length + 1); + cont_end = realize_value (&t->cont_end, c); if (cont_end < cont_beg) { tmsg (SE, RPD_ERR, _("Ending column for CONTINUED (%d) is less than " diff --git a/src/error.c b/src/error.c index 3c91f732..571e6393 100644 --- a/src/error.c +++ b/src/error.c @@ -204,11 +204,11 @@ err_hcf (int success) free(file_loc); file_loc = NULL; + nfile_loc = mfile_loc = 0; outp_done (); done_glob(); - exit (success ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/file-handle.q b/src/file-handle.q index 3f09d194..6b155027 100644 --- a/src/file-handle.q +++ b/src/file-handle.q @@ -235,7 +235,7 @@ mode_name (const char *mode) } -/* Tries to open FILE with the given TYPE and MODE. +/* Tries to open handle H with the given TYPE and MODE. TYPE is the sort of file, e.g. "system file". Only one given type of access is allowed on a given file handle at once. @@ -391,8 +391,7 @@ handle_get_mode (const struct file_handle *handle) return handle->mode; } -/* Returns the width of a logical record on HANDLE. Applicable - only to MODE_BINARY files. */ +/* Returns the width of a logical record on HANDLE. */ size_t handle_get_record_width (const struct file_handle *handle) { diff --git a/src/str.c b/src/str.c index 56b0491e..d497078a 100644 --- a/src/str.c +++ b/src/str.c @@ -306,7 +306,7 @@ void ds_destroy (struct string *st) { free (st->string); - st->string = NULL;x + st->string = NULL; } /* Truncates ST to zero length. */ diff --git a/src/vfm.c b/src/vfm.c index 90edfcd0..8f594797 100644 --- a/src/vfm.c +++ b/src/vfm.c @@ -259,7 +259,8 @@ write_case (struct write_case_data *wc_data) { if (compaction_necessary) { - dict_compact_case (temp_dict, &wc_data->sink_case, &wc_data->trns_case); + dict_compact_case (temp_dict, &wc_data->sink_case, + &wc_data->trns_case); vfm_sink->class->write (vfm_sink, &wc_data->sink_case); } else -- 2.30.2