]> git.draconx.ca Git - cdecl99.git/blob - doc/man/libcdecl.3
00280f5aae44d23528f46a6943b990c7f2b32f33
[cdecl99.git] / doc / man / libcdecl.3
1 .Dd July 18, 2011
2 .Os cdecl99
3 .Dt LIBCDECL \&3 "Cdecl99 Developer's Manual"
4 .Sh NAME
5 .Nm libcdecl
6 .Nd C library for making sense of C declarations
7 .Sh SYNOPSIS
8 .Fd #include <cdecl.h>
9 .Pp
10 .Fd struct cdecl *cdecl_parse_decl(const char *declstr);
11 .Fd struct cdecl *cdecl_parse_english(const char *english);
12 .Fd void cdecl_free(struct cdecl *decl);
13 .Pp
14 .Fd size_t cdecl_explain(char *buf, size_t n, struct cdecl *decl);
15 .Fd size_t cdecl_declare(char *buf, size_t n, struct cdecl *decl);
16 .Pp
17 .Fd const struct cdecl_error *cdecl_get_error(void);
18 .Pp
19 .Fd int cdecl_spec_kind(struct cdecl_declspec *spec);
20 .Fd bool cdecl_is_abstract(struct cdecl_declarator *declarator);
21 .Sh DESCRIPTION
22 .Nm
23 provides support for parsing C declarations and translating them to something
24 resembling English and vice-versa.  This manual describes the programmers'
25 interface only; for details such as what C language features are supported or
26 the syntax of English declarations, please see the
27 .Xr cdecl99 1
28 manual page.
29 .Pp
30 .Nm
31 is intended to be portable to any system with a working C implementation that
32 at least makes an effort to support C99.  The library is thread-safe when
33 appropriate facilities exist and are enabled at build time.
34 .Sh NAMESPACE
35 .Nm
36 reserves all identifiers beginning with either
37 .Li cdecl_
38 or
39 .Li CDECL_
40 in both the tag and ordinary identifier namespaces.  All external names
41 beginning with
42 .Li cdecl_
43 are reserved, and the library headers may define object-like macros beginning
44 with
45 .Li CDECL_ .
46 The
47 .Nm
48 library headers may use other identifiers where they do not pollute the global
49 namespaces, such as struct members or function parameter names.  Such internal
50 identifiers shall not contain any upper-case letters.  As these internal
51 identifiers can only conflict with object-like macros, this practice is safe as
52 long as the convention of defining object-like macros using upper-case letters
53 is adhered to.
54 .Pp
55 External names beginning with
56 .Li cdecl
57 followed by two consecutive underscores are not considered part of the ABI and
58 are thus subject to change at any time.
59 .Sh ABSTRACT SYNTAX TREE
60 The functions in
61 .Nm
62 generally operate on an abstract syntax tree representing a C declaration.
63 A string is parsed into an AST which can be subsequently rendered into another
64 format.  Since some information about the original string is discarded when
65 generating the AST, parsing a declaration and then rendering to the same format
66 is not the identity function.  The AST is represented by the following
67 structure:
68 .Bd -literal -offset indent
69 struct cdecl {
70         struct cdecl *next;
71         struct cdecl_declspec   *specifiers;
72         struct cdecl_declarator *declarators;
73 };
74 .Ed
75 .Pp
76 At the top level, every declaration consists of one or more declaration
77 specifiers followed by one or more full declarators; hence, the
78 .Va specifiers
79 and
80 .Va declarators
81 members are always non-null.  A declaration with more than one declarator is
82 represented by using the
83 .Va next
84 member to form a singly-linked list of ASTs, one element for each declarator.
85 In the case of the toplevel declaration, the declaration specifiers will be
86 identical for all elements of the list.  But when the same kind of list is used
87 to represent function parameters, the specifiers may be different for each
88 element.
89 .Pp
90 There are four kinds of declaration specifiers: storage-class, function and
91 type specifiers, as well as type qualifiers.  All are represented by the
92 structure:
93 .Bd -literal -offset indent
94 struct cdecl_declspec {
95         struct cdecl_declspec *next;
96         unsigned type;
97         char *ident;
98 };
99 .Ed
100 .Pp
101 When multiple declaration specifiers are present, they are represented as
102 a singly-linked list, one element for each specifier.  Specifiers can appear
103 in any order.  The function
104 .Pp
105 .Fd int cdecl_spec_kind(struct cdecl_declspec *spec);
106 .Pp
107 can be used to determine what kind of specifier
108 .Fa spec
109 is.  The result is one of the following values:
110 .Bl -column ".Dv CDECL_SPEC_TYPE"
111 .It Em Kind            Ta Em Description
112 .It Dv CDECL_SPEC_TYPE Ta Type specifier.
113 .It Dv CDECL_SPEC_STOR Ta Storage-class specifier.
114 .It Dv CDECL_SPEC_QUAL Ta Type qualifier.
115 .It Dv CDECL_SPEC_FUNC Ta Function specifier.
116 .El
117 .Pp
118 The following table describes all the possible types of declaration specifiers.
119 .Bl -column ".Dv CDECL_TYPE_IMAGINARY"
120 .It Em Em Type              Ta Em Description
121 .It Dv CDECL_TYPE_VOID      Ta Fa void       No type specifier.
122 .It Dv CDECL_TYPE_CHAR      Ta Fa char       No type specifier.
123 .It Dv CDECL_TYPE_SHORT     Ta Fa short      No type specifier.
124 .It Dv CDECL_TYPE_INT       Ta Fa int        No type specifier.
125 .It Dv CDECL_TYPE_LONG      Ta Fa long       No type specifier.
126 .It Dv CDECL_TYPE_FLOAT     Ta Fa float      No type specifier.
127 .It Dv CDECL_TYPE_DOUBLE    Ta Fa double     No type specifier.
128 .It Dv CDECL_TYPE_SIGNED    Ta Fa signed     No type specifier.
129 .It Dv CDECL_TYPE_UNSIGNED  Ta Fa unsigned   No type specifier.
130 .It Dv CDECL_TYPE_BOOL      Ta Fa _Bool      No type specifier.
131 .It Dv CDECL_TYPE_COMPLEX   Ta Fa _Comples   No type specifier.
132 .It Dv CDECL_TYPE_IMAGINARY Ta Fa _Imaginary No type specifier.
133 .It Dv CDECL_TYPE_STRUCT    Ta Fa struct     No type specifier.  The
134 .Va ident
135 member points to a C string containing the struct tag.
136 .It Dv CDECL_TYPE_UNION     Ta Fa union      No type specifier.  The
137 .Va ident
138 member points to a C string containing the union tag.
139 .It Dv CDECL_TYPE_ENUM      Ta Fa enum       No type specifier.  The
140 .Va ident
141 member points to a C string containing the enum tag.
142 .It Dv CDECL_TYPE_IDENT     Ta Typedef name type specifier.  The
143 .Va ident
144 member points to a C string containing the identifier.
145 .It Dv CDECL_STOR_TYPEDEF   Ta Fa typedef    No storage-class specifier.
146 .It Dv CDECL_STOR_EXTERN    Ta Fa extern     No storage-class specifier.
147 .It Dv CDECL_STOR_STATIC    Ta Fa static     No storage-class specifier.
148 .It Dv CDECL_STOR_AUTO      Ta Fa auto       No storage-class specifier.
149 .It Dv CDECL_STOR_REGISTER  Ta Fa register   No storage-class specifier.
150 .It Dv CDECL_QUAL_RESTRICT  Ta Fa restrict   No type qualifier.
151 .It Dv CDECL_QUAL_VOLATILE  Ta Fa volatile   No type qualifier.
152 .It Dv CDECL_QUAL_CONST     Ta Fa const      No type qualifier.
153 .It Dv CDECL_FUNC_INLINE    Ta Fa inline     No function specifier.
154 .El
155 .Pp
156 Declarators are represented by the structure:
157 .Bd -literal -offset indent
158 struct cdecl_declarator {
159         struct cdecl_declarator *child;
160         unsigned type;
161         union {
162                 char *ident;
163                 struct cdecl_pointer  pointer;
164                 struct cdecl_array    array;
165                 struct cdecl_function function;
166         } u;
167 };
168 .Ed
169 .Pp
170 With the exception of function parameters (which are handled separately),
171 declarators form a chain from
172 .Do outermost Dc to Do innermost Dc
173 declarator.  This relationship is expressed by the
174 .Va child
175 struct member, which points to the next innermost declarator in the chain.
176 Unfortunately, C's declaration syntax is, in a sense, inside-out.  Thus, one
177 needs to follow the chain backwards (from innermost to outermost) to understand
178 the semantic relationship between declarators in the chain.  In the next
179 section, we will use the word
180 .Va parent
181 to describe this inverted child relationship: we consider the outermost
182 declarator's
183 .Va parent
184 as the declaration's base type (found amongst the declaration specifiers, e.g.
185 .Li int , const unsigned long ,
186 etc.)
187
188 The five types of declarators, described below, are distinguished by the
189 .Va type
190 struct member.  Each declarator (except null declarators) carries additional
191 information specific to its type, which corresponds to the members of the union
192 .Va u .
193
194 contains a member for each declarator type (except null) containing additional
195 information.  The possible values are described by the following table.
196 .Bl -column ".Dv CDECL_DECL_FUNCTION" ".Em Union Member"
197 .It Em Declarator Type     Ta Em Union Member Ta Em Description
198 .It Dv CDECL_DECL_NULL     Ta (none)          Ta Declares nothing.  This
199 declarator terminates the declarator chain, and has a NULL
200 .Va child .
201 .It Dv CDECL_DECL_IDENT    Ta Va ident        Ta Declares an identifier.  This
202 declarator has a NULL
203 .Va child .
204 .It Dv CDECL_DECL_POINTER  Ta Va pointer      Ta Declares a pointer, as in
205 .Do pointer to Va parent Dc
206 .It Dv CDECL_DECL_ARRAY    Ta Va array        Ta Declares an array, as in
207 .Do array of Va parent Dc
208 .It Dv CDECL_DECL_FUNCTION Ta Va function     Ta Declares a function, as in
209 .Do function returning Va parent Dc
210 .El
211 .Ss Terminal Declarators
212 Null and identifier declarators have no children and are thus leaf nodes.  A
213 null declarator is not strictly a C language construct, but is used by
214 .Nm
215 to indicate an abstract declarator; that is, one which does not declare any
216 identifier.  Such declarators appear in type names and possibly function
217 parameters.  An identifier declarator has the obvious meaning; the
218 .Va ident
219 union member points to the C string containing the identifier.
220 .Pp
221 Since a null declarator may be deeply nested in the declarator chain, the
222 function
223 .Pp
224 .Fd bool cdecl_is_abstract(struct cdecl_declarator *declarator);
225 .Pp
226 can be used to determine whether or not a given declarator declares an
227 identifier.  The result is true if and only if the declarator is abstract.
228 .Ss Pointer Declarators
229 .Bd -literal -offset indent
230 struct cdecl_pointer {
231         struct cdecl_declspec *qualifiers;
232 };
233 .Ed
234 .Pp
235 If the
236 .Va qualifiers
237 member is non-null, then it points to the first element of a singly-linked list
238 of type qualifiers.
239 .Ss Array Declarators
240 .Bd -literal -offset indent
241 struct cdecl_array {
242         char *vla;
243         uintmax_t length;
244 };
245 .Ed
246 .Pp
247 If the
248 .Va vla
249 member is non-null, then this declarator is a variable-length array declarator.
250 The
251 .Va vla
252 member points to an identifier if it is known, else it points to the empty
253 string.
254 Otherwise, if
255 .Va length
256 is positive, then this is an array declarator with the specified length.
257 Otherwise, this is an incomplete array declarator.
258 .Ss Function Declarators
259 .Bd -literal -offset indent
260 struct cdecl_function {
261         struct cdecl *parameters;
262         _Bool variadic;
263 };
264 .Ed
265 .Pp
266 If
267 .Va parameters
268 is null, then this is a non-prototype function declarator.  Otherwise,
269 .Va parameters
270 points to the first element of a singly-linked list of declarations
271 representing the function parameters.  Note that, unlike toplevel declarations,
272 each function parameter has exactly one full declarator (abstract or
273 otherwise).   If
274 .Va variadic
275 is true, then the function is variadic.
276 .Pp
277 Note that old-style function declarations with non-empty identifier lists are
278 not directly represented here: this is because they are syntactically identical
279 to a prototype where every parameter is a typedef name.  Since
280 .Nm
281 isn't a C compiler, there is no way for the parser to tell these two kinds of
282 declarations apart.
283 .Sh ERROR HANDLING
284 Some functions in
285 .Nm
286 can fail.  Such functions will be documented as indicating an error condition
287 in a particular way.  It is sometimes necessary to know more about a particular
288 error in order to print an informative error message or perform some other
289 action.  To facilitate this,
290 .Nm
291 provides a structure which describes a particular error.
292 .Bd -literal -offset indent
293 struct cdecl_error {
294         unsigned code;
295         const char *str;
296 };
297 .Ed
298 .Pp
299 The
300 .Va code
301 member identifies the sort of error which has occurred, while the
302 .Va str
303 member points to a string containing a human-readable description of the error.
304 This error information can be retrieved by calling the function
305 .Pp
306 .Fd const struct cdecl_error *cdecl_get_error(void);
307 .Pp
308 which returns a pointer to the error structure most recently generated in the
309 current thread.  It is therefore thread-safe in that errors occurring in
310 another thread will not interfere with the current one.  The returned pointer
311 shall remain valid until the next call to any function from
312 .Nm
313 by the same thread, except that multiple consecutive calls to
314 .Va cdecl_get_error
315 shall all return the same value.  The same applies to the
316 .Va str
317 pointer inside the error structure itself.
318 .Pp
319 If this function is called before an error has been indicated by an earlier
320 call in the same thread, the behaviour is undefined.
321 .Sh PARSING DECLARATIONS
322 To parse a declaration, the function
323 .Pp
324 .Fd struct cdecl *cdecl_parse_decl(const char *declstr);
325 .Pp
326 can be used.  The provided string is parsed as a C declaration.  If successful,
327 this function returns a pointer to an abstract syntax tree representing the
328 declaration.  If the parse fails for any reason, the function returns NULL.
329 .Pp
330 Similarly, English declarations can be parsed by using the function
331 .Pp
332 .Fd struct cdecl *cdecl_parse_english(const char *english);
333 .Pp
334 When the AST is no longer needed, it must be freed by passing it to the
335 function
336 .Pp
337 .Fd void cdecl_free(struct cdecl *decl);
338 .Sh RENDERING DECLARATIONS
339 On the other hand, the abstract syntax tree can be rendered to a string for
340 output.  One can use the function
341 .Pp
342 .Fd size_t cdecl_explain(char *buf, size_t n, struct cdecl *decl);
343 .Pp
344 to format the AST pointed to by
345 .Fa decl
346 into something resembling English.  At most one full declarator is rendered
347 in this way; for declarations with more than one full declarator, this function
348 should be called on each
349 .Dv struct cdecl
350 in the singly-linked list.
351 .Pp
352 In a manner similar to that of
353 .Xr snprintf 3 ,
354 at most
355 .Fa n
356 bytes, including the '\\0' terminator, are written to
357 .Fa buf .
358 If
359 .Fa n
360 is zero, it is acceptable for
361 .Fa buf
362 to be a null pointer.  Regardless, the function returns the number of
363 characters that would be written to
364 .Fa buf
365 if
366 .Fa n
367 were long enough, not including the '\\0' terminator.  Thus, the entire string
368 was written if a value less than
369 .Fa n
370 is returned.
371 .Pp
372 Similarly, the function
373 .Pp
374 .Fd size_t cdecl_declare(char *buf, size_t n, struct cdecl *decl);
375 .Pp
376 will render the AST pointed to by
377 .Fa decl
378 into C code.
379 .Sh AUTHORS
380 Nick Bowler <nbowler@draconx.ca>
381 .Sh COPYRIGHT
382 Copyright \(co 2011 Nick Bowler
383 .Pp
384 Permission is granted to copy, distribute and/or modify this manual under the
385 terms of the Do What The Fuck You Want To Public License, version 2.
386 .Sh SEE ALSO
387 .Xr cdecl99 1