Adopt use of gnulib for portability.
[pspp-builds.git] / src / sel-if.c
1 /* PSPP - computes sample statistics.
2    Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3    Written by Ben Pfaff <blp@gnu.org>.
4
5    This program is free software; you can redistribute it and/or
6    modify it under the terms of the GNU General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18    02110-1301, USA. */
19
20 #include <config.h>
21 #include "alloc.h"
22 #include "command.h"
23 #include "dictionary.h"
24 #include "error.h"
25 #include "expressions/public.h"
26 #include "lexer.h"
27 #include "str.h"
28 #include "var.h"
29
30 #include "gettext.h"
31 #define _(msgid) gettext (msgid)
32
33 /* SELECT IF transformation. */
34 struct select_if_trns
35   {
36     struct trns_header h;
37     struct expression *e;       /* Test expression. */
38   };
39
40 static trns_proc_func select_if_proc;
41 static trns_free_func select_if_free;
42
43 /* Parses the SELECT IF transformation. */
44 int
45 cmd_select_if (void)
46 {
47   struct expression *e;
48   struct select_if_trns *t;
49
50   e = expr_parse (default_dict, EXPR_BOOLEAN);
51   if (!e)
52     return CMD_FAILURE;
53
54   if (token != '.')
55     {
56       expr_free (e);
57       lex_error (_("expecting end of command"));
58       return CMD_FAILURE;
59     }
60
61   t = xmalloc (sizeof *t);
62   t->h.proc = select_if_proc;
63   t->h.free = select_if_free;
64   t->e = e;
65   add_transformation ((struct trns_header *) t);
66
67   return CMD_SUCCESS;
68 }
69
70 /* Performs the SELECT IF transformation T on case C. */
71 static int
72 select_if_proc (struct trns_header *t_, struct ccase *c,
73                 int case_num)
74 {
75   struct select_if_trns *t = (struct select_if_trns *) t_;
76   return expr_evaluate_num (t->e, c, case_num) == 1.0 ? -1 : -2;
77 }
78
79 /* Frees SELECT IF transformation T. */
80 static void
81 select_if_free (struct trns_header * t)
82 {
83   expr_free (((struct select_if_trns *) t)->e);
84 }
85
86 /* Parses the FILTER command. */
87 int
88 cmd_filter (void)
89 {
90   if (lex_match_id ("OFF"))
91     dict_set_filter (default_dict, NULL);
92   else
93     {
94       struct variable *v;
95
96       lex_match (T_BY);
97       v = parse_variable ();
98       if (!v)
99         return CMD_FAILURE;
100
101       if (v->type == ALPHA)
102         {
103           msg (SE, _("The filter variable must be numeric."));
104           return CMD_FAILURE;
105         }
106
107       if (dict_class_from_id (v->name) == DC_SCRATCH)
108         {
109           msg (SE, _("The filter variable may not be scratch."));
110           return CMD_FAILURE;
111         }
112
113       dict_set_filter (default_dict, v);
114
115       FILTER_before_TEMPORARY = !temporary;
116     }
117
118   return CMD_SUCCESS;
119 }
120
121 /* Parses the PROCESS IF command. */
122 int
123 cmd_process_if (void)
124 {
125   struct expression *e;
126
127   e = expr_parse (default_dict, EXPR_BOOLEAN);
128   if (!e)
129     return CMD_FAILURE;
130
131   if (token != '.')
132     {
133       expr_free (e);
134       lex_error (_("expecting end of command"));
135       return CMD_FAILURE;
136     }
137
138   if (process_if_expr)
139     {
140       msg (MW, _("Only last instance of this command is in effect."));
141       expr_free (process_if_expr);
142     }
143   process_if_expr = e;
144
145   return CMD_SUCCESS;
146 }