]> iEval git - authen-passphrase-scrypt.git/blame - scrypt-1.2.1/libcperciva/util/getopt.h
Bump version and update Changes
[authen-passphrase-scrypt.git] / scrypt-1.2.1 / libcperciva / util / getopt.h
CommitLineData
0c1f3509
MG
1#ifndef _GETOPT_H_
2#define _GETOPT_H_
3
4#include <setjmp.h>
5#include <stddef.h>
6
7/**
8 * This getopt implementation parses options of the following forms:
9 * -a -b -c foo (single-character options)
10 * -abc foo (packed single-character options)
11 * -abcfoo (packed single-character options and an argument)
12 * --foo bar (long option)
13 * --foo=bar (long option and argument separated by '=')
14 *
15 * It does not support abbreviated options (e.g., interpreting --foo as
16 * --foobar when there are no other --foo* options) since that misfeature
17 * results in breakage when new options are added. It also does not support
18 * options appearing after non-options (e.g., "cp foo bar -R") since that is
19 * a horrible GNU perversion.
20 */
21
22/* Work around LLVM bug. */
23#ifdef __clang__
24#warning Working around bug in LLVM optimizer
25#warning For more details see https://llvm.org/bugs/show_bug.cgi?id=27190
26#define DO_SETJMP _DO_SETJMP(__LINE__)
27#define _DO_SETJMP(x) __DO_SETJMP(x)
28#define __DO_SETJMP(x) \
29 void * getopt_initloop = && getopt_initloop_ ## x; \
30 getopt_initloop_ ## x:
31#define DO_LONGJMP \
32 goto *getopt_initloop
33#else
34#define DO_SETJMP \
35 sigjmp_buf getopt_initloop; \
36 if (!getopt_initialized) \
37 sigsetjmp(getopt_initloop, 0)
38#define DO_LONGJMP \
39 siglongjmp(getopt_initloop, 1)
40#endif
41
42/* Avoid namespace collisions with libc getopt. */
43#define getopt libcperciva_getopt
44#define optarg libcperciva_optarg
45#define optind libcperciva_optind
46#define opterr libcperciva_opterr
47#define optreset libcperciva_optreset
48
49/* Standard getopt global variables. */
50extern const char * optarg;
51extern int optind, opterr, optreset;
52
53/* Dummy option string, equal to "(dummy)". */
54#define GETOPT_DUMMY getopt_dummy
55
56/**
57 * GETOPT(argc, argv):
58 * When called for the first time (or the first time after optreset is set to
59 * a nonzero value), return GETOPT_DUMMY, aka. "(dummy)". Thereafter, return
60 * the next option string and set optarg / optind appropriately; abort if not
61 * properly initialized when not being called for the first time.
62 */
63#define GETOPT(argc, argv) getopt(argc, argv)
64
65/**
66 * GETOPT_SWITCH(ch):
67 * Jump to the appropriate GETOPT_OPT, GETOPT_OPTARG, GETOPT_MISSING_ARG, or
68 * GETOPT_DEFAULT based on the option string ${ch}. When called for the first
69 * time, perform magic to index the options.
70 *
71 * GETOPT_SWITCH(ch) is equivalent to "switch (ch)" in a standard getopt loop.
72 */
73#define GETOPT_SWITCH(ch) \
74 volatile size_t getopt_ln_min = __LINE__; \
75 volatile size_t getopt_ln = getopt_ln_min - 1; \
76 volatile int getopt_default_missing = 0; \
77 DO_SETJMP; \
78 switch (getopt_initialized ? getopt_lookup(ch) + getopt_ln_min : getopt_ln++)
79
80/**
81 * GETOPT_OPT(os):
82 * Jump to this point when the option string ${os} is passed to GETOPT_SWITCH.
83 *
84 * GETOPT_OPT("-x") is equivalent to "case 'x'" in a standard getopt loop
85 * which has an optstring containing "x".
86 */
87#define GETOPT_OPT(os) _GETOPT_OPT(os, __LINE__)
88#define _GETOPT_OPT(os, ln) __GETOPT_OPT(os, ln)
89#define __GETOPT_OPT(os, ln) \
90 case ln: \
91 if (getopt_initialized) \
92 goto getopt_skip_ ## ln; \
93 getopt_register_opt(os, ln - getopt_ln_min, 0); \
94 DO_LONGJMP; \
95 getopt_skip_ ## ln
96
97/**
98 * GETOPT_OPTARG(os):
99 * Jump to this point when the option string ${os} is passed to GETOPT_SWITCH,
100 * unless no argument is available, in which case jump to GETOPT_MISSING_ARG
101 * (if present) or GETOPT_DEFAULT (if not).
102 *
103 * GETOPT_OPTARG("-x") is equivalent to "case 'x'" in a standard getopt loop
104 * which has an optstring containing "x:".
105 */
106#define GETOPT_OPTARG(os) _GETOPT_OPTARG(os, __LINE__)
107#define _GETOPT_OPTARG(os, ln) __GETOPT_OPTARG(os, ln)
108#define __GETOPT_OPTARG(os, ln) \
109 case ln: \
110 if (getopt_initialized) \
111 goto getopt_skip_ ## ln; \
112 getopt_register_opt(os, ln - getopt_ln_min, 1); \
113 DO_LONGJMP; \
114 getopt_skip_ ## ln
115
116/**
117 * GETOPT_MISSING_ARG:
118 * Jump to this point if an option string specified in GETOPT_OPTARG is seen
119 * but no argument is available.
120 *
121 * GETOPT_MISSING_ARG is equivalent to "case ':'" in a standard getopt loop
122 * which has an optstring starting with ":". As such, it also has the effect
123 * of disabling warnings about invalid options, as if opterr had been zeroed.
124 */
125#define GETOPT_MISSING_ARG _GETOPT_MISSING_ARG(__LINE__)
126#define _GETOPT_MISSING_ARG(ln) __GETOPT_MISSING_ARG(ln)
127#define __GETOPT_MISSING_ARG(ln) \
128 case ln: \
129 if (getopt_initialized) \
130 goto getopt_skip_ ## ln; \
131 getopt_register_missing(ln - getopt_ln_min); \
132 DO_LONGJMP; \
133 getopt_skip_ ## ln
134
135/**
136 * GETOPT_DEFAULT:
137 * Jump to this point if an unrecognized option is seen or if an option
138 * specified in GETOPT_OPTARG is seen, no argument is available, and there is
139 * no GETOPT_MISSING_ARG label.
140 *
141 * GETOPT_DEFAULT is equivalent to "case '?'" in a standard getopt loop.
142 *
143 * NOTE: This MUST be present in the GETOPT_SWITCH statement, and MUST occur
144 * after all other GETOPT_* labels.
145 */
146#define GETOPT_DEFAULT _GETOPT_DEFAULT(__LINE__)
147#define _GETOPT_DEFAULT(ln) __GETOPT_DEFAULT(ln)
148#define __GETOPT_DEFAULT(ln) \
149 goto getopt_skip_ ## ln; \
150 case ln: \
151 getopt_initialized = 1; \
152 break; \
153 default: \
154 if (getopt_initialized) \
155 goto getopt_skip_ ## ln; \
156 if (!getopt_default_missing) { \
157 getopt_setrange(ln - getopt_ln_min); \
158 getopt_default_missing = 1; \
159 } \
160 DO_LONGJMP; \
161 getopt_skip_ ## ln
162
163/*
164 * The back-end implementation. These should be considered internal
165 * interfaces and not used directly.
166 */
167const char * getopt(int, char * const []);
168size_t getopt_lookup(const char *);
169void getopt_register_opt(const char *, size_t, int);
170void getopt_register_missing(size_t);
171void getopt_setrange(size_t);
172extern const char * getopt_dummy;
173extern int getopt_initialized;
174
175#endif /* !_GETOPT_H_ */
This page took 0.044756 seconds and 4 git commands to generate.