Commit | Line | Data |
---|---|---|
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 | */ | |
84 | struct 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 | */ | |
93 | struct 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. */ | |
99 | typedef 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 | */ | |
114 | extern 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 | ||
515 | extern 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 | ||
533 | extern 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 | ||
550 | extern 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 | ||
573 | extern 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 |