X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/148832244970c409dfe187b66cb6c7aed5f60083..846e987e42c15064fa078e0b708872f7938ceb09:/doc/man/libcdecl.3 diff --git a/doc/man/libcdecl.3 b/doc/man/libcdecl.3 index d92dcbf..00280f5 100644 --- a/doc/man/libcdecl.3 +++ b/doc/man/libcdecl.3 @@ -14,7 +14,10 @@ .Fd size_t cdecl_explain(char *buf, size_t n, struct cdecl *decl); .Fd size_t cdecl_declare(char *buf, size_t n, struct cdecl *decl); .Pp +.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 @@ -164,38 +167,64 @@ struct cdecl_declarator { }; .Ed .Pp -There are five types of declarators, distinguished by the +With the exception of function parameters (which are handled separately), +declarators form a chain from +.Do outermost Dc to Do innermost Dc +declarator. This relationship is expressed by the +.Va child +struct member, which points to the next innermost declarator in the chain. +Unfortunately, C's declaration syntax is, in a sense, inside-out. Thus, one +needs to follow the chain backwards (from innermost to outermost) to understand +the semantic relationship between declarators in the chain. In the next +section, we will use the word +.Va parent +to describe this inverted child relationship: we consider the outermost +declarator's +.Va parent +as the declaration's base type (found amongst the declaration specifiers, e.g. +.Li int , const unsigned long , +etc.) + +The five types of declarators, described below, are distinguished by the .Va type -struct member. The union -.u +struct member. Each declarator (except null declarators) carries additional +information specific to its type, which corresponds to the members of the union +.Va u . + contains a member for each declarator type (except null) containing additional -information. The possible values are described by the following table. The -description of the child member is a lie. +information. The possible values are described by the following table. .Bl -column ".Dv CDECL_DECL_FUNCTION" ".Em Union Member" .It Em Declarator Type Ta Em Union Member Ta Em Description .It Dv CDECL_DECL_NULL Ta (none) Ta Declares nothing. This -declarator has no +declarator terminates the declarator chain, and has a NULL .Va child . .It Dv CDECL_DECL_IDENT Ta Va ident Ta Declares an identifier. This -declarator has no +declarator has a NULL .Va child . -.It Dv CDECL_DECL_POINTER Ta Va pointer Ta Declares a pointer. The -.Va child -member is interpreted as "pointer to child". -.It Dv CDECL_DECL_ARRAY Ta Va array Ta Declares an array. The -.Va child -member is interpreted as "array of child". -.It Dv CDECL_DECL_FUNCTION Ta Va function Ta Declares a function. The -.Va child -member is interpreted as "function returning child". +.It Dv CDECL_DECL_POINTER Ta Va pointer Ta Declares a pointer, as in +.Do pointer to Va parent Dc +.It Dv CDECL_DECL_ARRAY Ta Va array Ta Declares an array, as in +.Do array of Va parent Dc +.It Dv CDECL_DECL_FUNCTION Ta Va function Ta Declares a function, as in +.Do function returning Va parent Dc .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 { @@ -244,6 +273,51 @@ each function parameter has exactly one full declarator (abstract or otherwise). If .Va variadic is true, then the function is variadic. +.Pp +Note that old-style function declarations with non-empty identifier lists are +not directly represented here: this is because they are syntactically identical +to a prototype where every parameter is a typedef name. Since +.Nm +isn't a C compiler, there is no way for the parser to tell these two kinds of +declarations apart. +.Sh ERROR HANDLING +Some functions in +.Nm +can fail. Such functions will be documented as indicating an error condition +in a particular way. It is sometimes necessary to know more about a particular +error in order to print an informative error message or perform some other +action. To facilitate this, +.Nm +provides a structure which describes a particular error. +.Bd -literal -offset indent +struct cdecl_error { + unsigned code; + const char *str; +}; +.Ed +.Pp +The +.Va code +member identifies the sort of error which has occurred, while the +.Va str +member points to a string containing a human-readable description of the error. +This error information can be retrieved by calling the function +.Pp +.Fd const struct cdecl_error *cdecl_get_error(void); +.Pp +which returns a pointer to the error structure most recently generated in the +current thread. It is therefore thread-safe in that errors occurring in +another thread will not interfere with the current one. The returned pointer +shall remain valid until the next call to any function from +.Nm +by the same thread, except that multiple consecutive calls to +.Va cdecl_get_error +shall all return the same value. The same applies to the +.Va str +pointer inside the error structure itself. +.Pp +If this function is called before an error has been indicated by an earlier +call in the same thread, the behaviour is undefined. .Sh PARSING DECLARATIONS To parse a declaration, the function .Pp