Change explicit variable name checks into use of dict_class_from_id().
[pspp] / src / recode.c
index d799a38b4a70b838e9c2f32d90fbf15ba430b609..ee164b9c7c7889ea04bd6ecf12f941bfc9b5daaf 100644 (file)
 #include <config.h>
 #include <assert.h>
 #include <ctype.h>
+#include <math.h>
 #include <stdlib.h>
 #include "alloc.h"
-#include "approx.h"
-#include "cases.h"
 #include "command.h"
 #include "error.h"
 #include "lexer.h"
 #include "str.h"
 #include "var.h"
 
-#undef DEBUGGING
-/*#define DEBUGGING 1 */
 #include "debug-print.h"
 \f
 /* Definitions. */
 
+/* Type of source value for RECODE. */
 enum
   {
     RCD_END,                   /* sentinel value */
@@ -107,12 +105,12 @@ struct recode_trns
 static int parse_dest_spec (struct rcd_var * rcd, union value *v,
                            size_t *max_dst_width);
 static int parse_src_spec (struct rcd_var * rcd, int type, size_t max_src_width);
-static int recode_trns_proc (struct trns_header *, struct ccase *);
-static void recode_trns_free (struct trns_header *);
+static trns_proc_func recode_trns_proc;
+static trns_free_func recode_trns_free;
 static double convert_to_double (char *, int);
 
 #if DEBUGGING
-static void debug_print (rcd_var * head);
+static void debug_print (struct rcd_var * head);
 #endif
 \f
 /* Parser. */
@@ -167,7 +165,7 @@ cmd_recode (void)
       rcd->sysmis.f = 0;
 
       /* Parse variable names. */
-      if (!parse_variables (NULL, &v, &nv, PV_SAME_TYPE))
+      if (!parse_variables (default_dict, &v, &nv, PV_SAME_TYPE))
        goto lossage;
 
       /* Ensure all variables are same type; find length of longest
@@ -297,7 +295,7 @@ cmd_recode (void)
          if ((rcd->flags & RCD_DEST_MASK) == RCD_DEST_STRING)
            for (i = 0, iter = rcd; i < nv; i++, iter = iter->next)
              {
-               struct variable *v = find_variable (names[i]);
+               struct variable *v = dict_lookup_var (default_dict, names[i]);
 
                if (!v)
                  {
@@ -323,7 +321,7 @@ cmd_recode (void)
          else
            for (i = 0, iter = rcd; i < nv; i++, iter = iter->next)
              {
-               struct variable *v = find_variable (names[i]);
+               struct variable *v = dict_lookup_var (default_dict, names[i]);
 
                if (v)
                  {
@@ -415,17 +413,14 @@ cmd_recode (void)
   for (rcd = head; rcd; rcd = rcd->next)
     if (rcd->dest_name[0])
       {
-       rcd->dest = create_variable (&default_dict, rcd->dest_name,
-                                    NUMERIC, 0);
+       rcd->dest = dict_create_var (default_dict, rcd->dest_name, 0);
        if (!rcd->dest)
          {
-           /* This can occur if a destname is duplicated.  We could
-              give an error at parse time but I don't care enough. */
-           rcd->dest = find_variable (rcd->dest_name);
-           assert (rcd->dest != NULL);
+           /* FIXME: This can occur if a destname is duplicated.
+              We could give an error at parse time but I don't
+              care enough. */
+           rcd->dest = dict_lookup_var_assert (default_dict, rcd->dest_name);
          }
-       else
-         envector (rcd->dest);
       }
 
   trns = xmalloc (sizeof *trns);
@@ -493,6 +488,11 @@ parse_dest_spec (struct rcd_var * rcd, union value * v, size_t *max_dst_width)
          v->c = NULL;
        }
     }
+  else 
+    {
+      lex_error (_("expecting output value"));
+      return 0;
+    }
 
   if ((rcd->flags & RCD_DEST_MASK) == RCD_DEST_ERROR)
     rcd->flags |= flags;
@@ -722,19 +722,19 @@ find_src_numeric (struct rcd_var * v, struct ccase * c)
          return cp;
        break;
       case RCD_SINGLE:
-       if (approx_eq (cmp, cp->f1.f))
+       if (cmp == cp->f1.f)
          return cp;
        break;
       case RCD_HIGH:
-       if (approx_ge (cmp, cp->f1.f))
+       if (cmp >= cp->f1.f)
          return cp;
        break;
       case RCD_LOW:
-       if (approx_le (cmp, cp->f1.f))
+       if (cmp <= cp->f1.f)
          return cp;
        break;
       case RCD_RANGE:
-       if (approx_in_range (cmp, cp->f1.f, cp->f2.f))
+       if (cmp >= cp->f1.f && cmp <= cp->f2.f)
          return cp;
        break;
       case RCD_ELSE:
@@ -778,13 +778,15 @@ find_src_string (struct rcd_var * v, struct ccase * c)
 }
 
 static int
-recode_trns_proc (struct trns_header * t, struct ccase * c)
+recode_trns_proc (struct trns_header * t, struct ccase * c,
+                  int case_num UNUSED)
 {
   struct rcd_var *v;
-  struct coding *cp;
 
   for (v = ((struct recode_trns *) t)->codings; v; v = v->next)
     {
+      struct coding *cp;
+
       switch (v->flags & RCD_SRC_MASK)
        {
        case RCD_SRC_NUMERIC:
@@ -793,6 +795,8 @@ recode_trns_proc (struct trns_header * t, struct ccase * c)
        case RCD_SRC_STRING:
          cp = find_src_string (v, c);
          break;
+        default:
+          assert (0);
        }
       if (!cp)
        continue;
@@ -931,7 +935,7 @@ debug_print (struct rcd_var * head)
    success, NOT_LONG on failure.  On success stores a pointer to the
    first character after the number into *ENDPTR.  From the GNU C
    library. */
-long int
+static long int
 string_to_long (char *nptr, int width, char **endptr)
 {
   int negative;