1# getopt.m4 serial 21 2dnl Copyright (C) 2002-2006, 2008-2009 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 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. 21AC_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]) 27 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. 50AC_DEFUN([gl_GETOPT_CHECK_HEADERS], 51[ 52 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles 53 54 dnl Persuade Solaris <unistd.h> to declare optarg, optind, opterr, optopt. 55 AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) 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 BSD getopt_long uses an incompatible method to reset option processing, 70 dnl but the testsuite does not show a need to use this 'optreset' variable. 71 if false && test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then 72 AC_CHECK_DECL([optreset], [gl_replace_getopt=yes], [], 73 [#include <getopt.h>]) 74 fi 75 76 dnl mingw's getopt (in libmingwex.a) does weird things when the options 77 dnl strings starts with '+' and it's not the first call. Some internal state 78 dnl is left over from earlier calls, and neither setting optind = 0 nor 79 dnl setting optreset = 1 get rid of this internal state. 80 if test -z "$gl_replace_getopt"; then 81 AC_CACHE_CHECK([whether getopt is POSIX compatible], 82 [gl_cv_func_getopt_posix], 83 [ 84 dnl This test fails on mingw and succeeds on all other platforms. 85 AC_TRY_RUN([ 86#include <unistd.h> 87#include <stdlib.h> 88#include <string.h> 89 90/* The glibc implementation of getopt supports setting optind = 0 as a means 91 of clearing the internal state, but other implementations don't. */ 92#if (__GLIBC__ >= 2) 93# define OPTIND_MIN 0 94#else 95# define OPTIND_MIN 1 96#endif 97 98int 99main () 100{ 101 { 102 int argc = 0; 103 char *argv[10]; 104 int c; 105 106 argv[argc++] = "program"; 107 argv[argc++] = "-a"; 108 argv[argc++] = "foo"; 109 argv[argc++] = "bar"; 110 optind = OPTIND_MIN; 111 opterr = 0; 112 113 c = getopt (argc, argv, "ab"); 114 if (!(c == 'a')) 115 return 1; 116 c = getopt (argc, argv, "ab"); 117 if (!(c == -1)) 118 return 2; 119 if (!(optind == 2)) 120 return 3; 121 } 122 /* Some internal state exists at this point. */ 123 { 124 int argc = 0; 125 char *argv[10]; 126 int c; 127 128 argv[argc++] = "program"; 129 argv[argc++] = "donald"; 130 argv[argc++] = "-p"; 131 argv[argc++] = "billy"; 132 argv[argc++] = "duck"; 133 argv[argc++] = "-a"; 134 argv[argc++] = "bar"; 135 optind = OPTIND_MIN; 136 opterr = 0; 137 138 c = getopt (argc, argv, "+abp:q:"); 139 if (!(c == -1)) 140 return 4; 141 if (!(strcmp (argv[0], "program") == 0)) 142 return 5; 143 if (!(strcmp (argv[1], "donald") == 0)) 144 return 6; 145 if (!(strcmp (argv[2], "-p") == 0)) 146 return 7; 147 if (!(strcmp (argv[3], "billy") == 0)) 148 return 8; 149 if (!(strcmp (argv[4], "duck") == 0)) 150 return 9; 151 if (!(strcmp (argv[5], "-a") == 0)) 152 return 10; 153 if (!(strcmp (argv[6], "bar") == 0)) 154 return 11; 155 if (!(optind == 1)) 156 return 12; 157 } 158 159 return 0; 160} 161], 162 [gl_cv_func_getopt_posix=yes], [gl_cv_func_getopt_posix=no], 163 [case "$host_os" in 164 mingw*) gl_cv_func_getopt_posix="guessing no";; 165 *) gl_cv_func_getopt_posix="guessing yes";; 166 esac 167 ]) 168 ]) 169 case "$gl_cv_func_getopt_posix" in 170 *no) gl_replace_getopt=yes ;; 171 esac 172 fi 173 174 if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then 175 AC_CACHE_CHECK([for working GNU getopt function], [gl_cv_func_getopt_gnu], 176 [AC_RUN_IFELSE( 177 [AC_LANG_PROGRAM([[#include <getopt.h> 178 #include <stddef.h> 179 #include <string.h>]], 180 [[ 181 /* This code succeeds on glibc 2.8, OpenBSD 4.0, Cygwin, mingw, 182 and fails on MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, 183 OSF/1 5.1, Solaris 10. */ 184 { 185 char *myargv[3]; 186 myargv[0] = "conftest"; 187 myargv[1] = "-+"; 188 myargv[2] = 0; 189 opterr = 0; 190 if (getopt (2, myargv, "+a") != '?') 191 return 1; 192 } 193 /* This code succeeds on glibc 2.8, mingw, 194 and fails on MacOS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, 195 IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin. */ 196 { 197 char *argv[] = { "program", "-p", "foo", "bar" }; 198 199 optind = 1; 200 if (getopt (4, argv, "p::") != 'p') 201 return 2; 202 if (optarg != NULL) 203 return 3; 204 if (getopt (4, argv, "p::") != -1) 205 return 4; 206 if (optind != 2) 207 return 5; 208 } 209 return 0; 210 ]])], 211 [gl_cv_func_getopt_gnu=yes], 212 [gl_cv_func_getopt_gnu=no], 213 [dnl Cross compiling. Guess based on host and declarations. 214 case "$host_os" in 215 *-gnu* | mingw*) gl_cv_func_getopt_gnu=no;; 216 *) gl_cv_func_getopt_gnu=yes;; 217 esac 218 ]) 219 ]) 220 if test "$gl_cv_func_getopt_gnu" = "no"; then 221 gl_replace_getopt=yes 222 fi 223 fi 224]) 225 226# emacs' configure.in uses this. 227AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER], 228[ 229 GETOPT_H=getopt.h 230 AC_DEFINE([__GETOPT_PREFIX], [[rpl_]], 231 [Define to rpl_ if the getopt replacement functions and variables 232 should be used.]) 233 AC_SUBST([GETOPT_H]) 234]) 235 236# Prerequisites of lib/getopt*. 237# emacs' configure.in uses this. 238AC_DEFUN([gl_PREREQ_GETOPT], 239[ 240 AC_CHECK_DECLS_ONCE([getenv]) 241]) 242