Merge pull request #2046 from RincewindsHat/fix/format_string
[monitoring-plugins.git] / gl / m4 / getopt.m4
blob297722eae441b323f82311e68a514abcf491eb04
1 # getopt.m4
2 # serial 49
3 dnl Copyright (C) 2002-2006, 2008-2024 Free Software Foundation, Inc.
4 dnl This file is free software; the Free Software Foundation
5 dnl gives unlimited permission to copy and/or distribute it,
6 dnl with or without modifications, as long as this notice is preserved.
8 # Request a POSIX compliant getopt function.
9 AC_DEFUN([gl_FUNC_GETOPT_POSIX],
11   m4_divert_text([DEFAULTS], [gl_getopt_required=POSIX])
12   AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
13   AC_REQUIRE([gl_GETOPT_CHECK_HEADERS])
14   dnl Other modules can request the gnulib implementation of the getopt
15   dnl functions unconditionally, by defining gl_REPLACE_GETOPT_ALWAYS.
16   dnl argp.m4 does this.
17   m4_ifdef([gl_REPLACE_GETOPT_ALWAYS], [
18     REPLACE_GETOPT=1
19   ], [
20     REPLACE_GETOPT=0
21     if test -n "$gl_replace_getopt"; then
22       REPLACE_GETOPT=1
23     fi
24   ])
25   GL_GENERATE_GETOPT_H=false
26   GL_GENERATE_GETOPT_CDEFS_H=false
27   if test $REPLACE_GETOPT = 1; then
28     dnl Arrange for getopt.h to be created.
29     gl_GETOPT_SUBSTITUTE_HEADER
30   fi
33 # Request a POSIX compliant getopt function with GNU extensions (such as
34 # options with optional arguments) and the functions getopt_long,
35 # getopt_long_only.
36 AC_DEFUN([gl_FUNC_GETOPT_GNU],
38   dnl Set the variable gl_getopt_required, so that all invocations of
39   dnl gl_GETOPT_CHECK_HEADERS in the scope of the current configure file
40   dnl will check for getopt with GNU extensions.
41   dnl This means that if one gnulib-tool invocation requests getopt-posix
42   dnl and another gnulib-tool invocation requests getopt-gnu, it is as if
43   dnl both had requested getopt-gnu.
44   m4_divert_text([INIT_PREPARE], [gl_getopt_required=GNU])
46   dnl No need to invoke gl_FUNC_GETOPT_POSIX here; this is automatically
47   dnl done through the module dependency getopt-gnu -> getopt-posix.
50 # Determine whether to replace the entire getopt facility.
51 AC_DEFUN([gl_GETOPT_CHECK_HEADERS],
53   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
54   AC_REQUIRE([AC_PROG_AWK]) dnl for awk that supports ENVIRON
56   dnl Persuade Solaris <unistd.h> to declare optarg, optind, opterr, optopt.
57   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
59   gl_CHECK_NEXT_HEADERS([getopt.h])
60   if test $ac_cv_header_getopt_h = yes; then
61     HAVE_GETOPT_H=1
62   else
63     HAVE_GETOPT_H=0
64   fi
65   AC_SUBST([HAVE_GETOPT_H])
67   gl_replace_getopt=
69   dnl Test whether <getopt.h> is available.
70   if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then
71     AC_CHECK_HEADERS([getopt.h], [], [gl_replace_getopt=yes])
72   fi
74   dnl Test whether the function getopt_long is available.
75   if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then
76     AC_CHECK_FUNCS([getopt_long_only], [], [gl_replace_getopt=yes])
77   fi
79   dnl POSIX 2008 does not specify leading '+' behavior, but see
80   dnl http://austingroupbugs.net/view.php?id=191 for a recommendation on
81   dnl the next version of POSIX.  For now, we only guarantee leading '+'
82   dnl behavior with getopt-gnu.
83   if test -z "$gl_replace_getopt"; then
84     AC_CACHE_CHECK([whether getopt is POSIX compatible],
85       [gl_cv_func_getopt_posix],
86       [
87         dnl Merging these three different test programs into a single one
88         dnl would require a reset mechanism. On BSD systems, it can be done
89         dnl through 'optreset'; on some others (glibc), it can be done by
90         dnl setting 'optind' to 0; on others again (HP-UX, IRIX, OSF/1,
91         dnl Solaris 9, musl libc), there is no such mechanism.
92         if test $cross_compiling = no; then
93           dnl Sanity check. Succeeds everywhere (except on MSVC,
94           dnl which lacks <unistd.h> and getopt() entirely).
95           AC_RUN_IFELSE(
96             [AC_LANG_SOURCE([[
97 #include <unistd.h>
98 #include <stdlib.h>
99 #include <string.h>
102 main ()
104   static char program[] = "program";
105   static char a[] = "-a";
106   static char foo[] = "foo";
107   static char bar[] = "bar";
108   char *argv[] = { program, a, foo, bar, NULL };
109   int c;
111   c = getopt (4, argv, "ab");
112   if (!(c == 'a'))
113     return 1;
114   c = getopt (4, argv, "ab");
115   if (!(c == -1))
116     return 2;
117   if (!(optind == 2))
118     return 3;
119   return 0;
121 ]])],
122             [gl_cv_func_getopt_posix=maybe],
123             [gl_cv_func_getopt_posix=no])
124           if test $gl_cv_func_getopt_posix = maybe; then
125             dnl Sanity check with '+'. Succeeds everywhere (except on MSVC,
126             dnl which lacks <unistd.h> and getopt() entirely).
127             AC_RUN_IFELSE(
128               [AC_LANG_SOURCE([[
129 #include <unistd.h>
130 #include <stdlib.h>
131 #include <string.h>
134 main ()
136   static char program[] = "program";
137   static char donald[] = "donald";
138   static char p[] = "-p";
139   static char billy[] = "billy";
140   static char duck[] = "duck";
141   static char a[] = "-a";
142   static char bar[] = "bar";
143   char *argv[] = { program, donald, p, billy, duck, a, bar, NULL };
144   int c;
146   c = getopt (7, argv, "+abp:q:");
147   if (!(c == -1))
148     return 4;
149   if (!(strcmp (argv[0], "program") == 0))
150     return 5;
151   if (!(strcmp (argv[1], "donald") == 0))
152     return 6;
153   if (!(strcmp (argv[2], "-p") == 0))
154     return 7;
155   if (!(strcmp (argv[3], "billy") == 0))
156     return 8;
157   if (!(strcmp (argv[4], "duck") == 0))
158     return 9;
159   if (!(strcmp (argv[5], "-a") == 0))
160     return 10;
161   if (!(strcmp (argv[6], "bar") == 0))
162     return 11;
163   if (!(optind == 1))
164     return 12;
165   return 0;
167 ]])],
168               [gl_cv_func_getopt_posix=maybe],
169               [gl_cv_func_getopt_posix=no])
170           fi
171           if test $gl_cv_func_getopt_posix = maybe; then
172             dnl Detect Mac OS X 10.5, AIX 7.1, mingw bug.
173             AC_RUN_IFELSE(
174               [AC_LANG_SOURCE([[
175 #include <unistd.h>
176 #include <stdlib.h>
177 #include <string.h>
180 main ()
182   static char program[] = "program";
183   static char ab[] = "-ab";
184   char *argv[3] = { program, ab, NULL };
185   if (getopt (2, argv, "ab:") != 'a')
186     return 13;
187   if (getopt (2, argv, "ab:") != '?')
188     return 14;
189   if (optopt != 'b')
190     return 15;
191   if (optind != 2)
192     return 16;
193   return 0;
195 ]])],
196               [gl_cv_func_getopt_posix=yes],
197               [gl_cv_func_getopt_posix=no])
198           fi
199         else
200           case "$host_os" in
201             darwin* | aix* | mingw* | windows*) gl_cv_func_getopt_posix="guessing no";;
202             *)                                  gl_cv_func_getopt_posix="guessing yes";;
203           esac
204         fi
205       ])
206     case "$gl_cv_func_getopt_posix" in
207       *no) gl_replace_getopt=yes ;;
208     esac
209   fi
211   if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then
212     AC_CACHE_CHECK([for working GNU getopt function], [gl_cv_func_getopt_gnu],
213       [# Even with POSIXLY_CORRECT, the GNU extension of leading '-' in the
214        # optstring is necessary for programs like m4 that have POSIX-mandated
215        # semantics for supporting options interspersed with files.
216        # Also, since getopt_long is a GNU extension, we require optind=0.
217        # Bash ties 'set -o posix' to a non-exported POSIXLY_CORRECT;
218        # so take care to revert to the correct (non-)export state.
219 dnl GNU Coding Standards currently allow awk but not env; besides, env
220 dnl is ambiguous with environment values that contain newlines.
221        gl_awk_probe='BEGIN { if ("POSIXLY_CORRECT" in ENVIRON) print "x" }'
222        case ${POSIXLY_CORRECT+x}`$AWK "$gl_awk_probe" </dev/null` in
223          xx) gl_had_POSIXLY_CORRECT=exported ;;
224          x)  gl_had_POSIXLY_CORRECT=yes      ;;
225          *)  gl_had_POSIXLY_CORRECT=         ;;
226        esac
227        POSIXLY_CORRECT=1
228        export POSIXLY_CORRECT
229        AC_RUN_IFELSE(
230         [AC_LANG_PROGRAM([[#include <getopt.h>
231                            #include <stddef.h>
232                            #include <string.h>
233            ]GL_NOCRASH[
234            ]], [[
235              int result = 0;
237              nocrash_init();
239              /* This code succeeds on glibc 2.8, OpenBSD 4.0, Cygwin, mingw,
240                 and fails on Mac OS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5,
241                 OSF/1 5.1, Solaris 10.  */
242              {
243                static char conftest[] = "conftest";
244                static char plus[] = "-+";
245                char *argv[3] = { conftest, plus, NULL };
246                opterr = 0;
247                if (getopt (2, argv, "+a") != '?')
248                  result |= 1;
249              }
250              /* This code succeeds on glibc 2.8, mingw,
251                 and fails on Mac OS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11,
252                 IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x.  */
253              {
254                static char program[] = "program";
255                static char p[] = "-p";
256                static char foo[] = "foo";
257                static char bar[] = "bar";
258                char *argv[] = { program, p, foo, bar, NULL };
260                optind = 1;
261                if (getopt (4, argv, "p::") != 'p')
262                  result |= 2;
263                else if (optarg != NULL)
264                  result |= 4;
265                else if (getopt (4, argv, "p::") != -1)
266                  result |= 6;
267                else if (optind != 2)
268                  result |= 8;
269              }
270              /* This code succeeds on glibc 2.8 and fails on Cygwin 1.7.0.  */
271              {
272                static char program[] = "program";
273                static char foo[] = "foo";
274                static char p[] = "-p";
275                char *argv[] = { program, foo, p, NULL };
276                optind = 0;
277                if (getopt (3, argv, "-p") != 1)
278                  result |= 16;
279                else if (getopt (3, argv, "-p") != 'p')
280                  result |= 16;
281              }
282              /* This code fails on glibc 2.11.  */
283              {
284                static char program[] = "program";
285                static char b[] = "-b";
286                static char a[] = "-a";
287                char *argv[] = { program, b, a, NULL };
288                optind = opterr = 0;
289                if (getopt (3, argv, "+:a:b") != 'b')
290                  result |= 32;
291                else if (getopt (3, argv, "+:a:b") != ':')
292                  result |= 32;
293              }
294              /* This code dumps core on glibc 2.14.  */
295              {
296                static char program[] = "program";
297                static char w[] = "-W";
298                static char dummy[] = "dummy";
299                char *argv[] = { program, w, dummy, NULL };
300                optind = opterr = 1;
301                if (getopt (3, argv, "W;") != 'W')
302                  result |= 64;
303              }
304              return result;
305            ]])],
306         [gl_cv_func_getopt_gnu=yes],
307         [gl_cv_func_getopt_gnu=no],
308         [dnl Cross compiling.
309          dnl Assume the worst, even on glibc platforms.
310          dnl But obey --enable-cross-guesses.
311          gl_cv_func_getopt_gnu="$gl_cross_guess_normal"
312         ])
313        case $gl_had_POSIXLY_CORRECT in
314          exported) ;;
315          yes) AS_UNSET([POSIXLY_CORRECT]); POSIXLY_CORRECT=1 ;;
316          *) AS_UNSET([POSIXLY_CORRECT]) ;;
317        esac
318       ])
319     if test "$gl_cv_func_getopt_gnu" != yes; then
320       gl_replace_getopt=yes
321     else
322       AC_CACHE_CHECK([for working GNU getopt_long function],
323         [gl_cv_func_getopt_long_gnu],
324         [AC_RUN_IFELSE(
325            [AC_LANG_PROGRAM(
326               [[#include <getopt.h>
327                 #include <stddef.h>
328                 #include <string.h>
329               ]],
330               [[static const struct option long_options[] =
331                   {
332                     { "xtremely-",no_argument,       NULL, 1003 },
333                     { "xtra",     no_argument,       NULL, 1001 },
334                     { "xtreme",   no_argument,       NULL, 1002 },
335                     { "xtremely", no_argument,       NULL, 1003 },
336                     { NULL,       0,                 NULL, 0 }
337                   };
338                 /* This code fails on OpenBSD 5.0.  */
339                 {
340                   static char program[] = "program";
341                   static char xtremel[] = "--xtremel";
342                   char *argv[] = { program, xtremel, NULL };
343                   int option_index;
344                   optind = 1; opterr = 0;
345                   if (getopt_long (2, argv, "", long_options, &option_index) != 1003)
346                     return 1;
347                 }
348                 return 0;
349               ]])],
350            [gl_cv_func_getopt_long_gnu=yes],
351            [gl_cv_func_getopt_long_gnu=no],
352            [dnl Cross compiling. Guess no on OpenBSD, yes otherwise.
353             case "$host_os" in
354               openbsd*) gl_cv_func_getopt_long_gnu="guessing no";;
355               *)        gl_cv_func_getopt_long_gnu="guessing yes";;
356             esac
357            ])
358         ])
359       case "$gl_cv_func_getopt_long_gnu" in
360         *yes) ;;
361         *) gl_replace_getopt=yes ;;
362       esac
363     fi
364   fi
367 AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER],
369   AC_CHECK_HEADERS_ONCE([sys/cdefs.h])
370   if test $ac_cv_header_sys_cdefs_h = yes; then
371     HAVE_SYS_CDEFS_H=1
372   else
373     HAVE_SYS_CDEFS_H=0
374   fi
375   AC_SUBST([HAVE_SYS_CDEFS_H])
377   AC_DEFINE([__GETOPT_PREFIX], [[rpl_]],
378     [Define to rpl_ if the getopt replacement functions and variables
379      should be used.])
380   GL_GENERATE_GETOPT_H=true
381   GL_GENERATE_GETOPT_CDEFS_H=true