Prohibit LAG following TEMPORARY. This both matches SPSS behavior and
authorBen Pfaff <blp@gnu.org>
Mon, 1 May 2006 22:14:53 +0000 (22:14 +0000)
committerBen Pfaff <blp@gnu.org>
Mon, 1 May 2006 22:14:53 +0000 (22:14 +0000)
fixes a bug: we saved the cases for LAG before TEMPORARY but allowed
access to variables created afterward anyhow (which could cause a
segfault).

src/language/expressions/ChangeLog
src/language/expressions/generate.pl
src/language/expressions/operations.def
src/language/expressions/parse.c
src/language/expressions/parse.inc.pl
src/language/expressions/private.h

index 5b04f9ffdb49806ca7b1b92c47a371708da4ba56..7f21130e74bcd0f132cb9cb823eaad606a196859 100644 (file)
@@ -1,3 +1,21 @@
+Mon May  1 15:11:48 2006  Ben Pfaff  <blp@gnu.org>
+
+       Prohibit LAG following TEMPORARY.  This both matches SPSS behavior
+       and fixes a bug: we saved the cases for LAG before TEMPORARY but
+       allowed access to variables created afterward anyhow (which could
+       cause a segfault).
+
+       * generate.pl: Parse "perm_only" flag on operations.
+
+       * operations.def: Add "perm_only" flag to LAG operations.
+
+       * parse.c: Disallow OPF_PERM_ONLY operations after TEMPORARY.
+
+       * parse.inc.pl: Output OPF_PERM_ONLY flag for "perm_only"
+       operations.
+
+       * private.h: Add OPF_PERM_ONLY flag.
+
 Sun Apr 23 22:06:45 2006  Ben Pfaff  <blp@gnu.org>
 
        Continue reforming error message support.  In this phase, get rid
index 9d753867cc1f72865e8d251d289748fa21e0926b..4ad1764b1c3c96152703b90e8a22afb85f8120db 100644 (file)
@@ -233,6 +233,7 @@ sub parse_input {
        $op{OPTIMIZABLE} = 1;
        $op{UNIMPLEMENTED} = 0;
        $op{EXTENSION} = 0;
+       $op{PERM_ONLY} = 0;
        for (;;) {
            if (match ('extension')) {
                $op{EXTENSION} = 1;
@@ -240,6 +241,8 @@ sub parse_input {
                $op{OPTIMIZABLE} = 0;
            } elsif (match ('absorb_miss')) {
                $op{ABSORB_MISS} = 1;
+           } elsif (match ('perm_only')) {
+               $op{PERM_ONLY} = 1;
            } else {
                last;
            }
index bd5af76c4e68ad6d35e067f59f518d20220b7f73..95ac1e0b53ab2c14fdf86c8d4412e840f7335283 100644 (file)
@@ -956,7 +956,7 @@ no_opt string operator STR_VAR ()
   return s;
 }
 
-no_opt function LAG (num_var v, pos_int n_before)
+no_opt perm_only function LAG (num_var v, pos_int n_before)
 {
   struct ccase *c = lagged_case (n_before);
   if (c != NULL)
@@ -968,7 +968,7 @@ no_opt function LAG (num_var v, pos_int n_before)
     return SYSMIS;
 }
 
-no_opt function LAG (num_var v)
+no_opt perm_only function LAG (num_var v)
 {
   struct ccase *c = lagged_case (1);
   if (c != NULL)
@@ -980,7 +980,7 @@ no_opt function LAG (num_var v)
     return SYSMIS;
 }
 
-no_opt string function LAG (str_var v, pos_int n_before)
+no_opt perm_only string function LAG (str_var v, pos_int n_before)
      expression e;
 {
   struct ccase *c = lagged_case (n_before);
@@ -990,7 +990,7 @@ no_opt string function LAG (str_var v, pos_int n_before)
     return empty_string;
 }
 
-no_opt string function LAG (str_var v)
+no_opt perm_only string function LAG (str_var v)
      expression e;
 {
   struct ccase *c = lagged_case (1);
index f2bc3254224f258a51a938c879df0b2d03a72051..b4294c16b1dae0d39ee9b4515a43817f7cc038ba 100644 (file)
@@ -1222,6 +1222,11 @@ parse_function (struct expression *e)
       msg (SE, _("%s is not yet implemented."), f->prototype);
       goto fail;
     }
+  if ((f->flags & OPF_PERM_ONLY) && in_temporary_transformations ()) 
+    {
+      msg (SE, _("%s may not appear after TEMPORARY."), f->prototype);
+      goto fail;
+    }
   
   n = expr_allocate_composite (e, f - operations, args, arg_cnt);
   n->composite.min_valid = min_valid != -1 ? min_valid : f->array_min_elems; 
index ea878c92ccec4fe8db8a603a416203803da78689..47c590fb306f2c06bc7e1abb8ede6fbdf5773967 100644 (file)
@@ -55,6 +55,7 @@ sub generate_output {
        push (@flags, "OPF_NONOPTIMIZABLE") if !$op->{OPTIMIZABLE};
        push (@flags, "OPF_EXTENSION") if $op->{EXTENSION};
        push (@flags, "OPF_UNIMPLEMENTED") if $op->{UNIMPLEMENTED};
+       push (@flags, "OPF_PERM_ONLY") if $op->{PERM_ONLY};
        push (@members, @flags ? join (' | ', @flags) : 0);
 
        push (@members, "OP_$op->{RETURNS}{NAME}");
index 9e00bdf41b02574e44064e2244c9bc79e9212751..0d81c22cdbad8070ee0014f06ebf131a3522579d 100644 (file)
@@ -58,7 +58,11 @@ enum operation_flags
     OPF_UNIMPLEMENTED = 020,
 
     /* If set, this operation is a PSPP extension. */
-    OPF_EXTENSION = 040
+    OPF_EXTENSION = 040,
+
+    /* If set, this operation may not occur after TEMPORARY.
+       (Currently this applies only to LAG.) */
+    OPF_PERM_ONLY = 0100
   };
 
 #define EXPR_ARG_MAX 4