Fixed problem reading long string continuation records.
authorJohn Darrington <john@darrington.wattle.id.au>
Mon, 23 May 2005 04:07:23 +0000 (04:07 +0000)
committerJohn Darrington <john@darrington.wattle.id.au>
Mon, 23 May 2005 04:07:23 +0000 (04:07 +0000)
src/ChangeLog
src/sfm-read.c
tests/command/no_case_size.sh

index 9d954de0d462656ae50ce570bcf07dfb2fa5ebba..5bde5cc220f973826cdc086ff742b50ed9a4ad2e 100644 (file)
@@ -1,3 +1,8 @@
+Mon May 23 11:57:31 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       *sfm-read.c: Fixed some bugs regarding long string continuation
+       records, which the previous fix uncovered.
+
 Sat May 21 12:48:34 WST 2005 John Darrington <john@darrington.wattle.id.au>
 
        * sfm-read.c, sfmP.h:  Allow reading of system files when the 
index f0f9923d886097d6a81d788bedb3a46ad3abaa00..12df275e7f557cc7824709cf0b4a278db8c3fb5f 100644 (file)
@@ -59,7 +59,6 @@ struct sfm_reader
 
     /* Variables. */
     struct sfm_var *vars;       /* Variables. */
-    size_t var_cnt;             /* Number of variables. */
 
     /* File's special constants. */
     flt64 sysmis;
@@ -221,7 +220,6 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
   r->weight_idx = -1;
 
   r->vars = NULL;
-  r->var_cnt = 0;
 
   r->sysmis = -FLT64_MAX;
   r->highest = FLT64_MAX;
@@ -244,6 +242,7 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
   if (!read_header (r, *dict, info) || !read_variables (r, *dict, &var_by_idx))
     goto error;
 
+
   /* Handle weighting. */
   if (r->weight_idx != -1)
     {
@@ -740,7 +739,6 @@ read_variables (struct sfm_reader *r,
   int long_string_count = 0;   /* # of long string continuation
                                   records still expected. */
   int next_value = 0;          /* Index to next `value' structure. */
-  size_t var_cap = 0;
 
   assert(r);
 
@@ -748,7 +746,10 @@ read_variables (struct sfm_reader *r,
 
   /* Pre-allocate variables. */
   if ( r->value_cnt != -1 ) 
-    *var_by_idx = xmalloc(r->value_cnt * sizeof (**var_by_idx));
+    {
+      *var_by_idx = xmalloc(r->value_cnt * sizeof (**var_by_idx));
+      r->vars = xmalloc( r->value_cnt * sizeof (*r->vars) );
+    }
 
 
   /* Read in the entry for each variable and use the info to
@@ -756,7 +757,7 @@ read_variables (struct sfm_reader *r,
   for (i = 0; ; ++i)
     {
       struct variable *vv;
-      char name[9];
+      char name[SHORT_NAME_LEN + 1];
       int nv;
       int j;
 
@@ -779,11 +780,15 @@ read_variables (struct sfm_reader *r,
       if (sv.rec_type != 2)
        {
          buf_unread(r, sizeof sv);
+         r->value_cnt = i;
          break;
        }
 
       if ( -1 == r->value_cnt ) 
-       *var_by_idx = xrealloc (*var_by_idx, sizeof **var_by_idx * (i+1) );
+       {
+         *var_by_idx = xrealloc (*var_by_idx, sizeof **var_by_idx * (i + 1));
+         r->vars = xrealloc(r->vars,  (i + 1) * sizeof (*r->vars) );
+       }
 
       /* If there was a long string previously, make sure that the
         continuations are present; otherwise make sure there aren't
@@ -795,6 +800,8 @@ read_variables (struct sfm_reader *r,
                         "proper number of continuation records."),
                    handle_get_filename (r->fh), i));
 
+
+         r->vars[i].width = -1;
          (*var_by_idx)[i] = NULL;
          long_string_count--;
          continue;
@@ -962,15 +969,9 @@ read_variables (struct sfm_reader *r,
          || !parse_format_spec (r, sv.write, &vv->write, vv))
        goto error;
 
-      /* Add variable to list. */
-      if (var_cap >= r->var_cnt) 
-        {
-          var_cap = 2 + r->var_cnt * 2;
-          r->vars = xrealloc (r->vars, var_cap * sizeof *r->vars);
-        }
-      r->vars[r->var_cnt].width = vv->width;
-      r->vars[r->var_cnt].fv = vv->fv;
-      r->var_cnt++;
+      r->vars[i].width = vv->width;
+      r->vars[i].fv = vv->fv;
+
     }
 
   /* Some consistency checks. */
@@ -984,6 +985,7 @@ read_variables (struct sfm_reader *r,
                  "%d were read from file."),
            handle_get_filename (r->fh), r->value_cnt, next_value);
 
+
   return 1;
 
 error:
@@ -1328,7 +1330,7 @@ read_compressed_data (struct sfm_reader *r, flt64 *buf)
 
   for (;;)
     {
-      for (; p < p_end; p++)
+      for (; p < p_end; p++){
        switch (*p)
          {
          case 0:
@@ -1382,7 +1384,7 @@ read_compressed_data (struct sfm_reader *r, flt64 *buf)
              goto success;
            break;
          }
-
+      }
       /* We have reached the end of this instruction octet.  Read
         another. */
       if (r->ptr == NULL || r->ptr >= r->end)
@@ -1433,7 +1435,7 @@ sfm_read_case (struct sfm_reader *r, struct ccase *c)
         {
           int i;
           
-          for (i = 0; i < r->var_cnt; i++) 
+          for (i = 0; i < r->value_cnt; i++) 
             if (r->vars[i].width == 0)
               bswap_flt64 (&case_data_rw (c, r->vars[i].fv)->f);
         }
@@ -1445,7 +1447,7 @@ sfm_read_case (struct sfm_reader *r, struct ccase *c)
         {
           int i;
           
-          for (i = 0; i < r->var_cnt; i++) 
+          for (i = 0; i < r->value_cnt; i++) 
             if (r->vars[i].width == 0 && case_num (c, i) == r->sysmis)
               case_data_rw (c, r->vars[i].fv)->f = SYSMIS;
         }
@@ -1473,7 +1475,7 @@ sfm_read_case (struct sfm_reader *r, struct ccase *c)
           return 0;
         }
 
-      for (i = 0; i < r->var_cnt; i++)
+      for (i = 0; i < r->value_cnt; i++)
         {
           struct sfm_var *v = &r->vars[i];
 
@@ -1482,9 +1484,9 @@ sfm_read_case (struct sfm_reader *r, struct ccase *c)
               flt64 f = *bounce_cur++;
               if (r->reverse_endian)
                 bswap_flt64 (&f);
-              case_data_rw (c, i)->f = f == r->sysmis ? SYSMIS : f;
+              case_data_rw (c, v->fv)->f = f == r->sysmis ? SYSMIS : f;
             }
-          else 
+          else if (v->width != -1)
             {
               memcpy (case_data_rw (c, v->fv)->s, bounce_cur, v->width);
               bounce_cur += DIV_RND_UP (v->width, sizeof (flt64));
index d8e1893590fa5a96bbb8e909dacb5b4188eee0fb..1abfdbceca41a6ad12d5d9e4444c41ae68f0c2a2 100755 (executable)
@@ -52,6 +52,7 @@ mkdir -p $TEMPDIR
 
 cd $TEMPDIR
 
+activity="create program"
 cat <<EOF > $TESTFILE
 GET FILE='$top_srcdir/tests/no_case_size.sav'.
 DISPLAY DICTIONARY.
@@ -61,7 +62,7 @@ if [ $? -ne 0 ] ; then no_result ; fi
 
 
 activity="run program"
-$SUPERVISOR $here/../src/pspp --testing-mode -o raw-ascii $TESTFILE > /dev/null
+$SUPERVISOR $here/../src/pspp --testing-mode -o raw-ascii $TESTFILE
 if [ $? -ne 0 ] ; then no_result ; fi
 
 activity="compare output"
@@ -85,42 +86,13 @@ diff -b -B -w pspp.list - <<EOF
 
                             CONT     SIZE      POP    COUNT
 -------------------------------- -------- -------- --------
-Asia    
-        
-        
-        
-
-Africa  
-        
-        
-        
-
-North Am
-erica   
-        
-        
-
-South Am
-erica   
-        
-        
-
-Antarcti
-ca      
-        
-        
-
-Europe  
-        
-        
-        
-
-Australi
-a/Oceani
-a       
-        
-
-
+Asia                             44579000 3.67E+09    44.00 
+Africa                           30065000 7.78E+08    53.00 
+North America                    24256000 4.83E+08    23.00 
+South America                    17819000 3.42E+08    12.00 
+Antarctica                       13209000      .00      .00 
+Europe                            9938000 7.32E+08    46.00 
+Australia/Oceania                 7687000 31000000    14.00 
 
 EOF
 if [ $? -ne 0 ] ; then fail ; fi