1# getopt.m4 serial 44 2dnl Copyright (C) 2002-2006, 2008-2012 Free Software Foundation, Inc. 3dnl This file is free software; the Free Software Foundation 4dnl gives unlimited permission to copy and/or distribute it, 5dnl with or without modifications, as long as this notice is preserved. 6 7# Request a POSIX compliant getopt function. 8AC_DEFUN([gl_FUNC_GETOPT_POSIX], 9[ 10 m4_divert_text([DEFAULTS], [gl_getopt_required=POSIX]) 11 AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) 12 AC_REQUIRE([gl_GETOPT_CHECK_HEADERS]) 13 dnl Other modules can request the gnulib implementation of the getopt 14 dnl functions unconditionally, by defining gl_REPLACE_GETOPT_ALWAYS. 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 28]) 29 30# Request a POSIX compliant getopt function with GNU extensions (such as 31# options with optional arguments) and the functions getopt_long, 32# getopt_long_only. 33AC_DEFUN([gl_FUNC_GETOPT_GNU], 34[ 35 m4_divert_text([INIT_PREPARE], [gl_getopt_required=GNU]) 36 37 AC_REQUIRE([gl_FUNC_GETOPT_POSIX]) 38]) 39 40# Determine whether to replace the entire getopt facility. 41AC_DEFUN([gl_GETOPT_CHECK_HEADERS], 42[ 43 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 44 AC_REQUIRE([AC_PROG_AWK]) dnl for awk that supports ENVIRON 45 46 dnl Persuade Solaris <unistd.h> to declare optarg, optind, opterr, optopt. 47 AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) 48 49 gl_CHECK_NEXT_HEADERS([getopt.h]) 50 if test $ac_cv_header_getopt_h = yes; then 51 HAVE_GETOPT_H=1 52 else 53 HAVE_GETOPT_H=0 54 fi 55 AC_SUBST([HAVE_GETOPT_H]) 56 57 gl_replace_getopt= 58 59 dnl Test whether <getopt.h> is available. 60 if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then 61 AC_CHECK_HEADERS([getopt.h], [], [gl_replace_getopt=yes]) 62 fi 63 64 dnl Test whether the function getopt_long is available. 65 if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then 66 AC_CHECK_FUNCS([getopt_long_only], [], [gl_replace_getopt=yes]) 67 fi 68 69 dnl POSIX 2008 does not specify leading '+' behavior, but see 70 dnl http://austingroupbugs.net/view.php?id=191 for a recommendation on 71 dnl the next version of POSIX. For now, we only guarantee leading '+' 72 dnl behavior with getopt-gnu. 73 if test -z "$gl_replace_getopt"; then 74 AC_CACHE_CHECK([whether getopt is POSIX compatible], 75 [gl_cv_func_getopt_posix], 76 [ 77 dnl Merging these three different test programs into a single one 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([[ 87#include <unistd.h> 88#include <stdlib.h> 89#include <string.h> 90 91int 92main () 93{ 94 static char program[] = "program"; 95 static char a[] = "-a"; 96 static char foo[] = "foo"; 97 static char bar[] = "bar"; 98 char *argv[] = { program, a, foo, bar, NULL }; 99 int c; 100 101 c = getopt (4, argv, "ab"); 102 if (!(c == 'a')) 103 return 1; 104 c = getopt (4, argv, "ab"); 105 if (!(c == -1)) 106 return 2; 107 if (!(optind == 2)) 108 return 3; 109 return 0; 110} 111]])], 112 [gl_cv_func_getopt_posix=maybe], 113 [gl_cv_func_getopt_posix=no]) 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> 122 123int 124main () 125{ 126 static char program[] = "program"; 127 static char donald[] = "donald"; 128 static char p[] = "-p"; 129 static char billy[] = "billy"; 130 static char duck[] = "duck"; 131 static char a[] = "-a"; 132 static char bar[] = "bar"; 133 char *argv[] = { program, donald, p, billy, duck, a, bar, NULL }; 134 int c; 135 136 c = getopt (7, argv, "+abp:q:"); 137 if (!(c == -1)) 138 return 4; 139 if (!(strcmp (argv[0], "program") == 0)) 140 return 5; 141 if (!(strcmp (argv[1], "donald") == 0)) 142 return 6; 143 if (!(strcmp (argv[2], "-p") == 0)) 144 return 7; 145 if (!(strcmp (argv[3], "billy") == 0)) 146 return 8; 147 if (!(strcmp (argv[4], "duck") == 0)) 148 return 9; 149 if (!(strcmp (argv[5], "-a") == 0)) 150 return 10; 151 if (!(strcmp (argv[6], "bar") == 0)) 152 return 11; 153 if (!(optind == 1)) 154 return 12; 155 return 0; 156} 157]])], 158 [gl_cv_func_getopt_posix=maybe], 159 [gl_cv_func_getopt_posix=no]) 160 fi 161 if test $gl_cv_func_getopt_posix = maybe; then 162 dnl Detect Mac OS X 10.5, AIX 7.1, mingw bug. 163 AC_RUN_IFELSE( 164 [AC_LANG_SOURCE([[ 165#include <unistd.h> 166#include <stdlib.h> 167#include <string.h> 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; 183 return 0; 184} 185]])], 186 [gl_cv_func_getopt_posix=yes], 187 [gl_cv_func_getopt_posix=no]) 188 fi 189 else 190 case "$host_os" in 191 darwin* | aix* | mingw*) gl_cv_func_getopt_posix="guessing no";; 192 *) gl_cv_func_getopt_posix="guessing yes";; 193 esac 194 fi 195 ]) 196 case "$gl_cv_func_getopt_posix" in 197 *no) gl_replace_getopt=yes ;; 198 esac 199 fi 200 201 if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then 202 AC_CACHE_CHECK([for working GNU getopt function], [gl_cv_func_getopt_gnu], 203 [# Even with POSIXLY_CORRECT, the GNU extension of leading '-' in the 204 # optstring is necessary for programs like m4 that have POSIX-mandated 205 # semantics for supporting options interspersed with files. 206 # Also, since getopt_long is a GNU extension, we require optind=0. 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 218 export POSIXLY_CORRECT 219 AC_RUN_IFELSE( 220 [AC_LANG_PROGRAM([[#include <getopt.h> 221 #include <stddef.h> 222 #include <string.h> 223 ]GL_NOCRASH[ 224 ]], [[ 225 int result = 0; 226 227 nocrash_init(); 228 229 /* This code succeeds on glibc 2.8, OpenBSD 4.0, Cygwin, mingw, 230 and fails on Mac OS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, 231 OSF/1 5.1, Solaris 10. */ 232 { 233 static char conftest[] = "conftest"; 234 static char plus[] = "-+"; 235 char *argv[3] = { conftest, plus, NULL }; 236 opterr = 0; 237 if (getopt (2, argv, "+a") != '?') 238 result |= 1; 239 } 240 /* This code succeeds on glibc 2.8, mingw, 241 and fails on Mac OS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, 242 IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x. */ 243 { 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 }; 249 250 optind = 1; 251 if (getopt (4, argv, "p::") != 'p') 252 result |= 2; 253 else if (optarg != NULL) 254 result |= 4; 255 else if (getopt (4, argv, "p::") != -1) 256 result |= 6; 257 else if (optind != 2) 258 result |= 8; 259 } 260 /* This code succeeds on glibc 2.8 and fails on Cygwin 1.7.0. */ 261 { 262 static char program[] = "program"; 263 static char foo[] = "foo"; 264 static char p[] = "-p"; 265 char *argv[] = { program, foo, p, NULL }; 266 optind = 0; 267 if (getopt (3, argv, "-p") != 1) 268 result |= 16; 269 else if (getopt (3, argv, "-p") != 'p') 270 result |= 16; 271 } 272 /* This code fails on glibc 2.11. */ 273 { 274 static char program[] = "program"; 275 static char b[] = "-b"; 276 static char a[] = "-a"; 277 char *argv[] = { program, b, a, NULL }; 278 optind = opterr = 0; 279 if (getopt (3, argv, "+:a:b") != 'b') 280 result |= 32; 281 else if (getopt (3, argv, "+:a:b") != ':') 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; 293 } 294 return result; 295 ]])], 296 [gl_cv_func_getopt_gnu=yes], 297 [gl_cv_func_getopt_gnu=no], 298 [dnl Cross compiling. Assume the worst, even on glibc platforms. 299 gl_cv_func_getopt_gnu="guessing no" 300 ]) 301 case $gl_had_POSIXLY_CORRECT in 302 exported) ;; 303 yes) AS_UNSET([POSIXLY_CORRECT]); POSIXLY_CORRECT=1 ;; 304 *) AS_UNSET([POSIXLY_CORRECT]) ;; 305 esac 306 ]) 307 if test "$gl_cv_func_getopt_gnu" != yes; then 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 351 fi 352 fi 353]) 354 355AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER], 356[ 357 GETOPT_H=getopt.h 358 AC_DEFINE([__GETOPT_PREFIX], [[rpl_]], 359 [Define to rpl_ if the getopt replacement functions and variables 360 should be used.]) 361 AC_SUBST([GETOPT_H]) 362]) 363 364# Prerequisites of lib/getopt*. 365AC_DEFUN([gl_PREREQ_GETOPT], 366[ 367 AC_CHECK_DECLS_ONCE([getenv]) 368]) 369