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