lib/sod-hosted.c (sod_makev): Use two statements rather than tricky expression.
[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
c5161e0a 161 * terminator ends up in the @kwfirst_@ argument, and the tail is properly
9e91c8e7
MW
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
dcb086e9 177/* --- @K_VALIST@ --- *
9e91c8e7
MW
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
dcb086e9 187/* --- @K_TAB@ --- *
9e91c8e7
MW
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 *)) { \
0f3e4dbf
MW
325 set##_KWSET(KWSET__ARGVA) \
326 /*else*/ if (!strcmp(k, "kw.valist")) { \
9e91c8e7
MW
327 aap = va_arg(*ap, va_list *); \
328 kk = va_arg(*aap, const char *); \
329 set##_kwparse(kw, kk, aap, 0, 0); \
330 } else if (!strcmp(k, "kw.tab")) { \
331 vv = va_arg(*ap, const struct kwval *); \
332 nn = va_arg(*ap, size_t); \
333 set##_kwparse(kw, 0, 0, vv, nn); \
0f3e4dbf 334 } else kw_unknown(#set, k); \
9e91c8e7
MW
335 } \
336 \
337 while (n) { \
0f3e4dbf
MW
338 set##_KWSET(KWSET__ARGTAB) \
339 /*else*/ if (!strcmp(v->kw, "kw.valist")) { \
9e91c8e7
MW
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); \
0f3e4dbf 346 } else kw_unknown(#set, v->kw); \
9e91c8e7
MW
347 v++; n--; \
348 } \
349 }
0f3e4dbf 350
9e91c8e7 351#define KWSET__ARGVA(type, name, dflt) \
0f3e4dbf 352 if (!strcmp(k, #name)) { \
9e91c8e7
MW
353 kw->name##_suppliedp = 1; \
354 kw->name = va_arg(*ap, type); \
0f3e4dbf 355 } else
9e91c8e7 356#define KWSET__ARGTAB(type, name, dflt) \
0f3e4dbf 357 if (!strcmp(v->kw, #name)) { \
9e91c8e7
MW
358 kw->name##_suppliedp = 1; \
359 kw->name = *(type const *)v->val; \
0f3e4dbf 360 } else
9e91c8e7
MW
361
362/*----- Defining keyword-accepting functions ------------------------------*/
363
364/* --- @KWDECL@ --- *
365 *
366 * Arguments: @set@ = the keyword set name
367 * @kw@ = the name for the keyword argument structure value
368 *
369 * Use: Declares and initializes a keyword argument structure object
370 * @kw@. The `_suppliedp' members are initially all zero; the
371 * argument value members are set to their default values as
372 * specified in the keyword set definition macro.
373 */
374
375#define KWDECL(set, kw) \
376 struct set##_kwargs kw = \
377 { set##_KWSET(KWSET__SPINIT) set##_KWSET(KWSET__DFLT) }
378#define KWSET__SPINIT(type, name, dflt) 0,
379#define KWSET__DFLT(type, name, dflt) dflt,
380
381/* --- @KW_PARSE@, @KW_PARSE_EMPTY@ --- *
382 *
383 * Arguments: @set@ = the keyword set name
384 * @kw@ = the name of the keyword argument structure
385 * @kwfirst@ = the first keyword argument name from the
386 * variable-length argument tail (and, therefore, the
387 * final positional argument)
388 *
389 * Use: Invokes the appropriate `kwparse' function to process the
390 * function's variable-length argument tail as keyword
391 * arguments.
392 *
393 * It is recommended that functions avoid allocating resources
394 * or making observable changes to program state until they have
395 * successfully parsed their keyword arguments.
396 *
397 * It is not possible to define an empty keyword argument set.
398 * If a function currently accepts no keyword argumets, but
399 * wants to reserve the ability to accept them later, then it
400 * should use @KW_PARSE_EMPTY@ (or, better, @KWPARSE_EMPTY@
401 * below). The keyword argument set name here is used only for
402 * diagnostic purposes, and need not (and probably should not)
403 * correspond to a keyword-set definition macro.
404 */
405
406#define KW_PARSE(set, kw, kwfirst) do { \
407 va_list ap_; \
408 va_start(ap_, kwfirst); \
409 set##_kwparse(&(kw), kwfirst, &ap_, 0, 0); \
410 va_end(ap_); \
411} while (0)
412
413#define KW_PARSE_EMPTY(set, kwfirst) do { \
414 va_list ap_; \
415 va_start(ap_, kwfirst); \
416 kw_parseempty(#set, kwfirst, &ap, 0, 0); \
417 va_end(ap_); \
418} while (0)
419
420/* --- @KWPARSE@, @KWPARSE_EMPTY@ --- *
421 *
422 * Arguments: @set@ = the keyword set name
423 *
424 * Use: All-in-one keyword parsing for simple cases.
425 *
426 * This declares a keyword argument structure literally named
427 * @kw@, and parses the function's variable-length argument tail
428 * on the assumption that the function's argument list prototype
429 * contains a @KWTAIL@ marker.
430 *
431 * It is recommended that functions avoid allocating resources
432 * or making observable changes to program state until they have
433 * successfully parsed their keyword arguments.
434 *
435 * In C89, this macro must be placed precisely between the
436 * declarations at the start of the function body, and the
437 * statements after them.
438 *
439 * It is not possible to define an empty keyword argument set.
440 * If a function currently accepts no keyword argumets, but
441 * wants to reserve the ability to accept them later, then it
442 * should use @KWPARSE_EMPTY@. The keyword argument set name
443 * here is used only for diagnostic purposes, and need not (and
444 * probably should not) correspond to a keyword-set definition
445 * macro.
446 */
447
448#define KWPARSE(set) KWDECL(set, kw); KW_PARSE(set, kw, kwfirst_)
449
450#define KWPARSE_EMPTY(set) KW_PARSE_EMPTY(set, kwfirst_)
451
452/* --- @KW_COUNT@ --- *
453 *
454 * Arguments: @set@ = the keyword set name
455 *
456 * Use: Expands to the number of keywords defined in the @set@.
457 */
458
459#define KW_COUNT(set) (0u set##_KWSET(KW__COUNT))
460#define KW__COUNT(type, name, dflt) + 1u
461
462/* --- @KW_COPY@ --- *
463 *
464 * Arguments: @fromset@ = the source keyword set name
465 * @toset@ = the destination keyword set name
466 * @kw@ = the source keyword argument structure
467 * @v@ = the destination vector
468 * @n@ = next free index in vector
469 *
470 * Use: Copies arguments from the source structure @kw@ into the
471 * vector @v@. The structure @kw@ must have type @struct
472 * fromset_kwargs *@. The argument @v@ must have type @struct
dcb086e9
MW
473 * kwval *@ (after array-to-pointer decay), and there must be a
474 * variable @n@ of sufficiently large integral type suitably
9e91c8e7
MW
475 * initialized. Elements of the vector, starting with element
476 * @n@, will be filled in with those keyword arguments defined
477 * in @toset@ -- which must be a subset of @srcsrc@ from @kw@
478 * for which the `_suppliedp' flags are set. The @val@ members
479 * will point directly into the @kw@ structure. The @n@
480 * counter will be updated, and on completion will contain the
481 * index of the first unused entry in the vector.
482 */
483
484#define KW_COPY(fromset, toset, kw, v, n) do { \
485 const struct fromset##_kwargs *kw_ = &(kw); \
486 struct kwval *v_ = (v); \
487 size_t n_ = (n); \
488 toset##_KWSET(KW__COPY) \
489 (n) = n_; \
490} while (0)
491
492#define KW__COPY(type, name, dflt) \
493 if (kw_->name##_suppliedp) { \
494 v_[n_].kw = #name; \
495 v_[n_].val = &kw_->name; \
496 n_++; \
497 }
498
499/*----- Functions provided ------------------------------------------------*/
500
501/* --- @kw_unknown@ --- *
502 *
503 * Arguments: @const char *set@ = the keyword set name, as a string
504 * @const char *kw@ = the unknown keyword argument, as a string
505 *
506 * Returns: Doesn't.
507 *
508 * Use: Called when an unrecognized keyword argument is encountered
509 * during parsing. This calls the @kw_unkhook@ with the same
510 * arguments. Recovery via @longjmp@ or a similar machanism is
511 * acceptable.
512 */
513
514extern KW__NORETURN void kw_unknown(const char */*set*/, const char */*kw*/);
515
516/* --- @kw_defunknown@ --- *
517 *
518 * Arguments: @const char *set@ = keyword set name
519 * @const char *kw@ = the offending keyword name
520 *
521 * Returns: Doesn't.
522 *
523 * Use: This is the default @kw_unkhook@ hook function.
524 *
525 * In a hosted implementation, this function reports an internal
526 * error to stderr about the unknown keyword and calls @abort@.
527 * It is an implementation responsibility for freestanding
528 * implementations wanting to use this keyword argument
529 * mechanism.
530 */
531
532extern KW__NORETURN kw_unkhookfn kw_defunknown;
533
534/* --- @kw__hookfailed@ --- *
535 *
536 * Arguments: ---
537 *
538 * Returns: Doesn't.
539 *
540 * Use: Called by @kw_unknown@ if the @kw_unkhook@ hook function
541 * returns.
542 *
543 * User code is not expected to call this function. It exists
544 * as an implementation respensibility for freestanding
545 * implementations wanting to use this keyword argument
546 * mechanism.
547 */
548
549extern KW__NORETURN void kw__hookfailed(void);
550
551/* --- @kw_parseempty@ --- *
552 *
553 * Arguments: @const char *set@ = the keyword set name, as a string
554 * @const char *kwfirst@ = the first keyword argument name
555 * @va_list *ap@ = pointer to argument-tail extraction state
556 * @const struct kwval *v@ = base address of argument vector
557 * @size_t n@ = size of argument vector
558 *
559 * Returns: ---
560 *
561 * Use: Goes through the motions of parsing keyword arguments, but
562 * doesn't in fact handle any other than the standard ones
563 * described above (see @KWSET_PARSEFN@). This is useful when a
564 * function doesn't currently define any keyword arguments but
565 * wants to reserve the right to define some in the future.
566 * (The usual machinery can't be used in this case, since the
567 * argument structure would be empty. Besides, it would be
568 * pointless to include multiple copies of the same boilerplate
569 * code in a program.)
570 */
571
572extern void kw_parseempty(const char */*set*/,
573 const char */*kwfirst*/, va_list */*ap*/,
574 const struct kwval */*v*/, size_t /*n*/);
575
576/*----- That's all, folks -------------------------------------------------*/
577
578#ifdef __cplusplus
579 }
580#endif
581
582#endif