Commit | Line | Data |
---|---|---|
8aeb5be9 | 1 | # getopt.m4 serial 35 |
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 | [ | |
d6974efa PE |
92 | dnl BSD getopt_long uses an incompatible method to reset |
93 | dnl option processing. Existence of the variable, in and of | |
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. | |
100 | AC_COMPILE_IFELSE( | |
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 | { | |
124 | int argc = 0; | |
125 | char *argv[10]; | |
126 | int c; | |
127 | ||
128 | argv[argc++] = "program"; | |
129 | argv[argc++] = "-a"; | |
130 | argv[argc++] = "foo"; | |
131 | argv[argc++] = "bar"; | |
132 | argv[argc] = NULL; | |
133 | optind = OPTIND_MIN; | |
134 | opterr = 0; | |
135 | ||
136 | c = getopt (argc, argv, "ab"); | |
137 | if (!(c == 'a')) | |
138 | return 1; | |
139 | c = getopt (argc, argv, "ab"); | |
140 | if (!(c == -1)) | |
141 | return 2; | |
142 | if (!(optind == 2)) | |
143 | return 3; | |
144 | } | |
145 | /* Some internal state exists at this point. */ | |
146 | { | |
147 | int argc = 0; | |
148 | char *argv[10]; | |
149 | int c; | |
150 | ||
151 | argv[argc++] = "program"; | |
152 | argv[argc++] = "donald"; | |
153 | argv[argc++] = "-p"; | |
154 | argv[argc++] = "billy"; | |
155 | argv[argc++] = "duck"; | |
156 | argv[argc++] = "-a"; | |
157 | argv[argc++] = "bar"; | |
158 | argv[argc] = NULL; | |
159 | optind = OPTIND_MIN; | |
160 | opterr = 0; | |
161 | ||
162 | c = getopt (argc, argv, "+abp:q:"); | |
163 | if (!(c == -1)) | |
164 | return 4; | |
165 | if (!(strcmp (argv[0], "program") == 0)) | |
166 | return 5; | |
167 | if (!(strcmp (argv[1], "donald") == 0)) | |
168 | return 6; | |
169 | if (!(strcmp (argv[2], "-p") == 0)) | |
170 | return 7; | |
171 | if (!(strcmp (argv[3], "billy") == 0)) | |
172 | return 8; | |
173 | if (!(strcmp (argv[4], "duck") == 0)) | |
174 | return 9; | |
175 | if (!(strcmp (argv[5], "-a") == 0)) | |
176 | return 10; | |
177 | if (!(strcmp (argv[6], "bar") == 0)) | |
178 | return 11; | |
179 | if (!(optind == 1)) | |
180 | return 12; | |
181 | } | |
182 | /* Detect MacOS 10.5, AIX 7.1 bug. */ | |
183 | { | |
184 | char *argv[3] = { "program", "-ab", NULL }; | |
185 | optind = OPTIND_MIN; | |
186 | opterr = 0; | |
187 | if (getopt (2, argv, "ab:") != 'a') | |
188 | return 13; | |
189 | if (getopt (2, argv, "ab:") != '?') | |
190 | return 14; | |
191 | if (optopt != 'b') | |
192 | return 15; | |
193 | if (optind != 2) | |
194 | return 16; | |
195 | } | |
196 | ||
197 | return 0; | |
198 | } | |
199 | ]])], | |
200 | [gl_cv_func_getopt_posix=yes], [gl_cv_func_getopt_posix=no], | |
201 | [case "$host_os" in | |
202 | mingw*) gl_cv_func_getopt_posix="guessing no";; | |
203 | darwin* | aix*) gl_cv_func_getopt_posix="guessing no";; | |
204 | *) gl_cv_func_getopt_posix="guessing yes";; | |
205 | esac | |
206 | ]) | |
d6974efa | 207 | CPPFLAGS=$gl_save_CPPFLAGS |
e275c824 PE |
208 | ]) |
209 | case "$gl_cv_func_getopt_posix" in | |
210 | *no) gl_replace_getopt=yes ;; | |
211 | esac | |
212 | fi | |
213 | ||
214 | if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then | |
215 | AC_CACHE_CHECK([for working GNU getopt function], [gl_cv_func_getopt_gnu], | |
216 | [# Even with POSIXLY_CORRECT, the GNU extension of leading '-' in the | |
217 | # optstring is necessary for programs like m4 that have POSIX-mandated | |
218 | # semantics for supporting options interspersed with files. | |
219 | # Also, since getopt_long is a GNU extension, we require optind=0. | |
220 | # Bash ties 'set -o posix' to a non-exported POSIXLY_CORRECT; | |
221 | # so take care to revert to the correct (non-)export state. | |
222 | dnl GNU Coding Standards currently allow awk but not env; besides, env | |
223 | dnl is ambiguous with environment values that contain newlines. | |
224 | gl_awk_probe='BEGIN { if ("POSIXLY_CORRECT" in ENVIRON) print "x" }' | |
225 | case ${POSIXLY_CORRECT+x}`$AWK "$gl_awk_probe" </dev/null` in | |
226 | xx) gl_had_POSIXLY_CORRECT=exported ;; | |
227 | x) gl_had_POSIXLY_CORRECT=yes ;; | |
228 | *) gl_had_POSIXLY_CORRECT= ;; | |
229 | esac | |
230 | POSIXLY_CORRECT=1 | |
231 | export POSIXLY_CORRECT | |
232 | AC_RUN_IFELSE( | |
233 | [AC_LANG_PROGRAM([[#include <getopt.h> | |
234 | #include <stddef.h> | |
235 | #include <string.h> | |
236 | ]], [[ | |
237 | int result = 0; | |
238 | /* This code succeeds on glibc 2.8, OpenBSD 4.0, Cygwin, mingw, | |
239 | and fails on MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, | |
240 | OSF/1 5.1, Solaris 10. */ | |
241 | { | |
242 | char *myargv[3]; | |
243 | myargv[0] = "conftest"; | |
244 | myargv[1] = "-+"; | |
245 | myargv[2] = 0; | |
246 | opterr = 0; | |
247 | if (getopt (2, myargv, "+a") != '?') | |
248 | result |= 1; | |
249 | } | |
250 | /* This code succeeds on glibc 2.8, mingw, | |
251 | and fails on MacOS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, | |
252 | IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x. */ | |
253 | { | |
254 | char *argv[] = { "program", "-p", "foo", "bar", NULL }; | |
255 | ||
256 | optind = 1; | |
257 | if (getopt (4, argv, "p::") != 'p') | |
258 | result |= 2; | |
259 | else if (optarg != NULL) | |
260 | result |= 4; | |
261 | else if (getopt (4, argv, "p::") != -1) | |
262 | result |= 6; | |
263 | else if (optind != 2) | |
264 | result |= 8; | |
265 | } | |
266 | /* This code succeeds on glibc 2.8 and fails on Cygwin 1.7.0. */ | |
267 | { | |
268 | char *argv[] = { "program", "foo", "-p", NULL }; | |
269 | optind = 0; | |
270 | if (getopt (3, argv, "-p") != 1) | |
271 | result |= 16; | |
272 | else if (getopt (3, argv, "-p") != 'p') | |
273 | result |= 32; | |
274 | } | |
275 | /* This code fails on glibc 2.11. */ | |
276 | { | |
277 | char *argv[] = { "program", "-b", "-a", NULL }; | |
278 | optind = opterr = 0; | |
279 | if (getopt (3, argv, "+:a:b") != 'b') | |
280 | result |= 64; | |
281 | else if (getopt (3, argv, "+:a:b") != ':') | |
282 | result |= 64; | |
283 | } | |
284 | return result; | |
285 | ]])], | |
286 | [gl_cv_func_getopt_gnu=yes], | |
287 | [gl_cv_func_getopt_gnu=no], | |
288 | [dnl Cross compiling. Guess based on host and declarations. | |
289 | case $host_os:$ac_cv_have_decl_optreset in | |
290 | *-gnu*:* | mingw*:*) gl_cv_func_getopt_gnu=no;; | |
291 | *:yes) gl_cv_func_getopt_gnu=no;; | |
292 | *) gl_cv_func_getopt_gnu=yes;; | |
293 | esac | |
294 | ]) | |
295 | case $gl_had_POSIXLY_CORRECT in | |
296 | exported) ;; | |
297 | yes) AS_UNSET([POSIXLY_CORRECT]); POSIXLY_CORRECT=1 ;; | |
298 | *) AS_UNSET([POSIXLY_CORRECT]) ;; | |
299 | esac | |
300 | ]) | |
301 | if test "$gl_cv_func_getopt_gnu" = "no"; then | |
302 | gl_replace_getopt=yes | |
9eff9fe3 PE |
303 | fi |
304 | fi | |
305 | ]) | |
306 | ||
e275c824 PE |
307 | # emacs' configure.in uses this. |
308 | AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER], | |
9eff9fe3 | 309 | [ |
e275c824 PE |
310 | GETOPT_H=getopt.h |
311 | AC_DEFINE([__GETOPT_PREFIX], [[rpl_]], | |
312 | [Define to rpl_ if the getopt replacement functions and variables | |
313 | should be used.]) | |
314 | AC_SUBST([GETOPT_H]) | |
9eff9fe3 PE |
315 | ]) |
316 | ||
9eff9fe3 | 317 | # Prerequisites of lib/getopt*. |
e275c824 PE |
318 | # emacs' configure.in uses this. |
319 | AC_DEFUN([gl_PREREQ_GETOPT], | |
320 | [ | |
321 | AC_CHECK_DECLS_ONCE([getenv]) | |
322 | ]) |