]> git.draconx.ca Git - cdecl99.git/commitdiff
libcdecl: Fix output regression with multiple declarators.
authorNick Bowler <nbowler@draconx.ca>
Fri, 28 Jul 2023 04:22:11 +0000 (00:22 -0400)
committerNick Bowler <nbowler@draconx.ca>
Fri, 28 Jul 2023 04:22:11 +0000 (00:22 -0400)
It turns out that the cdecl99 program implemented the simplify command
using the undocumented behaviour of calling cdecl_declare with NULL
specifiers to output just the declarator part.

Recent changes to the library partially broke that usage by printing an
extra space in this case.  This went unnoticed as the simplify command
is only lightly tested and nothing checks its behaviour with multiple
declarators.

Fortunately it is very easy to restore the old behaviour in the library,
and to add a test case to verify this behaviour.

src/declare.c
tests/decl-good.at

index 0ee9640df4fe6c45706e74534e87b315e8421f53..119d2b24d157dfb33b2e7ab21cb6dd1936552b24 100644 (file)
@@ -30,9 +30,11 @@ declare_declarator(struct output_state *dst, struct cdecl_declarator *d);
 
 static void declare_decl(struct output_state *dst, struct cdecl *decl)
 {
-       cdecl__emit_specs(dst, decl->specifiers, -1);
+       const char *sep;
+
+       sep = cdecl__emit_specs(dst, decl->specifiers, -1);
        if (decl->declarators->type != CDECL_DECL_NULL)
-               cdecl__emit(dst, " ");
+               cdecl__emit(dst, sep);
 
        declare_declarator(dst, decl->declarators);
 }
index 79cc6f9187739f57de263a9da8d7c13908857360..df570c8807c1800852d7e6530b7f725e2e63d1ba 100644 (file)
@@ -69,6 +69,24 @@ AT_DATA([expout],
 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($@)
@@ -118,3 +136,15 @@ SIMPLE_DECLS_EXPLAIN(
     [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]])