]> git.draconx.ca Git - cdecl99.git/blobdiff - doc/libcdecl.3
Don't run configure tests for threading if disabled.
[cdecl99.git] / doc / libcdecl.3
index dd70f496e0bf3dd619c6b5ee21ab77cf9e6ce1ff..725566b2944fa8bbfcf2b9dc02460b820e4a8672 100644 (file)
@@ -1,6 +1,6 @@
-.Dd March 13, 2021
-.Os cdecl99
+.Dd January 17, 2024
 .Dt LIBCDECL \&3 "Cdecl99 Developer's Manual"
 .Dt LIBCDECL \&3 "Cdecl99 Developer's Manual"
+.Os cdecl99
 .Sh NAME
 .Nm libcdecl
 .Nd C library for making sense of C declarations
 .Sh NAME
 .Nm libcdecl
 .Nd C library for making sense of C declarations
 .Fd struct cdecl *cdecl_parse_english(const char *english);
 .Fd void cdecl_free(struct cdecl *decl);
 .Pp
 .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_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);
 .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
 .Sh DESCRIPTION
 .Nm
 provides support for parsing C declarations and translating them to something
@@ -29,8 +29,7 @@ see the
 manual page.
 .Pp
 .Nm
 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
 The library is thread-safe when appropriate facilities exist and are enabled at
 build time.
 .Sh NAMESPACE
@@ -190,8 +189,8 @@ In the next section, we will use the word
 to describe this inverted child relationship: we consider the outermost
 declarator's
 .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 ,
+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
 etc.)
 .Pp
 The five types of declarators, described below, are distinguished by the
@@ -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
 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.
 .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
 of type qualifiers.
 .Ss Array Declarators
 .Bd -literal -offset indent
+typedef unsigned long long cdecl_uintmax; /* depends on configuration */
 struct cdecl_array {
        char *vla;
 struct cdecl_array {
        char *vla;
-       uintmax_t length;
+       cdecl_uintmax length;
 };
 .Ed
 .Pp
 };
 .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.
 .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
 .Ss Function Declarators
 .Bd -literal -offset indent
+typedef _Bool cdecl_bool; /* depends on configuration */
 struct cdecl_function {
        struct cdecl *parameters;
 struct cdecl_function {
        struct cdecl *parameters;
-       _Bool variadic;
+       cdecl_bool variadic;
 };
 .Ed
 .Pp
 If
 .Va parameters
 };
 .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
 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
 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
 .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
 .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
 .Sh ERROR HANDLING
 Some functions in
 .Nm
@@ -338,41 +365,71 @@ from calling
 .Fn cdecl_get_error
 is unspecified.
 .Sh PARSING DECLARATIONS
 .Fn cdecl_get_error
 is unspecified.
 .Sh PARSING DECLARATIONS
-To parse a declaration, the function
+The functions
 .Pp
 .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
 .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
 .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
 .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);
 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
 .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
 .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
 .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
 .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 .
 .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.
 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
 .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
 .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 <nbowler@draconx.ca>
 .Sh COPYRIGHT
 .Sh AUTHORS
 Nick Bowler <nbowler@draconx.ca>
 .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
 .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