1 dnl PSPP - a program for statistical analysis.
2 dnl Copyright (C) 2017 Free Software Foundation, Inc.
4 dnl This program is free software: you can redistribute it and/or modify
5 dnl it under the terms of the GNU General Public License as published by
6 dnl the Free Software Foundation, either version 3 of the License, or
7 dnl (at your option) any later version.
9 dnl This program is distributed in the hope that it will be useful,
10 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
11 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 dnl GNU General Public License for more details.
14 dnl You should have received a copy of the GNU General Public License
15 dnl along with this program. If not, see <http://www.gnu.org/licenses/>.
17 AT_BANNER([expression parsing])
19 AT_SETUP([parse expression with unknown variable crash])
20 AT_KEYWORDS([expression expressions parse])
21 AT_DATA([parse.sps], [dnl
24 COMPUTE var1=NORMAL(100).
35 AT_CHECK([pspp -O format=csv parse.sps], [1], [dnl
36 "parse.sps:10.6: error: IF: Unknown identifier y.
40 parse.sps:11: error: Stopping syntax file processing here to avoid a cascade of dependent command failures.
44 AT_SETUP([parsing boolean expression with type mismatch])
45 AT_KEYWORDS([expression expressions parse])
46 AT_DATA([parse.sps], [dnl
47 DATA LIST NOTABLE/x 1(A).
50 AT_CHECK([pspp parse.sps], [1], [dnl
51 parse.sps:2.4-2.8: error: IF: Type mismatch: expression has string type, but a
52 boolean value is required here.
58 AT_SETUP([parsing numeric expression with type mismatch])
59 AT_KEYWORDS([expression expressions parse])
60 AT_DATA([parse.sps], [dnl
61 DATA LIST NOTABLE/x 1.
64 AT_CHECK([pspp parse.sps], [1], [dnl
65 parse.sps:2.11-2.15: error: COMPUTE: Type mismatch: expression has type
66 'string', but a numeric value is required.
72 AT_SETUP([parsing string expression with type mismatch])
73 AT_KEYWORDS([expression expressions parse negative])
74 AT_DATA([parse.sps], [dnl
75 DATA LIST NOTABLE/x 1(A).
78 AT_CHECK([pspp parse.sps], [1], [dnl
79 parse.sps:2.11: error: COMPUTE: Type mismatch: expression has type 'number',
80 but a string value is required.
86 AT_SETUP([assigning string expression to new variable])
87 AT_KEYWORDS([expression expressions parse negative])
88 AT_DATA([parse.sps], [dnl
89 DATA LIST NOTABLE/x 1(A).
92 AT_CHECK([pspp parse.sps], [1], [dnl
93 parse.sps:2.9: error: COMPUTE: This command tries to create a new variable y by
94 assigning a string value to it, but this is not supported. Use the STRING
95 command to create the new variable with the correct width before assigning to
96 it, e.g. STRING y(A20).
102 AT_SETUP([parse expression with unknown system variable])
103 AT_KEYWORDS([expression expressions parse negative])
104 AT_DATA([parse.sps], [dnl
105 DATA LIST NOTABLE/x 1.
106 COMPUTE x=$nonexistent.
108 AT_CHECK([pspp parse.sps], [1], [dnl
109 parse.sps:2.11-2.22: error: COMPUTE: Unknown system variable $nonexistent.
110 2 | COMPUTE x=$nonexistent.
115 AT_SETUP([parse expression with unknown identifier])
116 AT_KEYWORDS([expression expressions parse negative])
117 AT_DATA([parse.sps], [dnl
118 DATA LIST NOTABLE/x 1.
121 AT_CHECK([pspp parse.sps], [1], [dnl
122 parse.sps:2.11: error: COMPUTE: Unknown identifier y.
128 AT_SETUP([parse expression with extension function in compatibility mode])
129 AT_KEYWORDS([expression expressions parse negative])
130 AT_DATA([parse.sps], [dnl
131 DEBUG EVALUATE/ACOS(0)*0.
133 AT_CHECK([pspp --testing-mode --syntax=compatible parse.sps], [0], [dnl
134 parse.sps:1.16-1.22: warning: DEBUG EVALUATE: ACOS(number) is a PSPP extension.
135 1 | DEBUG EVALUATE/ACOS(0)*0.
142 AT_SETUP([LAG expression following TEMPORARY])
143 AT_KEYWORDS([expression expressions parse negative])
144 AT_DATA([parse.sps], [dnl
145 DATA LIST NOTABLE/x 1.
149 AT_CHECK([pspp parse.sps], [1], [dnl
150 parse.sps:3.11-3.16: error: COMPUTE: LAG(num_variable) may not appear after
152 3 | COMPUTE y=LAG(x).
157 AT_SETUP([parse expression with invalid logical expression])
158 AT_KEYWORDS([expression expressions parse negative])
159 AT_DATA([parse.sps], [dnl
162 COMPUTE var1=NORMAL(100).
170 AT_CHECK([pspp parse.sps], [1], [dnl
171 parse.sps:9.11: error: SELECT IF: This expression, which must be 0 or 1,
172 evaluated to 2. It will be treated as 0.
178 AT_SETUP([chaining operators that shouldn't be])
179 AT_KEYWORDS([expression expressions parse negative])
180 AT_DATA([parse.sps], [dnl
182 * These should provoke warnings.
183 COMPUTE a = 1 < 2 < 3.
184 COMPUTE b = 1 > 2 < 0.
187 * These should not provoke warnings.
188 COMPUTE d = (1 < 2) < 3.
189 COMPUTE e = (2**3)**4.
192 AT_CHECK([pspp parse.sps], [1], [dnl
193 parse.sps:3.13-3.21: warning: COMPUTE: Chaining relational operators (e.g. `a <
194 b < c') will not produce the mathematically expected result. Use the AND
195 logical operator to fix the problem (e.g. `a < b AND b < c'). To disable this
196 warning, insert parentheses.
197 3 | COMPUTE a = 1 < 2 < 3.
200 parse.sps:4.13-4.21: warning: COMPUTE: Chaining relational operators (e.g. `a <
201 b < c') will not produce the mathematically expected result. Use the AND
202 logical operator to fix the problem (e.g. `a < b AND b < c'). To disable this
203 warning, insert parentheses.
204 4 | COMPUTE b = 1 > 2 < 0.
207 parse.sps:5.13-5.19: warning: COMPUTE: The exponentiation operator (`**') is
208 left-associative: `a**b**c' equals `(a**b)**c', not `a**(b**c)'. To disable
209 this warning, insert parentheses.
210 5 | COMPUTE c = 2**3**4.
213 parse.sps:1.1-10.17: error: INPUT PROGRAM: Input program does not contain DATA
216 2 | * These should provoke warnings.
218 10 | END INPUT PROGRAM.
222 AT_SETUP([binary operator type mismatch])
223 AT_KEYWORDS([expression expressions parse negative])
224 AT_DATA([parse.sps], [dnl
225 DEBUG EVALUATE /1 + 'a'.
226 DEBUG EVALUATE /'a' + 1.
227 DEBUG EVALUATE /'a' + 'a'.
228 DEBUG EVALUATE /'a' + ('a').
230 DEBUG EVALUATE /1 < 'a'.
231 DEBUG EVALUATE /'a' < 1.
232 DEBUG EVALUATE /'a' < 'b' < 'c'.
234 AT_CHECK([pspp --testing-mode parse.sps], [1], [dnl
235 parse.sps:1.17-1.23: error: DEBUG EVALUATE: Both operands of + must be numeric.
236 1 | DEBUG EVALUATE /1 + 'a'.
239 parse.sps:1.17: note: DEBUG EVALUATE: This operand has type 'number'.
240 1 | DEBUG EVALUATE /1 + 'a'.
243 parse.sps:1.21-1.23: note: DEBUG EVALUATE: This operand has type 'string'.
244 1 | DEBUG EVALUATE /1 + 'a'.
249 parse.sps:2.17-2.23: error: DEBUG EVALUATE: Both operands of + must be numeric.
250 2 | DEBUG EVALUATE /'a' + 1.
253 parse.sps:2.17-2.19: note: DEBUG EVALUATE: This operand has type 'string'.
254 2 | DEBUG EVALUATE /'a' + 1.
257 parse.sps:2.23: note: DEBUG EVALUATE: This operand has type 'number'.
258 2 | DEBUG EVALUATE /'a' + 1.
265 parse.sps:4.17-4.26: error: DEBUG EVALUATE: Both operands of + must be numeric.
266 4 | DEBUG EVALUATE /'a' + ('a').
269 parse.sps:4.17-4.19: note: DEBUG EVALUATE: This operand has type 'string'.
270 4 | DEBUG EVALUATE /'a' + ('a').
273 parse.sps:4.24-4.26: note: DEBUG EVALUATE: This operand has type 'string'.
274 4 | DEBUG EVALUATE /'a' + ('a').
279 parse.sps:6.17-6.23: error: DEBUG EVALUATE: Both operands of < must have the
281 6 | DEBUG EVALUATE /1 < 'a'.
284 parse.sps:6.17: note: DEBUG EVALUATE: This operand has type 'number'.
285 6 | DEBUG EVALUATE /1 < 'a'.
288 parse.sps:6.21-6.23: note: DEBUG EVALUATE: This operand has type 'string'.
289 6 | DEBUG EVALUATE /1 < 'a'.
294 parse.sps:7.17-7.23: error: DEBUG EVALUATE: Both operands of < must have the
296 7 | DEBUG EVALUATE /'a' < 1.
299 parse.sps:7.17-7.19: note: DEBUG EVALUATE: This operand has type 'string'.
300 7 | DEBUG EVALUATE /'a' < 1.
303 parse.sps:7.23: note: DEBUG EVALUATE: This operand has type 'number'.
304 7 | DEBUG EVALUATE /'a' < 1.
309 parse.sps:8.17-8.31: error: DEBUG EVALUATE: Both operands of < must have the
311 8 | DEBUG EVALUATE /'a' < 'b' < 'c'.
314 parse.sps:8.17-8.25: note: DEBUG EVALUATE: This operand has type 'number'.
315 8 | DEBUG EVALUATE /'a' < 'b' < 'c'.
318 parse.sps:8.29-8.31: note: DEBUG EVALUATE: This operand has type 'string'.
319 8 | DEBUG EVALUATE /'a' < 'b' < 'c'.
322 'a' < 'b' < 'c' => error
326 AT_SETUP([unary operator type mismatch])
327 AT_KEYWORDS([expression expressions parse negative])
328 AT_DATA([parse.sps], [dnl
329 DEBUG EVALUATE /-'a'.
330 DEBUG EVALUATE /----'a'.
331 DEBUG EVALUATE /NOT 'a'.
332 DEBUG EVALUATE /NOT NOT NOT 'a'.
333 DEBUG EVALUATE /NOT F5.2.
335 AT_CHECK([pspp --testing-mode parse.sps], [1], [dnl
336 parse.sps:1.17-1.20: error: DEBUG EVALUATE: The unary - operator requires a
338 1 | DEBUG EVALUATE /-'a'.
341 parse.sps:1.18-1.20: note: DEBUG EVALUATE: The operand of - has type 'string'.
342 1 | DEBUG EVALUATE /-'a'.
347 parse.sps:2.17-2.23: error: DEBUG EVALUATE: The unary - operator requires a
349 2 | DEBUG EVALUATE /----'a'.
352 parse.sps:2.21-2.23: note: DEBUG EVALUATE: The operand of - has type 'string'.
353 2 | DEBUG EVALUATE /----'a'.
358 parse.sps:3.17-3.23: error: DEBUG EVALUATE: The unary NOT operator requires a
360 3 | DEBUG EVALUATE /NOT 'a'.
363 parse.sps:3.21-3.23: note: DEBUG EVALUATE: The operand of NOT has type
365 3 | DEBUG EVALUATE /NOT 'a'.
370 parse.sps:4.17-4.31: error: DEBUG EVALUATE: The unary NOT operator requires a
372 4 | DEBUG EVALUATE /NOT NOT NOT 'a'.
375 parse.sps:4.29-4.31: note: DEBUG EVALUATE: The operand of NOT has type
377 4 | DEBUG EVALUATE /NOT NOT NOT 'a'.
380 NOT NOT NOT 'a' => error
382 parse.sps:5.17-5.24: error: DEBUG EVALUATE: The unary NOT operator requires a
384 5 | DEBUG EVALUATE /NOT F5.2.
387 parse.sps:5.21-5.24: note: DEBUG EVALUATE: The operand of NOT has type
389 5 | DEBUG EVALUATE /NOT F5.2.
396 AT_SETUP([parsing with negative numbers])
397 AT_KEYWORDS([expression expressions parse])
398 AT_DATA([parse.sps], [dnl
399 DEBUG EVALUATE NOOPT POSTFIX /-2**3.
400 DEBUG EVALUATE NOOPT POSTFIX /-2**-3**-4.
401 DEBUG EVALUATE/1 - 2.
403 AT_CHECK([pspp --testing-mode parse.sps], [0], [dnl
404 number: n<2> number: n<3> POW NEG return_number
406 parse.sps:2.31-2.40: warning: DEBUG EVALUATE: The exponentiation operator
407 (`**') is left-associative: `a**b**c' equals `(a**b)**c', not `a**(b**c)'. To
408 disable this warning, insert parentheses.
409 2 | DEBUG EVALUATE NOOPT POSTFIX /-2**-3**-4.
412 number: n<2> number: n<-3> POW number: n<-4> POW NEG return_number
418 AT_SETUP([system variables])
419 AT_KEYWORDS([expression expressions parse])
420 AT_DATA([parse.sps], [dnl
421 DEBUG EVALUATE /$WIDTH.
422 DEBUG EVALUATE /$LENGTH.
423 DEBUG EVALUATE /$SYSMIS.
425 AT_CHECK([pspp --testing-mode parse.sps], [0], [dnl
434 # This test will fail if the current date changes during the test.
435 AT_SETUP([system variables - $DATE $DATE11 $JDATE $TIME])
436 AT_KEYWORDS([expression expressions parse])
437 # Get the date in the formats that $DATE and $DATE11 support.
438 date=$(date +%d-%^b-%y)
439 date11=$(date +%d-%^b-%Y)
440 echo "date=$date" # Should be date=DD-MMM-YY.
441 echo "date11=$date11" # Should be date11=DD-MMM-YYYY.
443 # Maybe we don't have the 'date' program or it doesn't work as we
444 # expect. Check by trying to see if $date and $date11 are in the
445 # expected format. If not, skip the test.
447 [[[0-9][0-9]-[A-Z][A-Z][A-Z]-[0-9][0-9]]], [],
450 [[[0-9][0-9]-[A-Z][A-Z][A-Z]-[0-9][0-9][0-9][0-9]]], [],
453 AT_DATA([parse.sps], [dnl
454 DEBUG EVALUATE /$DATE.
455 DEBUG EVALUATE /$DATE11.
456 DEBUG EVALUATE FORMAT=DATE9 /$JDATE * 86400.
457 DEBUG EVALUATE FORMAT=DATE9 /$TIME.
459 AT_CHECK_UNQUOTED([pspp --testing-mode parse.sps], [0], [dnl
462 \$DATE11 => "$date11"
464 \$JDATE * 86400 => $date
470 AT_SETUP([expressions - negative checks])
471 AT_KEYWORDS([expression expressions parse])
472 AT_DATA([evaluate-base.sps], [dnl
474 DEBUG EVALUATE SET opt.
475 DEBUG EVALUATE /$nonexistent.
476 DEBUG EVALUATE /RANGE(1, 2).
477 DEBUG EVALUATE /CONCAT.1('a', 'b').
478 DEBUG EVALUATE /foobar(x).
479 DEBUG EVALUATE /CONCAT.1('a' b).
480 DEBUG EVALUATE /NCDF.CHISQ(1, 2, 3).
481 DEBUG EVALUATE (a=1)(b=2) VECTOR/v('abc').
484 for opt in OPT NOOPT; do
486 sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
487 AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
488 evaluate.sps:3.17-3.28: error: DEBUG EVALUATE: Unknown system variable
490 3 | DEBUG EVALUATE /$nonexistent.
493 $nonexistent => error
495 evaluate.sps:4.17-4.27: error: DEBUG EVALUATE: RANGE(number, number, number[[,
496 number, number]]...) must have an odd number of arguments.
497 4 | DEBUG EVALUATE /RANGE(1, 2).
502 evaluate.sps:5.17-5.34: error: DEBUG EVALUATE: CONCAT(string[[, string]]...)
503 function cannot accept suffix .1 to specify the minimum number of valid
505 5 | DEBUG EVALUATE /CONCAT.1('a', 'b').
508 CONCAT.1('a', 'b') => error
510 evaluate.sps:6.17-6.22: error: DEBUG EVALUATE: No function or vector named
512 6 | DEBUG EVALUATE /foobar(x).
517 evaluate.sps:7.30: error: DEBUG EVALUATE: Syntax error expecting `,' or `@:}@'.
518 7 | DEBUG EVALUATE /CONCAT.1('a' b).
521 CONCAT.1('a' b) => error
523 evaluate.sps:8.17-8.35: error: DEBUG EVALUATE: NCDF.CHISQ(number, number,
524 number) is not available in this version of PSPP.
525 8 | DEBUG EVALUATE /NCDF.CHISQ(1, 2, 3).
526 | ^~~~~~~~~~~~~~~~~~~
528 NCDF.CHISQ(1, 2, 3) => error
530 evaluate.sps:9.34-9.41: error: DEBUG EVALUATE: A vector index must be numeric.
531 9 | DEBUG EVALUATE (a=1)(b=2) VECTOR/v('abc').
534 evaluate.sps:9.36-9.40: note: DEBUG EVALUATE: This vector index has type
536 9 | DEBUG EVALUATE (a=1)(b=2) VECTOR/v('abc').