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