]> git.draconx.ca Git - cdecl99.git/blobdiff - tests/decl-good.at
tests: Add sanity test for variable-length arrays.
[cdecl99.git] / tests / decl-good.at
index b0e648e1b38d89c90243712af4eae4cb460268d6..79cc6f9187739f57de263a9da8d7c13908857360 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright © 2020 Nick Bowler
+# Copyright © 2020-2021, 2023 Nick Bowler
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 
 AT_BANNER([C declarations])
 
-m4_define([CHECK_DECLS],
-[AT_CHECK([cdecl99 m4_map_args_sep([-e 'explain ], ['], [ ], m4_shift($@))],
-  [0], [[$1]m4_ifval([$1], [
-])])])
+dnl _SIMPLE_DECL_ARG([n1 n2], [arg1], ..., [argn])
+dnl
+dnl Similar to m4_argn, except the first argument has (up to) two argument
+dnl numbers, and the first nonempty matching argument is selected.
+dnl
+dnl The expansion is followed by a newline.
+m4_define([_SIMPLE_DECL_ARG],
+[m4_default(m4_map_args_w([$1], [m4_argn(], [, $2)], [,]))
+])
 
-m4_define([SIMPLE_DECLS],
-[AT_SETUP([Accept m4_car($1)])
-CHECK_DECLS(m4_join([
-], $2), $1)
+dnl SIMPLE_DECLS_EXPLAIN([arg], [arg...])
+dnl
+dnl Generate tests to validate correct parsing and output of each specification
+dnl argument.  The arguments are quoted list of quoted items, with the first
+dnl item of each list being the C declaration or type name to be explained.
+dnl
+dnl The expected output is the fourth item of the list, or, if that is empty,
+dnl the second item in the list (this allows the same lists to be used for
+dnl both SIMPLE_DECLS_DECLARE and SIMPLE_DECLS_EXPLAIN even in case of
+dnl various equivalent syntactic forms)
+dnl
+dnl The items should be related to each other as the user-visible test group
+dnl name is determined only by the first argument.
+m4_define([SIMPLE_DECLS_EXPLAIN],
+[AT_SETUP([Explain "m4_car($1)"m4_ifnblank([$2], [ etc.])])
+AT_DATA([test.dat],
+[m4_map_args([explain m4_curry([_SIMPLE_DECL_ARG], [1])], $@)])
+AT_DATA([expout],
+[m4_map_args([m4_curry([_SIMPLE_DECL_ARG], [4 2])], $@)])
+AT_CHECK([cdecl99 -f test.dat], [0], [expout])
+AT_CLEANUP])
+
+dnl SIMPLE_DECLS_DECLARE([arg], [arg ...])
+dnl
+dnl Similar to SIMPLE_DECLS_EXPLAIN, except in the opposite direction.  The
+dnl arguments are quoted lists of quoted items, with the second item of each
+dnl list being the input query.
+dnl
+dnl The expected output is the third item of the list, or, if that is empty,
+dnl the first item in the list (this allows the same lists to be used for
+dnl both SIMPLE_DECLS_DECLARE and SIMPLE_DECLS_EXPLAIN even in the case
+dnl of various equivalent syntactic forsm)
+dnl
+dnl The items should be related to each other as the user-visible test group
+dnl name is determined only by the first argument.
+m4_define([SIMPLE_DECLS_DECLARE],
+[AT_SETUP([Declare "m4_car($1)"m4_ifnblank([$2], [ etc.])])
+AT_DATA([test.dat],
+[m4_map_args([m4_curry([_SIMPLE_DECL_ARG], [2])], $@)])
+AT_DATA([expout],
+[m4_map_args([m4_curry([_SIMPLE_DECL_ARG], [3 1])], $@)])
+AT_CHECK([cdecl99 -f test.dat], [0], [expout])
 AT_CLEANUP])
-m4_define([SIMPLE_DECL], [SIMPLE_DECLS([[$1]], [[$2]])])
-
-SIMPLE_DECLS([[int **], [int **x]],
-  [[type pointer to pointer to int],
-   [declare x as pointer to pointer to int]])
-SIMPLE_DECLS([[int (*x)], [int (*)]],
-  [[declare x as pointer to int],
-   [type pointer to int]])
-SIMPLE_DECL([int (x*)], [type function (pointer to x) returning int])
+
+dnl SIMPLE_DECLS(arg, [arg ...])
+m4_define([SIMPLE_DECLS],
+[SIMPLE_DECLS_EXPLAIN($@)
+SIMPLE_DECLS_DECLARE($@)])
+
+SIMPLE_DECLS(
+  [[int **],  [type pointer to pointer to int]],
+  [[int **x], [declare x as pointer to pointer to int]])
+
+SIMPLE_DECLS(
+  [[int (*x)], [declare x as pointer to int], [int *x]],
+  [[int (*)],  [type pointer to int], [int *]])
+
+SIMPLE_DECLS(
+  [[int (x*)], [type function (pointer to x) returning int], [int (x *)]])
+
+SIMPLE_DECLS(
+  [[int (x)()], [declare x as function returning int], [int x()]])
+
+dnl Check that function reduction does not occur in english parses
+SIMPLE_DECLS(
+  [[int (x)], [type function (x) returning int], [], [declare x as int]])
+
+SIMPLE_DECLS(
+  [[int x@<:@@:>@], [declare x as array of int]],
+  [[int @<:@@:>@],  [type array of int]])
+
+SIMPLE_DECLS(
+  [[int x@<:@n@:>@], [declare x as variable-length array n of int]],
+  [[int x@<:@*@:>@], [declare x as variable-length array of int]],
+  [[int @<:@n@:>@],  [type variable-length array n of int]],
+  [[int @<:@*@:>@],  [type variable-length array of int]])
+
+SIMPLE_DECLS_EXPLAIN(
+  [[int ((int))], [type function (int) returning int], [int (int)]],
+  [[int (x(int))], [declare x as function (int) returning int], [int x(int)]],
+  [[int (())], [type function returning int], [int ()]])
+
+SIMPLE_DECLS_EXPLAIN(
+  [[int (x())], [declare x as function returning int], [int x()]],
+  [[int ((x)())], [declare x as function returning int], [int x()]])
+
+dnl Test that english-only keywords are not rejected as idenfitiers in C mode.
+SIMPLE_DECLS_EXPLAIN(
+  [[of array@<:@@:>@], [declare array as array of of]],
+  [[returning as(function)],
+    [declare as as function (function) returning returning]],
+  [[pointer *declare], [declare declare as pointer to pointer]],
+  [[type to], [declare to as type]])