Blame m4/c99-backport.m4

Packit 4e8bc4
# AC_PROG_CC_C99 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])
Packit 4e8bc4
# ----------------------------------------------------------------
Packit 4e8bc4
# If the C compiler is not in ISO C99 mode by default, try to add an
Packit 4e8bc4
# option to output variable CC to make it so.  This macro tries
Packit 4e8bc4
# various options that select ISO C99 on some system or another.  It
Packit 4e8bc4
# considers the compiler to be in ISO C99 mode if it handles _Bool,
Packit 4e8bc4
# // comments, flexible array members, inline, long long int, mixed
Packit 4e8bc4
# code and declarations, named initialization of structs, restrict,
Packit 4e8bc4
# va_copy, varargs macros, variable declarations in for loops and
Packit 4e8bc4
# variable length arrays.
Packit 4e8bc4
AC_DEFUN([AC_PROG_CC_C99],
Packit 4e8bc4
[AC_C_STD_TRY([c99],
Packit 4e8bc4
[[#include <stdarg.h>
Packit 4e8bc4
#include <stdbool.h>
Packit 4e8bc4
#include <stdlib.h>
Packit 4e8bc4
#include <wchar.h>
Packit 4e8bc4
#include <stdio.h>
Packit 4e8bc4
Packit 4e8bc4
// Check varargs macros.  These examples are taken from C99 6.10.3.5.
Packit 4e8bc4
#define debug(...) fprintf (stderr, __VA_ARGS__)
Packit 4e8bc4
#define showlist(...) puts (#__VA_ARGS__)
Packit 4e8bc4
#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
Packit 4e8bc4
static void
Packit 4e8bc4
test_varargs_macros (void)
Packit 4e8bc4
{
Packit 4e8bc4
  int x = 1234;
Packit 4e8bc4
  int y = 5678;
Packit 4e8bc4
  debug ("Flag");
Packit 4e8bc4
  debug ("X = %d\n", x);
Packit 4e8bc4
  showlist (The first, second, and third items.);
Packit 4e8bc4
  report (x>y, "x is %d but y is %d", x, y);
Packit 4e8bc4
}
Packit 4e8bc4
Packit 4e8bc4
// Check long long types.
Packit 4e8bc4
#define BIG64 18446744073709551615ull
Packit 4e8bc4
#define BIG32 4294967295ul
Packit 4e8bc4
#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
Packit 4e8bc4
#if !BIG_OK
Packit 4e8bc4
  your preprocessor is broken;
Packit 4e8bc4
#endif
Packit 4e8bc4
#if BIG_OK
Packit 4e8bc4
#else
Packit 4e8bc4
  your preprocessor is broken;
Packit 4e8bc4
#endif
Packit 4e8bc4
static long long int bignum = -9223372036854775807LL;
Packit 4e8bc4
static unsigned long long int ubignum = BIG64;
Packit 4e8bc4
Packit 4e8bc4
struct incomplete_array
Packit 4e8bc4
{
Packit 4e8bc4
  int datasize;
Packit 4e8bc4
  double data[];
Packit 4e8bc4
};
Packit 4e8bc4
Packit 4e8bc4
struct named_init {
Packit 4e8bc4
  int number;
Packit 4e8bc4
  const wchar_t *name;
Packit 4e8bc4
  double average;
Packit 4e8bc4
};
Packit 4e8bc4
Packit 4e8bc4
typedef const char *ccp;
Packit 4e8bc4
Packit 4e8bc4
static inline int
Packit 4e8bc4
test_restrict (ccp restrict text)
Packit 4e8bc4
{
Packit 4e8bc4
  // See if C++-style comments work.
Packit 4e8bc4
  // Iterate through items via the restricted pointer.
Packit 4e8bc4
  // Also check for declarations in for loops.
Packit 4e8bc4
  for (unsigned int i = 0; *(text+i) != '\0'; ++i)
Packit 4e8bc4
    continue;
Packit 4e8bc4
  return 0;
Packit 4e8bc4
}
Packit 4e8bc4
Packit 4e8bc4
// Check varargs and va_copy.
Packit 4e8bc4
static void
Packit 4e8bc4
test_varargs (const char *format, ...)
Packit 4e8bc4
{
Packit 4e8bc4
  va_list args;
Packit 4e8bc4
  va_start (args, format);
Packit 4e8bc4
  va_list args_copy;
Packit 4e8bc4
  va_copy (args_copy, args);
Packit 4e8bc4
Packit 4e8bc4
  const char *str;
Packit 4e8bc4
  int number;
Packit 4e8bc4
  float fnumber;
Packit 4e8bc4
Packit 4e8bc4
  while (*format)
Packit 4e8bc4
    {
Packit 4e8bc4
      switch (*format++)
Packit 4e8bc4
	{
Packit 4e8bc4
	case 's': // string
Packit 4e8bc4
	  str = va_arg (args_copy, const char *);
Packit 4e8bc4
	  break;
Packit 4e8bc4
	case 'd': // int
Packit 4e8bc4
	  number = va_arg (args_copy, int);
Packit 4e8bc4
	  break;
Packit 4e8bc4
	case 'f': // float
Packit 4e8bc4
	  fnumber = va_arg (args_copy, double);
Packit 4e8bc4
	  break;
Packit 4e8bc4
	default:
Packit 4e8bc4
	  break;
Packit 4e8bc4
	}
Packit 4e8bc4
    }
Packit 4e8bc4
  va_end (args_copy);
Packit 4e8bc4
  va_end (args);
Packit 4e8bc4
}
Packit 4e8bc4
]],
Packit 4e8bc4
[[
Packit 4e8bc4
  // Check bool.
Packit 4e8bc4
  _Bool success = false;
Packit 4e8bc4
Packit 4e8bc4
  // Check restrict.
Packit 4e8bc4
  if (test_restrict ("String literal") == 0)
Packit 4e8bc4
    success = true;
Packit 4e8bc4
  char *restrict newvar = "Another string";
Packit 4e8bc4
Packit 4e8bc4
  // Check varargs.
Packit 4e8bc4
  test_varargs ("s, d' f .", "string", 65, 34.234);
Packit 4e8bc4
  test_varargs_macros ();
Packit 4e8bc4
Packit 4e8bc4
  // Check flexible array members.
Packit 4e8bc4
  struct incomplete_array *ia =
Packit 4e8bc4
    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
Packit 4e8bc4
  ia->datasize = 10;
Packit 4e8bc4
  for (int i = 0; i < ia->datasize; ++i)
Packit 4e8bc4
    ia->data[i] = i * 1.234;
Packit 4e8bc4
Packit 4e8bc4
  // Check named initializers.
Packit 4e8bc4
  struct named_init ni = {
Packit 4e8bc4
    .number = 34,
Packit 4e8bc4
    .name = L"Test wide string",
Packit 4e8bc4
    .average = 543.34343,
Packit 4e8bc4
  };
Packit 4e8bc4
Packit 4e8bc4
  ni.number = 58;
Packit 4e8bc4
Packit 4e8bc4
  int dynamic_array[ni.number];
Packit 4e8bc4
  dynamic_array[ni.number - 1] = 543;
Packit 4e8bc4
Packit 4e8bc4
  // work around unused variable warnings
Packit 4e8bc4
  return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
Packit 4e8bc4
	  || dynamic_array[ni.number - 1] != 543);
Packit 4e8bc4
]],
Packit 4e8bc4
dnl Try
Packit 4e8bc4
dnl GCC		-std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999)
Packit 4e8bc4
dnl AIX		-qlanglvl=extc99 (unused restrictive mode: -qlanglvl=stdc99)
Packit 4e8bc4
dnl Intel ICC	-c99
Packit 4e8bc4
dnl IRIX	-c99
Packit 4e8bc4
dnl Solaris	(unused because it causes the compiler to assume C99 semantics for
Packit 4e8bc4
dnl		library functions, and this is invalid before Solaris 10: -xc99)
Packit 4e8bc4
dnl Tru64	-c99
Packit 4e8bc4
dnl with extended modes being tried first.
Packit 4e8bc4
[[-std=gnu99 -c99 -qlanglvl=extc99]], [$1], [$2])[]dnl
Packit 4e8bc4
])# AC_PROG_CC_C99
Packit 4e8bc4
Packit 4e8bc4
# AC_C_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST,
Packit 4e8bc4
#		ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE)
Packit 4e8bc4
# --------------------------------------------------------------
Packit 4e8bc4
# Check whether the C compiler accepts features of STANDARD (e.g `c89', `c99')
Packit 4e8bc4
# by trying to compile a program of TEST-PROLOGUE and TEST-BODY.  If this fails,
Packit 4e8bc4
# try again with each compiler option in the space-separated OPTION-LIST; if one
Packit 4e8bc4
# helps, append it to CC.  If eventually successful, run ACTION-IF-AVAILABLE,
Packit 4e8bc4
# else ACTION-IF-UNAVAILABLE.
Packit 4e8bc4
AC_DEFUN([AC_C_STD_TRY],
Packit 4e8bc4
[AC_MSG_CHECKING([for $CC option to accept ISO ]m4_translit($1, [c], [C]))
Packit 4e8bc4
AC_CACHE_VAL(ac_cv_prog_cc_$1,
Packit 4e8bc4
[ac_cv_prog_cc_$1=no
Packit 4e8bc4
ac_save_CC=$CC
Packit 4e8bc4
AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])
Packit 4e8bc4
for ac_arg in '' $4
Packit 4e8bc4
do
Packit 4e8bc4
  CC="$ac_save_CC $ac_arg"
Packit 4e8bc4
  _AC_COMPILE_IFELSE([], [ac_cv_prog_cc_$1=$ac_arg])
Packit 4e8bc4
  test "x$ac_cv_prog_cc_$1" != "xno" && break
Packit 4e8bc4
done
Packit 4e8bc4
rm -f conftest.$ac_ext
Packit 4e8bc4
CC=$ac_save_CC
Packit 4e8bc4
])# AC_CACHE_VAL
Packit 4e8bc4
case "x$ac_cv_prog_cc_$1" in
Packit 4e8bc4
  x)
Packit 4e8bc4
    AC_MSG_RESULT([none needed]) ;;
Packit 4e8bc4
  xno)
Packit 4e8bc4
    AC_MSG_RESULT([unsupported]) ;;
Packit 4e8bc4
  *)
Packit 4e8bc4
    CC="$CC $ac_cv_prog_cc_$1"
Packit 4e8bc4
    AC_MSG_RESULT([$ac_cv_prog_cc_$1]) ;;
Packit 4e8bc4
esac
Packit 4e8bc4
AS_IF([test "x$ac_cv_prog_cc_$1" != xno], [$5], [$6])
Packit 4e8bc4
])# AC_C_STD_TRY