From 519f8a57b1353d595b3e6e9aa0ff50eaffb164ca Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Sat, 6 Mar 2021 23:14:37 -0500 Subject: [PATCH] Minor manual updates. Fix some typographic errors and minor wording problems in the manuals. Additionally, flatten the directory hierarchy so the manuals are just under "doc". --- Makefile.am | 2 +- doc/{man => }/cdecl99.1 | 61 ++++++----- doc/{man => }/libcdecl.3 | 223 +++++++++++++++++++++------------------ 3 files changed, 159 insertions(+), 127 deletions(-) rename doc/{man => }/cdecl99.1 (78%) rename doc/{man => }/libcdecl.3 (60%) diff --git a/Makefile.am b/Makefile.am index 1d40ab3..44b4601 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,7 +31,7 @@ EXTRA_DIST = bootstrap $(DX_BASEDIR)/scripts/fix-gnulib.pl m4/gnulib-cache.m4 \ src/ordspecs.sed test/typegen.sh src/parse.y src/parse.stamp \ src/scan.l src/scan.stamp COPYING.WTFPL2 README.md INSTALL -dist_man_MANS = doc/man/cdecl99.1 doc/man/libcdecl.3 +dist_man_MANS = doc/cdecl99.1 doc/libcdecl.3 include_HEADERS = src/cdecl.h noinst_HEADERS = conf_pre.h conf_post.h src/scan.h src/parse.h \ diff --git a/doc/man/cdecl99.1 b/doc/cdecl99.1 similarity index 78% rename from doc/man/cdecl99.1 rename to doc/cdecl99.1 index eca715f..d458380 100644 --- a/doc/man/cdecl99.1 +++ b/doc/cdecl99.1 @@ -1,4 +1,4 @@ -.Dd July 18, 2011 +.Dd March 6, 2021 .Os cdecl99 .Dt CDECL99 \&1 "Cdecl99 User's Manual" .Sh NAME @@ -8,19 +8,21 @@ .Nm .Op Fl q .Op Fl b Ns | Ns Fl i -.Op Fl f file Ns | Ns Fl e Ar command Op Fl e Ar command ... +.Op Fl f Ar file Ns | Ns Fl e Ar command Op Fl e Ar command ... .Sh DESCRIPTION .Nm is the command-line interface to libcdecl, enabling you to make heads and tails -of complicated C declarations. It supports parsing almost any syntactically -valid C99 declaration, producing output similar to that of +of complicated C declarations. +It supports parsing almost any syntactically valid C99 declaration, producing +output similar to that of .Xr cdecl 1 . Unlike .Xr cdecl 1 , .Nm fully supports all relevant C99 keywords, has no undue restrictions on -identifiers, groks features such as complex types, variadic functions and named -parameters, and can also understand plain type names. On the other hand, +identifiers, groks features such as complex types, variadic functions and +named parameters, and can also understand plain type names. +On the other hand, .Nm does not support any older versions of C, nor does it support C++ other than the common subset of those other languages and C99. @@ -36,9 +38,10 @@ would accept. Suppress the welcome message when starting .Nm . .It Fl b , -batch -Run in batch (non-interactive) mode. Execute the commands provided on standard -input as usual, but do not print any prompts. Exit with status 0 if and only -if all commands complete successfully. +Run in batch (non-interactive) mode. +Execute the commands provided on standard input as usual, but do not print any +prompts. +Exit with status 0 if and only if all commands complete successfully. .Pp This option implies .Fl -quiet . @@ -47,9 +50,9 @@ Run in interactive mode. This is the default. .It Fl e , -execute Ar command Execute .Ar command -as if it were entered at the prompt, then exit. This option can be specified -multiple times; all commands are run in the same order as specified on the -command line. +as if it were entered at the prompt, then exit. +This option can be specified multiple times; all commands are run in the same +order as specified on the command line. .Pp This option implies .Fl -batch . @@ -75,7 +78,8 @@ Print a help message and exit. All interactive .Nm commands consist of a single word followed by one or more spaces, followed by -the argument. Whitespace preceding the command name is ignored. +the argument. +Whitespace preceding the command name is ignored. .Bl -tag -width indent .It explain Ar declaration Translates a given C declaration or type name into something resembling @@ -94,12 +98,13 @@ Exits the program. .El .Sh ENGLISH DECLARATIONS .Nm -uses a language similar to English to explain or construct C declarations. The -format is based on the one used in +uses a language similar to English to explain or construct C declarations. +The format is based on the one used in .Xr cdecl 1 , -and is described by the following context-free grammar. This grammar is for -illustrative purposes only: it is ambiguous and doesn't capture all the nuances -of the C language. In this grammar, nonterminals are represented +and is described by the following context-free grammar. +This grammar is for illustrative purposes only: it is ambiguous and doesn't +capture all the nuances of the C language. +In this grammar, nonterminals are represented .Va [ thusly ] , \[*e] represents the empty string, and both .Li | @@ -142,23 +147,25 @@ For example, the meaning of the declaration .Ic int f(int (foo)) depends on whether or not a typedef named .Va foo -is in scope. If such a typedef is in scope, this declares +is in scope. +If such a typedef is in scope, this declares .Va f as a function that takes (after adjustment) a pointer to a function that takes a .Va foo -and returns an int, returning an int. If there is no such typedef, then this -declares +and returns an int, returning an int. +If there is no such typedef, then this declares .Va f as a function that takes an int and returns an int. .Pp Since .Nm isn't a C compiler, on several occasions it has to arbitrarily pick one of two -possibilities. The rule that is generally applied is that +possibilities. +The rule that is generally applied is that .Nm -will choose the alternative with the simplest explanation. Thus, f is -interpreted as a function which takes an int and returns an int. +will choose the alternative with the simplest explanation. +Thus, f is interpreted as a function which takes an int and returns an int. .Sh EXAMPLES .Bl -tag -width Output: .It Input: @@ -199,10 +206,12 @@ interpreted as a function which takes an int and returns an int. .Sh AUTHORS Nick Bowler .Sh COPYRIGHT -Copyright \(co 2011 Nick Bowler +Copyright \(co 2011, 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 libcdecl 3 , .Xr cdecl 1 , diff --git a/doc/man/libcdecl.3 b/doc/libcdecl.3 similarity index 60% rename from doc/man/libcdecl.3 rename to doc/libcdecl.3 index 00280f5..495a353 100644 --- a/doc/man/libcdecl.3 +++ b/doc/libcdecl.3 @@ -1,4 +1,4 @@ -.Dd July 18, 2011 +.Dd March 6, 2021 .Os cdecl99 .Dt LIBCDECL \&3 "Cdecl99 Developer's Manual" .Sh NAME @@ -21,24 +21,26 @@ .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. +A 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 .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 -- 2.43.0