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