]> git.draconx.ca Git - cdecl99.git/blobdiff - doc/libcdecl.3
Minor manual updates.
[cdecl99.git] / doc / libcdecl.3
similarity index 60%
rename from doc/man/libcdecl.3
rename to doc/libcdecl.3
index 00280f5aae44d23528f46a6943b990c7f2b32f33..495a353f68b8810ee27b59f6876cc64abc86eb40 100644 (file)
@@ -1,4 +1,4 @@
-.Dd July 18, 2011
+.Dd March 6, 2021
 .Os cdecl99
 .Dt LIBCDECL \&3 "Cdecl99 Developer's Manual"
 .Sh NAME
 .Sh DESCRIPTION
 .Nm
 provides support for parsing C declarations and translating them to something
-resembling English and vice-versa.  This manual describes the programmers'
-interface only; for details such as what C language features are supported or
-the syntax of English declarations, please see the
+resembling English and vice-versa.
+This manual describes the programmers' interface only; for details such as what
+C language features are supported or the syntax of English declarations, please
+see the
 .Xr cdecl99 1
 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.  The library is thread-safe when
-appropriate facilities exist and are enabled at build time.
+at least makes an effort to support C99.
+The library is thread-safe when appropriate facilities exist and are enabled at
+build time.
 .Sh NAMESPACE
 .Nm
 reserves all identifiers beginning with either
 .Li cdecl_
 or
 .Li CDECL_
-in both the tag and ordinary identifier namespaces.  All external names
-beginning with
+in both the tag and ordinary identifier namespaces.
+All external names beginning with
 .Li cdecl_
 are reserved, and the library headers may define object-like macros beginning
 with
@@ -46,11 +48,11 @@ with
 The
 .Nm
 library headers may use other identifiers where they do not pollute the global
-namespaces, such as struct members or function parameter names.  Such internal
-identifiers shall not contain any upper-case letters.  As these internal
-identifiers can only conflict with object-like macros, this practice is safe as
-long as the convention of defining object-like macros using upper-case letters
-is adhered to.
+namespaces, such as struct members or function parameter names.
+Such internal identifiers shall not contain any upper-case letters.
+As these internal identifiers can only conflict with object-like macros, this
+practice is safe as long as the convention of defining object-like macros using
+upper-case letters is adhered to.
 .Pp
 External names beginning with
 .Li cdecl
@@ -61,10 +63,11 @@ The functions in
 .Nm
 generally operate on an abstract syntax tree representing a C declaration.
 A string is parsed into an AST which can be subsequently rendered into another
-format.  Since some information about the original string is discarded when
-generating the AST, parsing a declaration and then rendering to the same format
-is not the identity function.  The AST is represented by the following
-structure:
+format.
+Since some information about the original string is discarded when generating
+the AST, parsing a declaration and then rendering to the same format is not the
+identity function.
+The AST is represented by the following structure:
 .Bd -literal -offset indent
 struct cdecl {
        struct cdecl *next;
@@ -78,18 +81,18 @@ specifiers followed by one or more full declarators; hence, the
 .Va specifiers
 and
 .Va declarators
-members are always non-null.  A declaration with more than one declarator is
-represented by using the
+members are always non-null.
+A declaration with more than one declarator is represented by using the
 .Va next
 member to form a singly-linked list of ASTs, one element for each declarator.
 In the case of the toplevel declaration, the declaration specifiers will be
-identical for all elements of the list.  But when the same kind of list is used
-to represent function parameters, the specifiers may be different for each
-element.
+identical for all elements of the list.
+But when the same kind of list is used to represent function parameters, the
+specifiers may be different for each element.
 .Pp
 There are four kinds of declaration specifiers: storage-class, function and
-type specifiers, as well as type qualifiers.  All are represented by the
-structure:
+type specifiers, as well as type qualifiers.
+All are represented by the structure:
 .Bd -literal -offset indent
 struct cdecl_declspec {
        struct cdecl_declspec *next;
@@ -99,8 +102,9 @@ struct cdecl_declspec {
 .Ed
 .Pp
 When multiple declaration specifiers are present, they are represented as
-a singly-linked list, one element for each specifier.  Specifiers can appear
-in any order.  The function
+a singly-linked list, one element for each specifier.
+Specifiers can appear in any order.
+The function
 .Pp
 .Fd int cdecl_spec_kind(struct cdecl_declspec *spec);
 .Pp
@@ -109,48 +113,52 @@ can be used to determine what kind of specifier
 is.  The result is one of the following values:
 .Bl -column ".Dv CDECL_SPEC_TYPE"
 .It Em Kind            Ta Em Description
-.It Dv CDECL_SPEC_TYPE Ta Type specifier.
-.It Dv CDECL_SPEC_STOR Ta Storage-class specifier.
-.It Dv CDECL_SPEC_QUAL Ta Type qualifier.
-.It Dv CDECL_SPEC_FUNC Ta Function specifier.
+.It Dv CDECL_SPEC_TYPE Ta Type specifier .
+.It Dv CDECL_SPEC_STOR Ta Storage-class specifier .
+.It Dv CDECL_SPEC_QUAL Ta Type qualifier .
+.It Dv CDECL_SPEC_FUNC Ta Function specifier .
 .El
 .Pp
-The following table describes all the possible types of declaration specifiers.
+The following table describes all the possible types of declaration specifiers:
 .Bl -column ".Dv CDECL_TYPE_IMAGINARY"
 .It Em Em Type              Ta Em Description
-.It Dv CDECL_TYPE_VOID      Ta Fa void       No type specifier.
-.It Dv CDECL_TYPE_CHAR      Ta Fa char       No type specifier.
-.It Dv CDECL_TYPE_SHORT     Ta Fa short      No type specifier.
-.It Dv CDECL_TYPE_INT       Ta Fa int        No type specifier.
-.It Dv CDECL_TYPE_LONG      Ta Fa long       No type specifier.
-.It Dv CDECL_TYPE_FLOAT     Ta Fa float      No type specifier.
-.It Dv CDECL_TYPE_DOUBLE    Ta Fa double     No type specifier.
-.It Dv CDECL_TYPE_SIGNED    Ta Fa signed     No type specifier.
-.It Dv CDECL_TYPE_UNSIGNED  Ta Fa unsigned   No type specifier.
-.It Dv CDECL_TYPE_BOOL      Ta Fa _Bool      No type specifier.
-.It Dv CDECL_TYPE_COMPLEX   Ta Fa _Comples   No type specifier.
-.It Dv CDECL_TYPE_IMAGINARY Ta Fa _Imaginary No type specifier.
-.It Dv CDECL_TYPE_STRUCT    Ta Fa struct     No type specifier.  The
+.It Dv CDECL_TYPE_VOID      Ta Fa void       No type specifier .
+.It Dv CDECL_TYPE_CHAR      Ta Fa char       No type specifier .
+.It Dv CDECL_TYPE_SHORT     Ta Fa short      No type specifier .
+.It Dv CDECL_TYPE_INT       Ta Fa int        No type specifier .
+.It Dv CDECL_TYPE_LONG      Ta Fa long       No type specifier .
+.It Dv CDECL_TYPE_FLOAT     Ta Fa float      No type specifier .
+.It Dv CDECL_TYPE_DOUBLE    Ta Fa double     No type specifier .
+.It Dv CDECL_TYPE_SIGNED    Ta Fa signed     No type specifier .
+.It Dv CDECL_TYPE_UNSIGNED  Ta Fa unsigned   No type specifier .
+.It Dv CDECL_TYPE_BOOL      Ta Fa _Bool      No type specifier .
+.It Dv CDECL_TYPE_COMPLEX   Ta Fa _Comples   No type specifier .
+.It Dv CDECL_TYPE_IMAGINARY Ta Fa _Imaginary No type specifier .
+.It Dv CDECL_TYPE_STRUCT    Ta Fa struct     No type specifier .
+The
 .Va ident
 member points to a C string containing the struct tag.
-.It Dv CDECL_TYPE_UNION     Ta Fa union      No type specifier.  The
+.It Dv CDECL_TYPE_UNION     Ta Fa union      No type specifier .
+The
 .Va ident
 member points to a C string containing the union tag.
-.It Dv CDECL_TYPE_ENUM      Ta Fa enum       No type specifier.  The
+.It Dv CDECL_TYPE_ENUM      Ta Fa enum       No type specifier .
+The
 .Va ident
 member points to a C string containing the enum tag.
-.It Dv CDECL_TYPE_IDENT     Ta Typedef name type specifier.  The
+.It Dv CDECL_TYPE_IDENT     Ta Typedef name type specifier .
+The
 .Va ident
 member points to a C string containing the identifier.
-.It Dv CDECL_STOR_TYPEDEF   Ta Fa typedef    No storage-class specifier.
-.It Dv CDECL_STOR_EXTERN    Ta Fa extern     No storage-class specifier.
-.It Dv CDECL_STOR_STATIC    Ta Fa static     No storage-class specifier.
-.It Dv CDECL_STOR_AUTO      Ta Fa auto       No storage-class specifier.
-.It Dv CDECL_STOR_REGISTER  Ta Fa register   No storage-class specifier.
-.It Dv CDECL_QUAL_RESTRICT  Ta Fa restrict   No type qualifier.
-.It Dv CDECL_QUAL_VOLATILE  Ta Fa volatile   No type qualifier.
-.It Dv CDECL_QUAL_CONST     Ta Fa const      No type qualifier.
-.It Dv CDECL_FUNC_INLINE    Ta Fa inline     No function specifier.
+.It Dv CDECL_STOR_TYPEDEF   Ta Fa typedef    No storage-class specifier .
+.It Dv CDECL_STOR_EXTERN    Ta Fa extern     No storage-class specifier .
+.It Dv CDECL_STOR_STATIC    Ta Fa static     No storage-class specifier .
+.It Dv CDECL_STOR_AUTO      Ta Fa auto       No storage-class specifier .
+.It Dv CDECL_STOR_REGISTER  Ta Fa register   No storage-class specifier .
+.It Dv CDECL_QUAL_RESTRICT  Ta Fa restrict   No type qualifier .
+.It Dv CDECL_QUAL_VOLATILE  Ta Fa volatile   No type qualifier .
+.It Dv CDECL_QUAL_CONST     Ta Fa const      No type qualifier .
+.It Dv CDECL_FUNC_INLINE    Ta Fa inline     No function specifier .
 .El
 .Pp
 Declarators are represented by the structure:
@@ -170,13 +178,14 @@ struct cdecl_declarator {
 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
+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
+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
@@ -184,15 +193,14 @@ declarator's
 as the declaration's base type (found amongst the declaration specifiers, e.g.
 .Li int , const unsigned long ,
 etc.)
-
+.Pp
 The five types of declarators, described below, are distinguished by the
 .Va type
-struct member.  Each declarator (except null declarators) carries additional
-information specific to its type, which corresponds to the members of the union
+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 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
@@ -209,12 +217,13 @@ declarator has a NULL
 .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 is not strictly a C language construct, but is used by
+Null and identifier declarators have no children and are thus leaf nodes.
+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
+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
@@ -224,7 +233,8 @@ function
 .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.
+identifier.
+The result is true if and only if the declarator is abstract.
 .Ss Pointer Declarators
 .Bd -literal -offset indent
 struct cdecl_pointer {
@@ -265,28 +275,33 @@ struct cdecl_function {
 .Pp
 If
 .Va parameters
-is null, then this is a non-prototype function declarator.  Otherwise,
+is null, then this is a non-prototype function declarator.
+Otherwise,
 .Va parameters
 points to the first element of a singly-linked list of declarations
-representing the function parameters.  Note that, unlike toplevel declarations,
-each function parameter has exactly one full declarator (abstract or
-otherwise).   If
+representing the function parameters.
+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.
 .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
+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
+isn't a C compiler, there is no way for its 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,
+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
@@ -306,13 +321,16 @@ This error information can be retrieved by calling the function
 .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
+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
+shall all return the same value.
+The same applies to the
 .Va str
 pointer inside the error structure itself.
 .Pp
@@ -323,9 +341,11 @@ To parse a declaration, the function
 .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.
+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.
 .Pp
 Similarly, English declarations can be parsed by using the function
 .Pp
@@ -336,16 +356,16 @@ function
 .Pp
 .Fd void cdecl_free(struct cdecl *decl);
 .Sh RENDERING DECLARATIONS
-On the other hand, the abstract syntax tree can be rendered to a string for
-output.  One can use the function
+After parsing, the abstract syntax tree can be rendered to a string for output.
+Use the function
 .Pp
 .Fd size_t cdecl_explain(char *buf, size_t n, struct cdecl *decl);
 .Pp
 to format the AST pointed to by
 .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
+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
@@ -359,13 +379,14 @@ If
 .Fa n
 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
+to be a null pointer.
+Regardless, the function returns 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 long enough, not including the '\\0' terminator.
+Thus, the entire string was written if a value less than
 .Fa n
 is returned.
 .Pp
@@ -379,9 +400,11 @@ into C code.
 .Sh AUTHORS
 Nick Bowler <nbowler@draconx.ca>
 .Sh COPYRIGHT
-Copyright \(co 2011 Nick Bowler
+Copyright \(co 2011\(en2012, 2021 Nick Bowler
 .Pp
 Permission is granted to copy, distribute and/or modify this manual under the
-terms of the Do What The Fuck You Want To Public License, version 2.
+terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
 .Sh SEE ALSO
 .Xr cdecl99 1