dbe915caadc576a7611a6d96c3f2c2796a5e740a
[pspp-builds.git] / tests / xforms / expressions.sh
1 #! /bin/sh
2
3 # Tests the expression optimizer and evaluator.
4
5 TEMPDIR=/tmp/pspp-tst-$$
6
7 here=`pwd`;
8
9 # ensure that top_srcdir is absolute
10 cd $top_srcdir; top_srcdir=`pwd`
11
12 STAT_CONFIG_PATH=$top_srcdir/config
13 export STAT_CONFIG_PATH
14
15
16 cleanup()
17 {
18      cd /
19      rm -rf $TEMPDIR
20 }
21
22
23 fail()
24 {
25     echo $activity
26     echo FAILED
27     cleanup;
28     exit 1;
29 }
30
31
32 no_result()
33 {
34     echo $activity
35     echo NO RESULT;
36     cleanup;
37     exit 2;
38 }
39
40 pass()
41 {
42     cleanup;
43     exit 0;
44 }
45
46 mkdir -p $TEMPDIR
47
48 cd $TEMPDIR
49 activity="create expressions list"
50 cat > 00-num-syn.expr <<'EOF'
51 # Test numeric syntax.
52 1e2 => 100.00
53 1e+2 => 100.00
54 1e-2 => 0.01
55 1e-99 => 0.00
56 EOF
57
58 cat > 01-conv-to-num.expr <<'EOF'
59 # Test using numeric/string values as Booleans and vice-versa
60 0 AND 1 => false
61 $true AND 1 => true
62 1 OR $false => true
63 1 OR $sysmis => true
64 2 OR $sysmis => sysmis
65 2 AND $sysmis => false
66 'string' AND $sysmis => error
67 0 AND $sysmis => false
68 (1>2) + 1 => 1.00
69 $true + $false => 1.00
70 EOF
71
72 cat > 02-add-sub.expr <<'EOF'
73 # Addition and subtraction.
74 1 + 2 => 3.00
75 1 + $true => 2.00
76 $sysmis + 1 => sysmis
77 7676 + $sysmis => sysmis
78 ('foo') + 5 => error
79 ('foo') + ('bar') => error      # Arithmetic concatenation requires CONCAT.
80 'foo' + 'bar' => "foobar"       # Lexical concatentation succeeds.
81 1 +3 - 2 +4 -5 => 1.00
82 1 - $true => 0.00
83 $true - 4/3 => -0.33
84 'string' - 1e10 => error
85 9.5 - '' => error
86 1 - 2 => -1.00
87 52 -23 => 29.00 
88 EOF
89
90 cat > 03-mul-div.expr <<'EOF'
91 # Multiplication and division
92 5 * 10 => 50.00
93 10 * $true => 10.00
94 $true * 5 => 5.00
95 1.5 * $true => 1.50
96 5 * $sysmis => sysmis
97 $sysmis * 15 => sysmis
98 2 * 5 / 10 => 1.00
99 1 / 2 => 0.50
100 2 / 5 => 0.40
101 12 / 3 / 2 => 2.00
102 EOF
103
104 cat > 04-exp.expr <<'EOF'
105 # Exponentiation.
106 2**8 => 256.00
107 (2**3)**4 => 4096.00    # Irritating, but compatible.
108 2**3**4 => 4096.00
109 EOF
110
111 cat > 05-negation.expr <<'EOF'
112 # Unary minus.
113 2+-3 => -1.00
114 2*-3 => -6.00
115 -3**2 => -9.00
116 (-3)**2 => 9.00
117 2**-1 => 0.50
118 0**0 => sysmis
119 0**-1 => sysmis
120 (-3)**1.5 => sysmis
121 EOF
122
123 cat > 06-logical-and.expr <<'EOF'
124 # AND truth table.
125 $false AND $false => false
126 $false AND $true => false
127 $false AND $sysmis => false
128 $true AND $false => false
129 $true AND $true => true
130 $true AND $sysmis => sysmis
131 $sysmis AND $false => false
132 $sysmis AND $true => sysmis
133 $sysmis AND $sysmis => sysmis
134 $false & $false => false
135 $false & $true => false
136 $false & $sysmis => false
137 $true & $false => false
138 $true & $true => true
139 $true & $sysmis => sysmis
140 $sysmis & $false => false
141 $sysmis & $true => sysmis
142 $sysmis & $sysmis => sysmis
143 EOF
144
145 cat > 07-logical-or.expr <<'EOF'
146 # OR truth table.
147 $false OR $false => false
148 $false OR $true => true
149 $false OR $sysmis => sysmis
150 $true OR $false => true
151 $true OR $true => true
152 $true OR $sysmis => true
153 $sysmis OR $false => sysmis
154 $sysmis OR $true => true
155 $sysmis OR $sysmis => sysmis
156 $false | $false => false
157 $false | $true => true
158 $false | $sysmis => sysmis
159 $true | $false => true
160 $true | $true => true
161 $true | $sysmis => true
162 $sysmis | $false => sysmis
163 $sysmis | $true => true
164 $sysmis | $sysmis => sysmis
165 EOF
166
167 cat > 08-logical-not.expr <<'EOF'
168 # NOT truth table.
169 not $false => true
170 not 0 => true
171 not 2.5 => true
172 not $true => false
173 not 1 => false
174 not $sysmis => sysmis
175 ~ $false => true
176 ~ 0 => true
177 ~ 2.5 => true
178 ~ $true => false
179 ~ 1 => false
180 ~ $sysmis => sysmis
181 EOF
182
183 cat > 09-eq.expr <<'EOF'
184 # Relational operators.
185 1 eq 1 => true
186 1 = 1 => true
187 1 eq 2 => false
188 2 = 3 => false
189 1 eq 'foobar' => error
190 5 eq 'foobar' => error
191 'baz' = 10 => error
192 'quux' = 5.55 => error
193 'foobar' = 'foobar' => true
194 'quux' = 'bar' => false
195 'bar   ' = 'bar' => true
196 'asdf         ' = 'asdf  ' => true
197 'asdfj   ' = 'asdf' => false
198 1 + 2 = 3 => true               # Check precedence.
199 1 >= 2 = 2 ge 3 => false        # Check precedence.
200 3 ne 2 ~= 1 => false            # Mathematically true.
201 3 > 2 > 1 => false              # Mathematically true.
202 EOF
203
204 cat > 10-le.expr <<'EOF'
205 1 <= 2 => true
206 2.5 <= 1.5 => false
207 1 le 2 => true
208 2 <= 2 => true
209 2 le 2 => true
210 2 < = 2 => error        # Make sure <= token can't be split.
211 1 <= 'foobar' => error
212 5 <= 'foobar' => error
213 'baz' <= 10 => error
214 'quux' <= 5.55 => error
215 '0123' <= '0123' => true
216 '0123' <= '0124' => true
217 '0124' le '0123' => false
218 '0123  ' <= '0123' => true
219 '0123' le '0123  ' => true
220 EOF
221
222 cat > 11-lt.expr <<'EOF'
223 1 < 2 => true
224 2.5 < 1.5 => false
225 3.5 lt 4 => true
226 4 lt 3.5 => false
227 1 lt 'foobar' => error
228 5 lt 'foobar' => error
229 'baz' < 10 => error
230 'quux' < 5.55 => error
231 '0123' lt '0123' => false
232 '0123' < '0124' => true
233 '0124' lt '0123' => false
234 '0123  ' < '0123' => false
235 '0123' lt '0123  ' => false
236 EOF
237
238 cat > 12-ge.expr <<'EOF'
239 1 >= 2 => false
240 2.5 >= 1.5 => true
241 1 ge 2 => false
242 2 >= 2 => true
243 2 ge 2 => true
244 2 > = 2 => error        # Make sure >= token can't be split.
245 1 >= 'foobar' => error
246 5 ge 'foobar' => error
247 'baz' ge 10 => error
248 'quux' >= 5.55 => error
249 '0123' ge '0123' => true
250 '0123' >= '0124' => false
251 '0124' >= '0123' => true
252 '0123  ' ge '0123' => true
253 '0123' >= '0123  ' => true
254 EOF
255
256 cat > 13-gt.expr <<'EOF'
257 1 > 2 => false
258 2.5 > 1.5 => true
259 3.5 gt 4 => false
260 4 gt 3.5 => true
261 1 gt 'foobar' => error
262 5 gt 'foobar' => error
263 'baz' > 10 => error
264 'quux' > 5.55 => error
265 '0123' gt '0123' => false
266 '0123' > '0124' => false
267 '0124' gt '0123' => true
268 '0123  ' > '0123' => false
269 '0123' gt '0123  ' => false
270 EOF
271
272 cat > 14-ne.expr <<'EOF'
273 1 ne 1 => false
274 1 ~= 1 => false
275 1 <> 2 => true
276 2 ne 3 => true
277 1 ~= 'foobar' => error
278 5 <> 'foobar' => error
279 'baz' ne 10 => error
280 'quux' ~= 5.55 => error
281 'foobar' <> 'foobar' => false
282 'quux' ne 'bar' => true
283 'bar   ' <> 'bar' => false
284 'asdf         ' ~= 'asdf  ' => false
285 'asdfj   ' ne 'asdf' => true
286 1 < > 1 => error        # <> token can't be split
287 1 ~ = 1 => error        # ~= token can't be split
288 EOF
289
290 cat > 15-exp-log.expr <<'EOF'
291 exp(10) => 22026.47
292 exp('x') => error
293
294 lg10(500) => 2.70
295 lg10('x') => error
296
297 ln(10) => 2.30
298 ln('x') => error
299 EOF
300
301 cat > 16-sqrt-abs-mod.expr <<'EOF'
302 sqrt(500) => 22.36
303 sqrt('x') => error
304
305 abs(-10.5) => 10.50
306 abs(-55.79) => 55.79
307 abs(22) => 22.00
308 abs(0) => 0.00
309
310 mod(55.5, 2) => 1.50
311 mod(-55.5, 2) => -1.50
312 mod(55.5, -2) => 1.50
313 mod(-55.5, -2) => -1.50
314 mod('a', 2) => error
315 mod(2, 'a') => error
316 mod('a', 'b') => error
317
318 mod10(55.5) => 5.50
319 mod10(-55.5) => -5.50
320 mod10('x') => error
321 EOF
322
323 cat > 17-rnd-trunc.expr <<'EOF'
324 rnd(5.4) => 5.00
325 rnd(5.6) => 6.00
326 rnd(-5.4) => -5.00
327 rnd(-5.6) => -6.00
328 rnd('x') => error
329
330 trunc(1.2) => 1.00
331 trunc(1.9) => 1.00
332 trunc(-1.2) => -1.00
333 trunc(-1.9) => -1.00
334 trunc('x') => error
335 EOF
336
337 cat > 18-arc.expr <<'EOF'
338 acos(.5) / 3.14159 * 180 => 60.00
339 arcos(.75) / 3.14159 * 180 => 41.41
340 arcos(-.5) / 3.14159 * 180 => 120.00
341 acos(-.75) / 3.14159 * 180 => 138.59
342 acos(-1) / 3.14159 * 180 => 180.00
343 arcos(1) / 3.14159 * 180 => 0.00
344 acos(-1.01) => sysmis
345 arcos(1.01) => sysmis
346 acos('x') => error
347
348 arsin(.5) / 3.14159 * 180 => 30.00
349 asin(.25) / 3.14159 * 180 => 14.48
350 arsin(-.5) / 3.14159 * 180 => -30.00
351 asin(-.25) / 3.14159 * 180 => -14.48
352 arsin(-1.01) => sysmis
353 asin(1.01) => sysmis
354 arsin('x') => error
355
356 artan(1) / 3.14159 * 180 => 45.00
357 atan(10) / 3.14159 * 180 => 84.29
358 artan(-1) / 3.14159 * 180 => -45.00
359 atan(-10) / 3.14159 * 180 => -84.29
360 artan('x') => error
361 EOF
362
363 cat > 19-cos-sin-tan.expr <<'EOF'
364 cos(60 / 180 * 3.14159) => 0.50
365 cos(45 / 180 * 3.14159) => 0.71
366 cos(30 / 180 * 3.14159) => 0.87
367 cos(15 / 180 * 3.14159) => 0.97
368 cos(-60 / 180 * 3.14159) => 0.50
369 cos(-45 / 180 * 3.14159) => 0.71
370 cos(-30 / 180 * 3.14159) => 0.87
371 cos(-15 / 180 * 3.14159) => 0.97
372 cos(123 / 180 * 3.14159) => -0.54
373 cos(321 / 180 * 3.14159) => 0.78
374 cos('x') => error
375
376 sin(60 / 180 * 3.14159) => 0.87
377 sin(45 / 180 * 3.14159) => 0.71
378 sin(30 / 180 * 3.14159) => 0.50
379 sin(15 / 180 * 3.14159) => 0.26
380 sin(-60 / 180 * 3.14159) => -0.87
381 sin(-45 / 180 * 3.14159) => -0.71
382 sin(-30 / 180 * 3.14159) => -0.50
383 sin(-15 / 180 * 3.14159) => -0.26
384 sin(123 / 180 * 3.14159) => 0.84
385 sin(321 / 180 * 3.14159) => -0.63
386 sin('x') => error
387
388 tan(60 / 180 * 3.14159) => 1.73
389 tan(45 / 180 * 3.14159) => 1.00
390 tan(30 / 180 * 3.14159) => 0.58
391 tan(15 / 180 * 3.14159) => 0.27
392 tan(-60 / 180 * 3.14159) => -1.73
393 tan(-45 / 180 * 3.14159) => -1.00
394 tan(-30 / 180 * 3.14159) => -0.58
395 tan(-15 / 180 * 3.14159) => -0.27
396 tan(123 / 180 * 3.14159) => -1.54
397 tan(321 / 180 * 3.14159) => -0.81
398 tan('x') => error
399 EOF
400
401 cat > 20-missing.expr <<'EOF'
402 # FIXME: a variable name as the argument to SYSMIS is a special case
403 # that we don't yet test.  We also can't test VALUE this way.
404 missing(10) => false
405 missing($sysmis) => true
406 missing(asin(1.01)) => true
407 missing(asin(.5)) => false
408 missing('    ') => error
409 nmiss($sysmis) => 1.00
410 nmiss(0) => 0.00
411 nmiss($sysmis, $sysmis, $sysmis) => 3.00
412 nmiss(1, 2, 3, 4) => 0.00
413 nmiss(1, $sysmis, $sysmis, 2, 2, $sysmis, $sysmis, 3, 4) => 4.00
414 nvalid($sysmis) => 0.00
415 nvalid(0) => 1.00
416 nvalid($sysmis, $sysmis, $sysmis) => 0.00
417 nvalid(1, 2, 3, 4) => 4.00
418 nvalid(1, $sysmis, $sysmis, 2, 2, $sysmis, $sysmis, 3, 4) => 5.00
419 sysmis(10) => false
420 sysmis($sysmis) => true
421 sysmis(asin(1.01)) => true
422 sysmis(asin(.5)) => false
423 sysmis('    ') => error
424 EOF
425
426 cat > 21-any.expr <<'EOF'
427 any($sysmis, 1, $sysmis, 3) => sysmis
428 any(1, 1, 2, 3) => true
429 any(2, 1, 2, 3) => true
430 any(3, 1, 2, 3) => true
431 any(5, 1, 2, 3) => false
432 any(1, 1, 1, 1) => true
433 any($sysmis, 1, 1, 1) => sysmis
434 any(1, $sysmis, $sysmis, $sysmis) => sysmis
435 any($sysmis, $sysmis, $sysmis, $sysmis) => sysmis
436 any(1) => error
437 any('1', 2, 3, 4) => error
438 any(1, '2', 3, 4) => error
439 any(1, 2, '3', 4) => error
440 any(1, 2, 3, '4') => error
441
442 any('', 'a', '', 'c') => true
443 any('a', 'a', 'b', 'c') => true
444 any('b', 'a', 'b', 'c') => true
445 any('c', 'a', 'b', 'c') => true
446 any('e', 'a', 'b', 'c') => false
447 any('a', 'a', 'a', 'a') => true
448 any('', 'a', 'a', 'a') => false
449 any('a', '', '', '') => false
450 any('a') => error
451 any('a', 'a  ', 'b', 'c') => true
452 any('b   ', 'a', 'b', 'c') => true
453 any('c   ', 'a', 'b', 'c     ') => true
454 any(a, 'b', 'c', 'd') => error
455 any('a', b, 'c', 'd') => error
456 any('a', 'b', c, 'd') => error
457 any('a', 'b', 'c', d) => error
458 EOF
459
460 cat > 22-range.expr <<'EOF'
461 range(5, 1, 10) => true
462 range(1, 1, 10) => true
463 range(10, 1, 10) => true
464 range(-1, 1, 10) => false
465 range(12, 1, 10) => false
466 range($sysmis, 1, 10) => sysmis
467 range(5, 1, $sysmis) => sysmis
468 range(5, $sysmis, 10) => sysmis
469 range($sysmis, $sysmis, 10) => sysmis 
470 range($sysmis, 1, $sysmis) => sysmis
471 range($sysmis, $sysmis, $sysmis) => sysmis
472 range(0, 1, 8, 10, 18) => false
473 range(1, 1, 8, 10, 18) => true
474 range(6, 1, 8, 10, 18) => true
475 range(8, 1, 8, 10, 18) => true
476 range(9, 1, 8, 10, 18) => false
477 range(10, 1, 8, 10, 18) => true
478 range(13, 1, 8, 10, 18) => true
479 range(16, 1, 8, 10, 18) => true
480 range(18, 1, 8, 10, 18) => true
481 range(20, 1, 8, 10, 18) => false
482 range(1) => error
483 range(1, 2) => error
484 range(1, 2, 3, 4) => error
485 range(1, 2, 3, 4, 5, 6) => error
486 range('1', 2, 3) => error
487 range(1, '2', 3) => error
488 range(1, 2, '3') => error
489
490 range('123', '111', '888') => true
491 range('111', '111', '888') => true
492 range('888', '111', '888') => true
493 range('110', '111', '888') => false
494 range('889', '111', '888') => false
495 range('000', '111', '888') => false
496 range('999', '111', '888') => false
497 range('123   ', '111', '888') => true
498 range('123', '111   ', '888') => true
499 range('123', '111', '888   ') => true
500 range('123', '111    ', '888   ') => true
501 range('00', '01', '08', '10', '18') => false
502 range('01', '01', '08', '10', '18') => true
503 range('06', '01', '08', '10', '18') => true
504 range('08', '01', '08', '10', '18') => true
505 range('09', '01', '08', '10', '18') => false
506 range('10', '01', '08', '10', '18') => true
507 range('15', '01', '08', '10', '18') => true
508 range('18', '01', '08', '10', '18') => true
509 range('19', '01', '08', '10', '18') => false
510 range('1') => error
511 range('1', '2') => error
512 range('1', '2', '3', '4') => error
513 range('1', '2', '3', '4', '5', '6') => error
514 range(1, '2', '3') => error
515 range('1', 2, '3') => error
516 range('1', '2', 3) => error
517 EOF
518
519 cat > 23-max-min.expr <<'EOF'
520 max(1, 2, 3, 4, 5) => 5.00
521 max(1, $sysmis, 2, 3, $sysmis, 4, 5) => 5.00
522 max(1, 2) => 2.00
523 max() => error
524 max(1) => 1.00
525 max(1, $sysmis) => 1.00
526 max(1, 2, 3, $sysmis) => 3.00
527 max.4(1, 2, 3, $sysmis) => sysmis
528 max.4(1, 2, 3) => error
529
530 max("2", "3", "5", "1", "4") => "5"
531 max("1", "2") => "2"
532 max("1") => "1"
533
534 min(1, 2, 3, 4, 5) => 1.00
535 min(1, $sysmis, 2, 3, $sysmis, 4, 5) => 1.00
536 min(1, 2) => 1.00
537 min() => error
538 min(1) => 1.00
539 min(1, $sysmis) => 1.00
540 min(1, 2, 3, $sysmis) => 1.00
541 min.4(1, 2, 3, $sysmis) => sysmis
542 min.4(1, 2, 3) => error
543
544 min("2", "3", "5", "1", "4") => "1"
545 min("1", "2") => "1"
546 min("1") => "1"
547 EOF
548
549 cat > 24-moments.expr <<'EOF'
550 cfvar(1, 2, 3, 4, 5) => 0.53
551 cfvar(1, $sysmis, 2, 3, $sysmis, 4, 5) => 0.53
552 cfvar(1, 2) => 0.47
553 cfvar(1) => error
554 cfvar(1, $sysmis) => sysmis
555 cfvar(1, 2, 3, $sysmis) => 0.50
556 cfvar.4(1, 2, 3, $sysmis) => sysmis
557 cfvar.4(1, 2, 3) => error
558 cfvar('x') => error
559 cfvar('x', 1, 2, 3) => error
560
561 mean(1, 2, 3, 4, 5) => 3.00
562 mean(1, $sysmis, 2, 3, $sysmis, 4, 5) => 3.00
563 mean(1, 2) => 1.50
564 mean() => error
565 mean(1) => 1.00
566 mean(1, $sysmis) => 1.00
567 mean(1, 2, 3, $sysmis) => 2.00
568 mean.4(1, 2, 3, $sysmis) => sysmis
569 mean.4(1, 2, 3) => error
570
571 sd(1, 2, 3, 4, 5) => 1.58
572 sd(1, $sysmis, 2, 3, $sysmis, 4, 5) => 1.58
573 sd(1, 2) => 0.71
574 sd(1) => error
575 sd(1, $sysmis) => sysmis
576 sd(1, 2, 3, $sysmis) => 1.00
577 sd.4(1, 2, 3, $sysmis) => sysmis
578 sd.4(1, 2, 3) => error
579 sd('x') => error
580 sd('x', 1, 2, 3) => error
581
582 sum(1, 2, 3, 4, 5) => 15.00
583 sum(1, $sysmis, 2, 3, $sysmis, 4, 5) => 15.00
584 sum(1, 2) => 3.00
585 sum() => error
586 sum(1) => 1.00
587 sum(1, $sysmis) => 1.00
588 sum(1, 2, 3, $sysmis) => 6.00
589 sum.4(1, 2, 3, $sysmis) => sysmis
590 sum.4(1, 2, 3) => error
591
592 variance(1, 2, 3, 4, 5) => 2.50
593 variance(1, $sysmis, 2, 3, $sysmis, 4, 5) => 2.50
594 variance(1, 2) => 0.50
595 variance(1) => error
596 variance(1, $sysmis) => sysmis
597 variance(1, 2, 3, $sysmis) => 1.00
598 variance.4(1, 2, 3, $sysmis) => sysmis
599 variance.4(1, 2, 3) => error
600 variance('x') => error
601 variance('x', 1, 2, 3) => error
602 EOF
603
604 cat > 25-concat.expr <<'EOF'
605 concat('') => ""
606 concat('a', 'b') => "ab"
607 concat('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h') => "abcdefgh"
608 concat('abcdefgh', 'ijklmnopq') => "abcdefghijklmnopq"
609 concat('a', 1) => error
610 concat(1, 2) => error
611 EOF
612
613 cat > 26-index.expr <<'EOF'
614 index('abcbcde', 'bc') => 2.00
615 index('abcbcde', 'bcd') => 4.00
616 index('abcbcde', 'bcbc') => 2.00
617 index('abcdefgh', 'abc') => 1.00
618 index('abcdefgh', 'bcd') => 2.00
619 index('abcdefgh', 'cde') => 3.00
620 index('abcdefgh', 'def') => 4.00
621 index('abcdefgh', 'efg') => 5.00
622 index('abcdefgh', 'fgh') => 6.00
623 index('abcdefgh', 'fghi') => 0.00
624 index('abcdefgh', 'x') => 0.00
625 index('abcdefgh', 'abch') => 0.00
626 index('banana', 'na') => 3.00
627 index('banana', 'ana') => 2.00
628 index('', 'x') => 0.00
629 index('', '') => sysmis
630 index('abcdefgh', '') => sysmis
631 index('abcdefgh', 'alkjsfdjlskalkjfa') => 0.00
632
633 index('abcbcde', 'bc', 1) => 2.00
634 index('abcbcde', 'dc', 1) => 3.00
635 index('abcbcde', 'abc', 1) => 1.00
636 index('abcbcde', 'bc', 2) => 2.00
637 index('abcbcde', 'dc', 2) => 0.00
638 index('abcbcde', 'abc', 1) => 1.00
639 index('abcbcde', 'bccb', 2) => 2.00
640 index('abcbcde', 'bcbc', 2) => 2.00
641 index('abcbcde', 'bcbc', $sysmis) => sysmis
642 EOF
643
644 cat > 27-rindex.expr <<'EOF'
645 rindex('abcbcde', 'bc') => 4.00
646 rindex('abcbcde', 'bcd') => 4.00
647 rindex('abcbcde', 'bcbc') => 2.00
648 rindex('abcdefgh', 'abc') => 1.00
649 rindex('abcdefgh', 'bcd') => 2.00
650 rindex('abcdefgh', 'cde') => 3.00
651 rindex('abcdefgh', 'def') => 4.00
652 rindex('abcdefgh', 'efg') => 5.00
653 rindex('abcdefgh', 'fgh') => 6.00
654 rindex('abcdefgh', 'fghi') => 0.00
655 rindex('abcdefgh', 'x') => 0.00
656 rindex('abcdefgh', 'abch') => 0.00
657 rindex('banana', 'na') => 5.00
658 rindex('banana', 'ana') => 4.00
659 rindex('', 'x') => 0.00
660 rindex('', '') => sysmis
661 rindex('abcdefgh', '') => sysmis
662 rindex('abcdefgh', 'alkjsfdjlskalkjfa') => 0.00
663
664 rindex('abcbcde', 'bc', 1) => 5.00
665 rindex('abcbcde', 'dc', 1) => 6.00
666 rindex('abcbcde', 'abc', 1) => 5.00
667 rindex('abcbcde', 'bc', 2) => 4.00
668 rindex('abcbcde', 'dc', 2) => 0.00
669 rindex('abcbcde', 'abc', 1) => 5.00
670 rindex('abcbcde', 'bccb', 2) => 4.00
671 rindex('abcbcde', 'bcbc', 2) => 4.00
672 rindex('abcbcde', 'bcbc', $sysmis) => sysmis
673 rindex('abcbcde', 'bcbcg', 2) => sysmis
674 rindex('abcbcde', 'bcbcg', $sysmis) => sysmis
675 rindex('abcbcde', 'bcbcg', 'x') => error
676 rindex(1, 'bcdfkjl', 2) => error
677 rindex('aksj', 2, 2) => error
678 rindex(1, 2, 3) => error
679 rindex(1, 2, '3') => error
680 EOF
681
682 cat > 28-length.expr <<'EOF'
683 length('') => 0.00
684 length('a') => 1.00
685 length('xy') => 2.00
686 length('adsf    ') => 8.00
687 length('abcdefghijkl') => 12.00
688 length(0) => error
689 length($sysmis) => error
690 EOF
691
692 cat > 29-pad.expr <<'EOF'
693 lpad('abc', -1) => ""
694 lpad('abc', 0) => "abc"
695 lpad('abc', 2) => "abc"
696 lpad('abc', 3) => "abc"
697 lpad('abc', 10) => "       abc"
698 lpad('abc', 256) => ""
699 lpad('abc', $sysmis) => ""
700 lpad('abc', -1, '*') => ""
701 lpad('abc', 0, '*') => "abc"
702 lpad('abc', 2, '*') => "abc"
703 lpad('abc', 3, '*') => "abc"
704 lpad('abc', 10, '*') => "*******abc"
705 lpad('abc', 256, '*') => ""
706 lpad('abc', $sysmis, '*') => ""
707 lpad('abc', $sysmis, '') => ""
708 lpad('abc', $sysmis, 'xy') => ""
709 lpad(0, 10) => error
710 lpad('abc', 'def') => error
711 lpad(0, 10, ' ') => error
712 lpad('abc', 'def', ' ') => error
713 lpad('x', 5, 0) => error
714 lpad('x', 5, 2) => error
715
716 rpad('abc', -1) => ""
717 rpad('abc', 0) => "abc"
718 rpad('abc', 2) => "abc"
719 rpad('abc', 3) => "abc"
720 rpad('abc', 10) => "abc       "
721 rpad('abc', 256) => ""
722 rpad('abc', $sysmis) => ""
723 rpad('abc', -1, '*') => ""
724 rpad('abc', 0, '*') => "abc"
725 rpad('abc', 2, '*') => "abc"
726 rpad('abc', 3, '*') => "abc"
727 rpad('abc', 10, '*') => "abc*******"
728 rpad('abc', 256, '*') => ""
729 rpad('abc', $sysmis, '*') => ""
730 rpad('abc', $sysmis, '') => ""
731 rpad('abc', $sysmis, 'xy') => ""
732 rpad(0, 10) => error
733 rpad('abc', 'def') => error
734 rpad(0, 10, ' ') => error
735 rpad('abc', 'def', ' ') => error
736 rpad('x', 5, 0) => error
737 rpad('x', 5, 2) => error
738 EOF
739
740 cat > 30-num-str.expr <<'EOF'
741 number("123", f3.0) => 123.00
742 number(" 123", f3.0) => 12.00
743 number("123", f3.1) => 12.30
744 number("   ", f3.1) => sysmis
745
746 string(123.56, f5.1) => "123.6"
747 string($sysmis, f5.1) => "   . "
748 string("abc", A5) => error
749 EOF
750
751 cat > 31-trim.expr <<'EOF'
752 ltrim('   abc') => "abc"
753 rtrim('   abc   ') => "   abc"
754 ltrim('abc') => "abc"
755 ltrim(' abc') => "      abc"
756 ltrim('    ') => ""
757 ltrim('') => ""
758 ltrim(8) => error
759 ltrim('***abc', '*') => "abc"
760 ltrim('abc', '*') => "abc"
761 ltrim('*abc', '*') => "abc"
762 ltrim('', '*') => ""
763 ltrim(8, '*') => error
764 ltrim(' x', 8) => error
765 ltrim(8, 9) => error
766
767 rtrim('abc   ') => "abc"
768 rtrim('   abc   ') => "   abc"
769 rtrim('abc') => "abc"
770 rtrim('abc      ') => "abc      "
771 rtrim('    ') => ""
772 rtrim('') => ""
773 rtrim(8) => error
774 rtrim('abc***', '*') => "abc"
775 rtrim('abc', '*') => "abc"
776 rtrim('abc*', '*') => "abc"
777 rtrim('', '*') => ""
778 rtrim(8, '*') => error
779 rtrim(' x', 8) => error
780 rtrim(8, 9) => error
781 EOF
782
783 cat > 32-substr.expr <<'EOF'
784 substr('abcdefgh', -5) => ""
785 substr('abcdefgh', 0) => ""
786 substr('abcdefgh', 1) => "abcdefgh"
787 substr('abcdefgh', 3) => "cdefgh"
788 substr('abcdefgh', 5) => "efgh"
789 substr('abcdefgh', 6) => "fgh"
790 substr('abcdefgh', 7) => "gh"
791 substr('abcdefgh', 8) => "h"
792 substr('abcdefgh', 9) => ""
793 substr('abcdefgh', 10) => ""
794 substr('abcdefgh', 20) => ""
795 substr('abcdefgh', $sysmis) => ""
796 substr(0, 10) => error
797 substr('abcd', 'abc') => error
798 substr(0, 'abc') => error
799
800 substr('abcdefgh', 0, 0) => ""
801 substr('abcdefgh', 3, 0) => ""
802 substr('abcdefgh', 5, 0) => ""
803 substr('abcdefgh', 9, 0) => ""
804 substr('abcdefgh', 0, 1) => ""
805 substr('abcdefgh', 0, 5) => ""
806 substr('abcdefgh', 1, 8) => "abcdefgh"
807 substr('abcdefgh', 1, 10) => "abcdefgh"
808 substr('abcdefgh', 1, 20) => "abcdefgh"
809 substr('abcdefgh', 3, 4) => "cdef"
810 substr('abcdefgh', 5, 2) => "ef"
811 substr('abcdefgh', 6, 1) => "f"
812 substr('abcdefgh', 7, 10) => "gh"
813 substr('abcdefgh', 8, 1) => "h"
814 substr('abcdefgh', 8, 2) => "h"
815 substr('abcdefgh', 9, 11) => ""
816 substr('abcdefgh', 10, 52) => ""
817 substr('abcdefgh', 20, 1) => ""
818 substr('abcdefgh', $sysmis, 2) => ""
819 substr('abcdefgh', 9, $sysmis) => ""
820 substr('abcdefgh', $sysmis, $sysmis) => ""
821 substr('abc', 1, 'x') => error
822 substr(0, 10, 1) => error
823 substr(0, 10, 'x') => error
824 substr('abcd', 'abc', 0) => error
825 substr('abcd', 'abc', 'j') => error
826 substr(0, 'abc', 4) => error
827 substr(0, 'abc', 'k') => error
828 EOF
829
830 cat > 33-case.expr <<'EOF'
831 lower('ABCDEFGHIJKLMNOPQRSTUVWXYZ!@%&*(089') => "abcdefghijklmnopqrstuvwxyz!@%&*(089"
832 lower('') => ""
833 lower(1) => error
834
835 upcase('abcdefghijklmnopqrstuvwxyz!@%&*(089') => "ABCDEFGHIJKLMNOPQRSTUVWXYZ!@%&*(089"
836 upcase('') => ""
837 upcase(1) => error
838 EOF
839
840 cat > 34-time.expr <<'EOF'
841 time.days(1) => 86400.00
842 time.days(-1) => -86400.00
843 time.days(0.5) => 43200.00
844 time.days('x') => error
845 time.days($sysmis) => sysmis
846
847 time.hms(5, 6, 7) => 18367.00
848 time.hms(5, 6, 0) => 18360.00
849 time.hms(5, 0, 7) => 18007.00
850 time.hms(0, 6, 7) => 367.00
851 time.hms(-5, 6, -7) => sysmis
852 time.hms(-5, 5, -7) => sysmis
853 time.hms($sysmis, 6, 7) => sysmis
854 time.hms(5, $sysmis, 7) => sysmis
855 time.hms(5, $sysmis, 7) => sysmis
856 time.hms($sysmis, $sysmis, 7) => sysmis
857 time.hms(5, $sysmis, $sysmis) => sysmis
858 time.hms($sysmis, $sysmis, 7) => sysmis
859 time.hms($sysmis, $sysmis, $sysmis) => sysmis
860 EOF
861
862 cat > 35-ctime.expr <<'EOF'
863 ctime.days(106272) => 1.23
864 ctime.hours(106272) => 29.52
865 ctime.minutes(106272) => 1771.20
866 ctime.seconds(106272) => 106272.00
867 ctime.days(-106272) => -1.23
868 ctime.hours(-106272) => -29.52
869 ctime.minutes(-106272) => -1771.20
870 ctime.seconds(-106272) => -106272.00
871 ctime.days($sysmis) => sysmis
872 ctime.hours($sysmis) => sysmis
873 ctime.minutes($sysmis) => sysmis
874 ctime.seconds($sysmis) => sysmis
875 ctime.days('a') => error
876 ctime.hours('b') => error
877 ctime.minutes('c') => error
878 ctime.seconds('d') => error
879
880 ctime.days(date.dmy(15,10,1582)) => 1.00
881 ctime.days(date.dmy(6,9,1719)) => 50000.00
882 ctime.days(date.dmy(24,1,1583)) => 102.00
883 ctime.days(date.dmy(14,12,1585)) => 1157.00
884 ctime.days(date.dmy(26,11,1621)) => 14288.00
885 ctime.days(date.dmy(25,12,1821)) => 87365.00
886 ctime.days(date.dmy(3,12,1882)) => 109623.00
887 ctime.days(date.dmy(6,4,2002)) => 153211.00
888 ctime.days(date.dmy(19,12,1999)) => 152372.00
889 ctime.days(date.dmy(1,10,1978)) => 144623.00
890 ctime.days(date.dmy(0,10,1978)) => 144622.00
891 ctime.days(date.dmy(32,10,1978)) => sysmis
892 ctime.days(date.dmy(31,0,1978)) => 144349.00
893 ctime.days(date.dmy(31,13,1978)) => 144745.00
894 ctime.days(date.dmy($sysmis,10,1978)) => sysmis
895 ctime.days(date.dmy(31,$sysmis,1978)) => sysmis
896 ctime.days(date.dmy(31,10,$sysmis)) => sysmis
897 ctime.days(date.dmy($sysmis,$sysmis,1978)) => sysmis
898 ctime.days(date.dmy(31,$sysmis,$sysmis)) => sysmis
899 ctime.days(date.dmy($sysmis,10,$sysmis)) => sysmis
900 ctime.days(date.dmy($sysmis,$sysmis,$sysmis)) => sysmis
901 date.dmy('a',1,2) => error
902 date.dmy(1,'a',2) => error
903 date.dmy(1,2,'a') => error
904
905 ctime.days(date.mdy(10,15,1582)) => 1.00
906 ctime.days(date.mdy(9,6,1719)) => 50000.00
907 ctime.days(date.mdy(1,24,1583)) => 102.00
908 ctime.days(date.mdy(12,14,1585)) => 1157.00
909 ctime.days(date.mdy(11,26,1621)) => 14288.00
910 ctime.days(date.mdy(12,25,1821)) => 87365.00
911 ctime.days(date.mdy(12,3,1882)) => 109623.00
912 ctime.days(date.mdy(4,6,2002)) => 153211.00
913 ctime.days(date.mdy(12,19,1999)) => 152372.00
914 ctime.days(date.mdy(10,1,1978)) => 144623.00
915 ctime.days(date.mdy(10,0,1978)) => 144622.00
916 ctime.days(date.mdy(10,32,1978)) => sysmis
917 ctime.days(date.mdy(0,31,1978)) => 144349.00
918 ctime.days(date.mdy(13,31,1978)) => 144745.00
919 ctime.days(date.mdy(10,$sysmis,1978)) => sysmis
920 ctime.days(date.mdy($sysmis,31,1978)) => sysmis
921 ctime.days(date.mdy(10,31,$sysmis)) => sysmis
922 ctime.days(date.mdy($sysmis,$sysmis,1978)) => sysmis
923 ctime.days(date.mdy($sysmis,31,$sysmis)) => sysmis
924 ctime.days(date.mdy(10,$sysmis,$sysmis)) => sysmis
925 ctime.days(date.mdy($sysmis,$sysmis,$sysmis)) => sysmis
926 date.mdy('a',1,2) => error
927 date.mdy(1,'a',2) => error
928 date.mdy(1,2,'a') => error
929
930 ctime.days(date.moyr(1,2000)) => 152385.00
931 ctime.days(date.moyr(2,2000)) => 152416.00
932 ctime.days(date.moyr(3,2000)) => 152445.00
933 ctime.days(date.moyr(4,2000)) => 152476.00
934 ctime.days(date.moyr(5,2000)) => 152506.00
935 ctime.days(date.moyr(13,2000)) => 152751.00
936 ctime.days(date.moyr(14,2000)) => sysmis
937 ctime.days(date.moyr($sysmis,2000)) => sysmis
938 ctime.days(date.moyr(1,$sysmis)) => sysmis
939 ctime.days(date.moyr($sysmis,$sysmis)) => sysmis
940 date.moyr('a',2000) => error
941 date.moyr(5,'a') => error
942 date.moyr('a','b') => error
943
944 ctime.days(date.qyr(1,2000)) => 152385.00
945 ctime.days(date.qyr(2,2000)) => 152476.00
946 ctime.days(date.qyr(5,2000)) => 152751.00
947 ctime.days(date.qyr(6,2000)) => sysmis
948 ctime.days(date.qyr($sysmis,2000)) => sysmis
949 ctime.days(date.qyr(1,$sysmis)) => sysmis
950 ctime.days(date.qyr($sysmis,$sysmis)) => sysmis
951 date.qyr('a',2000) => error
952 date.qyr(5,'a') => error
953 date.qyr('a','b') => error
954
955 ctime.days(date.wkyr(1,2000)) => 152385.00
956 ctime.days(date.wkyr(15,1999)) => 152118.00
957 ctime.days(date.wkyr(36,1999)) => 152265.00
958 ctime.days(date.wkyr(54,1999)) => sysmis
959 ctime.days(date.wkyr($sysmis,1999)) => sysmis
960 ctime.days(date.wkyr(1,$sysmis)) => sysmis
961 ctime.days(date.wkyr($sysmis,$sysmis)) => sysmis
962 date.wkyr('a',1999) => error
963 date.wkyr(5,'a') => error
964 date.wkyr('a','b') => error
965
966 ctime.days(date.yrday(2000,1)) => 152385.00
967 ctime.days(date.yrday(2000,100)) => 152484.00
968 ctime.days(date.yrday(2000,253)) => 152637.00
969 ctime.days(date.yrday(2000,500)) => sysmis
970 ctime.days(date.yrday(2000,-100)) => sysmis
971 ctime.days(date.yrday(1999,$sysmis)) => sysmis
972 ctime.days(date.yrday($sysmis,1)) => sysmis
973 ctime.days(date.yrday($sysmis,$sysmis)) => sysmis
974 date.yrday(1999,'a') => error
975 date.yrday('a',5) => error
976 date.yrday('a','b') => error
977 EOF
978
979 # FIXME: XDATE.* functions
980 # FIXME: LAG
981 # FIXME: YRMODA
982
983 printf "expressions..."
984 for d in *.expr; do
985     base=`echo $d | sed 's/\.expr$//'`
986
987     # Remove comments.
988     sed -ne 's/#.*//;/^[        ]*$/!p' < $base.expr > $base.clean
989     if [ $? -ne 0 ] ; then no_result ; fi
990
991     for optimize in opt noopt; do
992         if test optimize = opt; then
993             opt_kw=''
994         else
995             opt_kw=' NOOPTIMIZE'
996         fi
997         
998         # Translate to DEBUG EVALUATE commands.
999         activity="$base, $optimize: create input"
1000         sed 's#^\(.*\) => \(.*\)$#DEBUG EVALUATE'"$opt_kw"'/\1.#' \
1001             < $base.clean > $base.$optimize.stat
1002         if [ $? -ne 0 ] ; then no_result ; fi
1003
1004         # Run.
1005         activity="$base, $optimize: run program"
1006         $SUPERVISOR $here/../src/pspp --testing-mode -o raw-ascii \
1007             $base.$optimize.stat > $base.$optimize.err 2> $base.$optimize.out
1008
1009         # Compare.
1010         activity="$base, $optimize: compare output"
1011         perl -pi -e 's/^\s*$//g' $base.clean $base.$optimize.out
1012         diff -b $base.clean $base.$optimize.out
1013         if [ $? -ne 0 ] ; then fail ; fi
1014     done
1015     num=`echo $d | sed 's/-.*//'`
1016     printf " $num"
1017 done
1018 printf ' ...done\n'
1019 pass