X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/b36da52d0e7798814d23cdc9979fc1900f8e9e51..da87235fd91665373a44dbc75b1750deaaf81abe:/tests/decl-good.at?ds=sidebyside diff --git a/tests/decl-good.at b/tests/decl-good.at index 5b8b9a6..002e482 100644 --- a/tests/decl-good.at +++ b/tests/decl-good.at @@ -1,4 +1,4 @@ -# Copyright © 2020 Nick Bowler +# Copyright © 2020-2021, 2023-2024 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 @@ -15,13 +15,217 @@ AT_BANNER([C declarations]) -m4_define([CHECK_DECL], -[AT_DATA([expout], [[$2]m4_newline]) -AT_CHECK([cdecl99 -e 'explain $1'], [0], [expout])]) +# _SIMPLE_DECL_ARG([n], [list]) +# _SIMPLE_DECL_ARG([n1 n2], [list]) +# +# Select one element (indexed from 1) from the given quoted list of quoted +# elements, either one or two elements may be indicated; in the two index form, +# element n1 is selected unless it is blank, in which case element n2 is used. +# +# The expansion of this macro is followed by a newline. +m4_define([_SIMPLE_DECL_ARG], +[m4_default(m4_map_args_w([$1], [m4_argn(], [, $2)], [,])) +]) + +# SIMPLE_DECLS_EXPLAIN([arg], [arg...]) +# +# Generate tests to validate correct parsing and output of each specification +# argument. The arguments are quoted list of quoted items, with the first +# item of each list being the C declaration or type name to be explained. +# +# The expected output is the fourth item of the list, or, if that is empty, +# the second item in the list (this allows the same lists to be used for +# both SIMPLE_DECLS_DECLARE and SIMPLE_DECLS_EXPLAIN even in case of +# various equivalent syntactic forms) +# +# The items should be related to each other as the user-visible test group +# 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]) + +# SIMPLE_DECLS_DECLARE([arg], [arg ...]) +# +# Similar to SIMPLE_DECLS_EXPLAIN, except in the opposite direction. The +# arguments are quoted lists of quoted items, with the second item of each +# list being the input query. +# +# The expected output is the third item of the list, or, if that is empty, +# the first item in the list (this allows the same lists to be used for +# both SIMPLE_DECLS_DECLARE and SIMPLE_DECLS_EXPLAIN even in the case +# of various equivalent syntactic forsm) +# +# The items should be related to each other as the user-visible test group +# 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], -[AT_SETUP([$1]) -CHECK_DECL([$1], [$2]) +# SIMPLE_DECLS_SIMPLIFY([arg], [arg ...]) +# +# Generate tests to validate the expected operation of the "simplify" +# command. The arguments are a quoted list of quoted items, with the +# first item of each list being the input declaration and the second +# item being the expected simplified output. +# +# The items should be related to each other as the user-visible test +# 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]) -SIMPLE_DECL([int (x*)], [type function (pointer to x) returning int]) +# 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()]]) + +# 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( + [[int f(a, b)], [declare f as function (a, b) returning int]], + [[int f(int, b)], [declare f as function (int, b) returning int]], + [[int f(a, int)], [declare f as function (a, int) returning int]], + [[int (a, b)], [type function (a, b) returning int]], + [[int (int, b)], [type function (int, b) returning int]], + [[int (a, int)], [type function (a, int) returning int]]) + +SIMPLE_DECLS( + [[int f(a, b, ...)], [declare f as function (a, b, ...) returning int]], + [[int f(int, b, ...)], [declare f as function (int, b, ...) returning int]], + [[int f(a, int, ...)], [declare f as function (a, int, ...) returning int]], + [[int (a, b, ...)], [type function (a, b, ...) returning int]], + [[int (int, b, ...)], [type function (int, b, ...) returning int]], + [[int (a, int, ...)], [type function (a, int, ...) returning int]]) + +SIMPLE_DECLS( + [[[int f(int (*)[])]], + [declare f as function (pointer to array of int) returning int]], + [[[int f(int (*)[][1])]], + [declare f as function (pointer to array of array 1 of int) returning int]], + [[[int f(int (*)())]], + [declare f as function (pointer to function returning int) returning int]], + [[[int f(a (*)[])]], + [declare f as function (pointer to array of a) returning int]], + [[[int f(a (*)[][1])]], + [declare f as function (pointer to array of array 1 of a) returning int]], + [[[int f(a (*)())]], + [declare f as function (pointer to function returning a) returning int]], + [[[int (int (*)[])]], + [type function (pointer to array of int) returning int]], + [[[int (int (*)[][1])]], + [type function (pointer to array of array 1 of int) returning int]], + [[[int (int (*)())]], + [type function (pointer to function returning int) returning int]], + [[[int (a (*)[])]], + [type function (pointer to array of a) returning int]], + [[[int (a (*)[][1])]], + [type function (pointer to array of array 1 of a) returning int]], + [[[int (a (*)())]], + [type function (pointer to function returning a) returning int]]) + +SIMPLE_DECLS_EXPLAIN( + [[[int f(int ([]))]], + [declare f as function (array of int) returning int], + [[int f(int [])]]], + [[[int f(a ([]))]], + [declare f as function (array of a) returning int], + [[int f(a [])]]], + [[[int f(int (()))]], + [declare f as function (function returning int) returning int], + [[int f(int ())]]], + [[[int f(a (()))]], + [declare f as function (function returning a) returning int], + [[int f(a ())]]], + [[[int (int ([]))]], + [type function (array of int) returning int], + [[int (int [])]]], + [[[int (a ([]))]], + [type function (array of a) returning int], + [[int (a [])]]], + [[[int (int (()))]], + [type function (function returning int) returning int], + [[int (int ())]]], + [[[int (a (()))]], + [type function (function returning a) returning int], + [[int (a ())]]]) + +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()]]) + +# 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]]) + +# Test the explain command with multiple declarators, which produces +# multiple lines of English output. +SIMPLE_DECLS_EXPLAIN( + [[int x, y], [m4_n([declare x as int])declare y as int]]) + +# Check output spacing around qualified pointers +SIMPLE_DECLS_DECLARE( + [[[int (* const)[]]], [type const pointer to array of int]], + [[[int (* volatile const)()]], + [type volatile const pointer to function returning int]], + [[[int (int * restrict const)]], + [type function (restrict const pointer to int) returning int]], + [[[int * const x]], [declare x as const pointer to int]], + [[[int * volatile * restrict x]], + [declare x as restrict pointer to volatile pointer to int]]) + +# Test the simplify command with multiple declarators. This is the only +# command in cdecl99 which will print a single C declaration with more than +# one full declarator. +SIMPLE_DECLS_SIMPLIFY( + [[int x, y], [int x, y]], + [[int (x), ((y))], [int x, y]])