This patch will replace PHP functions srand() / rand() / getrandmax() with the mt_*() ones. The mt_*() are changed to aliases. If nobody objects, I will commit this tomorrow. --Jani
Index: configure.in =================================================================== RCS file: /repository/php4/configure.in,v retrieving revision 1.263 diff -u -r1.263 configure.in --- configure.in 4 Aug 2001 04:47:24 -0000 1.263 +++ configure.in 4 Aug 2001 05:05:03 -0000 @@ -1,4 +1,4 @@ -dnl ## $Id: configure.in,v 1.263 2001/08/04 04:47:24 sniper Exp $ -*- sh -*- +dnl ## $Id: configure.in,v 1.262 2001/08/02 21:20:20 rasmus Exp $ -*- sh -*- dnl ## Process this file with autoconf to produce a configure script. divert(1) @@ -386,15 +386,12 @@ link \ localtime_r \ lockf \ -lrand48 \ memcpy \ memmove \ mkstemp \ mmap \ nl_langinfo \ putenv \ -random \ -rand_r \ regcomp \ res_search \ setitimer \ @@ -405,8 +402,6 @@ shutdown \ sin \ snprintf \ -srand48 \ -srandom \ statfs \ statvfs \ std_syslog \ Index: ext/standard/php_rand.h =================================================================== RCS file: /repository/php4/ext/standard/php_rand.h,v retrieving revision 1.8 diff -u -r1.8 php_rand.h --- ext/standard/php_rand.h 26 Feb 2001 06:07:23 -0000 1.8 +++ ext/standard/php_rand.h 4 Aug 2001 05:05:05 -0000 @@ -24,38 +24,12 @@ #ifndef PHP_RAND_H #define PHP_RAND_H -#include <stdlib.h> +#include "ext/standard/basic_functions.h" -#ifndef RAND_MAX -#define RAND_MAX (1<<15) -#endif +#define MT_RAND_MAX ((long)(0x7FFFFFFF)) /* (1<<31) - 1 */ +#define PHP_RAND_MAX MT_RAND_MAX -#if HAVE_LRAND48 -#define PHP_RAND_MAX 2147483647 -#else -#define PHP_RAND_MAX RAND_MAX -#endif - -/* Define rand Function wrapper */ -#ifdef HAVE_RANDOM -#define php_rand() random() -#else -#ifdef HAVE_LRAND48 -#define php_rand() lrand48() -#else -#define php_rand() rand() -#endif -#endif - -/* Define srand Function wrapper */ -#ifdef HAVE_SRANDOM -#define php_srand(seed) srandom((unsigned int)seed) -#else -#ifdef HAVE_SRAND48 -#define php_srand(seed) srand48((long)seed) -#else -#define php_srand(seed) srand((unsigned int)seed) -#endif -#endif +PHPAPI void php_seedMT(php_uint32 seed TSRMLS_DC); +PHPAPI php_uint32 php_randomMT(TSRMLS_D); #endif /* PHP_RAND_H */ Index: ext/standard/rand.c =================================================================== RCS file: /repository/php4/ext/standard/rand.c,v retrieving revision 1.29 diff -u -r1.29 rand.c --- ext/standard/rand.c 28 Jul 2001 11:36:18 -0000 1.29 +++ ext/standard/rand.c 4 Aug 2001 05:05:05 -0000 @@ -27,8 +27,6 @@ #include "php_math.h" #include "php_rand.h" -#include "basic_functions.h" - /* This is the ``Mersenne Twister'' random number generator MT19937, which generates pseudorandom integers uniformly distributed in 0..(2^32 - 1) @@ -92,11 +90,9 @@ #define loBits(u) ((u) & 0x7FFFFFFFU) /* mask the highest bit of u */ #define mixBits(u, v) (hiBit(u)|loBits(v)) /* move hi bit of u to hi bit of v */ -#define MT_RAND_MAX ((long)(0x7FFFFFFF)) /* (1<<31) - 1 */ - -/* {{{ seedMT +/* {{{ php_seedMT */ -static void seedMT(php_uint32 seed TSRMLS_DC) +PHPAPI void php_seedMT(php_uint32 seed TSRMLS_DC) { /* We initialize state[0..(N-1)] via the generator @@ -152,13 +148,15 @@ } /* }}} */ -static php_uint32 reloadMT(TSRMLS_D) +/* {{{ php_reloadMT + */ +static php_uint32 php_reloadMT(TSRMLS_D) { register php_uint32 *p0=BG(state), *p2=BG(state)+2, *pM=BG(state)+M, s0, s1; register int j; if(BG(left) < -1) - seedMT(4357U TSRMLS_CC); + php_seedMT(4357U TSRMLS_CC); BG(left)=N-1, BG(next)=BG(state)+1; @@ -174,15 +172,16 @@ s1 ^= (s1 << 15) & 0xEFC60000U; return(s1 ^ (s1 >> 18)); } +/* }}} */ - -static inline php_uint32 randomMT(void) +/* {{{ php_randomMT + */ +PHPAPI php_uint32 php_randomMT(TSRMLS_D) { php_uint32 y; - TSRMLS_FETCH(); if(--BG(left) < 0) - return(reloadMT(TSRMLS_C)); + return(php_reloadMT(TSRMLS_C)); y = *BG(next)++; y ^= (y >> 11); @@ -190,9 +189,10 @@ y ^= (y << 15) & 0xEFC60000U; return(y ^ (y >> 18)); } +/* }}} */ /* {{{ proto void srand(int seed) - Seeds random number generator */ + Seeds random number generator (MT) */ PHP_FUNCTION(srand) { pval **arg; @@ -201,26 +201,12 @@ WRONG_PARAM_COUNT; } convert_to_long_ex(arg); - php_srand((*arg)->value.lval); -} -/* }}} */ - -/* {{{ proto void mt_srand(int seed) - Seeds Mersenne Twister random number generator */ -PHP_FUNCTION(mt_srand) -{ - pval **arg; - - if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) { - WRONG_PARAM_COUNT; - } - convert_to_long_ex(arg); - seedMT((*arg)->value.lval TSRMLS_CC); + php_seedMT((*arg)->value.lval TSRMLS_CC); } /* }}} */ /* {{{ proto int rand([int min, int max]) - Returns a random number */ + Returns a random number (MT) */ PHP_FUNCTION(rand) { pval **p_min=NULL, **p_max=NULL; @@ -234,72 +220,10 @@ } convert_to_long_ex(p_min); convert_to_long_ex(p_max); - if ((*p_max)->value.lval-(*p_min)->value.lval < 0) { - php_error(E_WARNING,"rand(): Invalid range: %ld..%ld", (*p_min)->value.lval, (*p_max)->value.lval); - }else if ((*p_max)->value.lval-(*p_min)->value.lval > PHP_RAND_MAX){ - php3_error(E_WARNING,"rand(): Invalid range: %ld..%ld", (*p_min)->value.lval, (*p_max)->value.lval); - } - break; - default: - WRONG_PARAM_COUNT; - break; - } - - return_value->type = IS_LONG; - - return_value->value.lval = php_rand(); - - /* - * A bit of tricky math here. We want to avoid using a modulus because - * that simply tosses the high-order bits and might skew the distribution - * of random values over the range. Instead we map the range directly. - * - * We need to map the range from 0...M evenly to the range a...b - * Let n = the random number and n' = the mapped random number - * - * Then we have: n' = a + n(b-a)/M - * - * We have a problem here in that only n==M will get mapped to b which - # means the chances of getting b is much much less than getting any of - # the other values in the range. We can fix this by increasing our range - # artifically and using: - # - # n' = a + n(b-a+1)/M - * - # Now we only have a problem if n==M which would cause us to produce a - # number of b+1 which would be bad. So we bump M up by one to make sure - # this will never happen, and the final algorithm looks like this: - # - # n' = a + n(b-a+1)/(M+1) - * - * -RL - */ - if (p_min && p_max) { /* implement range */ - return_value->value.lval = (*p_min)->value.lval + - (int)((double)((*p_max)->value.lval - (*p_min)->value.lval + 1.0) * return_value->value.lval/(PHP_RAND_MAX+1.0)); - } -} -/* }}} */ - -/* {{{ proto int mt_rand([int min, int max]) - Returns a random number from Mersenne Twister */ -PHP_FUNCTION(mt_rand) -{ - pval **p_min=NULL, **p_max=NULL; - - switch (ZEND_NUM_ARGS()) { - case 0: - break; - case 2: - if (zend_get_parameters_ex(2, &p_min, &p_max)==FAILURE) { - RETURN_FALSE; - } - convert_to_long_ex(p_min); - convert_to_long_ex(p_max); if ((*p_max)->value.lval-(*p_min)->value.lval <= 0) { - php_error(E_WARNING,"mt_rand(): Invalid range: %ld..%ld", (*p_min)->value.lval, (*p_max)->value.lval); - }else if ((*p_max)->value.lval-(*p_min)->value.lval > MT_RAND_MAX){ - php3_error(E_WARNING,"mt_rand(): Invalid range: %ld..%ld",(*p_min)->value.lval, (*p_max)->value.lval); + php_error(E_WARNING,"rand(): Invalid range: +%ld..%ld", (*p_min)->value.lval, (*p_max)->value.lval); + } else if ((*p_max)->value.lval - (*p_min)->value.lval > +MT_RAND_MAX) { + php_error(E_WARNING,"rand(): Invalid range: +%ld..%ld",(*p_min)->value.lval, (*p_max)->value.lval); } break; default: @@ -316,34 +240,21 @@ * Update: * I talked with Cokus via email and it won't ruin the algorithm */ - return_value->value.lval = (long)(randomMT() >> 1); + return_value->value.lval = (long)(php_randomMT(TSRMLS_C) >> 1); if (p_min && p_max) { /* implement range */ - return_value->value.lval = (*p_min)->value.lval + - (long)((double)((*p_max)->value.lval - (*p_min)->value.lval + 1.0) * return_value->value.lval/(MT_RAND_MAX+1.0)); + return_value->value.lval = (*p_min)->value.lval + +(long)((double)((*p_max)->value.lval - + (*p_min)->value.lval + 1.0) * +return_value->value.lval/(MT_RAND_MAX+1.0)); } } /* }}} */ /* {{{ proto int getrandmax(void) - Returns the maximum value a random number can have */ + Returns the maximum value a random number can have (MT) */ PHP_FUNCTION(getrandmax) { return_value->type = IS_LONG; - return_value->value.lval = PHP_RAND_MAX; -} -/* }}} */ - -/* {{{ proto int mt_getrandmax(void) - Returns the maximum value a random number from Mersenne Twister can have */ -PHP_FUNCTION(mt_getrandmax) -{ - return_value->type = IS_LONG; - /* - * Melo: it could be 2^^32 but we only use 2^^31 to maintain - * compatibility with the previous php_rand - */ - return_value->value.lval = MT_RAND_MAX; /* 2^^31 */ + return_value->value.lval = MT_RAND_MAX; } /* }}} */ Index: ext/standard/array.c =================================================================== RCS file: /repository/php4/ext/standard/array.c,v retrieving revision 1.119 diff -u -r1.119 array.c --- ext/standard/array.c 3 Aug 2001 19:18:51 -0000 1.119 +++ ext/standard/array.c 4 Aug 2001 05:05:05 -0000 @@ -1378,8 +1378,10 @@ /* }}} */ -static int array_data_shuffle(const void *a, const void*b) { - return (php_rand() % 2) ? 1 : -1; +static int array_data_shuffle(const void *a, const void *b) +{ + TSRMLS_FETCH(); + return (php_randomMT(TSRMLS_C) % 2) ? 1 : -1; } @@ -2760,15 +2762,7 @@ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos); while (num_req_val && (key_type = zend_hash_get_current_key_ex(Z_ARRVAL_PP(input), &string_key, &string_key_len, &num_key, 0, &pos)) != HASH_KEY_NON_EXISTANT) { -#ifdef HAVE_RANDOM - randval = random(); -#else -#ifdef HAVE_LRAND48 - randval = lrand48(); -#else - randval = rand(); -#endif -#endif + randval = php_randomMT(TSRMLS_C); if ((double)(randval/(PHP_RAND_MAX+1.0)) < (double)num_req_val/(double)num_avail) { /* If we are returning a single result, just do it. */ Index: ext/standard/basic_functions.c =================================================================== RCS file: /repository/php4/ext/standard/basic_functions.c,v retrieving revision 1.375 diff -u -r1.375 basic_functions.c --- ext/standard/basic_functions.c 3 Aug 2001 09:50:38 -0000 1.375 +++ ext/standard/basic_functions.c 4 Aug 2001 05:05:06 -0000 @@ -238,9 +238,11 @@ PHP_FE(rand, NULL) PHP_FE(srand, NULL) PHP_FE(getrandmax, NULL) - PHP_FE(mt_rand, NULL) - PHP_FE(mt_srand, NULL) - PHP_FE(mt_getrandmax, NULL) + + /* For backwards compatibility */ + PHP_FALIAS(mt_rand, rand, NULL) + PHP_FALIAS(mt_srand, srand, NULL) + PHP_FALIAS(mt_getrandmax, getrandmax, NULL) #if HAVE_GETSERVBYNAME PHP_FE(getservbyname, NULL) Index: ext/standard/basic_functions.h =================================================================== RCS file: /repository/php4/ext/standard/basic_functions.h,v retrieving revision 1.86 diff -u -r1.86 basic_functions.h --- ext/standard/basic_functions.h 3 Aug 2001 09:50:38 -0000 1.86 +++ ext/standard/basic_functions.h 4 Aug 2001 05:05:06 -0000 @@ -170,9 +170,9 @@ struct stat lsb; /* rand.c */ - php_uint32 state[MT_N+1]; /* state vector + 1 extra to not violate ANSI C */ - php_uint32 *next; /* next random value is computed from here */ - int left; /* can *next++ this many times before reloading */ + php_uint32 state[MT_N+1]; /* state vector + 1 extra to not violate ANSI C */ + php_uint32 *next; /* next random value is computed from here */ + int left; /* can *next++ this many times before reloading */ /* syslog.c */ int syslog_started; Index: ext/mcrypt/mcrypt.c =================================================================== RCS file: /repository/php4/ext/mcrypt/mcrypt.c,v retrieving revision 1.57 diff -u -r1.57 mcrypt.c --- ext/mcrypt/mcrypt.c 30 Jul 2001 21:12:48 -0000 1.57 +++ ext/mcrypt/mcrypt.c 4 Aug 2001 05:05:06 -0000 @@ -34,7 +34,7 @@ #include "php_ini.h" #include "php_globals.h" #include "ext/standard/info.h" - +#include "ext/standard/php_rand.h" function_entry mcrypt_functions[] = { PHP_FE(mcrypt_ecb, NULL) @@ -1457,7 +1457,7 @@ close(fd); } else { while(i) { - iv[--i] = 255.0 * rand() / RAND_MAX; + iv[--i] = 255.0 * php_randomMT(TSRMLS_C) / PHP_RAND_MAX; } n = Z_LVAL_PP(size); } Index: ext/session/session.c =================================================================== RCS file: /repository/php4/ext/session/session.c,v retrieving revision 1.228 diff -u -r1.228 session.c --- ext/session/session.c 3 Aug 2001 11:00:16 -0000 1.228 +++ ext/session/session.c 4 Aug 2001 05:05:06 -0000 @@ -42,7 +42,6 @@ #include "ext/standard/datetime.h" #include "ext/standard/php_lcg.h" #include "ext/standard/url_scanner_ex.h" -#include "ext/standard/php_rand.h" /* for RAND_MAX */ #include "ext/standard/info.h" #include "ext/standard/php_smart_str.h" Index: main/php_reentrancy.h =================================================================== RCS file: /repository/php4/main/php_reentrancy.h,v retrieving revision 1.14 diff -u -r1.14 php_reentrancy.h --- main/php_reentrancy.h 20 May 2001 21:29:55 -0000 1.14 +++ main/php_reentrancy.h 4 Aug 2001 05:05:06 -0000 @@ -107,12 +107,6 @@ #endif #endif -#if !defined(HAVE_RAND_R) -PHPAPI int php_rand_r(unsigned int *seed); -#else -#define php_rand_r rand_r -#endif - #if !defined(ZTS) #undef PHP_NEED_REENTRANCY #endif Index: main/reentrancy.c =================================================================== RCS file: /repository/php4/main/reentrancy.c,v retrieving revision 1.30 diff -u -r1.30 reentrancy.c --- main/reentrancy.c 6 Jun 2001 13:05:53 -0000 1.30 +++ main/reentrancy.c 4 Aug 2001 05:05:06 -0000 @@ -29,7 +29,6 @@ #endif #include "php_reentrancy.h" -#include "ext/standard/php_rand.h" /* for RAND_MAX */ enum { LOCALTIME_R, @@ -258,63 +257,6 @@ for (i = 0; i < NUMBER_OF_LOCKS; i++) { tsrm_mutex_free(reentrant_locks[i]); } -} - -#endif - -#ifndef HAVE_RAND_R - -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Posix rand_r function added May 1999 by Wes Peters <[EMAIL PROTECTED]>. - */ - -#include <sys/types.h> -#include <stdlib.h> - -static int -do_rand(unsigned long *ctx) -{ - return ((*ctx = *ctx * 1103515245 + 12345) % ((u_long)RAND_MAX + 1)); -} - - -PHPAPI int -php_rand_r(unsigned int *ctx) -{ - u_long val = (u_long) *ctx; - *ctx = do_rand(&val); - return (int) *ctx; } #endif
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] To contact the list administrators, e-mail: [EMAIL PROTECTED]