diff options
Diffstat (limited to 'gl/m4/std-gnu11.m4')
-rw-r--r-- | gl/m4/std-gnu11.m4 | 829 |
1 files changed, 829 insertions, 0 deletions
diff --git a/gl/m4/std-gnu11.m4 b/gl/m4/std-gnu11.m4 new file mode 100644 index 00000000..7b1a042a --- /dev/null +++ b/gl/m4/std-gnu11.m4 | |||
@@ -0,0 +1,829 @@ | |||
1 | # Prefer GNU C11 and C++11 to earlier versions. -*- coding: utf-8 -*- | ||
2 | |||
3 | # This implementation is taken from GNU Autoconf lib/autoconf/c.m4 | ||
4 | # commit 017d5ddd82854911f0119691d91ea8a1438824d6 | ||
5 | # dated Sun Apr 3 13:57:17 2016 -0700 | ||
6 | # This implementation will be obsolete once we can assume Autoconf 2.70 | ||
7 | # or later is installed everywhere a Gnulib program might be developed. | ||
8 | |||
9 | m4_version_prereq([2.70], [], [ | ||
10 | |||
11 | |||
12 | # Copyright (C) 2001-2021 Free Software Foundation, Inc. | ||
13 | |||
14 | # This program is free software; you can redistribute it and/or modify | ||
15 | # it under the terms of the GNU General Public License as published by | ||
16 | # the Free Software Foundation, either version 3 of the License, or | ||
17 | # (at your option) any later version. | ||
18 | # | ||
19 | # This program is distributed in the hope that it will be useful, | ||
20 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | # GNU General Public License for more details. | ||
23 | # | ||
24 | # You should have received a copy of the GNU General Public License | ||
25 | # along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
26 | |||
27 | # Written by David MacKenzie, with help from | ||
28 | # Akim Demaille, Paul Eggert, | ||
29 | # François Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor, | ||
30 | # Roland McGrath, Noah Friedman, david d zuhn, and many others. | ||
31 | |||
32 | |||
33 | # AC_PROG_CC([COMPILER ...]) | ||
34 | # -------------------------- | ||
35 | # COMPILER ... is a space separated list of C compilers to search for. | ||
36 | # This just gives the user an opportunity to specify an alternative | ||
37 | # search list for the C compiler. | ||
38 | AC_DEFUN_ONCE([AC_PROG_CC], | ||
39 | [AC_LANG_PUSH(C)dnl | ||
40 | AC_ARG_VAR([CC], [C compiler command])dnl | ||
41 | AC_ARG_VAR([CFLAGS], [C compiler flags])dnl | ||
42 | _AC_ARG_VAR_LDFLAGS()dnl | ||
43 | _AC_ARG_VAR_LIBS()dnl | ||
44 | _AC_ARG_VAR_CPPFLAGS()dnl | ||
45 | m4_ifval([$1], | ||
46 | [AC_CHECK_TOOLS(CC, [$1])], | ||
47 | [AC_CHECK_TOOL(CC, gcc) | ||
48 | if test -z "$CC"; then | ||
49 | dnl Here we want: | ||
50 | dnl AC_CHECK_TOOL(CC, cc) | ||
51 | dnl but without the check for a tool without the prefix. | ||
52 | dnl Until the check is removed from there, copy the code: | ||
53 | if test -n "$ac_tool_prefix"; then | ||
54 | AC_CHECK_PROG(CC, [${ac_tool_prefix}cc], [${ac_tool_prefix}cc]) | ||
55 | fi | ||
56 | fi | ||
57 | if test -z "$CC"; then | ||
58 | AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc) | ||
59 | fi | ||
60 | if test -z "$CC"; then | ||
61 | AC_CHECK_TOOLS(CC, cl.exe) | ||
62 | fi | ||
63 | if test -z "$CC"; then | ||
64 | AC_CHECK_TOOL(CC, clang) | ||
65 | fi | ||
66 | ]) | ||
67 | |||
68 | test -z "$CC" && AC_MSG_FAILURE([no acceptable C compiler found in \$PATH]) | ||
69 | |||
70 | # Provide some information about the compiler. | ||
71 | _AS_ECHO_LOG([checking for _AC_LANG compiler version]) | ||
72 | set X $ac_compile | ||
73 | ac_compiler=$[2] | ||
74 | for ac_option in --version -v -V -qversion -version; do | ||
75 | _AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD]) | ||
76 | done | ||
77 | |||
78 | m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl | ||
79 | m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl | ||
80 | _AC_LANG_COMPILER_GNU | ||
81 | if test $ac_compiler_gnu = yes; then | ||
82 | GCC=yes | ||
83 | else | ||
84 | GCC= | ||
85 | fi | ||
86 | _AC_PROG_CC_G | ||
87 | dnl | ||
88 | dnl Set ac_prog_cc_stdc to the supported C version. | ||
89 | dnl Also set the documented variable ac_cv_prog_cc_stdc; | ||
90 | dnl its name was chosen when it was cached, but it is no longer cached. | ||
91 | _AC_PROG_CC_C11([ac_prog_cc_stdc=c11 | ||
92 | ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11], | ||
93 | [_AC_PROG_CC_C99([ac_prog_cc_stdc=c99 | ||
94 | ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99], | ||
95 | [_AC_PROG_CC_C89([ac_prog_cc_stdc=c89 | ||
96 | ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89], | ||
97 | [ac_prog_cc_stdc=no | ||
98 | ac_cv_prog_cc_stdc=no])])]) | ||
99 | dnl | ||
100 | AC_LANG_POP(C)dnl | ||
101 | ])# AC_PROG_CC | ||
102 | |||
103 | |||
104 | |||
105 | # AC_PROG_CXX([LIST-OF-COMPILERS]) | ||
106 | # -------------------------------- | ||
107 | # LIST-OF-COMPILERS is a space separated list of C++ compilers to search | ||
108 | # for (if not specified, a default list is used). This just gives the | ||
109 | # user an opportunity to specify an alternative search list for the C++ | ||
110 | # compiler. | ||
111 | # aCC HP-UX C++ compiler much better than `CC', so test before. | ||
112 | # FCC Fujitsu C++ compiler | ||
113 | # KCC KAI C++ compiler | ||
114 | # RCC Rational C++ | ||
115 | # xlC_r AIX C Set++ (with support for reentrant code) | ||
116 | # xlC AIX C Set++ | ||
117 | AC_DEFUN([AC_PROG_CXX], | ||
118 | [AC_LANG_PUSH(C++)dnl | ||
119 | AC_ARG_VAR([CXX], [C++ compiler command])dnl | ||
120 | AC_ARG_VAR([CXXFLAGS], [C++ compiler flags])dnl | ||
121 | _AC_ARG_VAR_LDFLAGS()dnl | ||
122 | _AC_ARG_VAR_LIBS()dnl | ||
123 | _AC_ARG_VAR_CPPFLAGS()dnl | ||
124 | _AC_ARG_VAR_PRECIOUS([CCC])dnl | ||
125 | if test -z "$CXX"; then | ||
126 | if test -n "$CCC"; then | ||
127 | CXX=$CCC | ||
128 | else | ||
129 | AC_CHECK_TOOLS(CXX, | ||
130 | [m4_default([$1], | ||
131 | [g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++])], | ||
132 | g++) | ||
133 | fi | ||
134 | fi | ||
135 | # Provide some information about the compiler. | ||
136 | _AS_ECHO_LOG([checking for _AC_LANG compiler version]) | ||
137 | set X $ac_compile | ||
138 | ac_compiler=$[2] | ||
139 | for ac_option in --version -v -V -qversion; do | ||
140 | _AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD]) | ||
141 | done | ||
142 | |||
143 | m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl | ||
144 | m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl | ||
145 | _AC_LANG_COMPILER_GNU | ||
146 | if test $ac_compiler_gnu = yes; then | ||
147 | GXX=yes | ||
148 | else | ||
149 | GXX= | ||
150 | fi | ||
151 | _AC_PROG_CXX_G | ||
152 | _AC_PROG_CXX_CXX11([ac_prog_cxx_stdcxx=cxx11 | ||
153 | ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 | ||
154 | ac_cv_prog_cxx_cxx98=$ac_cv_prog_cxx_cxx11], | ||
155 | [_AC_PROG_CXX_CXX98([ac_prog_cxx_stdcxx=cxx98 | ||
156 | ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98], | ||
157 | [ac_prog_cxx_stdcxx=no | ||
158 | ac_cv_prog_cxx_stdcxx=no])]) | ||
159 | AC_LANG_POP(C++)dnl | ||
160 | ])# AC_PROG_CXX | ||
161 | |||
162 | |||
163 | # _AC_C_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST, | ||
164 | # ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE) | ||
165 | # -------------------------------------------------------------- | ||
166 | # Check whether the C compiler accepts features of STANDARD (e.g `c89', `c99') | ||
167 | # by trying to compile a program of TEST-PROLOGUE and TEST-BODY. If this fails, | ||
168 | # try again with each compiler option in the space-separated OPTION-LIST; if one | ||
169 | # helps, append it to CC. If eventually successful, run ACTION-IF-AVAILABLE, | ||
170 | # else ACTION-IF-UNAVAILABLE. | ||
171 | AC_DEFUN([_AC_C_STD_TRY], | ||
172 | [AC_MSG_CHECKING([for $CC option to enable ]m4_translit($1, [c], [C])[ features]) | ||
173 | AC_CACHE_VAL(ac_cv_prog_cc_$1, | ||
174 | [ac_cv_prog_cc_$1=no | ||
175 | ac_save_CC=$CC | ||
176 | AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])]) | ||
177 | for ac_arg in '' $4 | ||
178 | do | ||
179 | CC="$ac_save_CC $ac_arg" | ||
180 | _AC_COMPILE_IFELSE([], [ac_cv_prog_cc_$1=$ac_arg]) | ||
181 | test "x$ac_cv_prog_cc_$1" != "xno" && break | ||
182 | done | ||
183 | rm -f conftest.$ac_ext | ||
184 | CC=$ac_save_CC | ||
185 | ])# AC_CACHE_VAL | ||
186 | ac_prog_cc_stdc_options= | ||
187 | case "x$ac_cv_prog_cc_$1" in | ||
188 | x) | ||
189 | AC_MSG_RESULT([none needed]) ;; | ||
190 | xno) | ||
191 | AC_MSG_RESULT([unsupported]) ;; | ||
192 | *) | ||
193 | ac_prog_cc_stdc_options=" $ac_cv_prog_cc_$1" | ||
194 | CC=$CC$ac_prog_cc_stdc_options | ||
195 | AC_MSG_RESULT([$ac_cv_prog_cc_$1]) ;; | ||
196 | esac | ||
197 | AS_IF([test "x$ac_cv_prog_cc_$1" != xno], [$5], [$6]) | ||
198 | ])# _AC_C_STD_TRY | ||
199 | |||
200 | # _AC_C_C99_TEST_HEADER | ||
201 | # --------------------- | ||
202 | # A C header suitable for testing for C99. | ||
203 | AC_DEFUN([_AC_C_C99_TEST_HEADER], | ||
204 | [[#include <stdarg.h> | ||
205 | #include <stdbool.h> | ||
206 | #include <stddef.h> | ||
207 | #include <stdlib.h> | ||
208 | #include <wchar.h> | ||
209 | #include <stdio.h> | ||
210 | |||
211 | // Check varargs macros. These examples are taken from C99 6.10.3.5. | ||
212 | #define debug(...) fprintf (stderr, __VA_ARGS__) | ||
213 | #define showlist(...) puts (#__VA_ARGS__) | ||
214 | #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) | ||
215 | static void | ||
216 | test_varargs_macros (void) | ||
217 | { | ||
218 | int x = 1234; | ||
219 | int y = 5678; | ||
220 | debug ("Flag"); | ||
221 | debug ("X = %d\n", x); | ||
222 | showlist (The first, second, and third items.); | ||
223 | report (x>y, "x is %d but y is %d", x, y); | ||
224 | } | ||
225 | |||
226 | // Check long long types. | ||
227 | #define BIG64 18446744073709551615ull | ||
228 | #define BIG32 4294967295ul | ||
229 | #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) | ||
230 | #if !BIG_OK | ||
231 | your preprocessor is broken; | ||
232 | #endif | ||
233 | #if BIG_OK | ||
234 | #else | ||
235 | your preprocessor is broken; | ||
236 | #endif | ||
237 | static long long int bignum = -9223372036854775807LL; | ||
238 | static unsigned long long int ubignum = BIG64; | ||
239 | |||
240 | struct incomplete_array | ||
241 | { | ||
242 | int datasize; | ||
243 | double data[]; | ||
244 | }; | ||
245 | |||
246 | struct named_init { | ||
247 | int number; | ||
248 | const wchar_t *name; | ||
249 | double average; | ||
250 | }; | ||
251 | |||
252 | typedef const char *ccp; | ||
253 | |||
254 | static inline int | ||
255 | test_restrict (ccp restrict text) | ||
256 | { | ||
257 | // See if C++-style comments work. | ||
258 | // Iterate through items via the restricted pointer. | ||
259 | // Also check for declarations in for loops. | ||
260 | for (unsigned int i = 0; *(text+i) != '\0'; ++i) | ||
261 | continue; | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | // Check varargs and va_copy. | ||
266 | static bool | ||
267 | test_varargs (const char *format, ...) | ||
268 | { | ||
269 | va_list args; | ||
270 | va_start (args, format); | ||
271 | va_list args_copy; | ||
272 | va_copy (args_copy, args); | ||
273 | |||
274 | const char *str = ""; | ||
275 | int number = 0; | ||
276 | float fnumber = 0; | ||
277 | |||
278 | while (*format) | ||
279 | { | ||
280 | switch (*format++) | ||
281 | { | ||
282 | case 's': // string | ||
283 | str = va_arg (args_copy, const char *); | ||
284 | break; | ||
285 | case 'd': // int | ||
286 | number = va_arg (args_copy, int); | ||
287 | break; | ||
288 | case 'f': // float | ||
289 | fnumber = va_arg (args_copy, double); | ||
290 | break; | ||
291 | default: | ||
292 | break; | ||
293 | } | ||
294 | } | ||
295 | va_end (args_copy); | ||
296 | va_end (args); | ||
297 | |||
298 | return *str && number && fnumber; | ||
299 | }]])# _AC_C_C99_TEST_HEADER | ||
300 | |||
301 | # _AC_C_C99_TEST_BODY | ||
302 | # ------------------- | ||
303 | # A C body suitable for testing for C99, assuming the corresponding header. | ||
304 | AC_DEFUN([_AC_C_C99_TEST_BODY], | ||
305 | [[ | ||
306 | // Check bool. | ||
307 | _Bool success = false; | ||
308 | |||
309 | // Check restrict. | ||
310 | if (test_restrict ("String literal") == 0) | ||
311 | success = true; | ||
312 | char *restrict newvar = "Another string"; | ||
313 | |||
314 | // Check varargs. | ||
315 | success &= test_varargs ("s, d' f .", "string", 65, 34.234); | ||
316 | test_varargs_macros (); | ||
317 | |||
318 | // Check flexible array members. | ||
319 | struct incomplete_array *ia = | ||
320 | malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); | ||
321 | ia->datasize = 10; | ||
322 | for (int i = 0; i < ia->datasize; ++i) | ||
323 | ia->data[i] = i * 1.234; | ||
324 | |||
325 | // Check named initializers. | ||
326 | struct named_init ni = { | ||
327 | .number = 34, | ||
328 | .name = L"Test wide string", | ||
329 | .average = 543.34343, | ||
330 | }; | ||
331 | |||
332 | ni.number = 58; | ||
333 | |||
334 | int dynamic_array[ni.number]; | ||
335 | dynamic_array[ni.number - 1] = 543; | ||
336 | |||
337 | // work around unused variable warnings | ||
338 | return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' | ||
339 | || dynamic_array[ni.number - 1] != 543); | ||
340 | ]]) | ||
341 | |||
342 | # _AC_PROG_CC_C99 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) | ||
343 | # ---------------------------------------------------------------- | ||
344 | # If the C compiler is not in ISO C99 mode by default, try to add an | ||
345 | # option to output variable CC to make it so. This macro tries | ||
346 | # various options that select ISO C99 on some system or another. It | ||
347 | # considers the compiler to be in ISO C99 mode if it handles _Bool, | ||
348 | # // comments, flexible array members, inline, long long int, mixed | ||
349 | # code and declarations, named initialization of structs, restrict, | ||
350 | # va_copy, varargs macros, variable declarations in for loops and | ||
351 | # variable length arrays. | ||
352 | AC_DEFUN([_AC_PROG_CC_C99], | ||
353 | [_AC_C_STD_TRY([c99], | ||
354 | [_AC_C_C99_TEST_HEADER], | ||
355 | [_AC_C_C99_TEST_BODY], | ||
356 | dnl Try | ||
357 | dnl GCC -std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999) | ||
358 | dnl IBM XL C -qlanglvl=extc1x (V12.1; does not pass C11 test) | ||
359 | dnl IBM XL C -qlanglvl=extc99 | ||
360 | dnl (pre-V12.1; unused restrictive mode: -qlanglvl=stdc99) | ||
361 | dnl HP cc -AC99 | ||
362 | dnl Intel ICC -std=c99, -c99 (deprecated) | ||
363 | dnl IRIX -c99 | ||
364 | dnl Solaris -D_STDC_C99= | ||
365 | dnl cc's -xc99 option uses linker magic to define the external | ||
366 | dnl symbol __xpg4 as if by "int __xpg4 = 1;", which enables C99 | ||
367 | dnl behavior for C library functions. This is not wanted here, | ||
368 | dnl because it means that a single module compiled with -xc99 | ||
369 | dnl alters C runtime behavior for the entire program, not for | ||
370 | dnl just the module. Instead, define the (private) symbol | ||
371 | dnl _STDC_C99, which suppresses a bogus failure in <stdbool.h>. | ||
372 | dnl The resulting compiler passes the test case here, and that's | ||
373 | dnl good enough. For more, please see the thread starting at: | ||
374 | dnl https://lists.gnu.org/r/autoconf/2010-12/msg00059.html | ||
375 | dnl Tru64 -c99 | ||
376 | dnl with extended modes being tried first. | ||
377 | [[-std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc1x -qlanglvl=extc99]], [$1], [$2])[]dnl | ||
378 | ])# _AC_PROG_CC_C99 | ||
379 | |||
380 | |||
381 | # _AC_PROG_CC_C11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) | ||
382 | # ---------------------------------------------------------------- | ||
383 | # If the C compiler is not in ISO C11 mode by default, try to add an | ||
384 | # option to output variable CC to make it so. This macro tries | ||
385 | # various options that select ISO C11 on some system or another. It | ||
386 | # considers the compiler to be in ISO C11 mode if it handles _Alignas, | ||
387 | # _Alignof, _Noreturn, _Static_assert, UTF-8 string literals, | ||
388 | # duplicate typedefs, and anonymous structures and unions. | ||
389 | AC_DEFUN([_AC_PROG_CC_C11], | ||
390 | [_AC_C_STD_TRY([c11], | ||
391 | [_AC_C_C99_TEST_HEADER[ | ||
392 | // Check _Alignas. | ||
393 | char _Alignas (double) aligned_as_double; | ||
394 | char _Alignas (0) no_special_alignment; | ||
395 | extern char aligned_as_int; | ||
396 | char _Alignas (0) _Alignas (int) aligned_as_int; | ||
397 | |||
398 | // Check _Alignof. | ||
399 | enum | ||
400 | { | ||
401 | int_alignment = _Alignof (int), | ||
402 | int_array_alignment = _Alignof (int[100]), | ||
403 | char_alignment = _Alignof (char) | ||
404 | }; | ||
405 | _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); | ||
406 | |||
407 | // Check _Noreturn. | ||
408 | int _Noreturn does_not_return (void) { for (;;) continue; } | ||
409 | |||
410 | // Check _Static_assert. | ||
411 | struct test_static_assert | ||
412 | { | ||
413 | int x; | ||
414 | _Static_assert (sizeof (int) <= sizeof (long int), | ||
415 | "_Static_assert does not work in struct"); | ||
416 | long int y; | ||
417 | }; | ||
418 | |||
419 | // Check UTF-8 literals. | ||
420 | #define u8 syntax error! | ||
421 | char const utf8_literal[] = u8"happens to be ASCII" "another string"; | ||
422 | |||
423 | // Check duplicate typedefs. | ||
424 | typedef long *long_ptr; | ||
425 | typedef long int *long_ptr; | ||
426 | typedef long_ptr long_ptr; | ||
427 | |||
428 | // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. | ||
429 | struct anonymous | ||
430 | { | ||
431 | union { | ||
432 | struct { int i; int j; }; | ||
433 | struct { int k; long int l; } w; | ||
434 | }; | ||
435 | int m; | ||
436 | } v1; | ||
437 | ]], | ||
438 | [_AC_C_C99_TEST_BODY[ | ||
439 | v1.i = 2; | ||
440 | v1.w.k = 5; | ||
441 | _Static_assert ((offsetof (struct anonymous, i) | ||
442 | == offsetof (struct anonymous, w.k)), | ||
443 | "Anonymous union alignment botch"); | ||
444 | ]], | ||
445 | dnl Try | ||
446 | dnl GCC -std=gnu11 (unused restrictive mode: -std=c11) | ||
447 | dnl with extended modes being tried first. | ||
448 | dnl | ||
449 | dnl Do not try -qlanglvl=extc1x, because IBM XL C V12.1 (the latest version as | ||
450 | dnl of September 2012) does not pass the C11 test. For now, try extc1x when | ||
451 | dnl compiling the C99 test instead, since it enables _Static_assert and | ||
452 | dnl _Noreturn, which is a win. If -qlanglvl=extc11 or -qlanglvl=extc1x passes | ||
453 | dnl the C11 test in some future version of IBM XL C, we'll add it here, | ||
454 | dnl preferably extc11. | ||
455 | [[-std=gnu11]], [$1], [$2])[]dnl | ||
456 | ])# _AC_PROG_CC_C11 | ||
457 | |||
458 | |||
459 | # AC_PROG_CC_C89 | ||
460 | # -------------- | ||
461 | # Do not use AU_ALIAS here and in AC_PROG_CC_C99 and AC_PROG_CC_STDC, | ||
462 | # as that'd be incompatible with how Automake redefines AC_PROG_CC. See | ||
463 | # <https://lists.gnu.org/r/autoconf/2012-10/msg00048.html>. | ||
464 | AU_DEFUN([AC_PROG_CC_C89], | ||
465 | [AC_REQUIRE([AC_PROG_CC])], | ||
466 | [$0 is obsolete; use AC_PROG_CC] | ||
467 | ) | ||
468 | |||
469 | # AC_PROG_CC_C99 | ||
470 | # -------------- | ||
471 | AU_DEFUN([AC_PROG_CC_C99], | ||
472 | [AC_REQUIRE([AC_PROG_CC])], | ||
473 | [$0 is obsolete; use AC_PROG_CC] | ||
474 | ) | ||
475 | |||
476 | # AC_PROG_CC_STDC | ||
477 | # --------------- | ||
478 | AU_DEFUN([AC_PROG_CC_STDC], | ||
479 | [AC_REQUIRE([AC_PROG_CC])], | ||
480 | [$0 is obsolete; use AC_PROG_CC] | ||
481 | ) | ||
482 | |||
483 | |||
484 | # AC_C_PROTOTYPES | ||
485 | # --------------- | ||
486 | # Check if the C compiler supports prototypes, included if it needs | ||
487 | # options. | ||
488 | AC_DEFUN([AC_C_PROTOTYPES], | ||
489 | [AC_REQUIRE([AC_PROG_CC])dnl | ||
490 | if test "$ac_prog_cc_stdc" != no; then | ||
491 | AC_DEFINE(PROTOTYPES, 1, | ||
492 | [Define to 1 if the C compiler supports function prototypes.]) | ||
493 | AC_DEFINE(__PROTOTYPES, 1, | ||
494 | [Define like PROTOTYPES; this can be used by system headers.]) | ||
495 | fi | ||
496 | ])# AC_C_PROTOTYPES | ||
497 | |||
498 | |||
499 | # _AC_CXX_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST, | ||
500 | # ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE) | ||
501 | # ---------------------------------------------------------------- | ||
502 | # Check whether the C++ compiler accepts features of STANDARD (e.g | ||
503 | # `cxx98', `cxx11') by trying to compile a program of TEST-PROLOGUE | ||
504 | # and TEST-BODY. If this fails, try again with each compiler option | ||
505 | # in the space-separated OPTION-LIST; if one helps, append it to CXX. | ||
506 | # If eventually successful, run ACTION-IF-AVAILABLE, else | ||
507 | # ACTION-IF-UNAVAILABLE. | ||
508 | AC_DEFUN([_AC_CXX_STD_TRY], | ||
509 | [AC_MSG_CHECKING([for $CXX option to enable ]m4_translit(m4_translit($1, [x], [+]), [a-z], [A-Z])[ features]) | ||
510 | AC_LANG_PUSH(C++)dnl | ||
511 | AC_CACHE_VAL(ac_cv_prog_cxx_$1, | ||
512 | [ac_cv_prog_cxx_$1=no | ||
513 | ac_save_CXX=$CXX | ||
514 | AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])]) | ||
515 | for ac_arg in '' $4 | ||
516 | do | ||
517 | CXX="$ac_save_CXX $ac_arg" | ||
518 | _AC_COMPILE_IFELSE([], [ac_cv_prog_cxx_$1=$ac_arg]) | ||
519 | test "x$ac_cv_prog_cxx_$1" != "xno" && break | ||
520 | done | ||
521 | rm -f conftest.$ac_ext | ||
522 | CXX=$ac_save_CXX | ||
523 | ])# AC_CACHE_VAL | ||
524 | ac_prog_cxx_stdcxx_options= | ||
525 | case "x$ac_cv_prog_cxx_$1" in | ||
526 | x) | ||
527 | AC_MSG_RESULT([none needed]) ;; | ||
528 | xno) | ||
529 | AC_MSG_RESULT([unsupported]) ;; | ||
530 | *) | ||
531 | ac_prog_cxx_stdcxx_options=" $ac_cv_prog_cxx_$1" | ||
532 | CXX=$CXX$ac_prog_cxx_stdcxx_options | ||
533 | AC_MSG_RESULT([$ac_cv_prog_cxx_$1]) ;; | ||
534 | esac | ||
535 | AC_LANG_POP(C++)dnl | ||
536 | AS_IF([test "x$ac_cv_prog_cxx_$1" != xno], [$5], [$6]) | ||
537 | ])# _AC_CXX_STD_TRY | ||
538 | |||
539 | # _AC_CXX_CXX98_TEST_HEADER | ||
540 | # ------------------------- | ||
541 | # A C++ header suitable for testing for CXX98. | ||
542 | AC_DEFUN([_AC_CXX_CXX98_TEST_HEADER], | ||
543 | [[ | ||
544 | #include <algorithm> | ||
545 | #include <cstdlib> | ||
546 | #include <fstream> | ||
547 | #include <iomanip> | ||
548 | #include <iostream> | ||
549 | #include <list> | ||
550 | #include <map> | ||
551 | #include <set> | ||
552 | #include <sstream> | ||
553 | #include <stdexcept> | ||
554 | #include <string> | ||
555 | #include <utility> | ||
556 | #include <vector> | ||
557 | |||
558 | namespace test { | ||
559 | typedef std::vector<std::string> string_vec; | ||
560 | typedef std::pair<int,bool> map_value; | ||
561 | typedef std::map<std::string,map_value> map_type; | ||
562 | typedef std::set<int> set_type; | ||
563 | |||
564 | template<typename T> | ||
565 | class printer { | ||
566 | public: | ||
567 | printer(std::ostringstream& os): os(os) {} | ||
568 | void operator() (T elem) { os << elem << std::endl; } | ||
569 | private: | ||
570 | std::ostringstream& os; | ||
571 | }; | ||
572 | } | ||
573 | ]])# _AC_CXX_CXX98_TEST_HEADER | ||
574 | |||
575 | # _AC_CXX_CXX98_TEST_BODY | ||
576 | # ----------------------- | ||
577 | # A C++ body suitable for testing for CXX98, assuming the corresponding header. | ||
578 | AC_DEFUN([_AC_CXX_CXX98_TEST_BODY], | ||
579 | [[ | ||
580 | |||
581 | try { | ||
582 | // Basic string. | ||
583 | std::string teststr("ASCII text"); | ||
584 | teststr += " string"; | ||
585 | |||
586 | // Simple vector. | ||
587 | test::string_vec testvec; | ||
588 | testvec.push_back(teststr); | ||
589 | testvec.push_back("foo"); | ||
590 | testvec.push_back("bar"); | ||
591 | if (testvec.size() != 3) { | ||
592 | throw std::runtime_error("vector size is not 1"); | ||
593 | } | ||
594 | |||
595 | // Dump vector into stringstream and obtain string. | ||
596 | std::ostringstream os; | ||
597 | for (test::string_vec::const_iterator i = testvec.begin(); | ||
598 | i != testvec.end(); ++i) { | ||
599 | if (i + 1 != testvec.end()) { | ||
600 | os << teststr << '\n'; | ||
601 | } | ||
602 | } | ||
603 | // Check algorithms work. | ||
604 | std::for_each(testvec.begin(), testvec.end(), test::printer<std::string>(os)); | ||
605 | std::string os_out = os.str(); | ||
606 | |||
607 | // Test pair and map. | ||
608 | test::map_type testmap; | ||
609 | testmap.insert(std::make_pair(std::string("key"), | ||
610 | std::make_pair(53,false))); | ||
611 | |||
612 | // Test set. | ||
613 | int values[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; | ||
614 | test::set_type testset(values, values + sizeof(values)/sizeof(values[0])); | ||
615 | std::list<int> testlist(testset.begin(), testset.end()); | ||
616 | std::copy(testset.begin(), testset.end(), std::back_inserter(testlist)); | ||
617 | } catch (const std::exception& e) { | ||
618 | std::cerr << "Caught exception: " << e.what() << std::endl; | ||
619 | |||
620 | // Test fstream | ||
621 | std::ofstream of("test.txt"); | ||
622 | of << "Test ASCII text\n" << std::flush; | ||
623 | of << "N= " << std::hex << std::setw(8) << std::left << 534 << std::endl; | ||
624 | of.close(); | ||
625 | } | ||
626 | std::exit(0); | ||
627 | ]]) | ||
628 | |||
629 | # _AC_CXX_CXX11_TEST_HEADER | ||
630 | # ------------------------- | ||
631 | # A C++ header suitable for testing for CXX11. | ||
632 | AC_DEFUN([_AC_CXX_CXX11_TEST_HEADER], | ||
633 | [[ | ||
634 | #include <deque> | ||
635 | #include <functional> | ||
636 | #include <memory> | ||
637 | #include <tuple> | ||
638 | #include <array> | ||
639 | #include <regex> | ||
640 | #include <iostream> | ||
641 | |||
642 | namespace cxx11test | ||
643 | { | ||
644 | typedef std::shared_ptr<std::string> sptr; | ||
645 | typedef std::weak_ptr<std::string> wptr; | ||
646 | |||
647 | typedef std::tuple<std::string,int,double> tp; | ||
648 | typedef std::array<int, 20> int_array; | ||
649 | |||
650 | constexpr int get_val() { return 20; } | ||
651 | |||
652 | struct testinit | ||
653 | { | ||
654 | int i; | ||
655 | double d; | ||
656 | }; | ||
657 | |||
658 | class delegate { | ||
659 | public: | ||
660 | delegate(int n) : n(n) {} | ||
661 | delegate(): delegate(2354) {} | ||
662 | |||
663 | virtual int getval() { return this->n; }; | ||
664 | protected: | ||
665 | int n; | ||
666 | }; | ||
667 | |||
668 | class overridden : public delegate { | ||
669 | public: | ||
670 | overridden(int n): delegate(n) {} | ||
671 | virtual int getval() override final { return this->n * 2; } | ||
672 | }; | ||
673 | |||
674 | class nocopy { | ||
675 | public: | ||
676 | nocopy(int i): i(i) {} | ||
677 | nocopy() = default; | ||
678 | nocopy(const nocopy&) = delete; | ||
679 | nocopy & operator=(const nocopy&) = delete; | ||
680 | private: | ||
681 | int i; | ||
682 | }; | ||
683 | } | ||
684 | ]])# _AC_CXX_CXX11_TEST_HEADER | ||
685 | |||
686 | # _AC_CXX_CXX11_TEST_BODY | ||
687 | # ----------------------- | ||
688 | # A C++ body suitable for testing for CXX11, assuming the corresponding header. | ||
689 | AC_DEFUN([_AC_CXX_CXX11_TEST_BODY], | ||
690 | [[ | ||
691 | { | ||
692 | // Test auto and decltype | ||
693 | std::deque<int> d; | ||
694 | d.push_front(43); | ||
695 | d.push_front(484); | ||
696 | d.push_front(3); | ||
697 | d.push_front(844); | ||
698 | int total = 0; | ||
699 | for (auto i = d.begin(); i != d.end(); ++i) { total += *i; } | ||
700 | |||
701 | auto a1 = 6538; | ||
702 | auto a2 = 48573953.4; | ||
703 | auto a3 = "String literal"; | ||
704 | |||
705 | decltype(a2) a4 = 34895.034; | ||
706 | } | ||
707 | { | ||
708 | // Test constexpr | ||
709 | short sa[cxx11test::get_val()] = { 0 }; | ||
710 | } | ||
711 | { | ||
712 | // Test initializer lists | ||
713 | cxx11test::testinit il = { 4323, 435234.23544 }; | ||
714 | } | ||
715 | { | ||
716 | // Test range-based for and lambda | ||
717 | cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; | ||
718 | for (int &x : array) { x += 23; } | ||
719 | std::for_each(array.begin(), array.end(), [](int v1){ std::cout << v1; }); | ||
720 | } | ||
721 | { | ||
722 | using cxx11test::sptr; | ||
723 | using cxx11test::wptr; | ||
724 | |||
725 | sptr sp(new std::string("ASCII string")); | ||
726 | wptr wp(sp); | ||
727 | sptr sp2(wp); | ||
728 | } | ||
729 | { | ||
730 | cxx11test::tp tuple("test", 54, 45.53434); | ||
731 | double d = std::get<2>(tuple); | ||
732 | std::string s; | ||
733 | int i; | ||
734 | std::tie(s,i,d) = tuple; | ||
735 | } | ||
736 | { | ||
737 | static std::regex filename_regex("^_?([a-z0-9_.]+-)+[a-z0-9]+$"); | ||
738 | std::string testmatch("Test if this string matches"); | ||
739 | bool match = std::regex_search(testmatch, filename_regex); | ||
740 | } | ||
741 | { | ||
742 | cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; | ||
743 | cxx11test::int_array::size_type size = array.size(); | ||
744 | } | ||
745 | { | ||
746 | // Test constructor delegation | ||
747 | cxx11test::delegate d1; | ||
748 | cxx11test::delegate d2(); | ||
749 | cxx11test::delegate d3(45); | ||
750 | } | ||
751 | { | ||
752 | // Test override and final | ||
753 | cxx11test::overridden o1(55464); | ||
754 | } | ||
755 | { | ||
756 | // Test nullptr | ||
757 | char *c = nullptr; | ||
758 | } | ||
759 | { | ||
760 | // Test template brackets | ||
761 | std::vector<std::pair<int,char*>> v1; | ||
762 | } | ||
763 | { | ||
764 | // Unicode literals | ||
765 | char const *utf8 = u8"UTF-8 string \u2500"; | ||
766 | char16_t const *utf16 = u"UTF-8 string \u2500"; | ||
767 | char32_t const *utf32 = U"UTF-32 string \u2500"; | ||
768 | } | ||
769 | ]]) | ||
770 | |||
771 | # _AC_PROG_CXX_CXX98 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) | ||
772 | # ------------------------------------------------------------------- | ||
773 | |||
774 | # If the C++ compiler is not in ISO C++98 mode by default, try to add | ||
775 | # an option to output variable CXX to make it so. This macro tries | ||
776 | # various options that select ISO C++98 on some system or another. It | ||
777 | # considers the compiler to be in ISO C++98 mode if it handles basic | ||
778 | # features of the std namespace including: string, containers (list, | ||
779 | # map, set, vector), streams (fstreams, iostreams, stringstreams, | ||
780 | # iomanip), pair, exceptions and algorithms. | ||
781 | |||
782 | |||
783 | AC_DEFUN([_AC_PROG_CXX_CXX98], | ||
784 | [_AC_CXX_STD_TRY([cxx98], | ||
785 | [_AC_CXX_CXX98_TEST_HEADER], | ||
786 | [_AC_CXX_CXX98_TEST_BODY], | ||
787 | dnl Try | ||
788 | dnl GCC -std=gnu++98 (unused restrictive mode: -std=c++98) | ||
789 | dnl IBM XL C -qlanglvl=extended | ||
790 | dnl HP aC++ -AA | ||
791 | dnl Intel ICC -std=gnu++98 | ||
792 | dnl Solaris N/A (default) | ||
793 | dnl Tru64 N/A (default, but -std gnu could be used) | ||
794 | dnl with extended modes being tried first. | ||
795 | [[-std=gnu++98 -std=c++98 -qlanglvl=extended -AA]], [$1], [$2])[]dnl | ||
796 | ])# _AC_PROG_CXX_CXX98 | ||
797 | |||
798 | # _AC_PROG_CXX_CXX11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) | ||
799 | # ------------------------------------------------------------------- | ||
800 | # If the C++ compiler is not in ISO CXX11 mode by default, try to add | ||
801 | # an option to output variable CXX to make it so. This macro tries | ||
802 | # various options that select ISO C++11 on some system or another. It | ||
803 | # considers the compiler to be in ISO C++11 mode if it handles all the | ||
804 | # tests from the C++98 checks, plus the following: Language features | ||
805 | # (auto, constexpr, decltype, default/deleted constructors, delegate | ||
806 | # constructors, final, initializer lists, lambda functions, nullptr, | ||
807 | # override, range-based for loops, template brackets without spaces, | ||
808 | # unicode literals) and library features (array, memory (shared_ptr, | ||
809 | # weak_ptr), regex and tuple types). | ||
810 | AC_DEFUN([_AC_PROG_CXX_CXX11], | ||
811 | [_AC_CXX_STD_TRY([cxx11], | ||
812 | [_AC_CXX_CXX11_TEST_HEADER | ||
813 | _AC_CXX_CXX98_TEST_HEADER], | ||
814 | [_AC_CXX_CXX11_TEST_BODY | ||
815 | _AC_CXX_CXX98_TEST_BODY], | ||
816 | dnl Try | ||
817 | dnl GCC -std=gnu++11 (unused restrictive mode: -std=c++11) [and 0x variants] | ||
818 | dnl IBM XL C -qlanglvl=extended0x | ||
819 | dnl (pre-V12.1; unused restrictive mode: -qlanglvl=stdcxx11) | ||
820 | dnl HP aC++ -AA | ||
821 | dnl Intel ICC -std=c++11 -std=c++0x | ||
822 | dnl Solaris N/A (no support) | ||
823 | dnl Tru64 N/A (no support) | ||
824 | dnl with extended modes being tried first. | ||
825 | [[-std=gnu++11 -std=c++11 -std=gnu++0x -std=c++0x -qlanglvl=extended0x -AA]], [$1], [$2])[]dnl | ||
826 | ])# _AC_PROG_CXX_CXX11 | ||
827 | |||
828 | |||
829 | ])# m4_version_prereq | ||