1181834Sroberto 2181834Sroberto/* 3285612Sdelphij * \file autoopts.h 4181834Sroberto * 5181834Sroberto * This file defines all the global structures and special values 6181834Sroberto * used in the automated option processing library. 7285612Sdelphij * 8285612Sdelphij * @group autoopts 9285612Sdelphij * @{ 10181834Sroberto */ 11181834Sroberto/* 12285612Sdelphij * This file is part of AutoOpts, a companion to AutoGen. 13285612Sdelphij * AutoOpts is free software. 14285612Sdelphij * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved 15181834Sroberto * 16285612Sdelphij * AutoOpts is available under any one of two licenses. The license 17285612Sdelphij * in use must be one of these two and the choice is under the control 18285612Sdelphij * of the user of the license. 19181834Sroberto * 20285612Sdelphij * The GNU Lesser General Public License, version 3 or later 21285612Sdelphij * See the files "COPYING.lgplv3" and "COPYING.gplv3" 22181834Sroberto * 23285612Sdelphij * The Modified Berkeley Software Distribution License 24285612Sdelphij * See the file "COPYING.mbsd" 25181834Sroberto * 26285612Sdelphij * These files have the following sha256 sums: 27181834Sroberto * 28285612Sdelphij * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 29285612Sdelphij * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 30285612Sdelphij * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd 31181834Sroberto */ 32181834Sroberto 33181834Sroberto#ifndef AUTOGEN_AUTOOPTS_H 34181834Sroberto#define AUTOGEN_AUTOOPTS_H 35285612Sdelphij#include <stdnoreturn.h> 36181834Sroberto 37181834Sroberto#define AO_NAME_LIMIT 127 38181834Sroberto#define AO_NAME_SIZE ((size_t)(AO_NAME_LIMIT + 1)) 39181834Sroberto 40181834Sroberto#ifndef AG_PATH_MAX 41181834Sroberto# ifdef PATH_MAX 42181834Sroberto# define AG_PATH_MAX ((size_t)PATH_MAX) 43181834Sroberto# else 44181834Sroberto# define AG_PATH_MAX ((size_t)4096) 45181834Sroberto# endif 46181834Sroberto#else 47181834Sroberto# if defined(PATH_MAX) && (PATH_MAX > MAXPATHLEN) 48181834Sroberto# undef AG_PATH_MAX 49181834Sroberto# define AG_PATH_MAX ((size_t)PATH_MAX) 50181834Sroberto# endif 51181834Sroberto#endif 52181834Sroberto 53181834Sroberto#undef EXPORT 54181834Sroberto#define EXPORT 55181834Sroberto 56285612Sdelphij#ifndef NUL 57285612Sdelphij#define NUL '\0' 58285612Sdelphij#endif 59285612Sdelphij#define BEL '\a' 60285612Sdelphij#define BS '\b' 61285612Sdelphij#define HT '\t' 62285612Sdelphij#define LF '\n' 63285612Sdelphij#define VT '\v' 64285612Sdelphij#define FF '\f' 65285612Sdelphij#define CR '\r' 66285612Sdelphij 67181834Sroberto#if defined(_WIN32) && !defined(__CYGWIN__) 68181834Sroberto# define DIRCH '\\' 69181834Sroberto#else 70181834Sroberto# define DIRCH '/' 71181834Sroberto#endif 72181834Sroberto 73285612Sdelphij#ifndef EX_USAGE 74285612Sdelphij /** 75285612Sdelphij * Command line usage problem 76285612Sdelphij */ 77285612Sdelphij# define EX_USAGE 64 78285612Sdelphij#endif 79285612Sdelphij#ifndef EX_DATAERR 80285612Sdelphij /** 81285612Sdelphij * The input data was incorrect in some way. 82285612Sdelphij */ 83285612Sdelphij# define EX_DATAERR 64 84285612Sdelphij#endif 85181834Sroberto#ifndef EX_NOINPUT 86285612Sdelphij /** 87285612Sdelphij * option state was requested from a file that cannot be loaded. 88285612Sdelphij */ 89181834Sroberto# define EX_NOINPUT 66 90181834Sroberto#endif 91181834Sroberto#ifndef EX_SOFTWARE 92285612Sdelphij /** 93285612Sdelphij * AutoOpts Software failure. 94285612Sdelphij */ 95181834Sroberto# define EX_SOFTWARE 70 96181834Sroberto#endif 97285612Sdelphij#ifndef EX_OSERR 98285612Sdelphij /** 99285612Sdelphij * Command line usage problem 100285612Sdelphij */ 101285612Sdelphij# define EX_OSERR 71 102181834Sroberto#endif 103181834Sroberto 104285612Sdelphij#define NL '\n' 105285612Sdelphij#ifndef C 106285612Sdelphij/** 107285612Sdelphij * Coercive cast. Compel an address to be interpreted as the type 108285612Sdelphij * of the first argument. No complaints, just do it. 109285612Sdelphij */ 110285612Sdelphij#define C(_t,_p) ((_t)VOIDP(_p)) 111285612Sdelphij#endif 112285612Sdelphij 113285612Sdelphij/* The __attribute__((__warn_unused_result__)) feature 114285612Sdelphij is available in gcc versions 3.4 and newer, 115285612Sdelphij while the typeof feature has been available since 2.7 at least. */ 116285612Sdelphij# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) 117285612Sdelphij# define ignore_val(x) ((void) (x)) 118285612Sdelphij# else 119285612Sdelphij# define ignore_val(x) (({ __typeof__ (x) __x = (x); (void) __x; })) 120285612Sdelphij# endif 121285612Sdelphij 122181834Sroberto/* 123181834Sroberto * Convert the number to a list usable in a printf call 124181834Sroberto */ 125181834Sroberto#define NUM_TO_VER(n) ((n) >> 12), ((n) >> 7) & 0x001F, (n) & 0x007F 126181834Sroberto 127181834Sroberto#define NAMED_OPTS(po) \ 128181834Sroberto (((po)->fOptSet & (OPTPROC_SHORTOPT | OPTPROC_LONGOPT)) == 0) 129181834Sroberto 130285612Sdelphij#define SKIP_OPT(p) (((p)->fOptState & OPTST_IMMUTABLE_MASK) != 0) 131181834Sroberto 132181834Srobertotypedef int tDirection; 133285612Sdelphij/** 134285612Sdelphij * handling option presets. Start with command line and work through 135285612Sdelphij * config settings in reverse order. 136285612Sdelphij */ 137181834Sroberto#define DIRECTION_PRESET -1 138285612Sdelphij/** 139285612Sdelphij * handling normal options. Start with first config file, then environment 140285612Sdelphij * variables and finally the command line. 141285612Sdelphij */ 142181834Sroberto#define DIRECTION_PROCESS 1 143285612Sdelphij/** 144285612Sdelphij * An initialzation phase or an option being loaded from program sources. 145285612Sdelphij */ 146181834Sroberto#define DIRECTION_CALLED 0 147181834Sroberto 148181834Sroberto#define PROCESSING(d) ((d)>0) 149181834Sroberto#define PRESETTING(d) ((d)<0) 150285612Sdelphij#define CALLED(d) ((d)==0) 151181834Sroberto 152285612Sdelphij/** 153181834Sroberto * When loading a line (or block) of text as an option, the value can 154285612Sdelphij * be processed in any of several modes. 155181834Sroberto */ 156181834Srobertotypedef enum { 157285612Sdelphij /** 158285612Sdelphij * If the value looks like a quoted string, then process it. Double 159285612Sdelphij * quoted strings are processed the way strings are in "C" programs, 160285612Sdelphij * except they are treated as regular characters if the following 161285612Sdelphij * character is not a well-established escape sequence. Single quoted 162285612Sdelphij * strings (quoted with apostrophies) are handled the way strings are 163285612Sdelphij * handled in shell scripts, *except* that backslash escapes are 164285612Sdelphij * honored before backslash escapes and apostrophies. 165285612Sdelphij */ 166181834Sroberto OPTION_LOAD_COOKED, 167285612Sdelphij 168285612Sdelphij /** 169285612Sdelphij * Even if the value begins with quote characters, do not do quote 170285612Sdelphij * processing. Strip leading and trailing white space. 171285612Sdelphij */ 172181834Sroberto OPTION_LOAD_UNCOOKED, 173285612Sdelphij 174285612Sdelphij /** 175285612Sdelphij * Keep every part of the value between the delimiters. 176285612Sdelphij */ 177181834Sroberto OPTION_LOAD_KEEP 178181834Sroberto} tOptionLoadMode; 179181834Sroberto 180285612Sdelphijstatic tOptionLoadMode option_load_mode; 181181834Sroberto 182285612Sdelphij/** 183181834Sroberto * The pager state is used by optionPagedUsage() procedure. 184181834Sroberto * When it runs, it sets itself up to be called again on exit. 185181834Sroberto * If, however, a routine needs a child process to do some work 186181834Sroberto * before it is done, then 'pagerState' must be set to 187181834Sroberto * 'PAGER_STATE_CHILD' so that optionPagedUsage() will not try 188181834Sroberto * to run the pager program before its time. 189181834Sroberto */ 190181834Srobertotypedef enum { 191285612Sdelphij PAGER_STATE_INITIAL, //@< initial option paging state 192285612Sdelphij 193285612Sdelphij /** 194285612Sdelphij * temp file created and optionPagedUsage is scheduled to run at exit 195285612Sdelphij */ 196181834Sroberto PAGER_STATE_READY, 197285612Sdelphij 198285612Sdelphij /** 199285612Sdelphij * This is a child process used in creating shell script usage. 200285612Sdelphij */ 201181834Sroberto PAGER_STATE_CHILD 202181834Sroberto} tePagerState; 203181834Sroberto 204181834Srobertotypedef enum { 205181834Sroberto ENV_ALL, 206181834Sroberto ENV_IMM, 207181834Sroberto ENV_NON_IMM 208181834Sroberto} teEnvPresetType; 209181834Sroberto 210181834Srobertotypedef enum { 211181834Sroberto TOPT_UNDEFINED = 0, 212181834Sroberto TOPT_SHORT, 213181834Sroberto TOPT_LONG, 214181834Sroberto TOPT_DEFAULT 215181834Sroberto} teOptType; 216181834Sroberto 217181834Srobertotypedef struct { 218285612Sdelphij tOptDesc * pOD; 219285612Sdelphij char const * pzOptArg; 220285612Sdelphij opt_state_mask_t flags; 221285612Sdelphij teOptType optType; 222181834Sroberto} tOptState; 223181834Sroberto#define OPTSTATE_INITIALIZER(st) \ 224181834Sroberto { NULL, NULL, OPTST_ ## st, TOPT_UNDEFINED } 225181834Sroberto 226181834Sroberto#define TEXTTO_TABLE \ 227285612Sdelphij _TT_(LONGUSAGE) \ 228285612Sdelphij _TT_(USAGE) \ 229285612Sdelphij _TT_(VERSION) 230181834Sroberto#define _TT_(n) \ 231181834Sroberto TT_ ## n , 232181834Sroberto 233181834Srobertotypedef enum { TEXTTO_TABLE COUNT_TT } teTextTo; 234181834Sroberto 235181834Sroberto#undef _TT_ 236181834Sroberto 237285612Sdelphij/** 238285612Sdelphij * option argument types. Used to create usage information for 239285612Sdelphij * particular options. 240285612Sdelphij */ 241181834Srobertotypedef struct { 242285612Sdelphij char const * pzStr; 243285612Sdelphij char const * pzReq; 244285612Sdelphij char const * pzNum; 245285612Sdelphij char const * pzFile; 246285612Sdelphij char const * pzKey; 247285612Sdelphij char const * pzKeyL; 248285612Sdelphij char const * pzBool; 249285612Sdelphij char const * pzNest; 250285612Sdelphij char const * pzOpt; 251285612Sdelphij char const * pzNo; 252285612Sdelphij char const * pzBrk; 253285612Sdelphij char const * pzNoF; 254285612Sdelphij char const * pzSpc; 255285612Sdelphij char const * pzOptFmt; 256285612Sdelphij char const * pzTime; 257181834Sroberto} arg_types_t; 258181834Sroberto 259285612Sdelphij#define AGALOC(_c, _w) ao_malloc((size_t)_c) 260285612Sdelphij#define AGREALOC(_p, _c, _w) ao_realloc(VOIDP(_p), (size_t)_c) 261285612Sdelphij#define AGFREE(_p) free(VOIDP(_p)) 262285612Sdelphij#define AGDUPSTR(_p, _s, _w) (_p = ao_strdup(_s)) 263181834Sroberto 264181834Srobertostatic void * 265285612Sdelphijao_malloc(size_t sz); 266181834Sroberto 267181834Srobertostatic void * 268285612Sdelphijao_realloc(void *p, size_t sz); 269181834Sroberto 270285612Sdelphij#define ao_free(_p) free(VOIDP(_p)) 271181834Sroberto 272181834Srobertostatic char * 273285612Sdelphijao_strdup(char const * str); 274181834Sroberto 275285612Sdelphij/** 276181834Sroberto * DO option handling? 277181834Sroberto * 278181834Sroberto * Options are examined at two times: at immediate handling time and at 279181834Sroberto * normal handling time. If an option is disabled, the timing may be 280181834Sroberto * different from the handling of the undisabled option. The OPTST_DIABLED 281181834Sroberto * bit indicates the state of the currently discovered option. 282181834Sroberto * So, here's how it works: 283181834Sroberto * 284181834Sroberto * A) handling at "immediate" time, either 1 or 2: 285181834Sroberto * 286181834Sroberto * 1. OPTST_DISABLED is not set: 287181834Sroberto * IMM must be set 288181834Sroberto * DISABLE_IMM don't care 289181834Sroberto * TWICE don't care 290181834Sroberto * DISABLE_TWICE don't care 291181834Sroberto * 0 -and- 1 x x x 292181834Sroberto * 293181834Sroberto * 2. OPTST_DISABLED is set: 294181834Sroberto * IMM don't care 295181834Sroberto * DISABLE_IMM must be set 296181834Sroberto * TWICE don't care 297181834Sroberto * DISABLE_TWICE don't care 298181834Sroberto * 1 -and- x 1 x x 299181834Sroberto */ 300181834Sroberto#define DO_IMMEDIATELY(_flg) \ 301181834Sroberto ( (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == OPTST_IMM) \ 302181834Sroberto || ( ((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) \ 303181834Sroberto == (OPTST_DISABLED|OPTST_DISABLE_IMM) )) 304181834Sroberto 305285612Sdelphij/** 306285612Sdelphij * B) handling at "regular" time because it was not immediate 307181834Sroberto * 308181834Sroberto * 1. OPTST_DISABLED is not set: 309181834Sroberto * IMM must *NOT* be set 310181834Sroberto * DISABLE_IMM don't care 311181834Sroberto * TWICE don't care 312181834Sroberto * DISABLE_TWICE don't care 313181834Sroberto * 0 -and- 0 x x x 314181834Sroberto * 315181834Sroberto * 2. OPTST_DISABLED is set: 316181834Sroberto * IMM don't care 317181834Sroberto * DISABLE_IMM don't care 318181834Sroberto * TWICE must be set 319181834Sroberto * DISABLE_TWICE don't care 320181834Sroberto * 1 -and- x x 1 x 321181834Sroberto */ 322181834Sroberto#define DO_NORMALLY(_flg) ( \ 323181834Sroberto (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == 0) \ 324181834Sroberto || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) == \ 325181834Sroberto OPTST_DISABLED) ) 326181834Sroberto 327285612Sdelphij/** 328285612Sdelphij * C) handling at "regular" time because it is to be handled twice. 329181834Sroberto * The immediate bit was already tested and found to be set: 330181834Sroberto * 331181834Sroberto * 3. OPTST_DISABLED is not set: 332181834Sroberto * IMM is set (but don't care) 333181834Sroberto * DISABLE_IMM don't care 334181834Sroberto * TWICE must be set 335181834Sroberto * DISABLE_TWICE don't care 336181834Sroberto * 0 -and- ? x 1 x 337181834Sroberto * 338181834Sroberto * 4. OPTST_DISABLED is set: 339181834Sroberto * IMM don't care 340181834Sroberto * DISABLE_IMM is set (but don't care) 341181834Sroberto * TWICE don't care 342181834Sroberto * DISABLE_TWICE must be set 343181834Sroberto * 1 -and- x ? x 1 344181834Sroberto */ 345181834Sroberto#define DO_SECOND_TIME(_flg) ( \ 346181834Sroberto (((_flg) & (OPTST_DISABLED|OPTST_TWICE)) == \ 347181834Sroberto OPTST_TWICE) \ 348181834Sroberto || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_TWICE)) == \ 349181834Sroberto (OPTST_DISABLED|OPTST_DISABLE_TWICE) )) 350181834Sroberto 351181834Sroberto/* 352181834Sroberto * text_mmap structure. Only active on platforms with mmap(2). 353181834Sroberto */ 354181834Sroberto#ifdef HAVE_SYS_MMAN_H 355181834Sroberto# include <sys/mman.h> 356181834Sroberto#else 357181834Sroberto# ifndef PROT_READ 358181834Sroberto# define PROT_READ 0x01 359181834Sroberto# endif 360181834Sroberto# ifndef PROT_WRITE 361181834Sroberto# define PROT_WRITE 0x02 362181834Sroberto# endif 363181834Sroberto# ifndef MAP_SHARED 364181834Sroberto# define MAP_SHARED 0x01 365181834Sroberto# endif 366181834Sroberto# ifndef MAP_PRIVATE 367181834Sroberto# define MAP_PRIVATE 0x02 368181834Sroberto# endif 369181834Sroberto#endif 370181834Sroberto 371181834Sroberto#ifndef MAP_FAILED 372285612Sdelphij# define MAP_FAILED VOIDP(-1) 373181834Sroberto#endif 374181834Sroberto 375181834Sroberto#ifndef _SC_PAGESIZE 376181834Sroberto# ifdef _SC_PAGE_SIZE 377181834Sroberto# define _SC_PAGESIZE _SC_PAGE_SIZE 378181834Sroberto# endif 379181834Sroberto#endif 380181834Sroberto 381181834Sroberto#ifndef HAVE_STRCHR 382285612Sdelphijextern char * strchr(char const * s, int c); 383285612Sdelphijextern char * strrchr(char const * s, int c); 384181834Sroberto#endif 385181834Sroberto 386285612Sdelphij/** 387285612Sdelphij * INQUERY_CALL() tests whether the option handling function has been 388285612Sdelphij * called by an inquery (help text needed, or option being reset), 389285612Sdelphij * or called by a set-the-option operation. 390285612Sdelphij */ 391285612Sdelphij#define INQUERY_CALL(_o, _d) ( \ 392285612Sdelphij ((_o) <= OPTPROC_EMIT_LIMIT) \ 393285612Sdelphij || ((_d) == NULL) \ 394285612Sdelphij || (((_d)->fOptState & OPTST_RESET) != 0) ) 395285612Sdelphij 396285612Sdelphij/** 397181834Sroberto * Define and initialize all the user visible strings. 398181834Sroberto * We do not do translations. If translations are to be done, then 399181834Sroberto * the client will provide a callback for that purpose. 400181834Sroberto */ 401181834Sroberto#undef DO_TRANSLATIONS 402181834Sroberto#include "autoopts/usage-txt.h" 403181834Sroberto 404285612Sdelphij/** 405181834Sroberto * File pointer for usage output 406181834Sroberto */ 407285612SdelphijFILE * option_usage_fp; 408285612Sdelphij/** 409285612Sdelphij * If provided in the option structure 410285612Sdelphij */ 411285612Sdelphijstatic char const * program_pkgdatadir; 412285612Sdelphij/** 413285612Sdelphij * privately exported functions 414285612Sdelphij */ 415181834Srobertoextern tOptProc optionPrintVersion, optionPagedUsage, optionLoadOpt; 416181834Sroberto 417285612Sdelphij#ifdef AUTOOPTS_INTERNAL 418285612Sdelphij 419285612Sdelphij#ifndef PKGDATADIR 420285612Sdelphij# define PKGDATADIR "" 421285612Sdelphij#endif 422285612Sdelphij#define APOSTROPHE '\'' 423285612Sdelphij 424285612Sdelphij#define OPTPROC_L_N_S (OPTPROC_LONGOPT | OPTPROC_SHORTOPT) 425285612Sdelphij#if defined(ENABLE_NLS) && defined(HAVE_LIBINTL_H) 426285612Sdelphij# include <libintl.h> 427285612Sdelphij#endif 428285612Sdelphij 429285612Sdelphijtypedef struct { 430285612Sdelphij size_t fnm_len; 431285612Sdelphij uint32_t fnm_mask; 432285612Sdelphij char const * fnm_name; 433285612Sdelphij} ao_flag_names_t; 434285612Sdelphij 435285612Sdelphij/** 436285612Sdelphij * Automated Options Usage Flags. 437285612Sdelphij * NB: no entry may be a prefix of another entry 438285612Sdelphij */ 439285612Sdelphij#define AOFLAG_TABLE \ 440285612Sdelphij _aof_(gnu, OPTPROC_GNUUSAGE ) \ 441285612Sdelphij _aof_(autoopts, ~OPTPROC_GNUUSAGE) \ 442285612Sdelphij _aof_(no_misuse_usage, OPTPROC_MISUSE ) \ 443285612Sdelphij _aof_(misuse_usage, ~OPTPROC_MISUSE ) \ 444285612Sdelphij _aof_(compute, OPTPROC_COMPUTE ) 445285612Sdelphij 446285612Sdelphij#define _aof_(_n, _f) AOUF_ ## _n ## _ID, 447285612Sdelphijtypedef enum { AOFLAG_TABLE AOUF_COUNT } ao_flag_id_t; 448285612Sdelphij#undef _aof_ 449285612Sdelphij 450285612Sdelphij#define _aof_(_n, _f) AOUF_ ## _n = (1 << AOUF_ ## _n ## _ID), 451285612Sdelphijtypedef enum { AOFLAG_TABLE } ao_flags_t; 452285612Sdelphij#undef _aof_ 453285612Sdelphij 454285612Sdelphijstatic char const zNil[] = ""; 455285612Sdelphijstatic arg_types_t argTypes = { NULL }; 456285612Sdelphijstatic char line_fmt_buf[32]; 457285612Sdelphijstatic bool displayEnum = false; 458285612Sdelphijstatic char const pkgdatadir_default[] = PKGDATADIR; 459285612Sdelphijstatic char const * program_pkgdatadir = pkgdatadir_default; 460285612Sdelphijstatic tOptionLoadMode option_load_mode = OPTION_LOAD_UNCOOKED; 461285612Sdelphijstatic tePagerState pagerState = PAGER_STATE_INITIAL; 462285612Sdelphij 463285612Sdelphij FILE * option_usage_fp = NULL; 464285612Sdelphij 465285612Sdelphijstatic char const * pz_enum_err_fmt; 466285612Sdelphij 467285612SdelphijtOptions * optionParseShellOptions = NULL; 468285612Sdelphij 469285612Sdelphijstatic char const * shell_prog = NULL; 470285612Sdelphijstatic char * script_leader = NULL; 471285612Sdelphijstatic char * script_trailer = NULL; 472285612Sdelphijstatic char * script_text = NULL; 473285612Sdelphijstatic bool print_exit = false; 474285612Sdelphij#endif /* AUTOOPTS_INTERNAL */ 475285612Sdelphij 476181834Sroberto#endif /* AUTOGEN_AUTOOPTS_H */ 477285612Sdelphij/** 478285612Sdelphij * @} 479181834Sroberto * Local Variables: 480181834Sroberto * mode: C 481181834Sroberto * c-file-style: "stroustrup" 482181834Sroberto * indent-tabs-mode: nil 483181834Sroberto * End: 484181834Sroberto * end of autoopts/autoopts.h */ 485