/*
 * Copyright (c) 2000 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "random_range.h"

/*
 * Internal format of the range array set up by parse_range()
 */

struct range {
	int	min;
	int	max;
	int	mult;
};

/*
 * parse_ranges() is a function to parse a comma-separated list of range
 * tokens each having the following form:
 *
 *		num
 *	or
 *		min:max[:mult]
 *
 * any of the values may be blank (ie. min::mult, :max, etc.) and default
 * values for missing arguments may be supplied by the caller.
 *
 * The special first form is short hand for 'num:num'.
 *
 * After parsing the string, the ranges are put into an array of integers,
 * which is malloc'd by the routine.  The min, max, and mult entries of each
 * range can be extracted from the array using the range_min(), range_max(),
 * and range_mult() functions.
 *
 * It is the responsibility of the caller to free the space allocated by
 * parse_ranges() - a single call to free() will free the space.
 *
 *	str		The string to parse - assumed to be a comma-separated
 *			list of tokens having the above format.
 *	defmin		default value to plug in for min, if it is missing
 *	defmax		default value to plug in for max, if it is missing     
 *	defmult		default value to plug in for mult, if missing
 *	parse_func	A user-supplied function pointer, which parse_ranges()
 *			can call to parse the min, max, and mult strings.  This
 *			allows for customized number formats.  The function
 *			MUST have the following prototype:
 *				parse_func(char *str, int *val)
 *			The function should return -1 if str cannot be parsed
 *			into an integer, or >= 0 if it was successfully 
 *			parsed.  The resulting integer will be stored in
 *			*val.  If parse_func is NULL, parse_ranges will parse
 *			the tokens in a manner consistent with the the sscanf
 *			%i format.
 *	range_ptr	A user-supplied char **, which will be set to point
 *			at malloc'd space which holds the parsed range
 *			values.   If range_ptr is NULL, parse_ranges() just
 *			parses the string.  The data returned in range_ptr
 *			should not be processed directly - use the functions
 *			range_min(), range_max(), and range_mult() to access
 *			data for a given range.
 *	errptr		user-supplied char ** which can be set to point to a
 *			static error string.  If errptr is NULL, it is ignored.
 *
 * parse_range() returns -1 on error, or the number of ranges parsed.
 */

static int       str_to_int();
static long long divider(long long, long long, long long, long long);

int
parse_ranges(str, defmin, defmax, defmult, parse_func, rangeptr, errptr)
char	*str;
int	defmin;
int	defmax;
int	defmult;
int	(*parse_func)();
char	**rangeptr;
char	**errptr;
{
	int		ncommas;
	char		*tmpstr, *cp, *tok, *n1str, *n2str, *multstr;
	struct range	*rp, *ranges;
	static char	errmsg[256];

	if (errptr != NULL) {
		*errptr = errmsg;
	}

	for (ncommas = 0, cp = str; *cp != '\0'; cp++) {
		if (*cp == ',') {
			ncommas++;
		}
	}

	if (parse_func == NULL) {
		parse_func = str_to_int;
	}

	tmpstr = strdup(str);
	ranges = (struct range *)malloc((ncommas+1) * sizeof(struct range));
	rp = ranges;

	tok = strtok(tmpstr, ",");
	while (tok != NULL) {
		n1str = tok;
		n2str = NULL;
		multstr = NULL;

		rp->min = defmin;
		rp->max = defmax;
		rp->mult = defmult;

		if ((cp = strchr(n1str, ':')) != NULL) {
			*cp = '\0';
			n2str = cp+1;

			if ((cp = strchr(n2str, ':')) != NULL) {
				*cp = '\0';
				multstr = cp+1;
			}
		}

		/*
		 * Parse the 'min' field - if it is zero length (:n2[:mult]
		 * format), retain the default value, otherwise, pass the
		 * string to the parse function.
		 */

		if ((int)strlen(n1str) > 0) {
			if ((*parse_func)(n1str, &rp->min) < 0) {
				sprintf(errmsg, "error parsing string %s into an integer", n1str);
				free(tmpstr);
				free(ranges);
				return -1;
			}
		}

		/*
		 * Process the 'max' field - if one was not present (n1 format)
		 * set max equal to min.  If the field was present, but 
		 * zero length (n1: format), retain the default.  Otherwise
		 * pass the string to the parse function.
		 */

		if (n2str == NULL) {
			rp->max = rp->min;
		} else if ((int)strlen(n2str) > 0) {
			if ((*parse_func)(n2str, &rp->max) < 0) {
				sprintf(errmsg, "error parsing string %s into an integer", n2str);
				free(tmpstr);
				free(ranges);
				return -1;
			}
		}

		/*
		 * Process the 'mult' field - if one was not present 
		 * (n1:n2 format), or the field was zero length (n1:n2: format)
		 * then set the mult field to defmult - otherwise pass then
		 * mult field to the parse function.
		 */

		if (multstr != NULL && (int)strlen(multstr) > 0) {
			if ((*parse_func)(multstr, &rp->mult) < 0) {
				sprintf(errmsg, "error parsing string %s into an integer", multstr);
				free(tmpstr);
				free(ranges);
				return -1;
			}
		}

		rp++;
		tok = strtok(NULL, ",");
	}

	free(tmpstr);

	if (rangeptr != NULL) {
		*rangeptr = (char *)ranges;
	} else {
		free(ranges);		/* just running in parse mode */
	}

	return (rp - ranges);
}

/*
 * The default integer-parsing function
 */

static int
str_to_int(str, ip)
char	*str;
int	*ip;
{
	char	c;

	if (sscanf(str, "%i%c", ip, &c) != 1) {
		return -1;
	} else {
		return 0;
	}
}

/*
 * Three simple functions to return the min, max, and mult values for a given
 * range.  It is assumed that rbuf is a range buffer set up by parse_ranges(),
 * and that r is a valid range within that buffer.
 */

int
range_min(rbuf, r)
char	*rbuf;
int	r;
{
	return ((struct range *)rbuf)[r].min;
}

int
range_max(rbuf, r)
char	*rbuf;
int	r;
{
	return ((struct range *)rbuf)[r].max;
}

int
range_mult(rbuf, r)
char	*rbuf;
int	r;
{
	return ((struct range *)rbuf)[r].mult;
}

/*****************************************************************************
 * random_range(int start, int end, int mult, char **errp)
 *
 * Returns a psuedo-random number which is >= 'start', <= 'end', and a multiple
 * of 'mult'.  Start and end may be any valid integer, but mult must be an
 * integer > 0.  errp is a char ** which will be set to point to a static
 * error message buffer if it is not NULL, and an error occurs.
 *
 * The errp is the only way to check if the routine fails - currently the only
 * failure conditions are:
 *
 *		mult < 1
 *		no numbers in the start-end range that are a multiple of 'mult'
 *
 * If random_range_fails, and errp is a valid pointer, it will point to an
 * internal error buffer.  If errp is a vaild pointer, and random_range
 * is successful, errp will be set to NULL.
 *
 * Note - if mult is 1 (the most common case), there are error conditions
 * possible, and errp need not be used.
 *
 * Note:    Uses lrand48(), assuming that set_random_seed() uses srand48() when
 *          setting the seed.
 *****************************************************************************/

long
random_range(min, max, mult, errp)
int	min;
int	max;
int	mult;
char	**errp;
{
	int     	r, nmults, orig_min, orig_max, orig_mult, tmp;
	extern long	lrand48();
	static char	errbuf[128];

	/*
	 * Sanity check
	 */

	if (mult < 1) {
		if (errp != NULL) {
			sprintf(errbuf, "mult arg must be greater than 0");
			*errp = errbuf;
		}
		return -1;
	}

	/*
	 * Save original parameter values for use in error message
	 */

	orig_min = min;
	orig_max = max;
	orig_mult = mult;

	/*
	 * switch min/max if max < min
	 */

	if (max < min) {
		tmp = max;
		max = min;
		min = tmp;
	}

	/*
	 * select the random number
	 */

    	if ((r = min % mult))     /* bump to the next higher 'mult' multiple */
        	min += mult - r;

    	if ((r = max % mult))     /* reduce to the next lower 'mult' multiple */
        	max -= r;

    	if (min > max) {         /* no 'mult' multiples between min & max */
		if (errp != NULL) {
			sprintf(errbuf, "no numbers in the range %d:%d that are a multiple of %d", orig_min, orig_max, orig_mult);
			*errp = errbuf;
		}
        	return -1;
	}

	if (errp != NULL) {
		*errp = NULL;
	}

    	nmults = ((max - min) / mult) + 1;
        return (min + ((lrand48() % nmults) * mult));
}

/*
 * Just like random_range, but all values are longs.
 */
long
random_rangel(min, max, mult, errp)
long	min;
long	max;
long	mult;
char	**errp;
{
	long     	r, nmults, orig_min, orig_max, orig_mult, tmp;
	extern long	lrand48();
	static char	errbuf[128];

	/*
	 * Sanity check
	 */

	if (mult < 1) {
		if (errp != NULL) {
			sprintf(errbuf, "mult arg must be greater than 0");
			*errp = errbuf;
		}
		return -1;
	}

	/*
	 * Save original parameter values for use in error message
	 */

	orig_min = min;
	orig_max = max;
	orig_mult = mult;

	/*
	 * switch min/max if max < min
	 */

	if (max < min) {
		tmp = max;
		max = min;
		min = tmp;
	}

	/*
	 * select the random number
	 */

    	if ((r = min % mult))     /* bump to the next higher 'mult' multiple */
        	min += mult - r;

    	if ((r = max % mult))     /* reduce to the next lower 'mult' multiple */
        	max -= r;

    	if (min > max) {         /* no 'mult' multiples between min & max */
		if (errp != NULL) {
		    sprintf(errbuf,
			"no numbers in the range %ld:%ld that are a multiple of %ld",
			orig_min, orig_max, orig_mult);
		    *errp = errbuf;
		}
        	return -1;
	}

	if (errp != NULL) {
		*errp = NULL;
	}

    	nmults = ((max - min) / mult) + 1;
#if (_MIPS_SZLONG == 64)
        /*
         * If max is less than 2gb, then the value can fit in 32 bits
         * and the standard lrand48() routine can be used.
         */
        if ( max <= (long)2147483647 ) {
            return (long) (min + (((long)lrand48() % nmults) * mult));
        } else {
            /*
             * max is greater than 2gb - meeds more than 32 bits.
             * Since lrand48 only will get a number up to 32bits.
             */
	    long randnum;
            randnum=divider(min, max, 0, -1);
            return (long) (min + ((randnum % nmults) * mult));
        }

#else
    	return (min + ((lrand48() % nmults) * mult));
#endif
}

/*
 *  Attempts to be just like random_range, but everything is long long (64 bit)
 */
long long
random_rangell(min, max, mult, errp)
long long	min;
long long	max;
long long	mult;
char		**errp;
{
	long long     	r, nmults, orig_min, orig_max, orig_mult, tmp;
        long long	randnum;
	extern long	lrand48();
	static char	errbuf[128];

	/*
	 * Sanity check
	 */

	if (mult < 1) {
		if (errp != NULL) {
			sprintf(errbuf, "mult arg must be greater than 0");
			*errp = errbuf;
		}
		return -1;
	}

	/*
	 * Save original parameter values for use in error message
	 */

	orig_min = min;
	orig_max = max;
	orig_mult = mult;

	/*
	 * switch min/max if max < min
	 */

	if (max < min) {
		tmp = max;
		max = min;
		min = tmp;
	}

	/*
	 * select the random number
	 */

    	if ((r = min % mult))     /* bump to the next higher 'mult' multiple */
        	min += mult - r;

    	if ((r = max % mult))     /* reduce to the next lower 'mult' multiple */
        	max -= r;

    	if (min > max) {         /* no 'mult' multiples between min & max */
		if (errp != NULL) {
		    sprintf(errbuf,
			"no numbers in the range %lld:%lld that are a multiple of %lld",
			orig_min, orig_max, orig_mult);
		    *errp = errbuf;
		}
        	return -1;
	}

	if (errp != NULL) {
		*errp = NULL;
	}

    	nmults = ((max - min) / mult) + 1;
        /*
	 * If max is less than 2gb, then the value can fit in 32 bits
	 * and the standard lrand48() routine can be used.
	 */
	if ( max <= (long)2147483647 ) {  
    	    return (long long) (min + (((long long)lrand48() % nmults) * mult));
	} else {
	    /*
	     * max is greater than 2gb - meeds more than 32 bits.
	     * Since lrand48 only will get a number up to 32bits.
	     */
	    randnum=divider(min, max, 0, -1);
	    return (long long) (min + ((randnum % nmults) * mult));
        }

}

/*
 * This functional will recusively call itself to return a random
 * number min and max.   It was designed to work the 64bit numbers
 * even when compiled as 32 bit process.
 * algorithm:  to use the official lrand48() routine - limited to 32 bits.
 *   find the difference between min and max (max-min).
 *   if the difference is 2g or less, use the random number gotton from lrand48().
 *   Determine the midway point between min and max.
 *   if the midway point is less than 2g from min or max,
 *      randomly add the random number gotton from lrand48() to
 *      either min or the midpoint.
 *   Otherwise, call outself with min and max being min and midway value or
 *   midway value and max.  This will reduce the range in half.
 */
static long long
divider(long long min, long long max, long long cnt, long long rand)
{
    long long med, half, diff;

    /*
     * prevent run away code.  We are dividing by two each count.
     * if we get to a count of more than 32, we should have gotten
     * to 2gb.
     */
    if ( cnt > 32 )
       return -1;

    /*
     * Only get a random number the first time.
     */
    if ( cnt == 0 || rand < -1 ) { 
        rand = (long long)lrand48();  /* 32 bit random number */
    }

    diff = max - min;

    if ( diff <= 2147483647 )
	return min + rand;

    half = diff/(long long)2;   /* half the distance between min and max */
    med = min + half;	        /* med way point between min and max */

#if DEBUG
printf("divider: min=%lld, max=%lld, cnt=%lld, rand=%lld\n", min, max, cnt, rand);
printf("   diff = %lld, half = %lld,   med = %lld\n", diff, half, med);
#endif

    if ( half <= 2147483647 ) {
        /*
         * If half is smaller than 2gb, we can use the random number
         * to pick the number within the min to med or med to max
         * if the cnt bit of rand is zero or one, respectively.
         */
        if ( rand & (1<<cnt) )
	    return med + rand;
        else
	    return min + rand;
    } else {
        /*
	 * recursively call ourself to reduce the value to the bottom half
	 * or top half (bit cnt is set).
         */
        if ( rand & (1<<cnt) ) {
	    return divider(med, max, cnt+1, rand);
	} else {
	    return divider(min, med, cnt+1, rand);
	}
	
    }

}


/*****************************************************************************
 * random_range_seed(s)
 *
 * Sets the random seed to s.  Uses srand48(), assuming that lrand48() will
 * be used in random_range().
 *****************************************************************************/

void
random_range_seed(s)
long    s;
{
    extern void srand48();

    srand48(s);
}

/****************************************************************************
 * random_bit(mask)
 *
 * This function randomly returns a single bit from the bits
 * set in mask.  If mask is zero, zero is returned.
 *
 ****************************************************************************/
long
random_bit(long mask)
{
    int nbits = 0;      /* number of set bits in mask */
    long bit;           /* used to count bits and num of set bits choosen */
    int nshift;         /* used to count bit shifts */

    if ( mask == 0 )
        return 0;

    /*
     * get the number of bits set in mask
     */
        bit=1L;
        for ( nshift=0; nshift<sizeof(long)*8; nshift++) {
                if ( mask & bit )
                        nbits++;
                bit=bit<<1;
        }

    /*
     * randomly choose a bit.
     */
    bit=random_range(1, nbits, 1, NULL);

    /*
     * shift bits until you determine which bit was randomly choosen.
     * nshift will hold the number of shifts to make.
     */

    nshift=0;
    while (bit) {
        /* check if the current one's bit is set */
        if ( mask & 1L ) {
            bit--;
        }
        mask = mask >> 1;
        nshift++;
    }

    return 01L << (nshift-1);

}


#if RANDOM_BIT_UNITTEST
/*
 *  The following is a unit test main function for random_bit().
 */
main(argc, argv)
int argc;
char **argv;
{
    int ind;
    int cnt, iter;
    long mask, ret;

    printf("test for first and last bit set\n");
    mask=1L;
    ret=random_bit(mask);
    printf("random_bit(%#o) returned %#o\n", mask, ret);

    mask=1L<<(sizeof(long)*8-1);
    ret=random_bit(mask);
    printf("random_bit(%#o) returned %#o\n", mask, ret);

    if ( argc >= 3 ) {
        iter=atoi(argv[1]);
        for (ind=2; ind<argc; ind++) {
            printf("Calling random_bit %d times for mask %#o\n", iter, mask);
            sscanf(argv[ind], "%i", &mask);
            for (cnt=0; cnt<iter; cnt++) {
                ret=random_bit(mask);
                printf("random_bit(%#o) returned %#o\n", mask, ret);
            }
        }
    }
    exit(0);
}

#endif /* end if RANDOM_BIT_UNITTEST */


#if UNIT_TEST
/*
 *  The following is a unit test main function for random_range*().
 */

#define PARTNUM	10	/* used to determine even distribution of random numbers */
#define MEG  1024*1024*1024
#define GIG 1073741824
int
main(argc, argv)
int argc;
char **argv;
{
    int ind;
    int cnt, iter=10;
    int imin=0, imult=1, itmin, itmax=0;
    int imax=1048576;

    long lret, lmin=0, lmult=1, ltmin, ltmax=0; 
#if (_MIPS_SZLONG == 64)
    long lmax=6*(long)GIG;	/* higher than 32 bits */
#else
    long lmax=1048576;
#endif
    long long llret, llmin=0, llmult=1, lltmin, lltmax=0;
    long long llmax=(long long)80*(long long)GIG;

    long part;
    long long lpart;
    long cntarr[PARTNUM];
    long valbound[PARTNUM];
    long long lvalbound[PARTNUM];

    for (ind=0; ind<PARTNUM; ind++ )
	cntarr[ind]=0;
    
    if ( argc < 2 ) {
        printf("Usage: %s func [iterations] \n", argv[0]);
	printf("func can be random_range, random_rangel, random_rangell\n");
	exit(1);
    }

    if ( argc >= 3 ) {
        if ( sscanf(argv[2], "%i", &iter) != 1 ) {
            printf("Usage: %s [func iterations] \n", argv[0]);
	    printf("argv[2] is not a number\n");
	    exit(1);
        }
    }


    /*
     * random_rangel ()
     */
    if ( strcmp(argv[1], "random_rangel") == 0 ) {
	ltmin=lmax;
        part = lmax/PARTNUM;
        for(ind=0; ind<PARTNUM; ind++) {
	    valbound[ind]=part*ind;
        }

	for(cnt=0; cnt<iter; cnt++) {
	    lret=random_rangel(lmin, lmax, lmult, NULL);
	    if ( iter < 100 )
	        printf("%ld\n", lret);
	    if ( lret < ltmin )
		ltmin = lret;
	    if ( lret > ltmax )
		ltmax = lret;
	    for(ind=0; ind<PARTNUM-1; ind++) {
		if ( valbound[ind]  < lret && lret <= valbound[ind+1] ) {
		    cntarr[ind]++;
		    break;
		}
	    }
	    if ( lret > valbound[PARTNUM-1] ) {
		cntarr[PARTNUM-1]++;
	    }
        }
        for(ind=0; ind<PARTNUM-1; ind++) {
	    printf("%2d %-13ld to  %-13ld   %5ld %4.4f\n", ind+1,
	        valbound[ind], valbound[ind+1], cntarr[ind],
	        (float)(cntarr[ind]/(float)iter));
        }
        printf("%2d %-13ld to  %-13ld   %5ld %4.4f\n", PARTNUM, 
	    valbound[PARTNUM-1], lmax, cntarr[PARTNUM-1],
	    (float)(cntarr[PARTNUM-1]/(float)iter));
	printf("  min=%ld,  max=%ld\n", ltmin, ltmax);

    } else if ( strcmp(argv[1], "random_rangell") == 0 ) {
       /*
	* random_rangell() unit test
        */
	 lltmin=llmax;
        lpart = llmax/PARTNUM;
        for(ind=0; ind<PARTNUM; ind++) {
	    lvalbound[ind]=(long long)(lpart*ind);
        }

	for(cnt=0; cnt<iter; cnt++) {
	    llret=random_rangell(llmin, llmax, llmult, NULL);
	    if ( iter < 100 )
	        printf("random_rangell returned %lld\n", llret);
            if ( llret < lltmin )
                lltmin = llret;
            if ( llret > lltmax )
                lltmax = llret;

	    for(ind=0; ind<PARTNUM-1; ind++) {
		if ( lvalbound[ind]  < llret && llret <= lvalbound[ind+1] ) {
		    cntarr[ind]++;
		    break;
		}
	    }
	    if ( llret > lvalbound[PARTNUM-1] ) {
		cntarr[PARTNUM-1]++;
	    }
        }
        for(ind=0; ind<PARTNUM-1; ind++) {
            printf("%2d %-13lld to  %-13lld   %5ld %4.4f\n", ind+1,
                lvalbound[ind], lvalbound[ind+1], cntarr[ind],
                (float)(cntarr[ind]/(float)iter));
        }
        printf("%2d %-13lld to  %-13lld   %5ld %4.4f\n", PARTNUM,
            lvalbound[PARTNUM-1], llmax, cntarr[PARTNUM-1],
            (float)(cntarr[PARTNUM-1]/(float)iter));
	printf("  min=%lld,  max=%lld\n", lltmin, lltmax);

    } else {
	/*
	 * random_range() unit test
         */
	itmin=imax;
        part = imax/PARTNUM;
        for(ind=0; ind<PARTNUM; ind++) {
	    valbound[ind]=part*ind;
        }

	for(cnt=0; cnt<iter; cnt++) {
	    lret=random_range(imin, imax, imult, NULL);
	    if ( iter < 100 )
	        printf("%ld\n", lret);
            if ( lret < itmin )
                itmin = lret;
            if ( lret > itmax )
                itmax = lret;

	    for(ind=0; ind<PARTNUM-1; ind++) {
		if ( valbound[ind]  < lret && lret <= valbound[ind+1] ) {
		    cntarr[ind]++;
		    break;
		}
	    }
	    if ( lret > valbound[PARTNUM-1] ) {
		cntarr[PARTNUM-1]++;
	    }
        }
        for(ind=0; ind<PARTNUM-1; ind++) {
	    printf("%2d %-13ld to  %-13ld   %5ld %4.4f\n", ind+1,
	        valbound[ind], valbound[ind+1], cntarr[ind],
	        (float)(cntarr[ind]/(float)iter));
        }
        printf("%2d %-13ld to  %-13ld   %5ld %4.4f\n", PARTNUM, 
	    valbound[PARTNUM-1], (long)imax, cntarr[PARTNUM-1],
	    (float)(cntarr[PARTNUM-1]/(float)iter));
	printf("  min=%d,  max=%d\n", itmin, itmax);

    }

    exit(0);
}

#endif
