xref: /netbsd-src/external/bsd/ntp/dist/sntp/libopts/autoopts.h (revision 6a493d6bc668897c91594964a732d38505b70cbb)
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