# 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 # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . AT_BANNER([C declarations]) 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)], [,])) ]) 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]) dnl SIMPLE_DECLS_SIMPLIFY([arg], [arg ...]) dnl dnl Generate tests to validate the expected operation of the "simplify" dnl command. The arguments are a quoted list of quoted items, with the dnl first item of each list being the input declaration and the second dnl item being the expected simplified output. dnl dnl The items should be related to each other as the user-visible test dnl group name is determined only by the first argument. m4_define([SIMPLE_DECLS_SIMPLIFY], [AT_SETUP([Simplify "m4_car($1)"m4_ifnblank([$2], [ etc.])]) AT_DATA([test.dat], [m4_map_args([simplify m4_curry([_SIMPLE_DECL_ARG], [1])], $@)]) AT_DATA([expout], [m4_map_args([m4_curry([_SIMPLE_DECL_ARG], [2])], $@)]) AT_CHECK([cdecl99 -f test.dat], [0], [expout]) AT_CLEANUP]) 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]]) dnl Test the explain command with multiple declarators, which produces dnl multiple lines of English output. SIMPLE_DECLS_EXPLAIN( [[int x, y], [m4_n([declare x as int])declare y as int]]) dnl Test the simplify command with multiple declarators. This is the only dnl command in cdecl99 which will print a single C declaration with more than dnl one full declarator. SIMPLE_DECLS_SIMPLIFY( [[int x, y], [int x, y]], [[int (x), ((y))], [int x, y]])