+Tue Jun 7 00:14:09 2005 Ben Pfaff <blp@gnu.org>
+
+ 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 <blp@gnu.org>
+
+ 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 <blp@gnu.org>
- Fix PR 11894.
+ Fix bug 11894.
* output.c: (outp_read_devices) Fix message.
Thu May 26 12:29:21 2005 Ben Pfaff <blp@gnu.org>
- 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
Tue May 17 00:06:43 2005 Ben Pfaff <blp@gnu.org>
- 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.
Mon May 16 22:34:06 2005 Ben Pfaff <blp@gnu.org>
- 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.
Sun May 15 23:38:10 2005 Ben Pfaff <blp@gnu.org>
- 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.
Tue May 10 19:56:35 2005 Ben Pfaff <blp@gnu.org>
- 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
Sun May 8 13:52:12 2005 Ben Pfaff <blp@gnu.org>
- "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.
Wed May 4 23:54:02 2005 Ben Pfaff <blp@gnu.org>
- 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
Mon May 2 23:37:19 2005 Ben Pfaff <blp@gnu.org>
- Partial fix for PR 12859.
+ Partial fix for bug 12859.
* data-list.c: (cmd_data_list) Add transformation properly in
vfm_source == NULL case.
Mon May 2 22:28:17 2005 Ben Pfaff <blp@gnu.org>
* 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 <blp@gnu.org>
- * flip.c: [HAVE_SYS_TYPES_H] Include <sys/types.h>. Fixes PR
+ * flip.c: [HAVE_SYS_TYPES_H] Include <sys/types.h>. Fixes bug
12789.
Mon May 2 22:02:52 2005 Ben Pfaff <blp@gnu.org>
Thu Apr 28 18:52:06 2005 Ben Pfaff <blp@gnu.org>
- * 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 <john@darrington.wattle.id.au>
Mon Apr 25 22:55:59 2005 Ben Pfaff <blp@gnu.org>
- 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().
Mon Apr 4 22:27:34 2005 Ben Pfaff <blp@gnu.org>
* 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 <blp@gnu.org>
Mon Mar 14 21:07:23 2005 Ben Pfaff <blp@gnu.org>
- 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.
Sun Mar 13 22:40:54 2005 Ben Pfaff <blp@gnu.org>
- 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.
Sat Mar 12 13:29:21 2005 Ben Pfaff <blp@gnu.org>
* 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 <blp@gnu.org>
- * 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 <blp@gnu.org>
Sun Mar 6 19:52:22 2005 Ben Pfaff <blp@gnu.org>
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.
Sun Feb 13 16:11:13 2005 Ben Pfaff <blp@gnu.org>
- Fix PR 11955.
+ Fix bug 11955.
* aggregate.c: (parse_aggregate_functions) Code cleanup.
Important part: get rid of spurious copying of function->format to
Fri Feb 11 00:08:36 2005 Ben Pfaff <blp@gnu.org>
- 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.
Mon Jan 3 17:44:37 2005 Ben Pfaff <blp@gnu.org>
* 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 <john@darrington.wattle.id.au>
{
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));
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;
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;
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;
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 ('/'))
{
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;
}
/* 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 ();
/* 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(). */
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 "
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 "
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 "
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 "