1 /* $NetBSD: autoopts.h,v 1.11 2020/05/25 20:47:34 christos Exp $ */ 2 3 4 /* 5 * \file autoopts.h 6 * 7 * This file defines all the global structures and special values 8 * used in the automated option processing library. 9 * 10 * @group autoopts 11 * @{ 12 */ 13 /* 14 * This file is part of AutoOpts, a companion to AutoGen. 15 * AutoOpts is free software. 16 * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved 17 * 18 * AutoOpts is available under any one of two licenses. The license 19 * in use must be one of these two and the choice is under the control 20 * of the user of the license. 21 * 22 * The GNU Lesser General Public License, version 3 or later 23 * See the files "COPYING.lgplv3" and "COPYING.gplv3" 24 * 25 * The Modified Berkeley Software Distribution License 26 * See the file "COPYING.mbsd" 27 * 28 * These files have the following sha256 sums: 29 * 30 * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 31 * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 32 * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd 33 */ 34 35 #ifndef AUTOGEN_AUTOOPTS_H 36 #define AUTOGEN_AUTOOPTS_H 37 #if 0 38 #include <stdnoreturn.h> 39 #else 40 #define noreturn __dead 41 #endif 42 43 #define AO_NAME_LIMIT 127 44 #define AO_NAME_SIZE ((size_t)(AO_NAME_LIMIT + 1)) 45 46 #ifndef AG_PATH_MAX 47 # ifdef PATH_MAX 48 # define AG_PATH_MAX ((size_t)PATH_MAX) 49 # else 50 # define AG_PATH_MAX ((size_t)4096) 51 # endif 52 #else 53 # if defined(PATH_MAX) && (PATH_MAX > MAXPATHLEN) 54 # undef AG_PATH_MAX 55 # define AG_PATH_MAX ((size_t)PATH_MAX) 56 # endif 57 #endif 58 59 #undef EXPORT 60 #define EXPORT 61 62 #ifndef NUL 63 #define NUL '\0' 64 #endif 65 #define BEL '\a' 66 #define BS '\b' 67 #define HT '\t' 68 #define LF '\n' 69 #define VT '\v' 70 #define FF '\f' 71 #define CR '\r' 72 73 #if defined(_WIN32) && !defined(__CYGWIN__) 74 # define DIRCH '\\' 75 #else 76 # define DIRCH '/' 77 #endif 78 79 #ifndef EX_USAGE 80 /** 81 * Command line usage problem 82 */ 83 # define EX_USAGE 64 84 #endif 85 #ifndef EX_DATAERR 86 /** 87 * The input data was incorrect in some way. 88 */ 89 # define EX_DATAERR 64 90 #endif 91 #ifndef EX_NOINPUT 92 /** 93 * option state was requested from a file that cannot be loaded. 94 */ 95 # define EX_NOINPUT 66 96 #endif 97 #ifndef EX_SOFTWARE 98 /** 99 * AutoOpts Software failure. 100 */ 101 # define EX_SOFTWARE 70 102 #endif 103 #ifndef EX_OSERR 104 /** 105 * Command line usage problem 106 */ 107 # define EX_OSERR 71 108 #endif 109 110 #define NL '\n' 111 #ifndef C 112 /** 113 * Coercive cast. Compel an address to be interpreted as the type 114 * of the first argument. No complaints, just do it. 115 */ 116 #define C(_t,_p) ((_t)VOIDP(_p)) 117 #endif 118 119 /* The __attribute__((__warn_unused_result__)) feature 120 is available in gcc versions 3.4 and newer, 121 while the typeof feature has been available since 2.7 at least. */ 122 # if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) 123 # define ignore_val(x) ((void) (x)) 124 # else 125 # define ignore_val(x) (({ __typeof__ (x) __x = (x); (void) __x; })) 126 # endif 127 128 /* 129 * Convert the number to a list usable in a printf call 130 */ 131 #define NUM_TO_VER(n) ((n) >> 12), ((n) >> 7) & 0x001F, (n) & 0x007F 132 133 #define NAMED_OPTS(po) \ 134 (((po)->fOptSet & (OPTPROC_SHORTOPT | OPTPROC_LONGOPT)) == 0) 135 136 #define SKIP_OPT(p) (((p)->fOptState & OPTST_IMMUTABLE_MASK) != 0) 137 138 typedef int tDirection; 139 /** 140 * handling option presets. Start with command line and work through 141 * config settings in reverse order. 142 */ 143 #define DIRECTION_PRESET -1 144 /** 145 * handling normal options. Start with first config file, then environment 146 * variables and finally the command line. 147 */ 148 #define DIRECTION_PROCESS 1 149 /** 150 * An initialzation phase or an option being loaded from program sources. 151 */ 152 #define DIRECTION_CALLED 0 153 154 #define PROCESSING(d) ((d)>0) 155 #define PRESETTING(d) ((d)<0) 156 #define CALLED(d) ((d)==0) 157 158 /** 159 * When loading a line (or block) of text as an option, the value can 160 * be processed in any of several modes. 161 */ 162 typedef enum { 163 /** 164 * If the value looks like a quoted string, then process it. Double 165 * quoted strings are processed the way strings are in "C" programs, 166 * except they are treated as regular characters if the following 167 * character is not a well-established escape sequence. Single quoted 168 * strings (quoted with apostrophies) are handled the way strings are 169 * handled in shell scripts, *except* that backslash escapes are 170 * honored before backslash escapes and apostrophies. 171 */ 172 OPTION_LOAD_COOKED, 173 174 /** 175 * Even if the value begins with quote characters, do not do quote 176 * processing. Strip leading and trailing white space. 177 */ 178 OPTION_LOAD_UNCOOKED, 179 180 /** 181 * Keep every part of the value between the delimiters. 182 */ 183 OPTION_LOAD_KEEP 184 } tOptionLoadMode; 185 186 static tOptionLoadMode option_load_mode; 187 188 /** 189 * The pager state is used by optionPagedUsage() procedure. 190 * When it runs, it sets itself up to be called again on exit. 191 * If, however, a routine needs a child process to do some work 192 * before it is done, then 'pagerState' must be set to 193 * 'PAGER_STATE_CHILD' so that optionPagedUsage() will not try 194 * to run the pager program before its time. 195 */ 196 typedef enum { 197 PAGER_STATE_INITIAL, //@< initial option paging state 198 199 /** 200 * temp file created and optionPagedUsage is scheduled to run at exit 201 */ 202 PAGER_STATE_READY, 203 204 /** 205 * This is a child process used in creating shell script usage. 206 */ 207 PAGER_STATE_CHILD 208 } tePagerState; 209 210 typedef enum { 211 ENV_ALL, 212 ENV_IMM, 213 ENV_NON_IMM 214 } teEnvPresetType; 215 216 typedef enum { 217 TOPT_UNDEFINED = 0, 218 TOPT_SHORT, 219 TOPT_LONG, 220 TOPT_DEFAULT 221 } teOptType; 222 223 typedef struct { 224 tOptDesc * pOD; 225 char const * pzOptArg; 226 opt_state_mask_t flags; 227 teOptType optType; 228 } tOptState; 229 #define OPTSTATE_INITIALIZER(st) \ 230 { NULL, NULL, OPTST_ ## st, TOPT_UNDEFINED } 231 232 #define TEXTTO_TABLE \ 233 _TT_(LONGUSAGE) \ 234 _TT_(USAGE) \ 235 _TT_(VERSION) 236 #define _TT_(n) \ 237 TT_ ## n , 238 239 typedef enum { TEXTTO_TABLE COUNT_TT } teTextTo; 240 241 #undef _TT_ 242 243 /** 244 * option argument types. Used to create usage information for 245 * particular options. 246 */ 247 typedef struct { 248 char const * pzStr; 249 char const * pzReq; 250 char const * pzNum; 251 char const * pzFile; 252 char const * pzKey; 253 char const * pzKeyL; 254 char const * pzBool; 255 char const * pzNest; 256 char const * pzOpt; 257 char const * pzNo; 258 char const * pzBrk; 259 char const * pzNoF; 260 char const * pzSpc; 261 char const * pzOptFmt; 262 char const * pzTime; 263 } arg_types_t; 264 265 #define AGALOC(_c, _w) ao_malloc((size_t)_c) 266 #define AGREALOC(_p, _c, _w) ao_realloc(VOIDP(_p), (size_t)_c) 267 #define AGFREE(_p) free(VOIDP(_p)) 268 #define AGDUPSTR(_p, _s, _w) (_p = ao_strdup(_s)) 269 270 static void * 271 ao_malloc(size_t sz); 272 273 static void * 274 ao_realloc(void *p, size_t sz); 275 276 #define ao_free(_p) free(VOIDP(_p)) 277 278 static char * 279 ao_strdup(char const * str); 280 281 /** 282 * DO option handling? 283 * 284 * Options are examined at two times: at immediate handling time and at 285 * normal handling time. If an option is disabled, the timing may be 286 * different from the handling of the undisabled option. The OPTST_DIABLED 287 * bit indicates the state of the currently discovered option. 288 * So, here's how it works: 289 * 290 * A) handling at "immediate" time, either 1 or 2: 291 * 292 * 1. OPTST_DISABLED is not set: 293 * IMM must be set 294 * DISABLE_IMM don't care 295 * TWICE don't care 296 * DISABLE_TWICE don't care 297 * 0 -and- 1 x x x 298 * 299 * 2. OPTST_DISABLED is set: 300 * IMM don't care 301 * DISABLE_IMM must be set 302 * TWICE don't care 303 * DISABLE_TWICE don't care 304 * 1 -and- x 1 x x 305 */ 306 #define DO_IMMEDIATELY(_flg) \ 307 ( (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == OPTST_IMM) \ 308 || ( ((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) \ 309 == (OPTST_DISABLED|OPTST_DISABLE_IMM) )) 310 311 /** 312 * B) handling at "regular" time because it was not immediate 313 * 314 * 1. OPTST_DISABLED is not set: 315 * IMM must *NOT* be set 316 * DISABLE_IMM don't care 317 * TWICE don't care 318 * DISABLE_TWICE don't care 319 * 0 -and- 0 x x x 320 * 321 * 2. OPTST_DISABLED is set: 322 * IMM don't care 323 * DISABLE_IMM don't care 324 * TWICE must be set 325 * DISABLE_TWICE don't care 326 * 1 -and- x x 1 x 327 */ 328 #define DO_NORMALLY(_flg) ( \ 329 (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == 0) \ 330 || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) == \ 331 OPTST_DISABLED) ) 332 333 /** 334 * C) handling at "regular" time because it is to be handled twice. 335 * The immediate bit was already tested and found to be set: 336 * 337 * 3. OPTST_DISABLED is not set: 338 * IMM is set (but don't care) 339 * DISABLE_IMM don't care 340 * TWICE must be set 341 * DISABLE_TWICE don't care 342 * 0 -and- ? x 1 x 343 * 344 * 4. OPTST_DISABLED is set: 345 * IMM don't care 346 * DISABLE_IMM is set (but don't care) 347 * TWICE don't care 348 * DISABLE_TWICE must be set 349 * 1 -and- x ? x 1 350 */ 351 #define DO_SECOND_TIME(_flg) ( \ 352 (((_flg) & (OPTST_DISABLED|OPTST_TWICE)) == \ 353 OPTST_TWICE) \ 354 || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_TWICE)) == \ 355 (OPTST_DISABLED|OPTST_DISABLE_TWICE) )) 356 357 /* 358 * text_mmap structure. Only active on platforms with mmap(2). 359 */ 360 #ifdef HAVE_SYS_MMAN_H 361 # include <sys/mman.h> 362 #else 363 # ifndef PROT_READ 364 # define PROT_READ 0x01 365 # endif 366 # ifndef PROT_WRITE 367 # define PROT_WRITE 0x02 368 # endif 369 # ifndef MAP_SHARED 370 # define MAP_SHARED 0x01 371 # endif 372 # ifndef MAP_PRIVATE 373 # define MAP_PRIVATE 0x02 374 # endif 375 #endif 376 377 #ifndef MAP_FAILED 378 # define MAP_FAILED VOIDP(-1) 379 #endif 380 381 #ifndef _SC_PAGESIZE 382 # ifdef _SC_PAGE_SIZE 383 # define _SC_PAGESIZE _SC_PAGE_SIZE 384 # endif 385 #endif 386 387 #ifndef HAVE_STRCHR 388 extern char * strchr(char const * s, int c); 389 extern char * strrchr(char const * s, int c); 390 #endif 391 392 /** 393 * INQUERY_CALL() tests whether the option handling function has been 394 * called by an inquery (help text needed, or option being reset), 395 * or called by a set-the-option operation. 396 */ 397 #define INQUERY_CALL(_o, _d) ( \ 398 ((_o) <= OPTPROC_EMIT_LIMIT) \ 399 || ((_d) == NULL) \ 400 || (((_d)->fOptState & OPTST_RESET) != 0) ) 401 402 /** 403 * Define and initialize all the user visible strings. 404 * We do not do translations. If translations are to be done, then 405 * the client will provide a callback for that purpose. 406 */ 407 #undef DO_TRANSLATIONS 408 #include "autoopts/usage-txt.h" 409 410 /** 411 * File pointer for usage output 412 */ 413 FILE * option_usage_fp; 414 /** 415 * If provided in the option structure 416 */ 417 static char const * program_pkgdatadir; 418 /** 419 * privately exported functions 420 */ 421 extern tOptProc optionPrintVersion, optionPagedUsage, optionLoadOpt; 422 423 #ifdef AUTOOPTS_INTERNAL 424 425 #ifndef PKGDATADIR 426 # define PKGDATADIR "" 427 #endif 428 #define APOSTROPHE '\'' 429 430 #define OPTPROC_L_N_S (OPTPROC_LONGOPT | OPTPROC_SHORTOPT) 431 #if defined(ENABLE_NLS) && defined(HAVE_LIBINTL_H) 432 # include <libintl.h> 433 #endif 434 435 typedef struct { 436 size_t fnm_len; 437 uint32_t fnm_mask; 438 char const * fnm_name; 439 } ao_flag_names_t; 440 441 /** 442 * Automated Options Usage Flags. 443 * NB: no entry may be a prefix of another entry 444 */ 445 #define AOFLAG_TABLE \ 446 _aof_(gnu, OPTPROC_GNUUSAGE ) \ 447 _aof_(autoopts, ~OPTPROC_GNUUSAGE) \ 448 _aof_(no_misuse_usage, OPTPROC_MISUSE ) \ 449 _aof_(misuse_usage, ~OPTPROC_MISUSE ) \ 450 _aof_(compute, OPTPROC_COMPUTE ) 451 452 #define _aof_(_n, _f) AOUF_ ## _n ## _ID, 453 typedef enum { AOFLAG_TABLE AOUF_COUNT } ao_flag_id_t; 454 #undef _aof_ 455 456 #define _aof_(_n, _f) AOUF_ ## _n = (1 << AOUF_ ## _n ## _ID), 457 typedef enum { AOFLAG_TABLE } ao_flags_t; 458 #undef _aof_ 459 460 static char const zNil[] = ""; 461 static arg_types_t argTypes = { .pzStr = NULL }; 462 static char line_fmt_buf[32]; 463 static bool displayEnum = false; 464 static char const pkgdatadir_default[] = PKGDATADIR; 465 static char const * program_pkgdatadir = pkgdatadir_default; 466 static tOptionLoadMode option_load_mode = OPTION_LOAD_UNCOOKED; 467 static tePagerState pagerState = PAGER_STATE_INITIAL; 468 469 FILE * option_usage_fp = NULL; 470 471 static char const * pz_enum_err_fmt; 472 473 tOptions * optionParseShellOptions = NULL; 474 475 static char const * shell_prog = NULL; 476 static char * script_leader = NULL; 477 static char * script_trailer = NULL; 478 static char * script_text = NULL; 479 static bool print_exit = false; 480 #endif /* AUTOOPTS_INTERNAL */ 481 482 #endif /* AUTOGEN_AUTOOPTS_H */ 483 /** 484 * @} 485 * Local Variables: 486 * mode: C 487 * c-file-style: "stroustrup" 488 * indent-tabs-mode: nil 489 * End: 490 * end of autoopts/autoopts.h */ 491