]> git.draconx.ca Git - cdecl99.git/commitdiff
Make is_abstract a proper library function.
authorNick Bowler <nbowler@draconx.ca>
Wed, 30 Nov 2011 01:08:54 +0000 (20:08 -0500)
committerNick Bowler <nbowler@draconx.ca>
Sat, 25 Feb 2012 22:06:54 +0000 (17:06 -0500)
This function is generally useful.  Add it to the public API.

doc/man/libcdecl.3
src/cdecl.h
src/parse-decl.c

index 489d7a9ef7eb8fce9a409c70d1aab18735e2efdd..8bcc39440e18379056c4bd2cdd3f726a190dfe89 100644 (file)
@@ -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 {
index 1493d4db53c17f940a3c99b554a87de2eb82879d..695024f5e8d63b9b9ada57e3b2db4b3170b89770 100644 (file)
@@ -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,
index 42931a3c866ada6229ce3212efb03421119a238e..5c8e6845afad1777f3f97f8e5876387fa19ae2dd 100644 (file)
 #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;
                }