]> git.draconx.ca Git - cdecl99.git/blob - tests/general.at
Release 1.3.
[cdecl99.git] / tests / general.at
1 # Copyright © 2012, 2020-2021, 2023-2024 Nick Bowler
2 #
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation, either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
15
16 m4_define([LIBTOOL_VARS],
17   [eval `sed -n[]m4_foreach([var], m4_cdr($@), [ -e '/^var='/p]) <$1`])
18
19 dnl Verify that all symbols in the static library are properly prefixed.
20 AT_SETUP([libcdecl static symbol prefixes])
21
22 AT_CHECK([{ $LIBTOOL --config || exit 99; } >libtool.cfg])
23 LIBTOOL_VARS([libtool.cfg], [objdir], [build_old_libs])
24 AT_SKIP_IF([test x"$build_old_libs" = x"no"])
25
26 LIBTOOL_VARS([$builddir/libcdecl.la], [old_library])
27 archive="$builddir/$objdir/$old_library"
28 AT_CHECK([$SHELL "$builddir/exported.sh" "$archive" || exit 99], [0], [stdout])
29 AT_CHECK([sed '/^cdecl_/d' stdout])
30
31 AT_CLEANUP
32
33 dnl Verify that empty commands do nothing.
34 AT_SETUP([cdecl99 empty command])
35
36 AT_DATA([input], [[explain int x[42];
37
38 declare x as array 42 of int
39
40 explain int
41
42 ]])
43
44 AT_CHECK([cdecl99 -f input], [0], [[declare x as array 42 of int
45 int x[42]
46 type int
47 ]])
48
49 AT_CLEANUP
50
51 dnl Verify that commands are not executed after "quit"
52 AT_SETUP([cdecl99 quit command])
53
54 AT_DATA([input], [[explain int;
55 quit
56 explain this is a syntax error
57 ]])
58
59 AT_CHECK([cdecl99 -f input], [0], [type int
60 ])
61
62 AT_CLEANUP
63
64 AT_SETUP([cdecl99 help command])
65
66 AT_DATA([input],
67 [[help
68 explain int
69 ]])
70
71 # Program to generate expected output based on src/execute.gperf
72 AT_DATA([expout.sed],
73 [[/^%%$/,/^%%$/ {
74   s/^exit.*//
75   s/,.*//p
76 }
77 $a\
78 type int
79 ]])
80 sed -n -f expout.sed "$srcdir/src/execute.gperf" >expout
81
82 # Program to filter the help output to extract the command list from "help"
83 # without any descriptions.
84 AT_DATA([filter.sed],
85 [[/^ /,$ !d
86 /^          /d
87 s/^  *\([^ ]*\).*/\1/
88 ]])
89
90 AT_CHECK([LC_ALL=C cdecl99 -f input >stdout && sed -f filter.sed stdout],
91   [0], [expout])
92
93 AT_CLEANUP
94
95 AT_SETUP([cdecl99 --execute option])
96
97 AT_CHECK([cdecl99 --execute 'explain int' --execute='declare x as int' \
98                   --execute='simplify int (x)()'], [0],
99 [[type int
100 int x
101 int x()
102 ]])
103
104 AT_CLEANUP
105
106 AT_SETUP([cdecl99 --file error message])
107
108 AT_CHECK([cdecl99 --file nonexistent || exit 42], [42], [], [stderr])
109 AT_CHECK([grep -v nonexistent stderr || true])
110
111 AT_CLEANUP
112
113 AT_SETUP([cdecl99 command error messages])
114
115 # Extract progname from --help usage message
116 # This will only get the start of progname if it includes spaces;
117 # so we won't worry too hard about the exact format later.
118 AT_CHECK([LC_ALL=C cdecl99 --help], [0], [stdout])
119 progname=`$AWK 'NR == 1 { gsub(/[[\\\\]]/, "/", $2); print $2; }' stdout`dnl'
120
121 # every line is erroneous
122 AT_DATA([input],
123 [[explain int a b c
124 simplify int a b c
125 declare a as b c
126 bad command
127 ]])
128
129 AT_DATA([check.awk],
130 [[BEGIN { status=0; }
131 { gsub(/[\\]/, "/"); }
132 $1 == progname || $1 == (progname ":") { next; }
133 { status=1; print "unprefixed message on line", NR ":", $0; }
134 END { exit(status); }
135 ]])
136
137 AT_CHECK([LC_ALL=C cdecl99 --file=input || exit 42], [42], [], [stderr])
138 AT_CHECK([$AWK -f check.awk progname="$progname" stderr])
139
140 exec 3<input
141 set x; shift
142 while read line <&3; do
143   set x "$@" "--execute=$line"; shift;
144 done
145 AT_CHECK([LC_ALL=C cdecl99 "$@" || exit 42], [42], [], [stderr])
146 AT_CHECK([$AWK f check.awk progname="$progname" stderr])
147
148 AT_CLEANUP
149
150 AT_SETUP([cdecl99 invalid character error messages])
151
152 $AWK 'BEGIN {
153   print "explain \1";
154   print "explain \377";
155   print "explain \a";
156   print "explain \b";
157   print "explain ?";
158 }' >test.dat </dev/null
159
160 AT_CHECK([LC_ALL=C cdecl99 -f test.dat || exit 42], [42], [], [stderr])
161 AT_CHECK([$AWK '{ print $NF; }' stderr], [0],
162 [['\001'
163 '\377'
164 '\a'
165 '\b'
166 '?'
167 ]])
168
169 AT_CLEANUP
170
171 dnl Ensure that parse error messages for misplaced keywords correctly
172 dnl include the keyword itself.
173 AT_SETUP([cdecl99 unexpected keyword error messages])
174
175 # We use the English syntax to reliably force a syntax error where we want
176 # it, as the "declare" form takes an identifier and not any other token,
177 AT_DATA([test.dat],
178 [[declare signed as int
179 declare typedef as int
180 declare volatile as int
181 declare inline as int
182 ]])
183
184 AT_DATA([test.awk],
185 [[{
186   for (i = 1; i <= $NF; i++) {
187     if ($i == "unexpected") {
188       sub(/,$/, "", $(i+1));
189       print $(i+1);
190       break;
191     }
192   }
193 }
194 ]])
195
196 AT_CHECK([LC_ALL=C cdecl99 -f test.dat || exit 42], [42], [], [stderr])
197 AT_CHECK([$AWK -f test.awk stderr], [0],
198 [[signed
199 typedef
200 volatile
201 inline
202 ]])
203
204 AT_CLEANUP
205
206 AT_SETUP([cdecl99 interactive mode])
207
208 AT_DATA([test.dat],
209 [[explain int () int
210 explain int x;
211 quit
212 ]])
213
214 AT_CHECK([cdecl99 --quiet --interactive <test.dat], [0], [stdout], [ignore])
215
216 # If built with readline support, then the input commands (including their
217 # trailing newlines) will be captured by AT_CHECK.  Otherwise, they are not:
218 # the output just directly follows the prompt, and the final prompt will
219 # not end with a newline.  Attempt to paper over these differences.
220 AT_DATA([check.sed],
221 [[/> [eq]/d
222 :loop
223 s/^> //
224 t loop
225 /^$/d
226 ]])
227
228 AT_CHECK([echo >>stdout; sed -f check.sed stdout], [0],
229 [declare x as int
230 ])
231
232 AT_CLEANUP
233
234 AT_SETUP([cdecl99 EOF in batch mode])
235
236 AT_CHECK([AS_ECHO_N(["explain int"]) | cdecl99 --batch | head], [0],
237 [[type int
238 ]])
239 AT_CHECK([cdecl99 --batch </dev/null])
240
241 AT_CLEANUP