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