Commit | Line | Data |
---|---|---|
4a621aae | 1 | # getopt.m4 serial 38 |
e275c824 | 2 | dnl Copyright (C) 2002-2006, 2008-2011 Free Software Foundation, Inc. |
9eff9fe3 PE |
3 | dnl This file is free software; the Free Software Foundation |
4 | dnl gives unlimited permission to copy and/or distribute it, | |
5 | dnl with or without modifications, as long as this notice is preserved. | |
6 | ||
e275c824 PE |
7 | # Request a POSIX compliant getopt function. |
8 | AC_DEFUN([gl_FUNC_GETOPT_POSIX], | |
9 | [ | |
10 | m4_divert_text([DEFAULTS], [gl_getopt_required=POSIX]) | |
11 | AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) | |
8aeb5be9 PE |
12 | dnl Other modules can request the gnulib implementation of the getopt |
13 | dnl functions unconditionally, by defining gl_REPLACE_GETOPT_ALWAYS. | |
14 | dnl argp.m4 does this. | |
15 | m4_ifdef([gl_REPLACE_GETOPT_ALWAYS], [ | |
16 | gl_GETOPT_IFELSE([], []) | |
17 | REPLACE_GETOPT=1 | |
18 | ], [ | |
19 | REPLACE_GETOPT=0 | |
20 | gl_GETOPT_IFELSE([ | |
21 | REPLACE_GETOPT=1 | |
22 | ], | |
23 | []) | |
24 | ]) | |
25 | if test $REPLACE_GETOPT = 1; then | |
26 | dnl Arrange for getopt.h to be created. | |
27 | gl_GETOPT_SUBSTITUTE_HEADER | |
28 | dnl Arrange for unistd.h to include getopt.h. | |
29 | GNULIB_UNISTD_H_GETOPT=1 | |
30 | fi | |
e275c824 PE |
31 | ]) |
32 | ||
33 | # Request a POSIX compliant getopt function with GNU extensions (such as | |
34 | # options with optional arguments) and the functions getopt_long, | |
35 | # getopt_long_only. | |
36 | AC_DEFUN([gl_FUNC_GETOPT_GNU], | |
37 | [ | |
38 | m4_divert_text([INIT_PREPARE], [gl_getopt_required=GNU]) | |
39 | ||
40 | AC_REQUIRE([gl_FUNC_GETOPT_POSIX]) | |
41 | ]) | |
9eff9fe3 | 42 | |
e275c824 PE |
43 | # emacs' configure.in uses this. |
44 | AC_DEFUN([gl_GETOPT_IFELSE], | |
9eff9fe3 | 45 | [ |
e275c824 PE |
46 | AC_REQUIRE([gl_GETOPT_CHECK_HEADERS]) |
47 | AS_IF([test -n "$gl_replace_getopt"], [$1], [$2]) | |
9eff9fe3 PE |
48 | ]) |
49 | ||
e275c824 | 50 | # Determine whether to replace the entire getopt facility. |
9eff9fe3 PE |
51 | AC_DEFUN([gl_GETOPT_CHECK_HEADERS], |
52 | [ | |
e275c824 PE |
53 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles |
54 | AC_REQUIRE([AC_PROG_AWK]) dnl for awk that supports ENVIRON | |
55 | ||
56 | dnl Persuade Solaris <unistd.h> to declare optarg, optind, opterr, optopt. | |
57 | AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) | |
58 | ||
59 | gl_CHECK_NEXT_HEADERS([getopt.h]) | |
e275c824 PE |
60 | if test $ac_cv_header_getopt_h = yes; then |
61 | HAVE_GETOPT_H=1 | |
62 | else | |
63 | HAVE_GETOPT_H=0 | |
64 | fi | |
65 | AC_SUBST([HAVE_GETOPT_H]) | |
66 | ||
67 | gl_replace_getopt= | |
68 | ||
69 | dnl Test whether <getopt.h> is available. | |
70 | if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then | |
71 | AC_CHECK_HEADERS([getopt.h], [], [gl_replace_getopt=yes]) | |
72 | fi | |
73 | ||
74 | dnl Test whether the function getopt_long is available. | |
75 | if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then | |
76 | AC_CHECK_FUNCS([getopt_long_only], [], [gl_replace_getopt=yes]) | |
9eff9fe3 PE |
77 | fi |
78 | ||
e275c824 PE |
79 | dnl mingw's getopt (in libmingwex.a) does weird things when the options |
80 | dnl strings starts with '+' and it's not the first call. Some internal state | |
81 | dnl is left over from earlier calls, and neither setting optind = 0 nor | |
82 | dnl setting optreset = 1 get rid of this internal state. | |
83 | dnl POSIX is silent on optind vs. optreset, so we allow either behavior. | |
84 | dnl POSIX 2008 does not specify leading '+' behavior, but see | |
85 | dnl http://austingroupbugs.net/view.php?id=191 for a recommendation on | |
86 | dnl the next version of POSIX. For now, we only guarantee leading '+' | |
87 | dnl behavior with getopt-gnu. | |
88 | if test -z "$gl_replace_getopt"; then | |
89 | AC_CACHE_CHECK([whether getopt is POSIX compatible], | |
90 | [gl_cv_func_getopt_posix], | |
91 | [ | |
4a621aae PE |
92 | dnl BSD getopt_long uses an incompatible method to reset option |
93 | dnl processing. Existence of the optreset variable, in and of | |
d6974efa PE |
94 | dnl itself, is not a reason to replace getopt, but knowledge |
95 | dnl of the variable is needed to determine how to reset and | |
96 | dnl whether a reset reparses the environment. Solaris | |
97 | dnl supports neither optreset nor optind=0, but keeps no state | |
98 | dnl that needs a reset beyond setting optind=1; detect Solaris | |
99 | dnl by getopt_clip. | |
4a621aae | 100 | AC_LINK_IFELSE( |
d6974efa PE |
101 | [AC_LANG_PROGRAM( |
102 | [[#include <unistd.h>]], | |
103 | [[int *p = &optreset; return optreset;]])], | |
104 | [gl_optind_min=1], | |
105 | [AC_COMPILE_IFELSE( | |
106 | [AC_LANG_PROGRAM( | |
107 | [[#include <getopt.h>]], | |
108 | [[return !getopt_clip;]])], | |
109 | [gl_optind_min=1], | |
110 | [gl_optind_min=0])]) | |
111 | ||
e275c824 | 112 | dnl This test fails on mingw and succeeds on many other platforms. |
d6974efa PE |
113 | gl_save_CPPFLAGS=$CPPFLAGS |
114 | CPPFLAGS="$CPPFLAGS -DOPTIND_MIN=$gl_optind_min" | |
e275c824 PE |
115 | AC_RUN_IFELSE([AC_LANG_SOURCE([[ |
116 | #include <unistd.h> | |
117 | #include <stdlib.h> | |
118 | #include <string.h> | |
119 | ||
e275c824 PE |
120 | int |
121 | main () | |
122 | { | |
123 | { | |
4a621aae PE |
124 | static char program[] = "program"; |
125 | static char a[] = "-a"; | |
126 | static char foo[] = "foo"; | |
127 | static char bar[] = "bar"; | |
128 | char *argv[] = { program, a, foo, bar, NULL }; | |
e275c824 PE |
129 | int c; |
130 | ||
e275c824 PE |
131 | optind = OPTIND_MIN; |
132 | opterr = 0; | |
133 | ||
4a621aae | 134 | c = getopt (4, argv, "ab"); |
e275c824 PE |
135 | if (!(c == 'a')) |
136 | return 1; | |
4a621aae | 137 | c = getopt (4, argv, "ab"); |
e275c824 PE |
138 | if (!(c == -1)) |
139 | return 2; | |
140 | if (!(optind == 2)) | |
141 | return 3; | |
142 | } | |
143 | /* Some internal state exists at this point. */ | |
144 | { | |
4a621aae PE |
145 | static char program[] = "program"; |
146 | static char donald[] = "donald"; | |
147 | static char p[] = "-p"; | |
148 | static char billy[] = "billy"; | |
149 | static char duck[] = "duck"; | |
150 | static char a[] = "-a"; | |
151 | static char bar[] = "bar"; | |
152 | char *argv[] = { program, donald, p, billy, duck, a, bar, NULL }; | |
e275c824 PE |
153 | int c; |
154 | ||
e275c824 PE |
155 | optind = OPTIND_MIN; |
156 | opterr = 0; | |
157 | ||
4a621aae | 158 | c = getopt (7, argv, "+abp:q:"); |
e275c824 PE |
159 | if (!(c == -1)) |
160 | return 4; | |
161 | if (!(strcmp (argv[0], "program") == 0)) | |
162 | return 5; | |
163 | if (!(strcmp (argv[1], "donald") == 0)) | |
164 | return 6; | |
165 | if (!(strcmp (argv[2], "-p") == 0)) | |
166 | return 7; | |
167 | if (!(strcmp (argv[3], "billy") == 0)) | |
168 | return 8; | |
169 | if (!(strcmp (argv[4], "duck") == 0)) | |
170 | return 9; | |
171 | if (!(strcmp (argv[5], "-a") == 0)) | |
172 | return 10; | |
173 | if (!(strcmp (argv[6], "bar") == 0)) | |
174 | return 11; | |
175 | if (!(optind == 1)) | |
176 | return 12; | |
177 | } | |
178 | /* Detect MacOS 10.5, AIX 7.1 bug. */ | |
179 | { | |
4a621aae PE |
180 | static char program[] = "program"; |
181 | static char ab[] = "-ab"; | |
182 | char *argv[3] = { program, ab, NULL }; | |
e275c824 PE |
183 | optind = OPTIND_MIN; |
184 | opterr = 0; | |
185 | if (getopt (2, argv, "ab:") != 'a') | |
186 | return 13; | |
187 | if (getopt (2, argv, "ab:") != '?') | |
188 | return 14; | |
189 | if (optopt != 'b') | |
190 | return 15; | |
191 | if (optind != 2) | |
192 | return 16; | |
193 | } | |
194 | ||
195 | return 0; | |
196 | } | |
197 | ]])], | |
198 | [gl_cv_func_getopt_posix=yes], [gl_cv_func_getopt_posix=no], | |
199 | [case "$host_os" in | |
200 | mingw*) gl_cv_func_getopt_posix="guessing no";; | |
201 | darwin* | aix*) gl_cv_func_getopt_posix="guessing no";; | |
202 | *) gl_cv_func_getopt_posix="guessing yes";; | |
203 | esac | |
204 | ]) | |
d6974efa | 205 | CPPFLAGS=$gl_save_CPPFLAGS |
e275c824 PE |
206 | ]) |
207 | case "$gl_cv_func_getopt_posix" in | |
208 | *no) gl_replace_getopt=yes ;; | |
209 | esac | |
210 | fi | |
211 | ||
212 | if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then | |
213 | AC_CACHE_CHECK([for working GNU getopt function], [gl_cv_func_getopt_gnu], | |
214 | [# Even with POSIXLY_CORRECT, the GNU extension of leading '-' in the | |
215 | # optstring is necessary for programs like m4 that have POSIX-mandated | |
216 | # semantics for supporting options interspersed with files. | |
217 | # Also, since getopt_long is a GNU extension, we require optind=0. | |
218 | # Bash ties 'set -o posix' to a non-exported POSIXLY_CORRECT; | |
219 | # so take care to revert to the correct (non-)export state. | |
220 | dnl GNU Coding Standards currently allow awk but not env; besides, env | |
221 | dnl is ambiguous with environment values that contain newlines. | |
222 | gl_awk_probe='BEGIN { if ("POSIXLY_CORRECT" in ENVIRON) print "x" }' | |
223 | case ${POSIXLY_CORRECT+x}`$AWK "$gl_awk_probe" </dev/null` in | |
224 | xx) gl_had_POSIXLY_CORRECT=exported ;; | |
225 | x) gl_had_POSIXLY_CORRECT=yes ;; | |
226 | *) gl_had_POSIXLY_CORRECT= ;; | |
227 | esac | |
228 | POSIXLY_CORRECT=1 | |
229 | export POSIXLY_CORRECT | |
230 | AC_RUN_IFELSE( | |
231 | [AC_LANG_PROGRAM([[#include <getopt.h> | |
232 | #include <stddef.h> | |
233 | #include <string.h> | |
234 | ]], [[ | |
235 | int result = 0; | |
236 | /* This code succeeds on glibc 2.8, OpenBSD 4.0, Cygwin, mingw, | |
237 | and fails on MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, | |
238 | OSF/1 5.1, Solaris 10. */ | |
239 | { | |
4a621aae PE |
240 | static char conftest[] = "conftest"; |
241 | static char plus[] = "-+"; | |
242 | char *argv[3] = { conftest, plus, NULL }; | |
e275c824 | 243 | opterr = 0; |
4a621aae | 244 | if (getopt (2, argv, "+a") != '?') |
e275c824 PE |
245 | result |= 1; |
246 | } | |
247 | /* This code succeeds on glibc 2.8, mingw, | |
248 | and fails on MacOS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, | |
249 | IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x. */ | |
250 | { | |
4a621aae PE |
251 | static char program[] = "program"; |
252 | static char p[] = "-p"; | |
253 | static char foo[] = "foo"; | |
254 | static char bar[] = "bar"; | |
255 | char *argv[] = { program, p, foo, bar, NULL }; | |
e275c824 PE |
256 | |
257 | optind = 1; | |
258 | if (getopt (4, argv, "p::") != 'p') | |
259 | result |= 2; | |
260 | else if (optarg != NULL) | |
261 | result |= 4; | |
262 | else if (getopt (4, argv, "p::") != -1) | |
263 | result |= 6; | |
264 | else if (optind != 2) | |
265 | result |= 8; | |
266 | } | |
267 | /* This code succeeds on glibc 2.8 and fails on Cygwin 1.7.0. */ | |
268 | { | |
4a621aae PE |
269 | static char program[] = "program"; |
270 | static char foo[] = "foo"; | |
271 | static char p[] = "-p"; | |
272 | char *argv[] = { program, foo, p, NULL }; | |
e275c824 PE |
273 | optind = 0; |
274 | if (getopt (3, argv, "-p") != 1) | |
275 | result |= 16; | |
276 | else if (getopt (3, argv, "-p") != 'p') | |
277 | result |= 32; | |
278 | } | |
279 | /* This code fails on glibc 2.11. */ | |
280 | { | |
4a621aae PE |
281 | static char program[] = "program"; |
282 | static char b[] = "-b"; | |
283 | static char a[] = "-a"; | |
284 | char *argv[] = { program, b, a, NULL }; | |
e275c824 PE |
285 | optind = opterr = 0; |
286 | if (getopt (3, argv, "+:a:b") != 'b') | |
287 | result |= 64; | |
288 | else if (getopt (3, argv, "+:a:b") != ':') | |
289 | result |= 64; | |
290 | } | |
4a621aae PE |
291 | /* This code dumps core on glibc 2.14. */ |
292 | { | |
293 | static char program[] = "program"; | |
294 | static char w[] = "-W"; | |
295 | static char dummy[] = "dummy"; | |
296 | char *argv[] = { program, w, dummy, NULL }; | |
297 | optind = opterr = 1; | |
298 | if (getopt (3, argv, "W;") != 'W') | |
299 | result |= 128; | |
300 | } | |
e275c824 PE |
301 | return result; |
302 | ]])], | |
303 | [gl_cv_func_getopt_gnu=yes], | |
304 | [gl_cv_func_getopt_gnu=no], | |
305 | [dnl Cross compiling. Guess based on host and declarations. | |
306 | case $host_os:$ac_cv_have_decl_optreset in | |
307 | *-gnu*:* | mingw*:*) gl_cv_func_getopt_gnu=no;; | |
308 | *:yes) gl_cv_func_getopt_gnu=no;; | |
309 | *) gl_cv_func_getopt_gnu=yes;; | |
310 | esac | |
311 | ]) | |
312 | case $gl_had_POSIXLY_CORRECT in | |
313 | exported) ;; | |
314 | yes) AS_UNSET([POSIXLY_CORRECT]); POSIXLY_CORRECT=1 ;; | |
315 | *) AS_UNSET([POSIXLY_CORRECT]) ;; | |
316 | esac | |
317 | ]) | |
318 | if test "$gl_cv_func_getopt_gnu" = "no"; then | |
319 | gl_replace_getopt=yes | |
9eff9fe3 PE |
320 | fi |
321 | fi | |
322 | ]) | |
323 | ||
e275c824 PE |
324 | # emacs' configure.in uses this. |
325 | AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER], | |
9eff9fe3 | 326 | [ |
e275c824 PE |
327 | GETOPT_H=getopt.h |
328 | AC_DEFINE([__GETOPT_PREFIX], [[rpl_]], | |
329 | [Define to rpl_ if the getopt replacement functions and variables | |
330 | should be used.]) | |
331 | AC_SUBST([GETOPT_H]) | |
9eff9fe3 PE |
332 | ]) |
333 | ||
9eff9fe3 | 334 | # Prerequisites of lib/getopt*. |
e275c824 PE |
335 | # emacs' configure.in uses this. |
336 | AC_DEFUN([gl_PREREQ_GETOPT], | |
337 | [ | |
338 | AC_CHECK_DECLS_ONCE([getenv]) | |
339 | ]) |