Rewrite PSPP output engine.
[pspp-builds.git] / tests / formats / 360.sh
1 #! /bin/sh
2
3 # Tests BINARY and 360 data file formats.
4
5 TEMPDIR=/tmp/pspp-tst-$$
6
7 # ensure that top_builddir  are absolute
8 if [ -z "$top_builddir" ] ; then top_builddir=. ; fi
9 if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi
10 top_builddir=`cd $top_builddir; pwd`
11 PSPP=$top_builddir/src/ui/terminal/pspp
12 : ${PERL:=perl}
13
14 # ensure that top_srcdir is absolute
15 top_srcdir=`cd $top_srcdir; pwd`
16
17 STAT_CONFIG_PATH=$top_srcdir/config
18 export STAT_CONFIG_PATH
19
20
21 cleanup()
22 {
23      if [ x"$PSPP_TEST_NO_CLEANUP" != x ] ; then 
24         echo "NOT cleaning $TEMPDIR" 
25         return ; 
26      fi
27      cd /
28      rm -rf $TEMPDIR
29 }
30
31
32 fail()
33 {
34     echo $activity
35     echo FAILED
36     cleanup;
37     exit 1;
38 }
39
40
41 no_result()
42 {
43     echo $activity
44     echo NO RESULT;
45     cleanup;
46     exit 2;
47 }
48
49 pass()
50 {
51     cleanup;
52     exit 0;
53 }
54
55 mkdir -p $TEMPDIR
56
57
58
59 cd $TEMPDIR
60
61 activity="create data file"
62 cat > $TEMPDIR/input.data <<EOF
63 07-22-2007
64 10-06-2007
65 321
66 07-14-1789
67 08-26-1789
68 4
69 01-01-1972
70 12-31-1999
71 682
72 EOF
73 if [ $? -ne 0 ] ; then no_result ; fi
74
75 activity="create program to transform data into 360 formats"
76 cat > $TEMPDIR/make-360.pl <<'EOF'
77 use strict;
78 use warnings;
79
80 # ASCII to EBCDIC translation table
81 our ($ascii2ebcdic) = ""
82 . "\x00\x01\x02\x03\x37\x2d\x2e\x2f"
83 . "\x16\x05\x25\x0b\x0c\x0d\x0e\x0f"
84 . "\x10\x11\x12\x13\x3c\x3d\x32\x26"
85 . "\x18\x19\x3f\x27\x1c\x1d\x1e\x1f"
86 . "\x40\x5a\x7f\x7b\x5b\x6c\x50\x7d"
87 . "\x4d\x5d\x5c\x4e\x6b\x60\x4b\x61"
88 . "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
89 . "\xf8\xf9\x7a\x5e\x4c\x7e\x6e\x6f"
90 . "\x7c\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
91 . "\xc8\xc9\xd1\xd2\xd3\xd4\xd5\xd6"
92 . "\xd7\xd8\xd9\xe2\xe3\xe4\xe5\xe6"
93 . "\xe7\xe8\xe9\xad\xe0\xbd\x9a\x6d"
94 . "\x79\x81\x82\x83\x84\x85\x86\x87"
95 . "\x88\x89\x91\x92\x93\x94\x95\x96"
96 . "\x97\x98\x99\xa2\xa3\xa4\xa5\xa6"
97 . "\xa7\xa8\xa9\xc0\x4f\xd0\x5f\x07"
98 . "\x20\x21\x22\x23\x24\x15\x06\x17"
99 . "\x28\x29\x2a\x2b\x2c\x09\x0a\x1b"
100 . "\x30\x31\x1a\x33\x34\x35\x36\x08"
101 . "\x38\x39\x3a\x3b\x04\x14\x3e\xe1"
102 . "\x41\x42\x43\x44\x45\x46\x47\x48"
103 . "\x49\x51\x52\x53\x54\x55\x56\x57"
104 . "\x58\x59\x62\x63\x64\x65\x66\x67"
105 . "\x68\x69\x70\x71\x72\x73\x74\x75"
106 . "\x76\x77\x78\x80\x8a\x8b\x8c\x8d"
107 . "\x8e\x8f\x90\x6a\x9b\x9c\x9d\x9e"
108 . "\x9f\xa0\xaa\xab\xac\x4a\xae\xaf"
109 . "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
110 . "\xb8\xb9\xba\xbb\xbc\xa1\xbe\xbf"
111 . "\xca\xcb\xcc\xcd\xce\xcf\xda\xdb"
112 . "\xdc\xdd\xde\xdf\xea\xeb\xec\xed"
113 . "\xee\xef\xfa\xfb\xfc\xfd\xfe\xff";
114 length ($ascii2ebcdic) == 256 || die;
115
116 open (INPUT, '<', 'input.data') or die "input.data: open: $!\n";
117 my (@data) = <INPUT> or die;
118 close (INPUT) or die;
119 chomp $_ foreach @data;
120
121 # Binary mode.
122 open (OUTPUT, '>', 'binary.bin') or die "binary.bin: create: $!\n";
123 for $_ (@data) {
124     my ($reclen) = pack ("V", length);
125     print OUTPUT $reclen, $_, $reclen;
126 }
127 close (OUTPUT) or die;
128
129 # Fixed mode.
130 open (OUTPUT, '>', 'fixed.bin') or die "fixed.bin: create: $!\n";
131 my ($lrecl) = 32;
132 for $_ (@data) {
133     my ($out) = substr ($_, 0, $lrecl);
134     $out .= ' ' x ($lrecl - length ($out));
135     length ($out) == 32 or die;
136     print OUTPUT a2e ($out);
137 }
138 close (OUTPUT) or die;
139
140 # Variable mode.
141 open (OUTPUT, '>', 'variable.bin') or die "variable.bin: create: $!\n";
142 our (@records);
143 for $_ (@data) {
144     push (@records, pack ("n xx", length ($_) + 4) . a2e ($_));
145 }
146 dump_records ();
147 close (OUTPUT) or die;
148
149 # Spanned mode.
150 open (OUTPUT, '>', 'spanned.bin') or die "spanned.bin: create: $!\n";
151 for my $line (@data) {
152     local ($_) = $line;
153     my (@r);
154     while (length) {
155         my ($n) = min (int (rand (5)), length);
156         push (@r, substr ($_, 0, $n, ''));
157     }
158     foreach my $i (0...$#r) {
159         my $scc = ($#r == 0 ? 0
160                    : $i == 0 ? 1
161                    : $i == $#r ? 2
162                    : 3);
163         push (@records,
164               pack ("nCx", length ($r[$i]) + 4, $scc) . a2e ($r[$i]));
165     }
166 }
167 dump_records ();
168 close (OUTPUT) or die;
169
170 sub a2e {
171     local ($_) = @_;
172     my ($s) = "";
173     foreach (split (//)) {
174         $s .= substr ($ascii2ebcdic, ord, 1);
175     }
176     return $s;
177 }
178
179 sub min {
180     my ($a, $b) = @_;
181     return $a < $b ? $a : $b
182 }
183
184 sub dump_records {
185     while (@records) {
186         my ($n) = min (int (rand (5)) + 1, scalar (@records));
187         my (@r) = splice (@records, 0, $n);
188         my ($len) = 0;
189         $len += length foreach @r;
190         print OUTPUT pack ("n xx", $len + 4);
191         print OUTPUT foreach @r;
192     }
193 }
194 EOF
195 if [ $? -ne 0 ] ; then no_result ; fi
196
197 activity="running make-360.pl"
198 $PERL make-360.pl
199 if [ $? -ne 0 ] ; then no_result ; fi
200
201 binary_fh='mode=binary'
202 fixed_fh='mode=360 /recform=fixed /lrecl=32'
203 variable_fh='mode=360 /recform=variable'
204 spanned_fh='mode=360 /recform=spanned'
205
206 for type in binary fixed variable spanned; do
207     activity="create $type.pspp"
208     eval fh=\$${type}_fh
209     cat > $type.pspp <<EOF
210 * Read the original file and list its data, to test reading these formats.
211 file handle input/name='$type.bin'/$fh.
212 data list fixed file=input notable
213         /1 start 1-10 (adate)
214         /2 end 1-10 (adate)
215         /3 count 1-3.
216 list.
217
218 * Output the data to a new file in the same format.
219 file handle output/name='${type}2.bin'/$fh.
220 compute count=count + 1.
221 print outfile=output/start end count.
222 execute.
223
224 * Re-read the new data and list it, to verify that it was written correctly.
225 data list fixed file=output notable/
226         start 2-11 (adate)
227         end 13-22 (adate)
228         count 24-26.
229 list.
230
231 EOF
232     if [ $? -ne 0 ] ; then no_result ; fi
233
234     # Make sure that pspp.csv isn't left over from another run.
235     rm -f pspp.csv
236
237     activity="run $type.pspp"
238     $SUPERVISOR $PSPP --testing-mode $type.pspp
239     if [ $? -ne 0 ] ; then fail ; fi
240
241     activity="compare $type.pspp output"
242     diff -c $TEMPDIR/pspp.csv - << EOF
243 Table: Data List
244 start,end,count
245 07/22/2007,10/06/2007,321
246 07/14/1789,08/26/1789,4
247 01/01/1972,12/31/1999,682
248
249 Table: Data List
250 start,end,count
251 07/22/2007,10/06/2007,322
252 07/14/1789,08/26/1789,5
253 01/01/1972,12/31/1999,683
254 EOF
255     if [ $? -ne 0 ] ; then fail ; fi
256 done
257
258 pass