Changed all the licence notices in all the files.
[pspp] / src / compute.c
index b08e76feddd9a62f2eb296312b147ab3961a06a9..945412e71d4fbfe7e4d62dcd188bde3aa4f5cc65 100644 (file)
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA. */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
 
 #include <config.h>
-#include <assert.h>
+#include "error.h"
 #include <stdlib.h>
 #include "alloc.h"
+#include "case.h"
 #include "command.h"
+#include "dictionary.h"
 #include "error.h"
-#include "expr.h"
+#include "expressions/public.h"
 #include "lexer.h"
 #include "misc.h"
 #include "str.h"
@@ -110,10 +112,9 @@ compute_num (struct trns_header *compute_, struct ccase *c,
   struct compute_trns *compute = (struct compute_trns *) compute_;
 
   if (compute->test == NULL
-      || expr_evaluate (compute->test, c, case_num, NULL) == 1.0) 
-    {
-      expr_evaluate (compute->rvalue, c, case_num, &c->data[compute->fv]); 
-    }
+      || expr_evaluate_num (compute->test, c, case_num) == 1.0) 
+    case_data_rw (c, compute->fv)->f = expr_evaluate_num (compute->rvalue, c,
+                                                          case_num); 
   
   return -1;
 }
@@ -127,29 +128,26 @@ compute_num_vec (struct trns_header *compute_, struct ccase *c,
   struct compute_trns *compute = (struct compute_trns *) compute_;
 
   if (compute->test == NULL
-      || expr_evaluate (compute->test, c, case_num, NULL) == 1.0) 
+      || expr_evaluate_num (compute->test, c, case_num) == 1.0) 
     {
-      /* Index into the vector. */
-      union value index;
-
-      /* Rounded index value. */
-      int rindx;
+      double index;     /* Index into the vector. */
+      int rindx;        /* Rounded index value. */
 
-      expr_evaluate (compute->element, c, case_num, &index);
-      rindx = floor (index.f + EPSILON);
-      if (index.f == SYSMIS || rindx < 1 || rindx > compute->vector->cnt)
+      index = expr_evaluate_num (compute->element, c, case_num);
+      rindx = floor (index + EPSILON);
+      if (index == SYSMIS || rindx < 1 || rindx > compute->vector->cnt)
         {
-          if (index.f == SYSMIS)
+          if (index == SYSMIS)
             msg (SW, _("When executing COMPUTE: SYSMIS is not a valid value as "
                        "an index into vector %s."), compute->vector->name);
           else
             msg (SW, _("When executing COMPUTE: %g is not a valid value as "
                        "an index into vector %s."),
-                 index.f, compute->vector->name);
+                 index, compute->vector->name);
           return -1;
         }
-      expr_evaluate (compute->rvalue, c, case_num,
-                     &c->data[compute->vector->var[rindx - 1]->fv]); 
+      case_data_rw (c, compute->vector->var[rindx - 1]->fv)->f
+        = expr_evaluate_num (compute->rvalue, c, case_num);
     }
   
   return -1;
@@ -163,15 +161,9 @@ compute_str (struct trns_header *compute_, struct ccase *c,
   struct compute_trns *compute = (struct compute_trns *) compute_;
 
   if (compute->test == NULL
-      || expr_evaluate (compute->test, c, case_num, NULL) == 1.0) 
-    {
-      /* Temporary storage for string expression return value. */
-      union value v;
-
-      expr_evaluate (compute->rvalue, c, case_num, &v);
-      st_bare_pad_len_copy (c->data[compute->fv].s, &v.c[1], compute->width,
-                            v.c[0]); 
-    }
+      || expr_evaluate_num (compute->test, c, case_num) == 1.0) 
+    expr_evaluate_str (compute->rvalue, c, case_num,
+                       case_data_rw (c, compute->fv)->s, compute->width);
   
   return -1;
 }
@@ -185,38 +177,32 @@ compute_str_vec (struct trns_header *compute_, struct ccase *c,
   struct compute_trns *compute = (struct compute_trns *) compute_;
 
   if (compute->test == NULL
-      || expr_evaluate (compute->test, c, case_num, NULL) == 1.0) 
+      || expr_evaluate_num (compute->test, c, case_num) == 1.0) 
     {
-      /* Temporary storage for string expression return value. */
-      union value v;
-
-      /* Index into the vector. */
-      union value index;
+      double index;             /* Index into the vector. */
+      int rindx;                /* Rounded index value. */
+      struct variable *vr;      /* Variable reference by indexed vector. */
 
-      /* Rounded index value. */
-      int rindx;
-
-      /* Variable reference by indexed vector. */
-      struct variable *vr;
-
-      expr_evaluate (compute->element, c, case_num, &index);
-      rindx = floor (index.f + EPSILON);
-      if (index.f == SYSMIS || rindx < 1 || rindx > compute->vector->cnt)
+      index = expr_evaluate_num (compute->element, c, case_num);
+      rindx = floor (index + EPSILON);
+      if (index == SYSMIS) 
         {
-          if (index.f == SYSMIS)
-            msg (SW, _("When executing COMPUTE: SYSMIS is not a valid "
-                       "value as an index into vector %s."),
-                 compute->vector->name);
-          else
-            msg (SW, _("When executing COMPUTE: %g is not a valid value as "
-                       "an index into vector %s."),
-                 index.f, compute->vector->name);
+          msg (SW, _("When executing COMPUTE: SYSMIS is not a valid "
+                     "value as an index into vector %s."),
+               compute->vector->name);
+          return -1; 
+        }
+      else if (rindx < 1 || rindx > compute->vector->cnt)
+        {
+          msg (SW, _("When executing COMPUTE: %g is not a valid value as "
+                     "an index into vector %s."),
+               index, compute->vector->name);
           return -1;
         }
 
-      expr_evaluate (compute->rvalue, c, case_num, &v);
       vr = compute->vector->var[rindx - 1];
-      st_bare_pad_len_copy (c->data[vr->fv].s, &v.c[1], vr->width, v.c[0]); 
+      expr_evaluate_str (compute->rvalue, c, case_num,
+                         case_data_rw (c, vr->fv)->s, vr->width);
     }
   
   return -1;
@@ -233,7 +219,7 @@ cmd_if (void)
   compute = compute_trns_create ();
 
   /* Test expression. */
-  compute->test = expr_parse (PXP_BOOLEAN);
+  compute->test = expr_parse (default_dict, EXPR_BOOLEAN);
   if (compute->test == NULL)
     goto fail;
 
@@ -276,7 +262,8 @@ parse_rvalue_expression (struct compute_trns *compute,
 
   assert (type == NUMERIC || type == ALPHA);
 
-  compute->rvalue = expr_parse (type == ALPHA ? PXP_STRING : PXP_NUMERIC);
+  compute->rvalue = expr_parse (default_dict,
+                                type == ALPHA ? EXPR_STRING : EXPR_NUMBER);
   if (compute->rvalue == NULL)
     return 0;
 
@@ -323,7 +310,7 @@ compute_trns_free (struct trns_header *compute_)
 /* COMPUTE or IF target variable or vector element. */
 struct lvalue
   {
-    char var_name[9];            /* Destination variable name, or "". */
+    char var_name[LONG_NAME_LEN + 1];   /* Destination variable name, or "". */
     const struct vector *vector; /* Destination vector, if any, or NULL. */
     struct expression *element;  /* Destination vector element, or NULL. */
   };
@@ -357,7 +344,7 @@ lvalue_parse (void)
       lex_get ();
       if (!lex_force_match ('('))
        goto lossage;
-      lvalue->element = expr_parse (PXP_NUMERIC);
+      lvalue->element = expr_parse (default_dict, EXPR_NUMBER);
       if (lvalue->element == NULL)
         goto lossage;
       if (!lex_force_match (')'))
@@ -366,8 +353,8 @@ lvalue_parse (void)
   else
     {
       /* Variable name. */
-      strncpy (lvalue->var_name, tokid, 8);
-      lvalue->var_name[8] = '\0';
+      strncpy (lvalue->var_name, tokid, LONG_NAME_LEN);
+      lvalue->var_name[LONG_NAME_LEN] = '\0';
       lex_get ();
     }
   return lvalue;
@@ -436,6 +423,9 @@ lvalue_finalize (struct lvalue *lvalue,
 static void 
 lvalue_destroy (struct lvalue *lvalue) 
 {
+  if ( ! lvalue ) 
+     return ;
+
   expr_free (lvalue->element);
   free (lvalue);
 }