summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
b1e5676)
Some renderings of pointer qualifiers have an unwanted trailing space,
for example:
> type const pointer to array of int
int (* const )[]
This exact bug was fixed before, more than 10 years ago, but as no test
case was added it took some time to notice the problem when the fix was
inadvertently deleted. This time, we fix it again, and also add some
test cases to verify the output.
/*
* Render C declarations.
/*
* Render C declarations.
- * Copyright © 2011, 2021, 2023 Nick Bowler
+ * Copyright © 2011, 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
*
* 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
static void declare_decl(struct output_state *dst, struct cdecl *decl)
{
static void declare_decl(struct output_state *dst, struct cdecl *decl)
{
+ struct cdecl_declarator *d = decl->declarators;
const char *sep;
sep = 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)
+ if (d->type != CDECL_DECL_NULL)
- declare_declarator(dst, decl->declarators);
+ declare_declarator(dst, d);
}
static void
declare_postfix_child(struct output_state *dst, struct cdecl_declarator *d)
{
}
static void
declare_postfix_child(struct output_state *dst, struct cdecl_declarator *d)
{
- if (d->type == CDECL_DECL_POINTER)
- cdecl__emit(dst, "(");
+ bool need_parens = (d->type == CDECL_DECL_POINTER);
+ if (need_parens) cdecl__emit(dst, "(");
declare_declarator(dst, d);
declare_declarator(dst, d);
-
- if (d->type == CDECL_DECL_POINTER)
- cdecl__emit(dst, ")");
+ if (need_parens) cdecl__emit(dst, ")");
-static void declare_pointer(struct output_state *dst, struct cdecl_pointer *p)
+static void declare_pointer(struct output_state *dst, struct cdecl_declarator *d)
- struct cdecl_declspec *q = p->qualifiers;
+ struct cdecl_declspec *q = d->u.pointer.qualifiers;
- cdecl__emit_specs(dst, q, -1);
- cdecl__emit(dst, " ");
+ sep = cdecl__emit_specs(dst, q, -1);
+ if (d->child->type != CDECL_DECL_NULL)
+ cdecl__emit(dst, sep);
} else {
cdecl__emit(dst, "*");
}
} else {
cdecl__emit(dst, "*");
}
cdecl__emit(dst, d->u.ident);
break;
case CDECL_DECL_POINTER:
cdecl__emit(dst, d->u.ident);
break;
case CDECL_DECL_POINTER:
- declare_pointer(dst, &d->u.pointer);
+ declare_pointer(dst, d);
break;
/*
* Arrays and functions are special: since they are postfix,
break;
/*
* Arrays and functions are special: since they are postfix,
SIMPLE_DECLS_EXPLAIN(
[[int x, y], [m4_n([declare x as int])declare y as int]])
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.
# 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.