From 0aa997a6eaad4cd730ddde283e8b156642510f32 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Tue, 29 Nov 2011 20:08:54 -0500 Subject: [PATCH] Make is_abstract a proper library function. This function is generally useful. Add it to the public API. --- doc/man/libcdecl.3 | 17 ++++++++++++++--- src/cdecl.h | 8 ++++++++ src/parse-decl.c | 17 +++-------------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/doc/man/libcdecl.3 b/doc/man/libcdecl.3 index 489d7a9..8bcc394 100644 --- a/doc/man/libcdecl.3 +++ b/doc/man/libcdecl.3 @@ -17,6 +17,7 @@ .Fd const struct cdecl_error *cdecl_get_error(void); .Pp .Fd int cdecl_spec_kind(struct cdecl_declspec *spec); +.Fd bool cdecl_is_abstract(struct cdecl_declarator *declarator); .Sh DESCRIPTION .Nm provides support for parsing C declarations and translating them to something @@ -193,11 +194,21 @@ member is interpreted as "function returning child". .El .Ss Terminal Declarators Null and identifier declarators have no children and are thus leaf nodes. A -null declarator indicates an abstract declarator; that is, one which does not -declare any identifier. Such declarators appear in type names and possibly -function parameters. An identifier declarator has the obvious meaning; the +null declarator is not strictly a C language construct, but is used by +.Nm +to indicate an abstract declarator; that is, one which does not declare any +identifier. Such declarators appear in type names and possibly function +parameters. An identifier declarator has the obvious meaning; the .Va ident union member points to the C string containing the identifier. +.Pp +Since a null declarator may be deeply nested in the declarator chain, the +function +.Pp +.Fd bool cdecl_is_abstract(struct cdecl_declarator *declarator); +.Pp +can be used to determine whether or not a given declarator declares an +identifier. The result is true if and only if the declarator is abstract. .Ss Pointer Declarators .Bd -literal -offset indent struct cdecl_pointer { diff --git a/src/cdecl.h b/src/cdecl.h index 1493d4d..695024f 100644 --- a/src/cdecl.h +++ b/src/cdecl.h @@ -107,6 +107,14 @@ static inline int cdecl_spec_kind(struct cdecl_declspec *spec) return spec->type & ~(CDECL_SPEC_TYPE-1u); } +static inline _Bool cdecl_is_abstract(struct cdecl_declarator *d) +{ + while (d->child) + d = d->child; + + return d->type != CDECL_DECL_IDENT; +} + /* Error handling. */ enum { CDECL_ENOMEM, diff --git a/src/parse-decl.c b/src/parse-decl.c index 42931a3..5c8e684 100644 --- a/src/parse-decl.c +++ b/src/parse-decl.c @@ -27,18 +27,6 @@ #include "i18n.h" #include "normalize.h" -/* - * Determine if a declarator declares an identifier (other than a function - * parameter). - */ -static bool is_abstract(struct cdecl_declarator *d) -{ - while (d->child) - d = d->child; - - return d->type != CDECL_DECL_IDENT; -} - /* * Verify the declaration specifiers of a declaration. If top is true, treat * this as a top-level declaration. Otherwise, treat this as a function @@ -48,7 +36,7 @@ static bool valid_declspecs(struct cdecl *decl, bool top) { struct cdecl_declspec *specs = decl->specifiers; struct cdecl_declarator *d = decl->declarators; - bool abstract = is_abstract(d); + bool abstract = cdecl_is_abstract(d); unsigned num_storage = 0; unsigned long typemap; @@ -456,7 +444,8 @@ struct cdecl *cdecl_parse_decl(const char *declstr) if (!valid_declspecs(i, true)) goto err; - if (is_abstract(i->declarators) && (i != decl || i->next)) { + if (cdecl_is_abstract(i->declarators) + && (i != decl || i->next)) { fprintf(stderr, "mixing type names and declarations is not allowed\n"); goto err; } -- 2.43.2