Some more cleanup with value labels.
authorBen Pfaff <blp@gnu.org>
Sun, 7 May 2006 02:04:12 +0000 (02:04 +0000)
committerBen Pfaff <blp@gnu.org>
Sun, 7 May 2006 02:04:12 +0000 (02:04 +0000)
src/data/ChangeLog
src/data/value-labels.c
src/data/value-labels.h
src/language/data-io/ChangeLog
src/language/data-io/get.c
src/language/dictionary/ChangeLog
src/language/dictionary/apply-dictionary.c

index 0c6215d0b917ea2c2c863bdf6cf7dcf14ce56038..c34816a21f01cc3f9d9e188f926a7c379b939a5b 100644 (file)
@@ -1,3 +1,10 @@
+Sat May  6 19:02:00 2006  Ben Pfaff  <blp@gnu.org>
+
+       * value-labels.c (val_labs_can_set_width): New function.
+       (val_labs_set_width) Clear labels if increasing width to long
+       string.
+       (val_labs_destroy) Remove unneeded test for null.
+       
 Sat May  6 16:14:08 2006  Ben Pfaff  <blp@gnu.org>
 
        * value-labels.h: Remove unneeded dependency on variable.h.
index 594518e07758611882ef428c519543a2f4af0fab..b9c85d54f1e1477f39bab8e0b2e3d9ccb189e6be 100644 (file)
@@ -47,8 +47,8 @@ struct val_labs
   };
 
 /* Creates and returns a new, empty set of value labels with the
-   given WIDTH, which must designate a numeric (0) or short
-   string (1...MAX_SHORT_STRING inclusive) width. */
+   given WIDTH.  To actually add any value labels, WIDTH must be
+   a numeric or short string width. */
 struct val_labs *
 val_labs_create (int width) 
 {
@@ -80,16 +80,53 @@ val_labs_copy (const struct val_labs *vls)
   return copy;
 }
 
+/* Determines whether VLS's width can be changed to NEW_WIDTH.
+   Numeric widths cannot be changed at all.
+   Strings can be widened.  They can be shortened only if the
+   characters that will be truncated are spaces. */
+bool
+val_labs_can_set_width (const struct val_labs *vls, int new_width) 
+{
+  assert ((vls->width == 0) == (new_width == 0));
+
+  if (vls->width == 0)
+    return new_width == 0;
+  else if (new_width < vls->width)
+    {
+      struct val_labs_iterator *i;
+      struct val_lab *lab;
+
+      for (lab = val_labs_first (vls, &i); lab != NULL;
+           lab = val_labs_next (vls, &i))
+        {
+          int j;
+
+          /* We can shorten the value labels only if all the
+             truncated characters are blanks. */
+          for (j = vls->width; j < new_width; j++)
+            if (lab->value.s[j] != ' ') 
+              {
+                val_labs_done (&i);
+                return false;
+              }
+        }
+      return true;
+    }
+  else
+    return true;
+}
+
 /* Changes the width of VLS to NEW_WIDTH.  If VLS is numeric,
    NEW_WIDTH must be 0, otherwise it must be within the range
    1...MAX_SHORT_STRING inclusive. */
 void
 val_labs_set_width (struct val_labs *vls, int new_width) 
 {
-  assert (vls != NULL);
-  assert ((vls->width == 0) == (new_width == 0));
+  assert (val_labs_can_set_width (vls, new_width));
 
   vls->width = new_width;
+  if (new_width > MAX_SHORT_STRING)
+    val_labs_clear (vls);
 }
 
 /* Destroys VLS. */
@@ -98,8 +135,7 @@ val_labs_destroy (struct val_labs *vls)
 {
   if (vls != NULL) 
     {
-      if (vls->labels != NULL)
-        hsh_destroy (vls->labels);
+      hsh_destroy (vls->labels);
       free (vls);
     }
 }
index 595d101a5a04aa066205f2d33ce13406bbe16708..f0ea0a6d2b09ad81695419ba4204d0506e16b53d 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef VAL_LABS_H
 #define VAL_LABS_H 1
 
+#include <stdbool.h>
 #include <stddef.h>
 
 #include <data/value.h>
@@ -35,11 +36,13 @@ struct val_lab
 
 struct val_labs *val_labs_create (int width);
 struct val_labs *val_labs_copy (const struct val_labs *);
-void val_labs_set_width (struct val_labs *, int new_width);
 void val_labs_destroy (struct val_labs *);
 void val_labs_clear (struct val_labs *);
 size_t val_labs_count (const struct val_labs *);
 
+bool val_labs_can_set_width (const struct val_labs *, int new_width);
+void val_labs_set_width (struct val_labs *, int new_width);
+
 int val_labs_add (struct val_labs *, union value, const char *);
 int val_labs_replace (struct val_labs *, union value, const char *);
 int val_labs_remove (struct val_labs *, union value);
index d03485fe07aa04ac5a84694ae59163f4d5911089..dc6a346ac5737f9c2b8fa386ed46ac43fc901f8b 100644 (file)
@@ -1,3 +1,7 @@
+Sat May  6 19:03:13 2006  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: (mtf_merge_dictionary) Fix value label memory leak.
+
 Sat May  6 13:51:16 2006  Ben Pfaff  <blp@gnu.org>
 
        Use a casefile, instead of a case sink, for MATCH FILES output.
index cdae706653af17a12965ed1f3b85b6dabb10cc9e..eb0a5cebc8d229e015d8e9787805e4e51dbbf0fb 100644 (file)
@@ -1540,8 +1540,11 @@ mtf_merge_dictionary (struct dictionary *const m, struct mtf_file *f)
           if (dv->width == mv->width)
             {
               if (val_labs_count (dv->val_labs)
-                  && !val_labs_count (mv->val_labs))
-                mv->val_labs = val_labs_copy (dv->val_labs);
+                  && !val_labs_count (mv->val_labs)) 
+                {
+                  val_labs_destroy (mv->val_labs);
+                  mv->val_labs = val_labs_copy (dv->val_labs); 
+                }
               if (!mv_is_empty (&dv->miss) && mv_is_empty (&mv->miss))
                 mv_copy (&mv->miss, &dv->miss);
             }
index 9718f7dbb262077bd96e6c37217cc8dadbb3fd7b..407a92e6fd84c40e30abca232a08cdc6692e95cd 100644 (file)
@@ -1,3 +1,8 @@
+Sat May  6 19:03:34 2006  Ben Pfaff  <blp@gnu.org>
+
+       * apply-dictionary.c: (cmd_apply_dictionary) Use new function
+       val_labs_can_set_width().
+
 Sat May  6 10:43:22 2006  Ben Pfaff  <blp@gnu.org>
 
        Continue reforming procedure execution.  In this phase, get rid of
index 1c9e7ef81a19d95647f0ca7f6cb6aea90969bc2b..e3a77e5d4ab3fcb9bfaccfd13f6a9361bacd7569 100644 (file)
@@ -91,38 +91,7 @@ cmd_apply_dictionary (void)
             s->name);
       else if (val_labs_count (s->val_labs))
        {
-          /* Whether to apply the value labels. */
-          int apply = 1;
-          
-         if (t->width < s->width)
-           {
-             struct val_labs_iterator *i;
-             struct val_lab *lab;
-
-              for (lab = val_labs_first (s->val_labs, &i); lab != NULL;
-                   lab = val_labs_next (s->val_labs, &i))
-               {
-                 int j;
-
-                 /* We will apply the value labels only if all
-                     the truncated characters are blanks. */
-                 for (j = t->width; j < s->width; j++)
-                   if (lab->value.s[j] != ' ') 
-                      {
-                        val_labs_done (&i);
-                        apply = 0;
-                        break; 
-                      }
-               }
-           }
-         else
-           {
-             /* Fortunately, we follow the convention that all value
-                label values are right-padded with spaces, so it is
-                unnecessary to bother padding values here. */
-           }
-
-         if (apply) 
+          if (val_labs_can_set_width (s->val_labs, t->width))
             {
               val_labs_destroy (t->val_labs);
               t->val_labs = s->val_labs;