| 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 | |
| 118 | /* These macros are intended to be conveniences rather than a proper |
| 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 | |
| 148 | /* --- @NO_KWARGS@ --- * |
| 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 | |
| 167 | /* --- @K@ --- * |
| 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 | } |
| 238 | #define KWSET__SUPPLIEDP(type, name, dflt) unsigned name##_suppliedp: 1; |
| 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 |