Initial commit
[authen-passphrase-scrypt.git] / scrypt-1.2.1 / libcperciva / util / getopt.h
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. */
50 extern const char * optarg;
51 extern 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 */
167 const char * getopt(int, char * const []);
168 size_t getopt_lookup(const char *);
169 void getopt_register_opt(const char *, size_t, int);
170 void getopt_register_missing(size_t);
171 void getopt_setrange(size_t);
172 extern const char * getopt_dummy;
173 extern int getopt_initialized;
174
175 #endif /* !_GETOPT_H_ */
This page took 0.025668 seconds and 4 git commands to generate.