18462SApril.Chin@Sun.COM /***********************************************************************
28462SApril.Chin@Sun.COM * *
38462SApril.Chin@Sun.COM * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1996-2010 AT&T Intellectual Property *
58462SApril.Chin@Sun.COM * and is licensed under the *
68462SApril.Chin@Sun.COM * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
88462SApril.Chin@Sun.COM * *
98462SApril.Chin@Sun.COM * A copy of the License is available at *
108462SApril.Chin@Sun.COM * http://www.opensource.org/licenses/cpl1.0.txt *
118462SApril.Chin@Sun.COM * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
128462SApril.Chin@Sun.COM * *
138462SApril.Chin@Sun.COM * Information and Software Systems Research *
148462SApril.Chin@Sun.COM * AT&T Research *
158462SApril.Chin@Sun.COM * Florham Park NJ *
168462SApril.Chin@Sun.COM * *
178462SApril.Chin@Sun.COM * Glenn Fowler <gsf@research.att.com> *
188462SApril.Chin@Sun.COM * *
198462SApril.Chin@Sun.COM ***********************************************************************/
208462SApril.Chin@Sun.COM #pragma prototyped
218462SApril.Chin@Sun.COM
228462SApril.Chin@Sun.COM /*
238462SApril.Chin@Sun.COM * prng
248462SApril.Chin@Sun.COM */
258462SApril.Chin@Sun.COM
268462SApril.Chin@Sun.COM #include <fnv.h>
278462SApril.Chin@Sun.COM
288462SApril.Chin@Sun.COM #define prng_description \
298462SApril.Chin@Sun.COM "32 bit PRNG (pseudo random number generator) hash."
308462SApril.Chin@Sun.COM #define prng_options "\
318462SApril.Chin@Sun.COM [+mpy?The 32 bit PRNG multiplier.]:[number:=0x01000193]\
328462SApril.Chin@Sun.COM [+add?The 32 bit PRNG addend.]:[number:=0]\
338462SApril.Chin@Sun.COM [+init?The PRNG initial value. 0xffffffff is used if \anumber\a is omitted.]:?[number:=0x811c9dc5]\
348462SApril.Chin@Sun.COM "
358462SApril.Chin@Sun.COM #define prng_match "prng"
368462SApril.Chin@Sun.COM #define prng_done long_done
378462SApril.Chin@Sun.COM #define prng_print long_print
388462SApril.Chin@Sun.COM #define prng_data long_data
398462SApril.Chin@Sun.COM #define prng_scale 0
408462SApril.Chin@Sun.COM
418462SApril.Chin@Sun.COM typedef uint32_t Prngnum_t;
428462SApril.Chin@Sun.COM
438462SApril.Chin@Sun.COM typedef struct Prng_s
448462SApril.Chin@Sun.COM {
458462SApril.Chin@Sun.COM _SUM_PUBLIC_
468462SApril.Chin@Sun.COM _SUM_PRIVATE_
478462SApril.Chin@Sun.COM _INTEGRAL_PRIVATE_
488462SApril.Chin@Sun.COM Prngnum_t init;
498462SApril.Chin@Sun.COM Prngnum_t mpy;
508462SApril.Chin@Sun.COM Prngnum_t add;
518462SApril.Chin@Sun.COM } Prng_t;
528462SApril.Chin@Sun.COM
538462SApril.Chin@Sun.COM static Sum_t*
prng_open(const Method_t * method,const char * name)548462SApril.Chin@Sun.COM prng_open(const Method_t* method, const char* name)
558462SApril.Chin@Sun.COM {
568462SApril.Chin@Sun.COM register Prng_t* sum;
578462SApril.Chin@Sun.COM register const char* s;
588462SApril.Chin@Sun.COM register const char* t;
598462SApril.Chin@Sun.COM register const char* v;
608462SApril.Chin@Sun.COM register int i;
618462SApril.Chin@Sun.COM
628462SApril.Chin@Sun.COM if (sum = newof(0, Prng_t, 1, 0))
638462SApril.Chin@Sun.COM {
648462SApril.Chin@Sun.COM sum->method = (Method_t*)method;
658462SApril.Chin@Sun.COM sum->name = name;
668462SApril.Chin@Sun.COM }
678462SApril.Chin@Sun.COM s = name;
688462SApril.Chin@Sun.COM while (*(t = s))
698462SApril.Chin@Sun.COM {
708462SApril.Chin@Sun.COM for (t = s, v = 0; *s && *s != '-'; s++)
718462SApril.Chin@Sun.COM if (*s == '=' && !v)
728462SApril.Chin@Sun.COM v = s;
738462SApril.Chin@Sun.COM i = (v ? v : s) - t;
748462SApril.Chin@Sun.COM if (isdigit(*t) || v && strneq(t, "mpy", i) && (t = v + 1))
758462SApril.Chin@Sun.COM sum->mpy = strtoul(t, NiL, 0);
768462SApril.Chin@Sun.COM else if (strneq(t, "add", i))
778462SApril.Chin@Sun.COM sum->add = v ? strtoul(v + 1, NiL, 0) : ~sum->add;
788462SApril.Chin@Sun.COM else if (strneq(t, "init", i))
798462SApril.Chin@Sun.COM sum->init = v ? strtoul(v + 1, NiL, 0) : ~sum->init;
808462SApril.Chin@Sun.COM if (*s == '-')
818462SApril.Chin@Sun.COM s++;
828462SApril.Chin@Sun.COM }
838462SApril.Chin@Sun.COM if (!sum->mpy)
848462SApril.Chin@Sun.COM {
858462SApril.Chin@Sun.COM sum->mpy = FNV_MULT;
868462SApril.Chin@Sun.COM if (!sum->init)
878462SApril.Chin@Sun.COM sum->init = FNV_INIT;
888462SApril.Chin@Sun.COM }
898462SApril.Chin@Sun.COM return (Sum_t*)sum;
908462SApril.Chin@Sun.COM }
918462SApril.Chin@Sun.COM
928462SApril.Chin@Sun.COM static int
prng_init(Sum_t * p)938462SApril.Chin@Sun.COM prng_init(Sum_t* p)
948462SApril.Chin@Sun.COM {
958462SApril.Chin@Sun.COM Prng_t* sum = (Prng_t*)p;
968462SApril.Chin@Sun.COM
978462SApril.Chin@Sun.COM sum->sum = sum->init;
988462SApril.Chin@Sun.COM return 0;
998462SApril.Chin@Sun.COM }
1008462SApril.Chin@Sun.COM
1018462SApril.Chin@Sun.COM static int
prng_block(Sum_t * p,const void * s,size_t n)1028462SApril.Chin@Sun.COM prng_block(Sum_t* p, const void* s, size_t n)
1038462SApril.Chin@Sun.COM {
1048462SApril.Chin@Sun.COM Prng_t* sum = (Prng_t*)p;
1058462SApril.Chin@Sun.COM register Prngnum_t c = sum->sum;
1068462SApril.Chin@Sun.COM register unsigned char* b = (unsigned char*)s;
1078462SApril.Chin@Sun.COM register unsigned char* e = b + n;
1088462SApril.Chin@Sun.COM
1098462SApril.Chin@Sun.COM while (b < e)
1108462SApril.Chin@Sun.COM c = c * sum->mpy + sum->add + *b++;
1118462SApril.Chin@Sun.COM sum->sum = c;
1128462SApril.Chin@Sun.COM return 0;
1138462SApril.Chin@Sun.COM }
114