]> git.draconx.ca Git - dxcommon.git/blob - tests/scripts.at
Implement the -a and -v options in join.awk.
[dxcommon.git] / tests / scripts.at
1 dnl Copyright © 2021-2022 Nick Bowler
2 dnl
3 dnl License WTFPL2: Do What The Fuck You Want To Public License, version 2.
4 dnl This is free software: you are free to do what the fuck you want to.
5 dnl There is NO WARRANTY, to the extent permitted by law.
6
7 AT_BANNER([Script tests])
8
9 AT_SETUP([gen-options.awk])
10
11 AT_DATA([options.def],
12 [[--option-only
13 --option-with-val (5)
14 --option-with-flagval (&x, 5)
15 --option-with-arg=ARG
16 some "text" goes here
17 --option-with-optional-arg[=OPTIONAL]
18
19 hello
20 -a, --option-with-sopt
21
22 -b, --option-with-sopt-and-arg=SOPTARG
23 -c, --option-with-sopt-and-optional-arg[=SOPTOPTIONAL]
24 --option-with-arg-and-val=ARGVAL (42)
25 --option-with-arg-and-flagval=ARGFLAGVAL (&a[1], 'x')
26 --option-with-optional-arg-and-val[=OPTIONALARGVAL] (54)
27 --option-with-optional-arg-and-flagval[=OPTIONALFLAGVAL] (0, 0)
28 --with-sopt
29 Here is a help string
30     that has a line randomly indented
31 # with a comment
32     @&t@
33 and a blank line
34 --with-arg=ARG
35 do stuff with ARG
36 --flagval
37 ]])
38
39 AT_CHECK([$AWK -f "$builddir/scripts/gen-options.awk" <options.def >options.h])
40
41 AT_DATA([context.h],
42 [[struct option { const char *name; int has_arg; int *flag; int val; };
43 int x, a[5];
44 ]])
45
46 # test 0: sanity test
47 AT_DATA([test0.c],
48 [[#include "context.h"
49 #include "options.h"
50
51 static const char sopts[] = SOPT_STRING;
52 static const struct option opts[] = { LOPTS_INITIALIZER, {0} };
53
54 int main(void)
55 {
56   return 0;
57 }
58 ]])
59 AT_CHECK([$CC -o test0$EXEEXT test0.c && ./test0$EXEEXT], [0], [], [ignore])
60
61 # test 1: long option names and help text
62 AT_DATA([test1.c],
63 [[#include <stdio.h>
64 #include <stdlib.h>
65
66 #include "context.h"
67 #include "options.h"
68
69 static const struct option opts[] = { LOPTS_INITIALIZER };
70
71 int main(void)
72 {
73   unsigned i;
74
75   for (i = 0; i < sizeof opts / sizeof opts[0]; i++) {
76     struct lopt_help help = { "INVALID", "INVALID" };
77
78     if (!lopt_get_help(&opts[i], &help))
79       return EXIT_FAILURE;
80
81     printf("--%s", opts[i].name);
82     if (opts[i].has_arg)
83       printf("=%s", help.arg);
84     printf("\n%s", help.desc);
85     if (help.desc[0])
86       putchar('\n');
87   }
88
89   return 0;
90 }
91 ]])
92
93 # pick out interesting bits from the definitions file
94 sed -n '/^-/s/^.*--\([[^\= @<:@]]*\).*$/\1/p' options.def >options
95 sed -n '/^-/{
96   s/[[^=]]*\(=[[^@:>@ ]]*\).*$/\1/
97   s/^[[^=]].*//
98   s/^=//
99   p
100 }' options.def >argnames
101
102 AS_ECHO(["-"]) | sed -n '1s/^-.*//p
103 1,/^-/d
104 t clear
105 :clear
106 s/^-.*//p
107 t
108 s/^#.*//
109 s/^ *//
110 t next
111 :next
112 N
113 s/\n-.*//
114 t done
115 s/\n#.*//
116 s/\n */\n/g
117 t next
118 :done
119 s/"/\\\\"/g
120 s/[[^\n]][[^\n]]*/\\"&\\"/g
121 s/^\n*//
122 s/\n*$//
123 s/\n\n*/ /g
124 p
125 ' options.def - >helptext
126
127 exec 3<options 4<argnames 5<helptext 6>expout
128 while read opt <&3 && read arg <&4 && read help <&5; do
129   if test ${arg:+y}; then
130     AS_ECHO(["--$opt=$arg"]) >&6
131   else
132     AS_ECHO(["--$opt"]) >&6
133   fi
134   eval "set x $help"; shift
135   for arg
136   do
137     AS_ECHO(["$arg"]) >&6
138   done
139 done
140 exec 3<&- 4<&- 5<&- 6>&-
141
142 AT_CHECK([$CC -o test1$EXEEXT test1.c && ./test1$EXEEXT],
143   [0], [expout], [ignore])
144
145 # test 2: short option string
146 AT_DATA([test2.c],
147 [[#include <stdio.h>
148 #include <stdlib.h>
149
150 #include "context.h"
151 #include "options.h"
152
153 int main(void)
154 {
155   struct option lopts[] = {LOPTS_INITIALIZER};
156   unsigned i, j;
157
158   for (i = 0; i < sizeof SOPT_STRING - 1; i++) {
159     if (SOPT_STRING[i] != ':') {
160       for (j = 0; j < sizeof lopts / sizeof lopts[0]; j++) {
161         if (lopts[j].val == SOPT_STRING[i]) {
162           printf("--%s ", lopts[j].name);
163           break;
164         }
165       }
166     }
167     putchar(SOPT_STRING[i]);
168     if (SOPT_STRING[i+1] != ':')
169       putchar('\n');
170   }
171 }
172 ]])
173
174 sed -n '/^-/{
175   s/=.*/:/
176   s/[[@<:@]]/:/
177   s/^-\([[^-]]\)[[^:]]*/\1/p
178   s/^-.*//p
179 }' options.def >sopts
180
181 exec 3<options 4<sopts 5>expout
182 while read lopt <&3 && read sopt <&4; do
183   if test ${sopt:+y}; then
184     AS_ECHO(["--$lopt $sopt"]) >&5
185   fi
186 done
187 exec 3<&- 4<&- 5>&-
188
189 AT_CHECK([$CC -o test2$EXEEXT test2.c && ./test2$EXEEXT],
190   [0], [expout], [ignore])
191
192 # Check that all help strings are translatable
193 sed 's/\([[^\\]]\\\)" /\1\\n\\" /g' helptext >help-po
194 exec 3<options 4<argnames 5<help-po 6>expected.po
195 while read opt <&3 && read arg <&4 && read help <&5; do
196   if test ${arg:+y}; then
197     AS_ECHO(["msgctxt \"$opt\" msgid \"$arg\""]) >&6
198   fi
199   AS_ECHO(["msgctxt \"$opt\" msgid${help:+ }$help"]) >&6
200 done
201 exec 3<&- 4<&- 5<&- 6>&-
202
203 AT_CHECK([xgettext --keyword=PN_:1c,2 options.h
204   test -f messages.po || exit 77])
205
206 LC_ALL=C sort expected.po >expout
207 AT_CHECK([sed -n '/^msgctxt/{
208 t next
209 :next
210 N
211 s/\nmsgstr.*//
212 t done
213 s/\s*""//
214 s/\n/ /
215 t next
216 :done
217 p
218 }' messages.po | LC_ALL=C sort], [0], [expout])
219
220 AT_CLEANUP
221
222 AT_SETUP([gen-strtab.awk])
223
224 AT_DATA([test.def],
225 [[
226 &a world
227 &b
228 hello world
229 &c
230 hello
231 world
232 &d world\n
233 &e
234 \\not a newline
235 &f
236 \not a newline
237 &g inline
238 continued
239 &h    no\
240 newline\
241 &i
242 \   leading whitespace
243 &j oneline
244 # with a comment
245 ]])
246
247 AT_CHECK([$AWK -f "$builddir/scripts/gen-strtab.awk" <test.def >test.h])
248
249 sed -n 's/^[[&]]\([[^ ]]*\).*/\1/p' test.def >identifiers
250
251 # test 0: sanity test
252 AT_DATA([test0.c],
253 [[#include "test.h"
254 #include <stdio.h>
255
256 int main(void)
257 {
258   printf("---\n");
259 ]])
260 exec 3<identifiers 4>>test0.c
261 while read ident <&3; do
262   AS_ECHO(['  printf("%s\n---\n", '"strtab+$ident);"]) >&4
263 done
264 AS_ECHO(['  return 0;']) >&4
265 AS_ECHO(['}']) >&4
266 exec 3<&- 4>&-
267
268 AT_CHECK([$CC -o test0$EXEEXT test0.c && ./test0$EXEEXT], [0], [---
269 world
270 ---
271 hello world
272
273 ---
274 hello
275 world
276
277 ---
278 world
279
280 ---
281 \not a newline
282
283 ---
284
285 ot a newline
286
287 ---
288 inline
289 continued
290
291 ---
292 nonewline
293 ---
294    leading whitespace
295
296 ---
297 oneline
298 ---
299 ], [ignore])
300
301 AT_CLEANUP
302
303 AT_SETUP([gen-tree.awk])
304 AT_DATA([tree.def],
305 [[ROOT0
306   r0a, r0a_OFFSET
307     r0b, r0b_OFFSET
308       r0c
309     r0d
310   r0e, r0e_OFFSET
311     r0f
312     r0g
313 ROOT1
314   r1a, r1a_OFFSET
315     r1b, r1b_OFFSET
316       r1b
317       r1e
318       r1b
319   r1c, r1c_OFFSET
320     r1d, r1d_OFFSET
321       r1e
322       r1b
323       r1e
324 ]])
325
326 AT_CHECK([$AWK -f "$builddir/scripts/gen-tree.awk" <tree.def >tree.h])
327
328 AT_DATA([test0.c],
329 [[#include "tree.h"
330 #include <stdio.h>
331
332 struct tree { unsigned id, subtree; };
333
334 static const struct tree tree0[] = {
335   ROOT0_INITIALIZER
336 };
337 static const struct tree tree1[] = {
338   ROOT1_INITIALIZER
339 };
340
341 void print_subtree(const struct tree *root, unsigned offset, int depth)
342 {
343   const struct tree *node;
344
345   for (node = &root[offset]; node->id; node++) {
346     printf("%*s%s", 2*depth, "", &tree_strtab[node->id]);
347     if (node->subtree) {
348       printf(", %s_OFFSET\n", &tree_strtab[node->id]);
349       print_subtree(root, node->subtree, depth+1);
350     } else {
351       putchar('\n');
352     }
353   }
354 }
355
356 int main(void)
357 {
358   printf("ROOT0\n");
359   print_subtree(tree0, 0, 1);
360   printf("ROOT1\n");
361   print_subtree(tree1, 0, 1);
362 }
363 ]])
364 cp tree.def expout
365 AT_CHECK([$CC -o test0$EXEEXT test0.c && ./test0$EXEEXT], [0], [expout])
366
367 AT_CLEANUP
368
369 AT_SETUP([join.awk])
370
371 JOIN="$AWK -f $builddir/scripts/join.awk --"
372
373 AT_DATA([a],
374 [[1 a
375 3 a1 x
376 3 a2 x
377 5 a
378 6 a
379 8 a1 x
380 8 a2 x
381 9 a1
382 9 a2
383 9 a3
384 ]])
385
386 AT_DATA([b],
387 [[2 b
388 2 b
389 3 b y
390 4 b
391 6 b1 y
392 6 b2 y
393 7 b
394 8 b1 y
395 8 b2 y
396 ]])
397
398 AT_CHECK([$JOIN a b], [0],
399 [[3 a1 x b y
400 3 a2 x b y
401 6 a b1 y
402 6 a b2 y
403 8 a1 x b1 y
404 8 a1 x b2 y
405 8 a2 x b1 y
406 8 a2 x b2 y
407 ]])
408
409 AT_CHECK([$JOIN -v1 a b], [0],
410 [[1 a
411 5 a
412 9 a1
413 9 a2
414 9 a3
415 ]])
416
417 AT_CHECK([$JOIN -v2 a b], [0],
418 [[2 b
419 2 b
420 4 b
421 7 b
422 ]])
423
424 AT_CHECK([$JOIN -v1 -v2 a b], [0],
425 [[1 a
426 2 b
427 2 b
428 4 b
429 5 a
430 7 b
431 9 a1
432 9 a2
433 9 a3
434 ]])
435
436 AT_CHECK([$JOIN -a1 a b], [0],
437 [[1 a
438 3 a1 x b y
439 3 a2 x b y
440 5 a
441 6 a b1 y
442 6 a b2 y
443 8 a1 x b1 y
444 8 a1 x b2 y
445 8 a2 x b1 y
446 8 a2 x b2 y
447 9 a1
448 9 a2
449 9 a3
450 ]])
451
452 AT_CHECK([$JOIN -a2 a b], [0],
453 [[2 b
454 2 b
455 3 a1 x b y
456 3 a2 x b y
457 4 b
458 6 a b1 y
459 6 a b2 y
460 7 b
461 8 a1 x b1 y
462 8 a1 x b2 y
463 8 a2 x b1 y
464 8 a2 x b2 y
465 ]])
466
467 AT_CHECK([$JOIN -a1 -a2 a b], [0],
468 [[1 a
469 2 b
470 2 b
471 3 a1 x b y
472 3 a2 x b y
473 4 b
474 5 a
475 6 a b1 y
476 6 a b2 y
477 7 b
478 8 a1 x b1 y
479 8 a1 x b2 y
480 8 a2 x b1 y
481 8 a2 x b2 y
482 9 a1
483 9 a2
484 9 a3
485 ]])
486
487 AT_CHECK([$JOIN b a], [0],
488 [[3 b y a1 x
489 3 b y a2 x
490 6 b1 y a
491 6 b2 y a
492 8 b1 y a1 x
493 8 b1 y a2 x
494 8 b2 y a1 x
495 8 b2 y a2 x
496 ]])
497
498 AT_CHECK([$JOIN -v1 b a], [0],
499 [[2 b
500 2 b
501 4 b
502 7 b
503 ]])
504
505 AT_CHECK([$JOIN -v2 b a], [0],
506 [[1 a
507 5 a
508 9 a1
509 9 a2
510 9 a3
511 ]])
512
513 AT_CHECK([$JOIN -v1 -v2 b a], [0],
514 [[1 a
515 2 b
516 2 b
517 4 b
518 5 a
519 7 b
520 9 a1
521 9 a2
522 9 a3
523 ]])
524
525 AT_CHECK([$JOIN -a1 b a], [0],
526 [[2 b
527 2 b
528 3 b y a1 x
529 3 b y a2 x
530 4 b
531 6 b1 y a
532 6 b2 y a
533 7 b
534 8 b1 y a1 x
535 8 b1 y a2 x
536 8 b2 y a1 x
537 8 b2 y a2 x
538 ]])
539
540 AT_CHECK([$JOIN -a2 b a], [0],
541 [[1 a
542 3 b y a1 x
543 3 b y a2 x
544 5 a
545 6 b1 y a
546 6 b2 y a
547 8 b1 y a1 x
548 8 b1 y a2 x
549 8 b2 y a1 x
550 8 b2 y a2 x
551 9 a1
552 9 a2
553 9 a3
554 ]])
555
556 AT_CHECK([$JOIN -a1 -a2 b a], [0],
557 [[1 a
558 2 b
559 2 b
560 3 b y a1 x
561 3 b y a2 x
562 4 b
563 5 a
564 6 b1 y a
565 6 b2 y a
566 7 b
567 8 b1 y a1 x
568 8 b1 y a2 x
569 8 b2 y a1 x
570 8 b2 y a2 x
571 9 a1
572 9 a2
573 9 a3
574 ]])
575
576 AT_CHECK([echo wat | $JOIN -v1 - /dev/null], [0],
577 [[wat
578 ]])
579
580 AT_CLEANUP