dnl CF_SRAND version: 23 updated: 2024/07/16 16:35:55
dnl --------
dnl Check for functions similar to srand() and rand().  lrand48() and random()
dnl return a 31-bit value, while rand() returns a value less than RAND_MAX
dnl which usually is only 16-bits.
dnl
dnl $1 = optional prefix for resulting shell variables.  The default "my_"
dnl      gives $my_srand and $my_rand to the caller, as well as MY_RAND_MAX.
dnl      These are all AC_SUBST'd and AC_DEFINE'd.
dnl $2 = default for the arc4random option
AC_DEFUN([CF_SRAND],[
AC_CHECK_HEADERS(limits.h)

AC_MSG_CHECKING(if you want to use arc4random)
AC_ARG_ENABLE(arc4random,
	[  --enable-arc4random     enable arc4random if available],
	[enable_arc4random=yes],
	[enable_arc4random=ifelse($2,,yes,$2)])
AC_MSG_RESULT($enable_arc4random)

cf_srand_arc4random=
if test "$enable_arc4random" = yes ; then
	AC_CHECK_FUNC(arc4random,,[AC_CHECK_LIB(bsd,arc4random,CF_ADD_LIB(bsd))])
	test "$ac_cv_func_arc4random" = yes && cf_srand_arc4random=arc4random_stir/arc4random
fi

AC_CACHE_CHECK(for random-integer functions, cf_cv_srand_func,[
cf_cv_srand_func=unknown
for cf_func in $cf_srand_arc4random srandom/random srand48/lrand48 srand/rand
do
	CF_SRAND_PARSE($cf_func,cf_srand_func,cf_rand_func)

AC_TRY_LINK([
$ac_includes_default
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
],[long seed = 1; $cf_srand_func(seed); seed = $cf_rand_func(); (void)seed],
[cf_cv_srand_func=$cf_func
 break])
done
])
if test "$cf_cv_srand_func" != unknown ; then
	AC_CACHE_CHECK(for range of random-integers, cf_cv_rand_max,[
		case "$cf_cv_srand_func" in
		(srand/rand)
			cf_cv_rand_max=RAND_MAX
			cf_rand_max=16
			;;
		(*/arc4random)
			cf_cv_rand_max=0xFFFFFFFFUL
			cf_rand_max=32
			;;
		(*)
			cf_cv_rand_max=INT_MAX
			cf_rand_max=31
			;;
		esac
		AC_TRY_COMPILE([
$ac_includes_default
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
		],[long x = $cf_cv_rand_max; (void)x],,
		[cf_cv_rand_max="(1UL<<$cf_rand_max)-1"])
	])

	case "$cf_cv_srand_func" in
	(*/arc4random)
		AC_MSG_CHECKING(if <bsd/stdlib.h> should be included)
		AC_TRY_COMPILE([
$ac_includes_default
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#include <bsd/stdlib.h>],
					   [void *arc4random(int);
						void *x = arc4random(1); (void)x],
					   [cf_bsd_stdlib_h=no],
					   [AC_TRY_COMPILE([
$ac_includes_default
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#include <bsd/stdlib.h>],
									   [unsigned long x = arc4random(); (void)x],
									   [cf_bsd_stdlib_h=yes],
									   [cf_bsd_stdlib_h=no])])
	    AC_MSG_RESULT($cf_bsd_stdlib_h)
		if test "$cf_bsd_stdlib_h" = yes
		then
			AC_DEFINE(HAVE_BSD_STDLIB_H,1,[Define to 1 if bsd/stdlib.h header should be used])
		else
			AC_MSG_CHECKING(if <bsd/random.h> should be included)
			AC_TRY_COMPILE([
$ac_includes_default
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#include <bsd/random.h>],
						   [void *arc4random(int);
							void *x = arc4random(1); (void)x],
						   [cf_bsd_random_h=no],
						   [AC_TRY_COMPILE([#include <bsd/random.h>],
										   [unsigned long x = arc4random(); (void)x],
										   [cf_bsd_random_h=yes],
										   [cf_bsd_random_h=no])])
			AC_MSG_RESULT($cf_bsd_random_h)
			if test "$cf_bsd_random_h" = yes
			then
				AC_DEFINE(HAVE_BSD_RANDOM_H,1,[Define to 1 if bsd/random.h header should be used])
			else
				AC_MSG_WARN(no header file found for arc4random)
			fi
		fi
		;;
	esac

	CF_SRAND_PARSE($cf_func,cf_srand_func,cf_rand_func)

	CF_UPPER(cf_rand_max,ifelse($1,,my_,$1)rand_max)
	AC_DEFINE_UNQUOTED(ifelse($1,,my_,$1)srand,$cf_srand_func,[Define to the name for the srand function])
	AC_DEFINE_UNQUOTED(ifelse($1,,my_,$1)rand, $cf_rand_func,[Define to the name for the rand function])
	AC_DEFINE_UNQUOTED([$]cf_rand_max, $cf_cv_rand_max,[Define to the name for the RAND_MAX constant])
fi
])dnl
