]> git.draconx.ca Git - cdecl99.git/blobdiff - doc/man/libcdecl.3
Add note about old-style function declarations to the manual.
[cdecl99.git] / doc / man / libcdecl.3
index 0bb7f9335a3188e5f735793b854d1b9abaa79161..a4dc5f45581fe9b85b7226411c5e9240dfd0f1a4 100644 (file)
@@ -6,15 +6,18 @@
 .Nd C library for making sense of C declarations
 .Sh SYNOPSIS
 .Fd #include <cdecl.h>
-
+.Pp
 .Fd struct cdecl *cdecl_parse_decl(const char *declstr);
 .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);
-
+.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
@@ -23,11 +26,36 @@ 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 maintains no global state
-and thus all functions should be safe for use in a multi-threaded environment.
+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
+.Li cdecl_
+are reserved, and the library headers may define object-like macros beginning
+with
+.Li CDECL_ .
+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.
+.Pp
+External names beginning with
+.Li cdecl
+followed by two consecutive underscores are not considered part of the ABI and
+are thus subject to change at any time.
 .Sh ABSTRACT SYNTAX TREE
 The functions in
 .Nm
@@ -44,7 +72,7 @@ struct cdecl {
        struct cdecl_declarator *declarators;
 };
 .Ed
-
+.Pp
 At the top level, every declaration consists of one or more declaration
 specifiers followed by one or more full declarators; hence, the
 .Va specifiers
@@ -58,7 +86,7 @@ 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.
-
+.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:
@@ -69,13 +97,13 @@ struct cdecl_declspec {
        char *ident;
 };
 .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
-
+.Pp
 .Fd int cdecl_spec_kind(struct cdecl_declspec *spec);
-
+.Pp
 can be used to determine what kind of specifier
 .Fa spec
 is.  The result is one of the following values:
@@ -86,7 +114,7 @@ is.  The result is one of the following values:
 .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.
 .Bl -column ".Dv CDECL_TYPE_IMAGINARY"
 .It Em Em Type              Ta Em Description
@@ -124,7 +152,7 @@ member points to a C string containing the identifier.
 .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:
 .Bd -literal -offset indent
 struct cdecl_declarator {
@@ -138,7 +166,7 @@ struct cdecl_declarator {
        } u;
 };
 .Ed
-
+.Pp
 There are five types of declarators, distinguished by the
 .Va type
 struct member.  The union
@@ -166,18 +194,28 @@ member is interpreted as "function returning child".
 .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 {
        struct cdecl_declspec *qualifiers;
 };
 .Ed
-
+.Pp
 If the
 .Va qualifiers
 member is non-null, then it points to the first element of a singly-linked list
@@ -189,7 +227,7 @@ struct cdecl_array {
        uintmax_t length;
 };
 .Ed
-
+.Pp
 If the
 .Va vla
 member is non-null, then this declarator is a variable-length array declarator.
@@ -208,7 +246,7 @@ struct cdecl_function {
        _Bool variadic;
 };
 .Ed
-
+.Pp
 If
 .Va parameters
 is null, then this is a non-prototype function declarator.  Otherwise,
@@ -219,29 +257,74 @@ 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
 .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.
-
+.Pp
 Similarly, English declarations can be parsed by using the function
-
+.Pp
 .Fd struct cdecl *cdecl_parse_english(const char *english);
-
+.Pp
 When the AST is no longer needed, it must be freed by passing it to the
 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
-
+.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
@@ -249,7 +332,7 @@ 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
@@ -269,11 +352,11 @@ were long enough, not including the '\\0' terminator.  Thus, the entire string
 was written if a value less than
 .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.
@@ -281,7 +364,7 @@ into C code.
 Nick Bowler <nbowler@draconx.ca>
 .Sh COPYRIGHT
 Copyright \(co 2011 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.
 .Sh SEE ALSO