chiark / gitweb /
Various, style: Generally prefer `: ' over ` : '.
[sod] / lib / keyword.h
CommitLineData
9e91c8e7
MW
1/* -*-c-*-
2 *
3 * Keyword argument handling
4 *
5 * (c) 2015 Straylight/Edgeware
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of the Sensible Object Design, an object system for C.
11 *
12 * SOD is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Library General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
16 *
17 * SOD is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with SOD; if not, write to the Free
24 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 * MA 02111-1307, USA.
26 */
27
28#ifndef KEYWORD_H
29#define KEYWORD_H
30
31#ifdef __cplusplus
32 extern "C" {
33#endif
34
35/*----- Header files ------------------------------------------------------*/
36
37#include <stdarg.h>
38#include <stddef.h>
39#include <string.h>
40
41/*----- Function annotations ----------------------------------------------*/
42
43/* Some macros are defined for annotating functions. They may improve
44 * compiler diagnostics when used properly. They should be included as part
45 * of the function's declaration specifiers.
46 *
47 * * @KWCALL@ marks a function as expecting keyword arguments. The
48 * compiler may check that there are an odd number of arguments, that the
49 * even-numbered (starting from zero) arguments have pointer-to-character
50 * type, and that the final argument is null.
51 *
52 * * @KW__NORETURN@ marks a function as never returning. Applied to
53 * @kw_unknown@ and its various friends. Users are not expected to use
54 * this.
55 */
56
57#if defined(__GNUC__)
58# define KW__GCC_VERSION_P(maj, min) \
59 (__GNUC__ > (maj) || (__GNUC__ == (maj) && __GNUC_MINOR__ >= (min)))
60# if KW__GCC_VERSION_P(2, 5)
61# define KW__NORETURN __attribute__((__noreturn__))
62# endif
63# if KW__GCC_VERSION_P(4, 0)
64# define KWCALL __attribute__((__sentinel__))
65# endif
66#endif
67
68/* --- Trivial definitions, if we don't have compiler support --- */
69
70#ifndef KW__NORETURN
71# define KW__NORETURN
72#endif
73
74#ifndef KWCALL
75# define KWCALL
76#endif
77
78/*----- Type definitions --------------------------------------------------*/
79
80/* A keyword/value pair. A vector of these can be passed as the value of the
81 * special keyword `kw.tab'. This is a rather cumbersome way of constructing
82 * lists of keyword arguments for a function in a programmatic way.
83 */
84struct kwval {
85 const char *kw; /* The keyword name, as a string */
86 const void *val; /* A pointer to the keyword value */
87};
88
89/* A table of keyword/value pairs. This is used as the value of a `kw.tab'
90 * argument which is itself in a @struct kwval@ table, since it's not
91 * possible to store both the vector and length directly.
92 */
93struct kwtab {
94 const struct kwval *v; /* The address of the vector */
95 size_t n; /* The number of keywords */
96};
97
98/* The type of unknown-keyword handler functions. */
99typedef void kw_unkhookfn(const char */*set*/, const char */*kw*/);
100
101/*----- Global variables --------------------------------------------------*/
102
103/* A global hook function for handling unknown-keyword errors. The default
104 * function prints a message to the standard error stream and aborts.
105 *
106 * The hook function must not return. It's not possible to recover from an
107 * unknown-keyword error while parsing a variable-length argument tail, since
108 * it's impossible to find out what type the corresponding argument value is.
109 *
110 * Having a single global hook isn't really very satisfactory, but a fully
111 * adequate solution gets complicated quickly. An external library will
112 * eventually be available to pick up the slack.
113 */
114extern kw_unkhookfn *kw_unkhook;
115
116/*----- Argument list macros ----------------------------------------------*/
117
a79bc435 118/* These macros are intended to be conveniences rather than a proper
9e91c8e7
MW
119 * abstraction. Functions with more complicated interfaces, and their
120 * callers, will have to make their own arrangements.
121 */
122
123/* --- @KWTAIL@ --- *
124 *
125 * Arguments: ---
126 *
127 * Use: Marker to be included in a function prototype (at the end of
128 * the argument list) to indicate that the function accepts
129 * keyword arguments. It is acceptable for the @KWTAIL@ marker
130 * to be only thing in the argument list.
131 */
132
133#define KWTAIL const char *kwfirst_, ...
134
135/* --- @KWARGS@ --- *
136 *
137 * Arguments: @body@ = a sequence of @K(kw, value)@ macro calls, without
138 * separators
139 *
140 * Use: A package of actual keyword arguments. In C89, the @body@
141 * must not be empty: to pass no keywords, use @NO_KWARGS@
142 * instead.
143 */
144
145#define KWARGS(body) body KW__END
146#define KW__END ((const char *)0)
147
a79bc435 148/* --- @NO_KWARGS@ --- *
9e91c8e7
MW
149 *
150 * Arguments: ---
151 *
152 * Use: Special marker to include in an actual argument list to
153 * indicate that no keyword arguments are to be passed. See
154 * @KWARGS@ above.
155 */
156
157#define NO_KWARGS KW__END, KW__END
158 /* Slight hack. The @KWCALL@ macro sets GCC and similar compilers up to
159 * check for a sentinal null pointer at the end of the variable-length
160 * argument tail. Alas, if there are no keywords at all, then the null
161 * terminator ends up in the @kwfirst_@ argument, and the tail is propetly
162 * empty, with the result that the compiler gives an annoying warning.
163 * Supplying an extra argument here is obviously harmless, and makes the
164 * otherwise useful warning go away in this case where it's not wanted.
165 */
166
a79bc435 167/* --- @K@ --- *
9e91c8e7
MW
168 *
169 * Arguments: @kw@ = keyword name, as an unquoted token list
170 * @val@ = keyword value, as an expression
171 *
172 * Use: Bundles a keyword @kw@ and value @val@ together.
173 */
174
175#define K(kw, val) #kw, (val),
176
177/* --- @KW_VALIST@ --- *
178 *
179 * Arguments: @va_list ap@ = argument-list extraction state
180 *
181 * Use: Passes a reified variable-length argument tail into a keyword
182 * function.
183 */
184
185#define K_VALIST(ap) "kw.valist", &(ap),
186
187/* --- @KW_TAB@ --- *
188 *
189 * Arguments: @const struct kwval *v@ = base address of argument vector
190 * @size_t n@ = length of argument vector
191 *
192 * Use: Passes an vector of keyword arguments into a keyword
193 * function.
194 */
195
196#define K_TAB(v, n) "kw.tab", (v), (size_t)(n),
197
198/*----- Keyword set definitions -------------------------------------------*
199 *
200 * A `keyword set' describes the collection of keyword arguments to be
201 * accepted by a function (or group of functions). Keyword sets have names,
202 * which are C identifiers. A keyword set must not be empty: use
203 * @kw_parseempty@ instead of this machinery when defining a function which
204 * may later accept keyword arguments but which currently doesn't define any.
205 *
206 * A keyword set definition is a macro of a single argument, conventionally
207 * named `@_@'. The macro for a keyword set called @foo@ is named
208 * @foo_KWSET@. It should consist of a triple @_(type, key, dflt)@ for each
209 * keyword argument, where @type@ is the C type of the argument, @key@ is the
210 * name of the argument (as a C identifier), and @dflt@ is an expression
211 * (valid to use in an aggregate initializer) to provide the default value
212 * for the argument. The @type@ must be such that @type *@ is the type of a
213 * pointer to object of @type@.
214 */
215
216/* --- @KWSET_STRUCT@ --- *
217 *
218 * Arguments: @set@ = the keyword set name
219 *
220 * Use: Defines the keyword set argument structure @struct
221 * set_kwargs@.
222 *
223 * The structure is used to communicate argument values between
224 * a function accepting keyword arguments and the argument
225 * parsing function constructed by @KWSET_PARSEFN@. It contains
226 * two members for each keyword argument: one with the name of
227 * the argument and the appropriate type to hold its value; the
228 * other is a one-bit-wide bitfield named with a `_suppliedp'
229 * suffix, and is set to indicate whether the caller provided a
230 * a value for the corresponding keyword argument.
231 */
232
233#define KWSET_STRUCT(set) \
234 struct set##_kwargs { \
235 set##_KWSET(KWSET__SUPPLIEDP) \
236 set##_KWSET(KWSET__STRUCTMEM) \
237 }
fd040f06 238#define KWSET__SUPPLIEDP(type, name, dflt) unsigned name##_suppliedp: 1;
9e91c8e7
MW
239#define KWSET__STRUCTMEM(type, name, dflt) type name;
240
241/* --- @KWSET_PARSEFN@ --- *
242 *
243 * Arguments: @set@ = the keyword set name
244 *
245 * Use: Defines the keyword argument parsing function @set_kwparse@.
246 * A call to this macro may be preceded by a storage-class
247 * specifier, e.g., @static@, to specify the linkage for the
248 * parsing function's name.
249 *
250 * This function takes five arguments:
251 *
252 * @struct set_kwargs *kw@ = pointer to keyword set argument
253 * structure to fill in
254 * @const char *kwfirst@ = first keyword argument name from the
255 * variable-length argument tail, or null if the
256 * argument tail is empty
257 * @va_list *ap@ = pointer to variable-length tail extraction
258 * state object
259 * @const struct kwval *v@ = base address of argument vector
260 * @size_t n@ = length of argument vector
261 *
262 * The `kwparse' function extracts keyword arguments from the
263 * argument tail (via @*ap@), and then the vector @v@; it
264 * updates the structure @*kw@ with their values, and sets the
265 * `_suppliedp' flags accordingly. It's unusual to call the
266 * `kwparse' function with both a nontrivial argument tail and
267 * vector, but the effect is nonetheless well-defined.
268 *
269 * The argument tail consists of alternating keyword argument
270 * names (as pointers to null-terminated strings) and values,
271 * terminated by a null pointer. The argument values are simply
272 * copied into the structure. Passing the @kwfirst@ argument
273 * separately allows functions to declare an explicit positional
274 * argument for the first keyword name, which is useful if the
275 * function has no other positional arguments.
276 *
277 * The argument vector consists of @struct kwval@ items, each of
278 * which contains a keyword name (as a pointer to a null-
279 * terminated string) and the address of its value. Argument
280 * values are again copied into the structure. Note that a
281 * vector doesn't store the arguments directly. This makes them
282 * rather cumbersome to set up, but the benefit is a simple and
283 * uniform approach for all keyword arguments.
284 *
285 * The main application for argument vectors is for `front-end'
286 * functions which want to pass on some subset of their keywords
287 * to another function. There isn't currently any macrology
288 * provided for achieving this, but it's not especially
289 * difficult.
290 *
291 * There are (currently) two special keyword arguments, whose
292 * names are not valid identifiers. Future additions will also
293 * have names beginning `kw.'.
294 *
295 * * `kw.valist' -- the corresponding argument has type
296 * @va_list *@, and represents an entire variable-length
297 * argument tail to process, including the first keyword
298 * name.
299 *
300 * * `kw.tab' -- the corresponding argument is a vector of
301 * @struct kwval@ items to process. In a variable-length
302 * argument tail, this is passed as two arguments: the base
303 * address of the vector, and the length (as a @size_t@).
304 * In an argument vector, this is passed instead as a value
305 * of type @struct kwtab@.
306 *
307 * If an unknown keyword is encountered while parsing, the
308 * function @kw_unknown@ is called.
309 *
310 * The keyword argument `kw.unknown' will never be defined.
311 */
312
313#define KWSET_PARSEFN(set) \
314 void set##_kwparse(struct set##_kwargs *kw, \
315 const char *kwfirst, va_list *ap, \
316 const struct kwval *v, size_t n) \
317 { \
318 const char *k, *kk; \
319 va_list *aap; \
320 const struct kwtab *t; \
321 const struct kwval *vv; \
322 size_t nn; \
323 \
324 for (k = kwfirst; k; k = va_arg(*ap, const char *)) { \
325 if (!strcmp(k, "kw.valist")) { \
326 aap = va_arg(*ap, va_list *); \
327 kk = va_arg(*aap, const char *); \
328 set##_kwparse(kw, kk, aap, 0, 0); \
329 } else if (!strcmp(k, "kw.tab")) { \
330 vv = va_arg(*ap, const struct kwval *); \
331 nn = va_arg(*ap, size_t); \
332 set##_kwparse(kw, 0, 0, vv, nn); \
333 } \
334 set##_KWSET(KWSET__ARGVA) \
335 else kw_unknown(#set, k); \
336 } \
337 \
338 while (n) { \
339 if (!strcmp(v->kw, "kw.valist")) { \
340 aap = *(va_list *const *)v->val; \
341 kk = va_arg(*aap, const char *); \
342 set##_kwparse(kw, kk, aap, 0, 0); \
343 } else if (!strcmp(v->kw, "kw.tab")) { \
344 t = (const struct kwtab *)v->val; \
345 set##_kwparse(kw, 0, 0, t->v, t->n); \
346 } \
347 set##_KWSET(KWSET__ARGTAB) \
348 else kw_unknown(#set, v->kw); \
349 v++; n--; \
350 } \
351 }
352#define KWSET__ARGVA(type, name, dflt) \
353 else if (!strcmp(k, #name)) { \
354 kw->name##_suppliedp = 1; \
355 kw->name = va_arg(*ap, type); \
356 }
357#define KWSET__ARGTAB(type, name, dflt) \
358 else if (!strcmp(v->kw, #name)) { \
359 kw->name##_suppliedp = 1; \
360 kw->name = *(type const *)v->val; \
361 }
362
363/*----- Defining keyword-accepting functions ------------------------------*/
364
365/* --- @KWDECL@ --- *
366 *
367 * Arguments: @set@ = the keyword set name
368 * @kw@ = the name for the keyword argument structure value
369 *
370 * Use: Declares and initializes a keyword argument structure object
371 * @kw@. The `_suppliedp' members are initially all zero; the
372 * argument value members are set to their default values as
373 * specified in the keyword set definition macro.
374 */
375
376#define KWDECL(set, kw) \
377 struct set##_kwargs kw = \
378 { set##_KWSET(KWSET__SPINIT) set##_KWSET(KWSET__DFLT) }
379#define KWSET__SPINIT(type, name, dflt) 0,
380#define KWSET__DFLT(type, name, dflt) dflt,
381
382/* --- @KW_PARSE@, @KW_PARSE_EMPTY@ --- *
383 *
384 * Arguments: @set@ = the keyword set name
385 * @kw@ = the name of the keyword argument structure
386 * @kwfirst@ = the first keyword argument name from the
387 * variable-length argument tail (and, therefore, the
388 * final positional argument)
389 *
390 * Use: Invokes the appropriate `kwparse' function to process the
391 * function's variable-length argument tail as keyword
392 * arguments.
393 *
394 * It is recommended that functions avoid allocating resources
395 * or making observable changes to program state until they have
396 * successfully parsed their keyword arguments.
397 *
398 * It is not possible to define an empty keyword argument set.
399 * If a function currently accepts no keyword argumets, but
400 * wants to reserve the ability to accept them later, then it
401 * should use @KW_PARSE_EMPTY@ (or, better, @KWPARSE_EMPTY@
402 * below). The keyword argument set name here is used only for
403 * diagnostic purposes, and need not (and probably should not)
404 * correspond to a keyword-set definition macro.
405 */
406
407#define KW_PARSE(set, kw, kwfirst) do { \
408 va_list ap_; \
409 va_start(ap_, kwfirst); \
410 set##_kwparse(&(kw), kwfirst, &ap_, 0, 0); \
411 va_end(ap_); \
412} while (0)
413
414#define KW_PARSE_EMPTY(set, kwfirst) do { \
415 va_list ap_; \
416 va_start(ap_, kwfirst); \
417 kw_parseempty(#set, kwfirst, &ap, 0, 0); \
418 va_end(ap_); \
419} while (0)
420
421/* --- @KWPARSE@, @KWPARSE_EMPTY@ --- *
422 *
423 * Arguments: @set@ = the keyword set name
424 *
425 * Use: All-in-one keyword parsing for simple cases.
426 *
427 * This declares a keyword argument structure literally named
428 * @kw@, and parses the function's variable-length argument tail
429 * on the assumption that the function's argument list prototype
430 * contains a @KWTAIL@ marker.
431 *
432 * It is recommended that functions avoid allocating resources
433 * or making observable changes to program state until they have
434 * successfully parsed their keyword arguments.
435 *
436 * In C89, this macro must be placed precisely between the
437 * declarations at the start of the function body, and the
438 * statements after them.
439 *
440 * It is not possible to define an empty keyword argument set.
441 * If a function currently accepts no keyword argumets, but
442 * wants to reserve the ability to accept them later, then it
443 * should use @KWPARSE_EMPTY@. The keyword argument set name
444 * here is used only for diagnostic purposes, and need not (and
445 * probably should not) correspond to a keyword-set definition
446 * macro.
447 */
448
449#define KWPARSE(set) KWDECL(set, kw); KW_PARSE(set, kw, kwfirst_)
450
451#define KWPARSE_EMPTY(set) KW_PARSE_EMPTY(set, kwfirst_)
452
453/* --- @KW_COUNT@ --- *
454 *
455 * Arguments: @set@ = the keyword set name
456 *
457 * Use: Expands to the number of keywords defined in the @set@.
458 */
459
460#define KW_COUNT(set) (0u set##_KWSET(KW__COUNT))
461#define KW__COUNT(type, name, dflt) + 1u
462
463/* --- @KW_COPY@ --- *
464 *
465 * Arguments: @fromset@ = the source keyword set name
466 * @toset@ = the destination keyword set name
467 * @kw@ = the source keyword argument structure
468 * @v@ = the destination vector
469 * @n@ = next free index in vector
470 *
471 * Use: Copies arguments from the source structure @kw@ into the
472 * vector @v@. The structure @kw@ must have type @struct
473 * fromset_kwargs *@. The argument @v@ must have type @struct
474 * kwval *@ (after array-to- pointer decay), and there must be a
475 * variable @v_n@ of sufficiently large integral type suitably
476 * initialized. Elements of the vector, starting with element
477 * @n@, will be filled in with those keyword arguments defined
478 * in @toset@ -- which must be a subset of @srcsrc@ from @kw@
479 * for which the `_suppliedp' flags are set. The @val@ members
480 * will point directly into the @kw@ structure. The @n@
481 * counter will be updated, and on completion will contain the
482 * index of the first unused entry in the vector.
483 */
484
485#define KW_COPY(fromset, toset, kw, v, n) do { \
486 const struct fromset##_kwargs *kw_ = &(kw); \
487 struct kwval *v_ = (v); \
488 size_t n_ = (n); \
489 toset##_KWSET(KW__COPY) \
490 (n) = n_; \
491} while (0)
492
493#define KW__COPY(type, name, dflt) \
494 if (kw_->name##_suppliedp) { \
495 v_[n_].kw = #name; \
496 v_[n_].val = &kw_->name; \
497 n_++; \
498 }
499
500/*----- Functions provided ------------------------------------------------*/
501
502/* --- @kw_unknown@ --- *
503 *
504 * Arguments: @const char *set@ = the keyword set name, as a string
505 * @const char *kw@ = the unknown keyword argument, as a string
506 *
507 * Returns: Doesn't.
508 *
509 * Use: Called when an unrecognized keyword argument is encountered
510 * during parsing. This calls the @kw_unkhook@ with the same
511 * arguments. Recovery via @longjmp@ or a similar machanism is
512 * acceptable.
513 */
514
515extern KW__NORETURN void kw_unknown(const char */*set*/, const char */*kw*/);
516
517/* --- @kw_defunknown@ --- *
518 *
519 * Arguments: @const char *set@ = keyword set name
520 * @const char *kw@ = the offending keyword name
521 *
522 * Returns: Doesn't.
523 *
524 * Use: This is the default @kw_unkhook@ hook function.
525 *
526 * In a hosted implementation, this function reports an internal
527 * error to stderr about the unknown keyword and calls @abort@.
528 * It is an implementation responsibility for freestanding
529 * implementations wanting to use this keyword argument
530 * mechanism.
531 */
532
533extern KW__NORETURN kw_unkhookfn kw_defunknown;
534
535/* --- @kw__hookfailed@ --- *
536 *
537 * Arguments: ---
538 *
539 * Returns: Doesn't.
540 *
541 * Use: Called by @kw_unknown@ if the @kw_unkhook@ hook function
542 * returns.
543 *
544 * User code is not expected to call this function. It exists
545 * as an implementation respensibility for freestanding
546 * implementations wanting to use this keyword argument
547 * mechanism.
548 */
549
550extern KW__NORETURN void kw__hookfailed(void);
551
552/* --- @kw_parseempty@ --- *
553 *
554 * Arguments: @const char *set@ = the keyword set name, as a string
555 * @const char *kwfirst@ = the first keyword argument name
556 * @va_list *ap@ = pointer to argument-tail extraction state
557 * @const struct kwval *v@ = base address of argument vector
558 * @size_t n@ = size of argument vector
559 *
560 * Returns: ---
561 *
562 * Use: Goes through the motions of parsing keyword arguments, but
563 * doesn't in fact handle any other than the standard ones
564 * described above (see @KWSET_PARSEFN@). This is useful when a
565 * function doesn't currently define any keyword arguments but
566 * wants to reserve the right to define some in the future.
567 * (The usual machinery can't be used in this case, since the
568 * argument structure would be empty. Besides, it would be
569 * pointless to include multiple copies of the same boilerplate
570 * code in a program.)
571 */
572
573extern void kw_parseempty(const char */*set*/,
574 const char */*kwfirst*/, va_list */*ap*/,
575 const struct kwval */*v*/, size_t /*n*/);
576
577/*----- That's all, folks -------------------------------------------------*/
578
579#ifdef __cplusplus
580 }
581#endif
582
583#endif