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