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