X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/8496fc5619ac0e78e1a663e07e2c6bb84802ca0d..HEAD:/doc/libcdecl.3 diff --git a/doc/libcdecl.3 b/doc/libcdecl.3 index 74ce280..725566b 100644 --- a/doc/libcdecl.3 +++ b/doc/libcdecl.3 @@ -1,6 +1,6 @@ -.Dd March 13, 2021 -.Os cdecl99 +.Dd January 17, 2024 .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 @@ -29,8 +29,7 @@ see the manual page. .Pp .Nm -is intended to be portable to any system with a working C implementation that -at least makes an effort to support C99. +is intended to be portable to any system with a standard C compiler. The library is thread-safe when appropriate facilities exist and are enabled at build time. .Sh NAMESPACE @@ -230,7 +229,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. @@ -248,9 +247,10 @@ member is non-null, then it points to the first element of a singly-linked list of type qualifiers. .Ss Array Declarators .Bd -literal -offset indent +typedef unsigned long long cdecl_uintmax; /* depends on configuration */ struct cdecl_array { char *vla; - uintmax_t length; + cdecl_uintmax length; }; .Ed .Pp @@ -265,17 +265,32 @@ Otherwise, if .Va length is positive, then this is an array declarator with the specified length. Otherwise, this is an incomplete array declarator. +.Pp +If the library was configured using a compiler which does not support +.Vt unsigned long long , +then the +.Vt cdecl_uintmax +type is defined as +.Vt unsigned long +instead. +Prior versions of +.Nm +used +.Vt uintmax_t +directly. .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 +299,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 +365,71 @@ from calling .Fn cdecl_get_error is unspecified. .Sh PARSING DECLARATIONS -To parse a declaration, the function +The functions .Pp -.Fd struct cdecl *cdecl_parse_decl(const char *declstr); -.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 -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 +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 +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 +438,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\(en2024 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