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: 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).
100 AT_SETUP([parse expression with unknown system variable])
101 AT_KEYWORDS([expression expressions parse negative])
102 AT_DATA([parse.sps], [dnl
103 DATA LIST NOTABLE/x 1.
104 COMPUTE x=$nonexistent.
106 AT_CHECK([pspp parse.sps], [1], [dnl
107 parse.sps:2.11-2.22: error: COMPUTE: Unknown system variable $nonexistent.
108 2 | COMPUTE x=$nonexistent.
113 AT_SETUP([parse expression with unknown identifier])
114 AT_KEYWORDS([expression expressions parse negative])
115 AT_DATA([parse.sps], [dnl
116 DATA LIST NOTABLE/x 1.
119 AT_CHECK([pspp parse.sps], [1], [dnl
120 parse.sps:2.11: error: COMPUTE: Unknown identifier y.
126 AT_SETUP([parse expression with extension function in compatibility mode])
127 AT_KEYWORDS([expression expressions parse negative])
128 AT_DATA([parse.sps], [dnl
129 DEBUG EVALUATE/ACOS(0)*0.
131 AT_CHECK([pspp --testing-mode --syntax=compatible parse.sps], [0], [dnl
132 parse.sps:1.16-1.22: warning: DEBUG EVALUATE: ACOS(number) is a PSPP extension.
133 1 | DEBUG EVALUATE/ACOS(0)*0.
140 AT_SETUP([LAG expression following TEMPORARY])
141 AT_KEYWORDS([expression expressions parse negative])
142 AT_DATA([parse.sps], [dnl
143 DATA LIST NOTABLE/x 1.
147 AT_CHECK([pspp parse.sps], [1], [dnl
148 parse.sps:3.11-3.16: error: COMPUTE: LAG(num_variable) may not appear after
150 3 | COMPUTE y=LAG(x).
155 AT_SETUP([parse expression with invalid logical expression])
156 AT_KEYWORDS([expression expressions parse negative])
157 AT_DATA([parse.sps], [dnl
160 COMPUTE var1=NORMAL(100).
168 AT_CHECK([pspp parse.sps], [1], [dnl
169 parse.sps:9.11: error: SELECT IF: This expression, which must be 0 or 1,
170 evaluated to 2. It will be treated as 0.
176 AT_SETUP([chaining operators that shouldn't be])
177 AT_KEYWORDS([expression expressions parse negative])
178 AT_DATA([parse.sps], [dnl
180 * These should provoke warnings.
181 COMPUTE a = 1 < 2 < 3.
182 COMPUTE b = 1 > 2 < 0.
185 * These should not provoke warnings.
186 COMPUTE d = (1 < 2) < 3.
187 COMPUTE e = (2**3)**4.
190 AT_CHECK([pspp parse.sps], [1], [dnl
191 parse.sps:3.13-3.21: warning: COMPUTE: Chaining relational operators (e.g. `a <
192 b < c') will not produce the mathematically expected result. Use the AND
193 logical operator to fix the problem (e.g. `a < b AND b < c'). To disable this
194 warning, insert parentheses.
195 3 | COMPUTE a = 1 < 2 < 3.
198 parse.sps:4.13-4.21: warning: COMPUTE: Chaining relational operators (e.g. `a <
199 b < c') will not produce the mathematically expected result. Use the AND
200 logical operator to fix the problem (e.g. `a < b AND b < c'). To disable this
201 warning, insert parentheses.
202 4 | COMPUTE b = 1 > 2 < 0.
205 parse.sps:5.13-5.19: warning: COMPUTE: The exponentiation operator (`**') is
206 left-associative: `a**b**c' equals `(a**b)**c', not `a**(b**c)'. To disable
207 this warning, insert parentheses.
208 5 | COMPUTE c = 2**3**4.
211 parse.sps:10: error: INPUT PROGRAM: Input program must contain DATA LIST or END
216 AT_SETUP([binary operator type mismatch])
217 AT_KEYWORDS([expression expressions parse negative])
218 AT_DATA([parse.sps], [dnl
219 DEBUG EVALUATE /1 + 'a'.
220 DEBUG EVALUATE /'a' + 1.
221 DEBUG EVALUATE /'a' + 'a'.
222 DEBUG EVALUATE /'a' + ('a').
224 DEBUG EVALUATE /1 < 'a'.
225 DEBUG EVALUATE /'a' < 1.
226 DEBUG EVALUATE /'a' < 'b' < 'c'.
228 AT_CHECK([pspp --testing-mode parse.sps], [1], [dnl
229 parse.sps:1.17-1.23: error: DEBUG EVALUATE: Both operands of + must be numeric.
230 1 | DEBUG EVALUATE /1 + 'a'.
233 parse.sps:1.17: note: DEBUG EVALUATE: This operand has type 'number'.
234 1 | DEBUG EVALUATE /1 + 'a'.
237 parse.sps:1.21-1.23: note: DEBUG EVALUATE: This operand has type 'string'.
238 1 | DEBUG EVALUATE /1 + 'a'.
243 parse.sps:2.17-2.23: error: DEBUG EVALUATE: Both operands of + must be numeric.
244 2 | DEBUG EVALUATE /'a' + 1.
247 parse.sps:2.17-2.19: note: DEBUG EVALUATE: This operand has type 'string'.
248 2 | DEBUG EVALUATE /'a' + 1.
251 parse.sps:2.23: note: DEBUG EVALUATE: This operand has type 'number'.
252 2 | DEBUG EVALUATE /'a' + 1.
259 parse.sps:4.17-4.26: error: DEBUG EVALUATE: Both operands of + must be numeric.
260 4 | DEBUG EVALUATE /'a' + ('a').
263 parse.sps:4.17-4.19: note: DEBUG EVALUATE: This operand has type 'string'.
264 4 | DEBUG EVALUATE /'a' + ('a').
267 parse.sps:4.24-4.26: note: DEBUG EVALUATE: This operand has type 'string'.
268 4 | DEBUG EVALUATE /'a' + ('a').
273 parse.sps:6.17-6.23: error: DEBUG EVALUATE: Both operands of < must have the
275 6 | DEBUG EVALUATE /1 < 'a'.
278 parse.sps:6.17: note: DEBUG EVALUATE: This operand has type 'number'.
279 6 | DEBUG EVALUATE /1 < 'a'.
282 parse.sps:6.21-6.23: note: DEBUG EVALUATE: This operand has type 'string'.
283 6 | DEBUG EVALUATE /1 < 'a'.
288 parse.sps:7.17-7.23: error: DEBUG EVALUATE: Both operands of < must have the
290 7 | DEBUG EVALUATE /'a' < 1.
293 parse.sps:7.17-7.19: note: DEBUG EVALUATE: This operand has type 'string'.
294 7 | DEBUG EVALUATE /'a' < 1.
297 parse.sps:7.23: note: DEBUG EVALUATE: This operand has type 'number'.
298 7 | DEBUG EVALUATE /'a' < 1.
303 parse.sps:8.17-8.31: error: DEBUG EVALUATE: Both operands of < must have the
305 8 | DEBUG EVALUATE /'a' < 'b' < 'c'.
308 parse.sps:8.17-8.25: note: DEBUG EVALUATE: This operand has type 'number'.
309 8 | DEBUG EVALUATE /'a' < 'b' < 'c'.
312 parse.sps:8.29-8.31: note: DEBUG EVALUATE: This operand has type 'string'.
313 8 | DEBUG EVALUATE /'a' < 'b' < 'c'.
316 'a' < 'b' < 'c' => error
320 AT_SETUP([unary operator type mismatch])
321 AT_KEYWORDS([expression expressions parse negative])
322 AT_DATA([parse.sps], [dnl
323 DEBUG EVALUATE /-'a'.
324 DEBUG EVALUATE /----'a'.
325 DEBUG EVALUATE /NOT 'a'.
326 DEBUG EVALUATE /NOT NOT NOT 'a'.
327 DEBUG EVALUATE /NOT F5.2.
329 AT_CHECK([pspp --testing-mode parse.sps], [1], [dnl
330 parse.sps:1.17-1.20: error: DEBUG EVALUATE: The unary - operator requires a
332 1 | DEBUG EVALUATE /-'a'.
335 parse.sps:1.18-1.20: note: DEBUG EVALUATE: The operand of - has type 'string'.
336 1 | DEBUG EVALUATE /-'a'.
341 parse.sps:2.17-2.23: error: DEBUG EVALUATE: The unary - operator requires a
343 2 | DEBUG EVALUATE /----'a'.
346 parse.sps:2.21-2.23: note: DEBUG EVALUATE: The operand of - has type 'string'.
347 2 | DEBUG EVALUATE /----'a'.
352 parse.sps:3.17-3.23: error: DEBUG EVALUATE: The unary NOT operator requires a
354 3 | DEBUG EVALUATE /NOT 'a'.
357 parse.sps:3.21-3.23: note: DEBUG EVALUATE: The operand of NOT has type
359 3 | DEBUG EVALUATE /NOT 'a'.
364 parse.sps:4.17-4.31: error: DEBUG EVALUATE: The unary NOT operator requires a
366 4 | DEBUG EVALUATE /NOT NOT NOT 'a'.
369 parse.sps:4.29-4.31: note: DEBUG EVALUATE: The operand of NOT has type
371 4 | DEBUG EVALUATE /NOT NOT NOT 'a'.
374 NOT NOT NOT 'a' => error
376 parse.sps:5.17-5.24: error: DEBUG EVALUATE: The unary NOT operator requires a
378 5 | DEBUG EVALUATE /NOT F5.2.
381 parse.sps:5.21-5.24: note: DEBUG EVALUATE: The operand of NOT has type
383 5 | DEBUG EVALUATE /NOT F5.2.
390 AT_SETUP([parsing with negative numbers])
391 AT_KEYWORDS([expression expressions parse])
392 AT_DATA([parse.sps], [dnl
393 DEBUG EVALUATE NOOPT POSTFIX /-2**3.
394 DEBUG EVALUATE NOOPT POSTFIX /-2**-3**-4.
395 DEBUG EVALUATE/1 - 2.
397 AT_CHECK([pspp --testing-mode parse.sps], [0], [dnl
398 number: n<2> number: n<3> POW NEG return_number
400 parse.sps:2.31-2.40: warning: DEBUG EVALUATE: The exponentiation operator
401 (`**') is left-associative: `a**b**c' equals `(a**b)**c', not `a**(b**c)'. To
402 disable this warning, insert parentheses.
403 2 | DEBUG EVALUATE NOOPT POSTFIX /-2**-3**-4.
406 number: n<2> number: n<-3> POW number: n<-4> POW NEG return_number
412 AT_SETUP([system variables])
413 AT_KEYWORDS([expression expressions parse])
414 AT_DATA([parse.sps], [dnl
415 DEBUG EVALUATE /$WIDTH.
416 DEBUG EVALUATE /$LENGTH.
417 DEBUG EVALUATE /$SYSMIS.
419 AT_CHECK([pspp --testing-mode parse.sps], [0], [dnl
428 # This test will fail if the current date changes during the test.
429 AT_SETUP([system variables - $DATE $DATE11 $JDATE $TIME])
430 AT_KEYWORDS([expression expressions parse])
431 # Get the date in the formats that $DATE and $DATE11 support.
432 date=$(date +%d-%^b-%y)
433 date11=$(date +%d-%^b-%Y)
434 echo "date=$date" # Should be date=DD-MMM-YY.
435 echo "date11=$date11" # Should be date11=DD-MMM-YYYY.
437 # Maybe we don't have the 'date' program or it doesn't work as we
438 # expect. Check by trying to see if $date and $date11 are in the
439 # expected format. If not, skip the test.
441 [[[0-9][0-9]-[A-Z][A-Z][A-Z]-[0-9][0-9]]], [],
444 [[[0-9][0-9]-[A-Z][A-Z][A-Z]-[0-9][0-9][0-9][0-9]]], [],
447 AT_DATA([parse.sps], [dnl
448 DEBUG EVALUATE /$DATE.
449 DEBUG EVALUATE /$DATE11.
450 DEBUG EVALUATE FORMAT=DATE9 /$JDATE * 86400.
451 DEBUG EVALUATE FORMAT=DATE9 /$TIME.
453 AT_CHECK_UNQUOTED([pspp --testing-mode parse.sps], [0], [dnl
456 \$DATE11 => "$date11"
458 \$JDATE * 86400 => $date
464 AT_SETUP([expressions - negative checks])
465 AT_KEYWORDS([expression expressions parse])
466 AT_DATA([evaluate-base.sps], [dnl
468 DEBUG EVALUATE SET opt.
469 DEBUG EVALUATE /$nonexistent.
470 DEBUG EVALUATE /RANGE(1, 2).
471 DEBUG EVALUATE /CONCAT.1('a', 'b').
472 DEBUG EVALUATE /foobar(x).
473 DEBUG EVALUATE /CONCAT.1('a' b).
474 DEBUG EVALUATE /NCDF.CHISQ(1, 2, 3).
475 DEBUG EVALUATE (a=1)(b=2) VECTOR/v('abc').
478 for opt in OPT NOOPT; do
480 sed "s/opt/$opt/" < evaluate-base.sps > evaluate.sps
481 AT_CHECK([pspp --testing-mode evaluate.sps], [1], [dnl
482 evaluate.sps:3.17-3.28: error: DEBUG EVALUATE: Unknown system variable
484 3 | DEBUG EVALUATE /$nonexistent.
487 $nonexistent => error
489 evaluate.sps:4.17-4.27: error: DEBUG EVALUATE: RANGE(number, number, number[[,
490 number, number]]...) must have an odd number of arguments.
491 4 | DEBUG EVALUATE /RANGE(1, 2).
496 evaluate.sps:5.17-5.34: error: DEBUG EVALUATE: CONCAT(string[[, string]]...)
497 function cannot accept suffix .1 to specify the minimum number of valid
499 5 | DEBUG EVALUATE /CONCAT.1('a', 'b').
502 CONCAT.1('a', 'b') => error
504 evaluate.sps:6.17-6.22: error: DEBUG EVALUATE: No function or vector named
506 6 | DEBUG EVALUATE /foobar(x).
511 evaluate.sps:7.30: error: DEBUG EVALUATE: Syntax error expecting `,' or `@:}@'.
512 7 | DEBUG EVALUATE /CONCAT.1('a' b).
515 CONCAT.1('a' b) => error
517 evaluate.sps:8.17-8.35: error: DEBUG EVALUATE: NCDF.CHISQ(number, number,
518 number) is not available in this version of PSPP.
519 8 | DEBUG EVALUATE /NCDF.CHISQ(1, 2, 3).
520 | ^~~~~~~~~~~~~~~~~~~
522 NCDF.CHISQ(1, 2, 3) => error
524 evaluate.sps:9.34-9.41: error: DEBUG EVALUATE: A vector index must be numeric.
525 9 | DEBUG EVALUATE (a=1)(b=2) VECTOR/v('abc').
528 evaluate.sps:9.36-9.40: note: DEBUG EVALUATE: This vector index has type
530 9 | DEBUG EVALUATE (a=1)(b=2) VECTOR/v('abc').