Sat Dec 27 16:16:49 2003 Ben Pfaff <blp@gnu.org>
[pspp-builds.git] / src / apply-dict.c
index 082a8bd89735aa119bdf3cc25b67f0d32b8843aa..541d93382ddafed986cfe1811a684438573cdf85 100644 (file)
 
 #include <config.h>
 #include <stdlib.h>
-#include "avl.h"
 #include "command.h"
 #include "error.h"
 #include "file-handle.h"
+#include "hash.h"
 #include "lexer.h"
 #include "sfm.h"
 #include "str.h"
+#include "value-labels.h"
 #include "var.h"
 
 #include "debug-print.h"
@@ -54,10 +55,10 @@ cmd_apply_dictionary (void)
   if (dict == NULL)
     return CMD_FAILURE;
 
-  for (i = 0; i < dict->nvar; i++)
+  for (i = 0; i < dict_get_var_cnt (dict); i++)
     {
-      struct variable *s = dict->var[i];
-      struct variable *t = find_variable (s->name);
+      struct variable *s = dict_get_var (dict, i);
+      struct variable *t = dict_lookup_var (default_dict, s->name);
       if (t == NULL)
        continue;
 
@@ -79,27 +80,34 @@ cmd_apply_dictionary (void)
          s->label = NULL;
        }
 
-      if (s->val_lab && t->width > MAX_SHORT_STRING)
+      if (val_labs_count (s->val_labs) && t->width > MAX_SHORT_STRING)
        msg (SW, _("Cannot add value labels from source file to "
                   "long string variable %s."),
             s->name);
-      else if (s->val_lab)
+      else if (val_labs_count (s->val_labs))
        {
+          /* Whether to apply the value labels. */
+          int apply = 1;
+          
          if (t->width < s->width)
            {
-             avl_traverser iter;
-             struct value_label *lab;
+             struct val_labs_iterator *i;
+             struct val_lab *lab;
 
-             avl_traverser_init (iter);
-             while ((lab = avl_traverse (s->val_lab, &iter)) != NULL)
+              for (lab = val_labs_first (s->val_labs, &i); lab != NULL;
+                   lab = val_labs_next (s->val_labs, &i))
                {
                  int j;
 
-                 /* If the truncated characters aren't all blanks
-                    anyway, then don't apply the value labels. */
+                 /* We will apply the value labels only if all
+                     the truncated characters are blanks. */
                  for (j = t->width; j < s->width; j++)
-                   if (lab->v.s[j] != ' ')
-                     goto skip_value_labels;
+                   if (lab->value.s[j] != ' ') 
+                      {
+                        val_labs_done (&i);
+                        apply = 0;
+                        break; 
+                      }
                }
            }
          else
@@ -108,12 +116,15 @@ cmd_apply_dictionary (void)
                 label values are right-padded with spaces, so it is
                 unnecessary to bother padding values here. */
            }
-         
-         avl_destroy (t->val_lab, free_val_lab);
-         t->val_lab = s->val_lab;
-         s->val_lab = NULL;
+
+         if (apply) 
+            {
+              val_labs_destroy (t->val_labs);
+              t->val_labs = s->val_labs;
+              val_labs_set_width (t->val_labs, t->width);
+              s->val_labs = val_labs_create (s->width);
+            }
        }
-    skip_value_labels: ;
 
       if (s->miss_type != MISSING_NONE && t->width > MAX_SHORT_STRING)
        msg (SW, _("Cannot apply missing values from source file to "
@@ -139,6 +150,7 @@ cmd_apply_dictionary (void)
          t->miss_type = s->miss_type;
          memcpy (t->missing, s->missing, sizeof s->missing);
        }
+    skip_missing_values: ;
 
       if (s->type == NUMERIC)
        {
@@ -152,29 +164,14 @@ cmd_apply_dictionary (void)
               "and target files."));
       
   /* Weighting. */
-  {
-    const int tfw = find_variable (default_dict.weight_var) != 0;
-    const int sfw = dict->weight_var[0] != 0;
-    struct variable *w;
-
-    switch (10 * tfw + sfw)
-      {
-      case 10:
-       /* The working file retains its weighting variable. */
-       break;
-
-      case 00:
-      case 01:
-       /* Fall through to case 11. */
-
-      case 11:
-       w = find_variable (dict->weight_var);
-       if (w)
-         strcpy (default_dict.weight_var, dict->weight_var);
-       break;
-      }
-  }
- skip_missing_values: ;
+  if (dict_get_weight (dict) != NULL) 
+    {
+      struct variable *new_weight
+        = dict_lookup_var (default_dict, dict_get_weight (dict)->name);
+
+      if (new_weight != NULL)
+        dict_set_weight (default_dict, new_weight);
+    }
   
   sfm_maybe_close (handle);