X-Git-Url: http://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/ad973d63e038f293f2b158f19b04c1582e616af0..d546887cd6d807f258fc4fb2f47a655310e356ba:/doc/libcdecl.3 diff --git a/doc/libcdecl.3 b/doc/libcdecl.3 index dd70f49..4a882a0 100644 --- a/doc/libcdecl.3 +++ b/doc/libcdecl.3 @@ -1,6 +1,6 @@ -.Dd March 13, 2021 -.Os cdecl99 +.Dd December 3, 2023 .Dt LIBCDECL \&3 "Cdecl99 Developer's Manual" +.Os cdecl99 .Sh NAME .Nm libcdecl .Nd C library for making sense of C declarations @@ -11,13 +11,13 @@ .Fd struct cdecl *cdecl_parse_english(const char *english); .Fd void cdecl_free(struct cdecl *decl); .Pp -.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); +.Fd size_t cdecl_explain(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); +.Fd int cdecl_is_abstract(struct cdecl_declarator *declarator); .Sh DESCRIPTION .Nm provides support for parsing C declarations and translating them to something @@ -190,8 +190,8 @@ In the next section, we will use the word 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 , +as the declaration's base type (found amongst the declaration specifiers, +.No e.g. Li int , const unsigned long , etc.) .Pp The five types of declarators, described below, are distinguished by the @@ -230,7 +230,7 @@ union member points to the C string containing the identifier. Since a null declarator may be deeply nested in the declarator chain, the function .Pp -.Fd bool cdecl_is_abstract(struct cdecl_declarator *declarator); +.Fd int cdecl_is_abstract(struct cdecl_declarator *declarator); .Pp can be used to determine whether or not a given declarator declares an identifier. @@ -267,15 +267,17 @@ is positive, then this is an array declarator with the specified length. Otherwise, this is an incomplete array declarator. .Ss Function Declarators .Bd -literal -offset indent +typedef _Bool cdecl_bool; /* depends on configuration */ struct cdecl_function { struct cdecl *parameters; - _Bool variadic; + cdecl_bool variadic; }; .Ed .Pp If .Va parameters -is null, then this is a non-prototype function declarator. +is null, then this is a non-prototype function declarator with an empty +identifier list. Otherwise, .Va parameters points to the first element of a singly-linked list of declarations @@ -284,15 +286,27 @@ Note that, unlike toplevel declarations, each function parameter has exactly one full declarator (abstract or otherwise). If .Va variadic -is true, then the function is variadic. +is non-zero, then the function is variadic. +.Pp +Please note that if the compiler used to build the library does not support +.Vt _Bool , +then +.Vt cdecl_bool +will be defined as +.Vt signed char +instead. +In most cases these will have a compatible binary representation, provided +that applications do not set +.Va variadic +to any values besides 0 or 1. .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 +Old-style function declarations with non-empty identifier lists cannot be +directly represented by this structure. +Such declarations are syntactically identical to a prototype with every +parameter consisting solely of a typedef name. .Nm -isn't a C compiler, there is no way for its parser to tell these two kinds of -declarations apart. +cannot tell these apart when parsing and thus will return a parameter +list, which can be rendered as expected. .Sh ERROR HANDLING Some functions in .Nm @@ -338,41 +352,71 @@ from calling .Fn cdecl_get_error is unspecified. .Sh PARSING DECLARATIONS -To parse a declaration, the function -.Pp -.Fd struct cdecl *cdecl_parse_decl(const char *declstr); +The functions .Pp -can be used. -The provided string is parsed as a C declaration. -If successful, this function returns a pointer to an abstract syntax tree -representing the declaration. -If the parse fails for any reason, the function returns NULL. +.Fd struct cdecl *cdecl_parse_decl(const char *decl); +.Fd struct cdecl *cdecl_parse_english(const char *english); .Pp -Similarly, English declarations can be parsed by using the function +parse a string into an abstract syntax tree representing the declaration. +The +.Fn cdecl_parse_decl +function interprets the string as C declaration syntax, while +.Fn cdecl_parse_english +uses the English declaration syntax. +If successful, a pointer to the abstract syntax tree representing the +declaration is returned. +If the parse fails for any reason, the function returns NULL, and +.Fn cdecl_get_error +may be used to retrieve the reason for failure. .Pp -.Fd struct cdecl *cdecl_parse_english(const char *english); +The manner in which memory is allocated by these functions for the returned +tree structure is unspecified. +In particular, multiple nodes may share memory or may be implemented as +read-only static allocations. +Thus, the caller should not directly modify any part of the returned structure, +as the results may be unexpected. +A copy should be made if modifications are required. .Pp -When the AST is no longer needed, it must be freed by passing it to the +When the structure returned by either parsing function is no longer needed, the function .Pp .Fd void cdecl_free(struct cdecl *decl); +.Pp +may be used to release all memory allocations associated with that parse tree. .Sh RENDERING DECLARATIONS -After parsing, the abstract syntax tree can be rendered to a string for output. -Use the function +An abstract syntax tree (which may be the result of calling one of the parsing +functions or constructed explicitly by the program) can be rendered to a string +for output. +The functions .Pp +.Fd size_t cdecl_declare(char *buf, size_t n, struct cdecl *decl); .Fd size_t cdecl_explain(char *buf, size_t n, struct cdecl *decl); .Pp -to format the AST pointed to by +perform this rendering. +The +.Fa cdecl_declare +function produces output in C declaration syntax, while the +.Fa cdecl_explain +function produces output in the English declaration syntax. +.Pp +Only one top-level full declarator is rendered by each call; that is, these +functions do not traverse the +.Fa decl +linked list at the top level. +The caller can traverse this list to render multiple declarators. +In order to assist with generating C declaration syntax, as a special case, +when calling +.Fn cdecl_declare +the +.Va specifiers +member of the .Fa decl -into something resembling English. -At most one full declarator is rendered in this way; for declarations with more -than one full declarator, this function should be called on each -.Dv struct cdecl -in the singly-linked list. -.Pp -In a manner similar to that of -.Xr snprintf 3 , -at most +structure may be a null pointer. +In this case, only the declarator is rendered. +.Pp +The string is output in a manner similar to that of +.Xr snprintf 3 . +At most .Fa n bytes, including the '\\0' terminator, are written to .Fa buf . @@ -381,27 +425,21 @@ If is zero, it is acceptable for .Fa buf to be a null pointer. -Regardless, the function returns the number of characters that would be written -to +.Pp +The number of characters that would be written to .Fa buf if .Fa n -were long enough, not including the '\\0' terminator. -Thus, the entire string was written if a value less than +were large enough is returned, not including the '\\0' terminator. +Hence the entire string was written if the returned value is less than +.Fa n . +If .Fa n -is returned. -.Pp -Similarly, the function -.Pp -.Fd size_t cdecl_declare(char *buf, size_t n, struct cdecl *decl); -.Pp -will render the AST pointed to by -.Fa decl -into C code. +is non-zero, the resulting string is '\\0' terminated even if it was truncated. .Sh AUTHORS Nick Bowler .Sh COPYRIGHT -Copyright \(co 2011\(en2012, 2021 Nick Bowler +Copyright \(co 2011\(en2012, 2021, 2023 Nick Bowler .Pp Permission is granted to copy, distribute and/or modify this manual under the terms of the GNU General Public License as published by the Free Software