Fix first part of bug #18982. Thanks to John Darrington for finding
[pspp-builds.git] / tests / formats / num-in.sh
1 #! /bin/sh
2
3 TEMPDIR=/tmp/pspp-tst-$$
4 mkdir -p $TEMPDIR
5 trap 'cd /; rm -rf $TEMPDIR' 0
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
13 # ensure that top_srcdir is absolute
14 top_srcdir=`cd $top_srcdir; pwd`
15
16 STAT_CONFIG_PATH=$top_srcdir/config
17 export STAT_CONFIG_PATH
18
19 fail()
20 {
21     echo $activity
22     echo FAILED
23     exit 1;
24 }
25
26
27 no_result()
28 {
29     echo $activity
30     echo NO RESULT;
31     exit 2;
32 }
33
34 pass()
35 {
36     exit 0;
37 }
38
39 cd $TEMPDIR
40
41 activity="write PRNG fragment"
42 cat > my-rand.pl <<'EOF'
43 # This random number generator and the test for it below are drawn
44 # from Park and Miller, "Random Number Generators: Good Ones are Hard
45 # to Come By", Communications of the ACM 31:10 (October 1988).  It is
46 # documented to function properly on systems with a 46-bit or longer
47 # real significand, which includes systems that have 64-bit IEEE reals
48 # (with 53-bit significand).  The test should catch any systems for
49 # which this is not true, in any case.
50
51 our ($seed) = 1;
52 sub my_rand {
53   my ($modulo) = @_;
54   my ($a) = 16807;
55   my ($m) = 2147483647;
56   my ($tmp) = $a * $seed;
57   $seed = $tmp - $m * int ($tmp / $m);
58   return $seed % $modulo;
59 }
60 EOF
61 if [ $? -ne 0 ] ; then no_result ; fi
62
63 activity="write PRNG test program"
64 cat > test-my-rand.pl <<'EOF'
65 #! /usr/bin/perl
66 use strict;
67 use warnings;
68 do 'my-rand.pl';
69 my_rand (1) foreach 1...10000;
70 our $seed;
71 die $seed if $seed != 1043618065;
72 EOF
73 if [ $? -ne 0 ] ; then no_result ; fi
74
75 activity="test PRNG"
76 $PERL test-my-rand.pl
77 if [ $? -ne 0 ] ; then no_result ; fi
78
79 activity="write Perl program"
80 cat > num-in.pl <<'EOF'
81 #! /usr/bin/perl
82
83 use POSIX;
84 use strict;
85 use warnings;
86
87 do 'my-rand.pl';
88
89 for my $number (0, 1, .5, .015625, 123) {
90     my ($base_exp) = floor ($number ? log10 ($number) : 0);
91     for my $offset (-3...3) {
92         my ($exponent) = $base_exp + $offset;
93         my ($fraction) = $number / 10**$offset;
94
95         permute_zeros ($fraction, $exponent);
96     }
97 }
98
99 sub permute_zeros {
100     my ($fraction, $exponent) = @_;
101
102     my ($frac_rep) = sprintf ("%f", $fraction);
103     my ($leading_zeros) = length (($frac_rep =~ /^(0*)/)[0]);
104     my ($trailing_zeros) = length (($frac_rep =~ /(\.?0*)$/)[0]);
105     for my $i (0...$leading_zeros) {
106         for my $j (0...$trailing_zeros) {
107             my ($trimmed) = substr ($frac_rep, $i,
108                                     length ($frac_rep) - $i - $j);
109             next if $trimmed eq '.' || $trimmed eq '';
110
111             permute_commas ($trimmed, $exponent);
112         }
113     }
114 }
115
116 sub permute_commas {
117     my ($frac_rep, $exponent) = @_;
118     permute_dot_comma ($frac_rep, $exponent);
119     my ($pos) = int (my_rand (length ($frac_rep) + 1));
120     $frac_rep = substr ($frac_rep, 0, $pos) . "," . substr ($frac_rep, $pos);
121     permute_dot_comma ($frac_rep, $exponent);
122 }
123
124 sub permute_dot_comma {
125     my ($frac_rep, $exponent) = @_;
126     permute_exponent_syntax ($frac_rep, $exponent);
127     if ($frac_rep =~ /[,.]/) {
128         $frac_rep =~ tr/.,/,./;
129         permute_exponent_syntax ($frac_rep, $exponent);
130     }
131 }
132
133 sub permute_exponent_syntax {
134     my ($frac_rep, $exponent) = @_;
135     my (@exp_reps);
136     if ($exponent == 0) {
137         @exp_reps = pick ('', 'e0', 'e-0', 'e+0', '-0', '+0');
138     } elsif ($exponent > 0) {
139         @exp_reps = pick ("e$exponent", "e+$exponent", "+$exponent");
140     } else {
141         my ($abs_exp) = -$exponent;
142         @exp_reps = pick ("e-$abs_exp", , "e-$abs_exp", "-$abs_exp");
143     }
144     permute_sign_and_affix ($frac_rep, $_) foreach @exp_reps;
145 }
146
147 sub permute_sign_and_affix {
148     my ($frac_rep, $exp_rep) = @_;
149     for my $prefix (pick ('', '$'),
150                     pick ('-', '-$', '$-', '$-$'),
151                     pick ('+', '+$', '$+', '$+$')) {
152         for my $suffix ('', '%') {
153             permute_spaces ("$prefix$frac_rep$exp_rep$suffix");
154         }
155     }
156 }
157
158 sub permute_spaces {
159     my ($s) = @_;
160     $s =~ s/([-+\$e%])/ $1 /g;
161     my (@fields) = split (' ', $s);
162     print join ('', @fields), "\n";
163
164     if ($#fields > 0) {
165         my ($pos) = int (my_rand ($#fields)) + 1;
166         print join ('', @fields[0...$pos - 1]);
167         print " ";
168         print join ('', @fields[$pos...$#fields]);
169         print "\n";
170     }
171 }
172
173 sub pick {
174     return $_[int (my_rand ($#_ + 1))];
175 }
176 EOF
177
178 activity="generate data"
179 $PERL num-in.pl > num-in.data
180 if [ $? -ne 0 ] ; then no_result ; fi
181 echo -n .
182
183 activity="generate pspp syntax"
184 cat > num-in.pspp <<EOF
185 SET ERRORS=NONE.
186 SET MXERRS=10000000.
187 SET MXWARNS=10000000.
188 DATA LIST FILE='num-in.data' /
189         f 1-40 (f)
190         comma 1-40 (comma)
191         dot 1-40 (dot)
192         dollar 1-40 (dollar)
193         pct 1-40 (pct)
194         e 1-40 (e).
195 PRINT OUTFILE='num-in.out'/all (6f10.4).
196 EXECUTE.
197 EOF
198 if [ $? -ne 0 ] ; then no_result ; fi
199 echo -n .
200
201 activity="run program"
202 $SUPERVISOR $PSPP --testing-mode num-in.pspp
203 if [ $? -ne 0 ] ; then no_result ; fi
204 echo -n .
205
206 activity="gunzip expected results"
207 gzip -cd < $top_srcdir/tests/formats/num-in.expected.gz > num-in.expected
208 if [ $? -ne 0 ] ; then no_result ; fi
209 echo -n .
210
211 activity="compare output"
212 diff -u num-in.expected num-in.out
213 if [ $? -ne 0 ] ; then fail ; fi
214
215 echo .
216
217 pass