Continue work on bug 12859, plus some code cleanup.
authorBen Pfaff <blp@gnu.org>
Tue, 7 Jun 2005 07:20:50 +0000 (07:20 +0000)
committerBen Pfaff <blp@gnu.org>
Tue, 7 Jun 2005 07:20:50 +0000 (07:20 +0000)
src/ChangeLog
src/data-list.c
src/dfm-read.c
src/error.c
src/output.c
src/str.c
src/vfm.c

index 992454aefb3eb3300aba970f7abc433780a3d2a0..08b651374158f4d2b3e9df682153e21dab447ec2 100644 (file)
@@ -1,6 +1,32 @@
+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.
 
@@ -13,7 +39,7 @@ Fri May 27 12:34:43 WST 2005 John Darrington <john@darrington.wattle.id.au>
        
 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
@@ -60,7 +86,7 @@ Tue May 17 18:29:35 2005  Ben Pfaff  <blp@gnu.org>
 
 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.
@@ -76,7 +102,7 @@ Tue May 17 00:06:43 2005  Ben Pfaff  <blp@gnu.org>
        
 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.
@@ -106,7 +132,7 @@ Mon May 16 22:31:15 2005  Ben Pfaff  <blp@gnu.org>
 
 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.
@@ -153,7 +179,7 @@ Tue May 10 20:08:18 2005  Ben Pfaff  <blp@gnu.org>
 
 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
@@ -169,7 +195,7 @@ Mon May  9 07:14:29 WST 2005 John Darrington <john@darrington.wattle.id.au>
 
 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.
@@ -185,7 +211,7 @@ Sun May  8 08:08:07 WST 2005 John Darrington <john@darrington.wattle.id.au>
 
 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
@@ -241,7 +267,7 @@ Mon May  2 23:45:01 2005  Ben Pfaff  <blp@gnu.org>
 
 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.
@@ -253,11 +279,11 @@ Mon May  2 23:27:28 2005  Ben Pfaff  <blp@gnu.org>
 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>
@@ -476,7 +502,7 @@ Sun May  1 15:05:54 WST 2005 John Darrington <john@darrington.wattle.id.au>
 
 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>
 
@@ -494,7 +520,7 @@ Wed Apr 27 07:43:50 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().
@@ -589,7 +615,7 @@ Thu Apr 14 2005 John Darrington
 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>
@@ -611,7 +637,7 @@ Mon Mar 14 21:52:34 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.
@@ -666,7 +692,7 @@ Sun Mar 13 22:52:05 2005  Ben Pfaff  <blp@gnu.org>
        
 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.
@@ -734,11 +760,11 @@ Sun Mar 13 14:54:27 WST 2005 John Darrington <john@darrington.wattle.id.au>
 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>
@@ -822,7 +848,7 @@ Sun Mar  6 23:25:40 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.
 
@@ -1027,7 +1053,7 @@ Fri Feb 25 21:11:35 WST 2005 John Darrington <john@darrington.wattle.id.au>
 
 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
@@ -1035,7 +1061,7 @@ Sun Feb 13 16:11:13 2005  Ben Pfaff  <blp@gnu.org>
 
 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.
        
@@ -1228,7 +1254,7 @@ Wed Jan  5 08:30:48 WST 2005 John Darrington <john@darrington.wattle.id.au>
 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>
 
index 92eaab9a940d7eec4f9a1edfc03a97abb31b88cb..2ed1f673fc5290d5f7c10e967c93eda2fc51aaab 100644 (file)
@@ -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 "
index 32b458e00f64be9f2b0255e38c2a9a510f6688d6..76f80ad0520f3a969e30575aefe901a84e681033 100644 (file)
@@ -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;
         }
     }
index f3f805c60a3992b538c40c1a365cb24e20d9607a..3c91f73266ef4848f5a66931322e32ce43e9b2d0 100644 (file)
@@ -203,6 +203,8 @@ err_hcf (int success)
   getl_uninitialize ();
 
   free(file_loc);
+  file_loc = NULL;
+  
   outp_done ();
   done_glob();
 
index 60d240104afc5b940427f8d8e742b86a263d1dd1..b9f465dbfcb78351f2adfb35b6ced889c7ae353d 100644 (file)
@@ -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;
 }
index 2a766520b135f8d01b01b7ca0a638c589fe459de..56b0491eec793656b4bddd6438414ca0d7ad49dd 100644 (file)
--- 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. */
index 6944df2b7d530f287cc5278a3bc392ae47f4fc4f..90edfcd02694cc74aed682ad7ac8fccc04bedeea 100644 (file)
--- 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;
 }
 \f