From 2e02472cf15ddb64c33a1477cf4cfbf3be2d0c95 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 7 Jun 2005 07:20:50 +0000 Subject: [PATCH] Continue work on bug 12859, plus some code cleanup. --- src/ChangeLog | 70 +++++++++++++++++++--------- src/data-list.c | 118 +++++++++++++++++++++++------------------------- src/dfm-read.c | 7 +-- src/error.c | 2 + src/output.c | 5 ++ src/str.c | 1 + src/vfm.c | 2 +- 7 files changed, 118 insertions(+), 87 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 992454ae..08b65137 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,6 +1,32 @@ +Tue Jun 7 00:14:09 2005 Ben Pfaff + + Make some code tolerant of reentry. Should not be needed if other + code is correct but it is good to be generally tolerant. + + * error.c: (err_hcf) Set file_loc to null after free(). + + * output.c: (outp_done) Similar changes. + + * str.c: (ds_destroy) Ditto. + +Tue Jun 7 00:10:20 2005 Ben Pfaff + + Continue work on bug 12859, plus some code cleanup. + + * data-list.c: (cmd_repeating_data) Replace `seen' bitmap by + boolean variables. Don't try to compute starts_end, cont_end for + inline file. Calculate length only after parsing variable + specifications. Add proper transformation to list. + (realize_value) If the rpd_num_or_var has no value, return new + DEFAULT_MEMBER argument (for use with inline file). + (repeating_data_trns_proc) Pass default values. + + * dfm-read.c: (dfm_close_reader) Only skip data if *not* still + open, and only if we actually started reading data. + Sun Jun 5 18:39:36 2005 Ben Pfaff - Fix PR 11894. + Fix bug 11894. * output.c: (outp_read_devices) Fix message. @@ -13,7 +39,7 @@ Fri May 27 12:34:43 WST 2005 John Darrington Thu May 26 12:29:21 2005 Ben Pfaff - Fix PR 13192. + Fix bug 13192. * sort.c: (sort_parse_criteria) Only set *saw_direction if saw_direction is non-null. Thanks to John Darrington for @@ -60,7 +86,7 @@ Tue May 17 18:29:35 2005 Ben Pfaff Tue May 17 00:06:43 2005 Ben Pfaff - Fix PR 11119. + Fix bug 11119. * som.c: (output_encodings) If some cell in the table won't fit with the horizontal or vertical headers, cancel those headers. @@ -76,7 +102,7 @@ Tue May 17 00:06:43 2005 Ben Pfaff Mon May 16 22:34:06 2005 Ben Pfaff - Fix rest of PR 13054. + Fix rest of bug 13054. * format.def: Fix EDATE, SDATE, ADATE, JDATE, QYR, MOYR, WKYR, DATETIME, TIME system/portable file values. @@ -106,7 +132,7 @@ Mon May 16 22:31:15 2005 Ben Pfaff Sun May 15 23:38:10 2005 Ben Pfaff - Fix more of PR 13054. + Fix more of bug 13054. * format.def: FMT_A should allow 255-character output. FMT_AHEX should allow 510-character input and output. @@ -153,7 +179,7 @@ Tue May 10 20:08:18 2005 Ben Pfaff Tue May 10 19:56:35 2005 Ben Pfaff - Start to fix PR 13054. + Start to fix bug 13054. * format.c: (check_input_specifier) Improve error message. (check_input_specifier) Check F, COMMA, and DOLLAR formats for @@ -169,7 +195,7 @@ Mon May 9 07:14:29 WST 2005 John Darrington Sun May 8 13:52:12 2005 Ben Pfaff - "Fix" PR 13021 by disabling FILE TYPE. Eventually, we should + "Fix" bug 13021 by disabling FILE TYPE. Eventually, we should actually implement it. * command.c: (FILE_TYPE_okay) Always return 1. @@ -185,7 +211,7 @@ Sun May 8 08:08:07 WST 2005 John Darrington Wed May 4 23:54:02 2005 Ben Pfaff - Fix PR 12948. See also new test in + Fix bug 12948. See also new test in tests/bugs/match-file-scratch.sh. * get.c: (mtf_merge_dictionary) Don't compact dictionary because @@ -241,7 +267,7 @@ Mon May 2 23:45:01 2005 Ben Pfaff Mon May 2 23:37:19 2005 Ben Pfaff - Partial fix for PR 12859. + Partial fix for bug 12859. * data-list.c: (cmd_data_list) Add transformation properly in vfm_source == NULL case. @@ -253,11 +279,11 @@ Mon May 2 23:27:28 2005 Ben Pfaff Mon May 2 22:28:17 2005 Ben Pfaff * get.c: (cmd_match_files) Check token type before trying to match - tokid. Fixes PR 12923. + tokid. Fixes bug 12923. Mon May 2 22:16:51 2005 Ben Pfaff - * flip.c: [HAVE_SYS_TYPES_H] Include . Fixes PR + * flip.c: [HAVE_SYS_TYPES_H] Include . Fixes bug 12789. Mon May 2 22:02:52 2005 Ben Pfaff @@ -476,7 +502,7 @@ Sun May 1 15:05:54 WST 2005 John Darrington Thu Apr 28 18:52:06 2005 Ben Pfaff - * expressions/parse.c: Improve previous fix for PR 12858 (LAG). + * expressions/parse.c: Improve previous fix for bug 12858 (LAG). Fri Apr 29 09:28:00 WST 2005 John Darrington @@ -494,7 +520,7 @@ Wed Apr 27 07:43:50 WST 2005 John Darrington Mon Apr 25 22:55:59 2005 Ben Pfaff - Finish fixing MATCH FILES (PR 11677). + Finish fixing MATCH FILES (bug 11677). * get.c: (trim_dictionary) Rewrite in terms of drop_variables(), keep_variables(), rename_variables(). @@ -589,7 +615,7 @@ Thu Apr 14 2005 John Darrington Mon Apr 4 22:27:34 2005 Ben Pfaff * aggregate.c: (parse_aggregate_functions) If dict_create_var() - fails, don't dereference the resulting null pointer (PR 12427). + fails, don't dereference the resulting null pointer (bug 12427). Also, fix double free error. Sat Mar 19 23:06:02 2005 Ben Pfaff @@ -611,7 +637,7 @@ Mon Mar 14 21:52:34 2005 Ben Pfaff Mon Mar 14 21:07:23 2005 Ben Pfaff - Make sort stable (PR 12313). + Make sort stable (bug 12313). * sort.c: Don't need to include some headers anymore. (static var min_buffers) New variable. @@ -666,7 +692,7 @@ Sun Mar 13 22:52:05 2005 Ben Pfaff Sun Mar 13 22:40:54 2005 Ben Pfaff - First phase of making SORT CASES stable (PR 12313). + First phase of making SORT CASES stable (bug 12313). * sort.c: (struct indexed_case) New structure. (do_internal_sort) Rewrite to make internal sorting stable. @@ -734,11 +760,11 @@ Sun Mar 13 14:54:27 WST 2005 John Darrington Sat Mar 12 13:29:21 2005 Ben Pfaff * split-file.c: (cmd_split_file) Ignore LAYERED and SEPARATE - keywords (PR 11628). + keywords (bug 11628). Sat Mar 12 13:17:12 2005 Ben Pfaff - * vfm.c: (procedure_with_splits) Fix PR 11492: end_func() must be + * vfm.c: (procedure_with_splits) Fix bug 11492: end_func() must be called *before* close_active_file(). Sat Mar 12 12:20:57 2005 Ben Pfaff @@ -822,7 +848,7 @@ Sun Mar 6 23:25:40 2005 Ben Pfaff Sun Mar 6 19:52:22 2005 Ben Pfaff DATA LIST with free-field formats should not have implied decimal - places (PR 12035). Also clean up data-in.c a bit. + places (bug 12035). Also clean up data-in.c a bit. * data-in.h: (enum) Add DI_IMPLIED_DECIMALS. @@ -1027,7 +1053,7 @@ Fri Feb 25 21:11:35 WST 2005 John Darrington Sun Feb 13 16:11:13 2005 Ben Pfaff - Fix PR 11955. + Fix bug 11955. * aggregate.c: (parse_aggregate_functions) Code cleanup. Important part: get rid of spurious copying of function->format to @@ -1035,7 +1061,7 @@ Sun Feb 13 16:11:13 2005 Ben Pfaff Fri Feb 11 00:08:36 2005 Ben Pfaff - Fix PR 11916, which was confusing a variable's `index' member + Fix bug 11916, which was confusing a variable's `index' member with the variable's position in a var_set. Although these are usually the same, they are not for array `var_set's. @@ -1228,7 +1254,7 @@ Wed Jan 5 08:30:48 WST 2005 John Darrington Mon Jan 3 17:44:37 2005 Ben Pfaff * pfm-read.c: (read_variables) Remove direct manipulation of - v->aux, which is no longer needed. Fixes PR 11483. + v->aux, which is no longer needed. Fixes bug 11483. Sat Jan 1 19:01:16 WST 2005 John Darrington diff --git a/src/data-list.c b/src/data-list.c index 92eaab9a..2ed1f673 100644 --- a/src/data-list.c +++ b/src/data-list.c @@ -1369,7 +1369,11 @@ cmd_repeating_data (void) { struct repeating_data_trns *rpd; int table = 1; /* Print table? */ - unsigned seen = 0; /* Mark subcommands as already seen. */ + bool saw_starts = false; /* Saw STARTS subcommand? */ + bool saw_occurs = false; /* Saw OCCURS subcommand? */ + bool saw_length = false; /* Saw LENGTH subcommand? */ + bool saw_continued = false; /* Saw CONTINUED subcommand? */ + bool saw_id = false; /* Saw ID subcommand? */ struct file_handle *const fh = default_handle; assert (case_source_is_complex (vfm_source)); @@ -1406,13 +1410,13 @@ cmd_repeating_data (void) else if (lex_match_id ("STARTS")) { lex_match ('='); - if (seen & 1) + if (saw_starts) { msg (SE, _("%s subcommand given multiple times."),"STARTS"); goto error; } - seen |= 1; - + saw_starts = true; + if (!parse_num_or_var (&rpd->starts_beg, "STARTS beginning column")) goto error; @@ -1441,12 +1445,12 @@ cmd_repeating_data (void) else if (lex_match_id ("OCCURS")) { lex_match ('='); - if (seen & 2) + if (saw_occurs) { msg (SE, _("%s subcommand given multiple times."),"OCCURS"); goto error; } - seen |= 2; + saw_occurs |= 2; if (!parse_num_or_var (&rpd->occurs, "OCCURS")) goto error; @@ -1454,12 +1458,12 @@ cmd_repeating_data (void) else if (lex_match_id ("LENGTH")) { lex_match ('='); - if (seen & 4) + if (saw_length & 4) { msg (SE, _("%s subcommand given multiple times."),"LENGTH"); goto error; } - seen |= 4; + saw_length |= 4; if (!parse_num_or_var (&rpd->length, "LENGTH")) goto error; @@ -1467,12 +1471,12 @@ cmd_repeating_data (void) else if (lex_match_id ("CONTINUED")) { lex_match ('='); - if (seen & 8) + if (saw_continued & 8) { msg (SE, _("%s subcommand given multiple times."),"CONTINUED"); goto error; } - seen |= 8; + saw_continued |= 8; if (!lex_match ('/')) { @@ -1500,12 +1504,12 @@ cmd_repeating_data (void) else if (lex_match_id ("ID")) { lex_match ('='); - if (seen & 16) + if (saw_id & 16) { msg (SE, _("%s subcommand given multiple times."),"ID"); goto error; } - seen |= 16; + saw_id |= 16; if (!lex_force_int ()) goto error; @@ -1569,58 +1573,52 @@ cmd_repeating_data (void) } /* Comes here when DATA specification encountered. */ - if ((seen & (1 | 2)) != (1 | 2)) + if (!saw_starts || !saw_occurs) { - if ((seen & 1) == 0) + if (!saw_starts) msg (SE, _("Missing required specification STARTS.")); - if ((seen & 2) == 0) + if (!saw_occurs) msg (SE, _("Missing required specification OCCURS.")); goto error; } /* Enforce ID restriction. */ - if ((seen & 16) && !(seen & 8)) + if (saw_id && !saw_continued) { msg (SE, _("ID specified without CONTINUED.")); goto error; } - /* Calculate starts_end, cont_end if necessary. */ - 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); - - /* Calculate length if possible. */ - if ((seen & 4) == 0) + /* Calculate starts_end, cont_end if necessary and possible. */ + if (fh != NULL) { - struct dls_var_spec *iter; - - for (iter = rpd->first; iter; iter = iter->next) - { - if (iter->lc > rpd->length.num) - rpd->length.num = iter->lc; - } - assert (rpd->length.num != 0); + 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); } lex_match ('='); if (!parse_repeating_data (&rpd->first, &rpd->last)) goto error; + /* Calculate length if necessary. */ + if (!saw_length) + { + struct dls_var_spec *iter; + + for (iter = rpd->first; iter; iter = iter->next) + if (iter->lc > rpd->length.num) + rpd->length.num = iter->lc; + assert (rpd->length.num != 0); + } + if (table) dump_fixed_table (rpd->first, fh, rpd->last->rec); - { - struct repeating_data_trns *new_trns; - - 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); - add_transformation ((struct trns_header *) new_trns); - } + rpd->h.proc = repeating_data_trns_proc; + rpd->h.free = repeating_data_trns_free; + add_transformation (&rpd->h); return lex_end_of_command (); @@ -1746,25 +1744,23 @@ 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. */ + invalid. If N does not have a value, returns DEFAULT_VALUE, + which must be nonzero if this is possible. */ static int -realize_value (struct rpd_num_or_var *n, struct ccase *c) +realize_value (struct rpd_num_or_var *n, struct ccase *c, int default_value) { - if (n->num > 0) + if (n->num != 0) return n->num; - - assert (n->num == 0); - if (n->var != NULL) + else if (n->var != NULL) { double v = case_num (c, n->var->fv); - - if (v == SYSMIS || v <= INT_MIN || v >= INT_MAX) - return -1; - else - return v; + return v != SYSMIS && v >= INT_MIN && v <= INT_MAX ? v : -1; + } + else + { + assert (default_value != 0); + return default_value; } - else - return 0; } /* Parameter record passed to rpd_parse_record(). */ @@ -1919,13 +1915,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); + occurs_left = occurs = realize_value (&t->occurs, c, 0); if (occurs <= 0) { tmsg (SE, RPD_ERR, _("Invalid value %d for OCCURS."), occurs); return -3; } - starts_beg = realize_value (&t->starts_beg, c); + starts_beg = realize_value (&t->starts_beg, c, 0); if (starts_beg <= 0) { tmsg (SE, RPD_ERR, _("Beginning column for STARTS (%d) must be " @@ -1933,7 +1929,7 @@ repeating_data_trns_proc (struct trns_header *trns, struct ccase *c, starts_beg); return -3; } - starts_end = realize_value (&t->starts_end, c); + starts_end = realize_value (&t->starts_end, c, line.length + 1); if (starts_end < starts_beg) { tmsg (SE, RPD_ERR, _("Ending column for STARTS (%d) is less than " @@ -1941,14 +1937,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); + length = realize_value (&t->length, c, 0); 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); + cont_beg = realize_value (&t->cont_beg, c, 0); if (cont_beg < 0) { tmsg (SE, RPD_ERR, _("Beginning column for CONTINUED (%d) must be " @@ -1956,7 +1952,7 @@ repeating_data_trns_proc (struct trns_header *trns, struct ccase *c, cont_beg); return -2; } - cont_end = realize_value (&t->cont_end, c); + cont_end = realize_value (&t->cont_end, c, line.length + 1); if (cont_end < cont_beg) { tmsg (SE, RPD_ERR, _("Ending column for CONTINUED (%d) is less than " diff --git a/src/dfm-read.c b/src/dfm-read.c index 32b458e0..76f80ad0 100644 --- a/src/dfm-read.c +++ b/src/dfm-read.c @@ -78,11 +78,12 @@ dfm_close_reader (struct dfm_reader *r) assert (inline_open_cnt > 0); still_open = --inline_open_cnt; - if (still_open) + if (!still_open) { /* Skip any remaining data on the inline file. */ - while ((r->flags & DFM_EOF) == 0) - read_record (r); + if (r->flags & DFM_SAW_BEGIN_DATA) + while ((r->flags & DFM_EOF) == 0) + read_record (r); inline_file = NULL; } } diff --git a/src/error.c b/src/error.c index f3f805c6..3c91f732 100644 --- a/src/error.c +++ b/src/error.c @@ -203,6 +203,8 @@ err_hcf (int success) getl_uninitialize (); free(file_loc); + file_loc = NULL; + outp_done (); done_glob(); diff --git a/src/output.c b/src/output.c index 60d24010..b9f465db 100644 --- a/src/output.c +++ b/src/output.c @@ -455,8 +455,13 @@ outp_done (void) free(n); n = next; } + outp_class_list = NULL; + free (outp_title); + outp_title = NULL; + free (outp_subtitle); + outp_subtitle = NULL; return 1; } diff --git a/src/str.c b/src/str.c index 2a766520..56b0491e 100644 --- a/src/str.c +++ b/src/str.c @@ -306,6 +306,7 @@ void ds_destroy (struct string *st) { free (st->string); + st->string = NULL;x } /* Truncates ST to zero length. */ diff --git a/src/vfm.c b/src/vfm.c index 6944df2b..90edfcd0 100644 --- a/src/vfm.c +++ b/src/vfm.c @@ -626,7 +626,7 @@ cancel_transformations (void) } n_trns = f_trns = 0; free (t_trns); - t_trns=NULL; + t_trns = NULL; m_trns = 0; } -- 2.30.2