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([data input (data-in)])
19 m4_divert_push([PREPARE_TESTS])
21 cat > my-rand.pl <<'EOF'
22 # This random number generator and the test for it below are drawn
23 # from Park and Miller, "Random Number Generators: Good Ones are Hard
24 # to Come By", Communications of the ACM 31:10 (October 1988). It is
25 # documented to function properly on systems with a 46-bit or longer
26 # real significand, which includes systems that have 64-bit IEEE reals
27 # (with 53-bit significand). The test should catch any systems for
28 # which this is not true, in any case.
35 my ($tmp) = $a * $seed;
36 $seed = $tmp - $m * int ($tmp / $m);
37 return $seed % $modulo;
40 cat > test-my-rand.pl <<'EOF'
45 my_rand (1) foreach 1...10000;
47 die $seed if $seed != 1043618065;
51 m4_divert_pop([PREPARE_TESTS])
53 AT_SETUP([numeric input formats])
54 AT_KEYWORDS([data-in])
56 AT_CHECK([$PERL test-my-rand.pl])
66 for my $number (0, 1, .5, .015625, 123) {
67 my ($base_exp) = floor ($number ? log10 ($number) : 0);
68 for my $offset (-3...3) {
69 my ($exponent) = $base_exp + $offset;
70 my ($fraction) = $number / 10**$offset;
72 permute_zeros ($fraction, $exponent);
77 my ($fraction, $exponent) = @_;
79 my ($frac_rep) = sprintf ("%f", $fraction);
80 my ($leading_zeros) = length (($frac_rep =~ /^(0*)/)[0]);
81 my ($trailing_zeros) = length (($frac_rep =~ /(\.?0*)$/)[0]);
82 for my $i (0...$leading_zeros) {
83 for my $j (0...$trailing_zeros) {
84 my ($trimmed) = substr ($frac_rep, $i,
85 length ($frac_rep) - $i - $j);
86 next if $trimmed eq '.' || $trimmed eq '';
88 permute_commas ($trimmed, $exponent);
94 my ($frac_rep, $exponent) = @_;
95 permute_dot_comma ($frac_rep, $exponent);
96 my ($pos) = int (my_rand (length ($frac_rep) + 1));
97 $frac_rep = substr ($frac_rep, 0, $pos) . "," . substr ($frac_rep, $pos);
98 permute_dot_comma ($frac_rep, $exponent);
101 sub permute_dot_comma {
102 my ($frac_rep, $exponent) = @_;
103 permute_exponent_syntax ($frac_rep, $exponent);
104 if ($frac_rep =~ /[,.]/) {
105 $frac_rep =~ tr/.,/,./;
106 permute_exponent_syntax ($frac_rep, $exponent);
110 sub permute_exponent_syntax {
111 my ($frac_rep, $exponent) = @_;
113 if ($exponent == 0) {
114 @exp_reps = pick ('', 'e0', 'e-0', 'e+0', '-0', '+0');
115 } elsif ($exponent > 0) {
116 @exp_reps = pick ("e$exponent", "e+$exponent", "+$exponent");
118 my ($abs_exp) = -$exponent;
119 @exp_reps = pick ("e-$abs_exp", , "e-$abs_exp", "-$abs_exp");
121 permute_sign_and_affix ($frac_rep, $_) foreach @exp_reps;
124 sub permute_sign_and_affix {
125 my ($frac_rep, $exp_rep) = @_;
126 for my $prefix (pick ('', '$'),
127 pick ('-', '-$', '$-', '$-$'),
128 pick ('+', '+$', '$+', '$+$')) {
129 for my $suffix ('', '%') {
130 permute_spaces ("$prefix$frac_rep$exp_rep$suffix");
137 $s =~ s/([-+\$e%])/ $1 /g;
138 my (@fields) = split (' ', $s);
139 print join ('', @fields), "\n";
142 my ($pos) = int (my_rand ($#fields)) + 1;
143 print join ('', @fields[0...$pos - 1]);
145 print join ('', @fields[$pos...$#fields]);
151 return $_[int (my_rand ($#_ + 1))];
154 AT_CHECK([$PERL num-in.pl > num-in.data])
155 AT_DATA([num-in.sps], [dnl
158 SET MXWARNS=10000000.
159 DATA LIST FILE='num-in.data' NOTABLE/
166 PRINT OUTFILE='num-in.out'/all (6f10.4).
169 AT_CHECK([pspp -O format=csv num-in.sps])
170 AT_CHECK([gzip -cd < $top_srcdir/tests/data/num-in.expected.gz > expout])
171 AT_CHECK([cat num-in.out], [0], [expout])
174 dnl Some very old version of PSPP crashed reading big numbers,
175 dnl so this checks for regressions.
176 AT_SETUP([reading big numbers])
177 AT_KEYWORDS([data-in])
178 AT_DATA([bignum.txt], [dnl
209 199999999999999999999
210 1234567890123456789012
211 19999999999999999999999
212 123456789012345678901234
213 1999999999999999999999999
214 12345678901234567890123456
215 199999999999999999999999999
216 1234567890123456789012345678
217 19999999999999999999999999999
218 123456789012345678901234567890
219 1999999999999999999999999999999
220 12345678901234567890123456789012
221 199999999999999999999999999999999
222 1234567890123456789012345678901234
223 19999999999999999999999999999999999
224 123456789012345678901234567890123456
225 1999999999999999999999999999999999999
226 12345678901234567890123456789012345678
227 199999999999999999999999999999999999999
228 1234567890123456789012345678901234567890
229 1999999999999999999999999999999999999999
243 AT_DATA([bignum.sps], [dnl
244 title 'Test use of big numbers'.
246 *** Do the portable output.
247 data list file='bignum.txt'/BIGNUM 1-40.
250 *** Do the nonportable output for fun.
253 AT_CHECK([pspp -o pspp.csv bignum.sps], [0], [ignore])
256 AT_SETUP([DATE input format])
257 AT_KEYWORDS([data-in])
258 AT_CHECK([python $top_srcdir/tests/data/test-date-input.py date d-m-y])
259 AT_FAIL_IF([test ! -s date.sps || test ! -s date.input || test ! -s expout])
260 AT_CHECK([pspp -O format=csv date.sps])
261 AT_CHECK([cat date.output], [0], [expout])
264 AT_SETUP([ADATE input format])
265 AT_KEYWORDS([data-in])
266 AT_CHECK([python $top_srcdir/tests/data/test-date-input.py adate m-d-y])
267 AT_FAIL_IF([test ! -s adate.sps || test ! -s adate.input || test ! -s expout])
268 AT_CHECK([pspp -O format=csv adate.sps])
269 AT_CHECK([cat adate.output], [0], [expout])
272 AT_SETUP([EDATE input format])
273 AT_KEYWORDS([data-in])
274 AT_CHECK([python $top_srcdir/tests/data/test-date-input.py edate d-m-y])
275 AT_FAIL_IF([test ! -s edate.sps || test ! -s edate.input || test ! -s expout])
276 AT_CHECK([pspp -O format=csv edate.sps])
277 AT_CHECK([cat edate.output], [0], [expout])
280 AT_SETUP([JDATE input format])
281 AT_KEYWORDS([data-in])
282 AT_CHECK([python $top_srcdir/tests/data/test-date-input.py jdate j])
283 AT_FAIL_IF([test ! -s jdate.sps || test ! -s jdate.input || test ! -s expout])
284 AT_CHECK([pspp -O format=csv jdate.sps])
285 AT_CHECK([cat jdate.output], [0], [expout])
288 AT_SETUP([SDATE input format])
289 AT_KEYWORDS([data-in])
290 AT_CHECK([python $top_srcdir/tests/data/test-date-input.py sdate y-m-d])
291 AT_FAIL_IF([test ! -s sdate.sps || test ! -s sdate.input || test ! -s expout])
292 AT_CHECK([pspp -O format=csv sdate.sps])
293 AT_CHECK([cat sdate.output], [0], [expout])
296 AT_SETUP([QYR input format])
297 AT_KEYWORDS([data-in])
298 AT_CHECK([python $top_srcdir/tests/data/test-date-input.py qyr qQy])
299 AT_FAIL_IF([test ! -s qyr.sps || test ! -s qyr.input || test ! -s expout])
300 AT_CHECK([pspp -O format=csv qyr.sps])
301 AT_CHECK([cat qyr.output], [0], [expout])
304 AT_SETUP([MOYR input format])
305 AT_KEYWORDS([data-in])
306 AT_CHECK([python $top_srcdir/tests/data/test-date-input.py moyr m-y])
307 AT_FAIL_IF([test ! -s moyr.sps || test ! -s moyr.input || test ! -s expout])
308 AT_CHECK([pspp -O format=csv moyr.sps])
309 AT_CHECK([cat moyr.output], [0], [expout])
312 AT_SETUP([WKYR input format])
313 AT_KEYWORDS([data-in])
314 AT_CHECK([python $top_srcdir/tests/data/test-date-input.py wkyr wWy])
315 AT_FAIL_IF([test ! -s wkyr.sps || test ! -s wkyr.input || test ! -s expout])
316 AT_CHECK([pspp -O format=csv wkyr.sps])
317 AT_CHECK([cat wkyr.output], [0], [expout])
320 AT_SETUP([DATETIME input format])
321 AT_KEYWORDS([data-in])
322 AT_CHECK([python $top_srcdir/tests/data/test-date-input.py datetime "d-m-y +H:M" "d-m-y +H:M:S"])
323 AT_FAIL_IF([test ! -s datetime.sps || test ! -s datetime.input || \
325 AT_CHECK([pspp -O format=csv datetime.sps])
326 AT_CHECK([cat datetime.output], [0], [expout])
329 AT_SETUP([TIME input format])
330 AT_KEYWORDS([data-in])
331 AT_CHECK([python $top_srcdir/tests/data/test-time-input.py time +H:M +H:M:S])
332 AT_FAIL_IF([test ! -s time.sps || test ! -s time.input || test ! -s expout])
333 AT_CHECK([pspp -O format=csv time.sps])
334 AT_CHECK([cat time.output], [0], [expout])
337 AT_SETUP([DTIME input format])
338 AT_KEYWORDS([data-in])
339 AT_CHECK([python $top_srcdir/tests/data/test-time-input.py dtime '+D H:M' '+D H:M:S'])
340 AT_FAIL_IF([test ! -s dtime.sps || test ! -s dtime.input || test ! -s expout])
341 AT_CHECK([pspp -O format=csv dtime.sps])
342 AT_CHECK([cat dtime.output], [0], [expout])
345 AT_SETUP([binary and hexadecimal input (IB, PIB, and PIBHEX formats)])
346 AT_CHECK([$PERL -e 'print pack "n", $_ foreach 0...65535' > binhex-in.data])
347 AT_CHECK([[wc -c < binhex-in.data | sed 's/[ ]//g']], [0], [131072
349 AT_DATA([binhex-in.sps], [dnl
352 SET MXWARNS=10000000.
354 FILE HANDLE data/NAME='binhex-in.data'/MODE=IMAGE/LRECL=2.
355 DATA LIST FILE=data NOTABLE/ib 1-2 (IB) pib 1-2 (PIB) pibhex 1-2 (PIBHEX).
356 COMPUTE x=$CASENUM - 1.
357 PRINT OUTFILE='binhex-in.out'/x (PIBHEX4) ' ' ib pib pibhex.
360 AT_CHECK([gzip -cd < $top_srcdir/tests/data/binhex-in.expected.cmp.gz | \
361 $PERL -pe "printf ' %04X ', $.-1" > expout])
362 AT_CHECK([pspp -O format=csv binhex-in.sps], [0])
363 AT_CHECK([cat binhex-in.out], [0], [expout])
366 AT_SETUP([BCD input (P and PK formats)])
367 AT_CHECK([$PERL -e 'print pack "n", $_ foreach 0...65535' > bcd-in.data])
368 AT_CHECK([[wc -c < bcd-in.data | sed 's/[ ]//g']], [0], [131072
370 AT_DATA([bcd-in.sps], [dnl
372 SET MXWARNS=10000000.
374 FILE HANDLE data/NAME='bcd-in.data'/MODE=IMAGE/LRECL=2.
375 DATA LIST FILE=data NOTABLE/p 1-2 (P) pk 1-2 (PK).
376 COMPUTE x=$CASENUM - 1.
377 PRINT OUTFILE='bcd-in.out'/x (PIBHEX4) ' ' P PK.
380 AT_CHECK([gzip -cd < $top_srcdir/tests/data/bcd-in.expected.cmp.gz | \
381 $PERL -pe "printf ' %04X ', $.-1" > expout])
382 AT_CHECK([pspp -O format=csv bcd-in.sps])
383 AT_CHECK([cat bcd-in.out], [0], [expout])
386 AT_SETUP([legacy input (N and Z formats)])
387 AT_CHECK([$PERL -e 'print pack "n", $_ foreach 0...65535' > legacy-in.data])
388 AT_CHECK([[wc -c < legacy-in.data | sed 's/[ ]//g']], [0], [131072
390 AT_DATA([legacy-in.sps], [dnl
392 SET MXWARNS=10000000.
394 FILE HANDLE data/NAME='legacy-in.data'/MODE=IMAGE/LRECL=2.
395 DATA LIST NOTABLE FILE=data/n 1-2 (N) z 1-2 (z).
396 COMPUTE x=$CASENUM - 1.
397 PRINT OUTFILE='legacy-in.out'/x (PIBHEX4) ' ' N Z.
400 AT_CHECK([gzip -cd < $top_srcdir/tests/data/legacy-in.expected.cmp.gz | \
401 $PERL -pe "printf ' %04X ', $.-1" > expout])
402 AT_CHECK([pspp -O format=csv legacy-in.sps])
403 AT_CHECK([cat legacy-in.out], [0], [expout])
406 AT_SETUP([WKDAY input format])
407 AT_DATA([wkday.sps], [dnl
408 DATA LIST NOTABLE /wkday2 1-2 (wkday)
416 wkday10 1-10 (wkday).
429 FORMATS ALL (WKDAY2).
430 PRINT OUTFILE='wkday.out'/ALL.
433 AT_CHECK([pspp -O format=csv wkday.sps], [0], [dnl
434 wkday.sps:20.1-20.2: warning: Data for variable wkday2 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
436 wkday.sps:20.1-20.3: warning: Data for variable wkday3 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
438 wkday.sps:20.1-20.4: warning: Data for variable wkday4 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
440 wkday.sps:20.1-20.5: warning: Data for variable wkday5 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
442 wkday.sps:20.1-20.6: warning: Data for variable wkday6 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
444 wkday.sps:20.1-20.7: warning: Data for variable wkday7 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
446 wkday.sps:20.1-20.8: warning: Data for variable wkday8 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
448 wkday.sps:20.1-20.9: warning: Data for variable wkday9 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
450 wkday.sps:20.1-20.10: warning: Data for variable wkday10 is not valid as format WKDAY: Unrecognized weekday name. At least the first two letters of an English weekday name must be specified.
452 AT_CHECK([cat wkday.out], [0], [dnl
453 . . . . . . . . . @&t@
454 . . . . . . . . . @&t@
455 MO MO MO MO MO MO MO MO MO @&t@
456 TU TU TU TU TU TU TU TU TU @&t@
457 WE WE WE WE WE WE WE WE WE @&t@
458 TH TH TH TH TH TH TH TH TH @&t@
459 FR FR FR FR FR FR FR FR FR @&t@
460 SA SA SA SA SA SA SA SA SA @&t@
461 SU SU SU SU SU SU SU SU SU @&t@
462 . . . . . . . . . @&t@
466 AT_SETUP([MONTH input format])
467 AT_DATA([month.sps], [dnl
468 DATA LIST NOTABLE /month3 1-3 (MONTH)
475 month10 1-10 (MONTH).
524 FORMATS ALL (MONTH3).
525 PRINT OUTFILE='month.out'/ALL.
528 AT_CHECK([pspp -O format=csv month.sps], [0], [dnl
529 month.sps:15.1-15.4: warning: Data for variable month4 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
531 month.sps:15.1-15.5: warning: Data for variable month5 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
533 month.sps:15.1-15.6: warning: Data for variable month6 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
535 month.sps:15.1-15.7: warning: Data for variable month7 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
537 month.sps:15.1-15.8: warning: Data for variable month8 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
539 month.sps:15.1-15.9: warning: Data for variable month9 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
541 month.sps:15.1-15.10: warning: Data for variable month10 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
543 month.sps:26.1-26.3: warning: Data for variable month3 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
545 month.sps:26.1-26.4: warning: Data for variable month4 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
547 month.sps:26.1-26.5: warning: Data for variable month5 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
549 month.sps:26.1-26.6: warning: Data for variable month6 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
551 month.sps:26.1-26.7: warning: Data for variable month7 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
553 month.sps:26.1-26.8: warning: Data for variable month8 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
555 month.sps:26.1-26.9: warning: Data for variable month9 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
557 month.sps:26.1-26.10: warning: Data for variable month10 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
559 month.sps:39.1-39.3: warning: Data for variable month3 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
561 month.sps:39.1-39.4: warning: Data for variable month4 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
563 month.sps:39.1-39.5: warning: Data for variable month5 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
565 month.sps:39.1-39.6: warning: Data for variable month6 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
567 month.sps:39.1-39.7: warning: Data for variable month7 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
569 month.sps:39.1-39.8: warning: Data for variable month8 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
571 month.sps:39.1-39.9: warning: Data for variable month9 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
573 month.sps:39.1-39.10: warning: Data for variable month10 is not valid as format MONTH: Unrecognized month format. Months may be specified as Arabic or Roman numerals or as at least 3 letters of their English names.
575 AT_CHECK([cat month.out], [0], [dnl
578 JAN JAN JAN JAN JAN JAN JAN JAN @&t@
579 FEB FEB FEB FEB FEB FEB FEB FEB @&t@
580 MAR MAR MAR MAR MAR MAR MAR MAR @&t@
581 MAR . . . . . . . @&t@
582 APR APR APR APR APR APR APR APR @&t@
583 MAY MAY MAY MAY MAY MAY MAY MAY @&t@
584 JUN JUN JUN JUN JUN JUN JUN JUN @&t@
585 JUL JUL JUL JUL JUL JUL JUL JUL @&t@
586 JUL AUG AUG AUG AUG AUG AUG AUG @&t@
587 SEP SEP SEP SEP SEP SEP SEP SEP @&t@
588 JUL AUG AUG AUG AUG AUG AUG AUG @&t@
589 OCT OCT OCT OCT OCT OCT OCT OCT @&t@
590 NOV NOV NOV NOV NOV NOV NOV NOV @&t@
591 DEC DEC DEC DEC DEC DEC DEC DEC @&t@
593 JAN JAN JAN JAN JAN JAN JAN JAN @&t@
594 FEB FEB FEB FEB FEB FEB FEB FEB @&t@
595 MAR MAR MAR MAR MAR MAR MAR MAR @&t@
596 APR APR APR APR APR APR APR APR @&t@
597 MAY MAY MAY MAY MAY MAY MAY MAY @&t@
598 JUN JUN JUN JUN JUN JUN JUN JUN @&t@
599 JUL JUL JUL JUL JUL JUL JUL JUL @&t@
600 AUG AUG AUG AUG AUG AUG AUG AUG @&t@
601 SEP SEP SEP SEP SEP SEP SEP SEP @&t@
602 OCT OCT OCT OCT OCT OCT OCT OCT @&t@
603 NOV NOV NOV NOV NOV NOV NOV NOV @&t@
604 DEC DEC DEC DEC DEC DEC DEC DEC @&t@
606 JAN JAN JAN JAN JAN JAN JAN JAN @&t@
607 JAN JAN JAN JAN JAN JAN JAN JAN @&t@
608 FEB FEB FEB FEB FEB FEB FEB FEB @&t@
609 FEB FEB FEB FEB FEB FEB FEB FEB @&t@
610 MAR MAR MAR MAR MAR MAR MAR MAR @&t@
611 MAR MAR MAR MAR MAR MAR MAR MAR @&t@
612 APR APR APR APR APR APR APR APR @&t@
613 MAY MAY MAY MAY MAY MAY MAY MAY @&t@
614 JUN JUN JUN JUN JUN JUN JUN JUN @&t@
615 JUL JUL JUL JUL JUL JUL JUL JUL @&t@
616 AUG AUG AUG AUG AUG AUG AUG AUG @&t@
617 SEP SEP SEP SEP SEP SEP SEP SEP @&t@
618 OCT OCT OCT OCT OCT OCT OCT OCT @&t@
619 NOV NOV NOV NOV NOV NOV NOV NOV @&t@
620 DEC DEC DEC DEC DEC DEC DEC DEC @&t@
621 DEC DEC DEC DEC DEC DEC DEC DEC @&t@