+U32
+Perl_parse_unicode_opts(pTHX_ const char **popt)
+{
+ const char *p = *popt;
+ U32 opt = 0;
+
+ if (*p) {
+ if (isDIGIT(*p)) {
+ opt = (U32) atoi(p);
+ while (isDIGIT(*p)) p++;
+ if (*p && *p != '\n' && *p != '\r')
+ Perl_croak(aTHX_ "Unknown Unicode option letter '%c'", *p);
+ }
+ else {
+ for (; *p; p++) {
+ switch (*p) {
+ case PERL_UNICODE_STDIN:
+ opt |= PERL_UNICODE_STDIN_FLAG; break;
+ case PERL_UNICODE_STDOUT:
+ opt |= PERL_UNICODE_STDOUT_FLAG; break;
+ case PERL_UNICODE_STDERR:
+ opt |= PERL_UNICODE_STDERR_FLAG; break;
+ case PERL_UNICODE_STD:
+ opt |= PERL_UNICODE_STD_FLAG; break;
+ case PERL_UNICODE_IN:
+ opt |= PERL_UNICODE_IN_FLAG; break;
+ case PERL_UNICODE_OUT:
+ opt |= PERL_UNICODE_OUT_FLAG; break;
+ case PERL_UNICODE_INOUT:
+ opt |= PERL_UNICODE_INOUT_FLAG; break;
+ case PERL_UNICODE_LOCALE:
+ opt |= PERL_UNICODE_LOCALE_FLAG; break;
+ case PERL_UNICODE_ARGV:
+ opt |= PERL_UNICODE_ARGV_FLAG; break;
+ default:
+ if (*p != '\n' && *p != '\r')
+ Perl_croak(aTHX_
+ "Unknown Unicode option letter '%c'", *p);
+ }
+ }
+ }
+ }
+ else
+ opt = PERL_UNICODE_DEFAULT_FLAGS;
+
+ if (opt & ~PERL_UNICODE_ALL_FLAGS)
+ Perl_croak(aTHX_ "Unknown Unicode option value %"UVuf,
+ (UV) (opt & ~PERL_UNICODE_ALL_FLAGS));
+
+ *popt = p;
+
+ return opt;
+}
+
+U32
+Perl_seed(pTHX)
+{
+ /*
+ * This is really just a quick hack which grabs various garbage
+ * values. It really should be a real hash algorithm which
+ * spreads the effect of every input bit onto every output bit,
+ * if someone who knows about such things would bother to write it.
+ * Might be a good idea to add that function to CORE as well.
+ * No numbers below come from careful analysis or anything here,
+ * except they are primes and SEED_C1 > 1E6 to get a full-width
+ * value from (tv_sec * SEED_C1 + tv_usec). The multipliers should
+ * probably be bigger too.
+ */
+#if RANDBITS > 16
+# define SEED_C1 1000003
+#define SEED_C4 73819
+#else
+# define SEED_C1 25747
+#define SEED_C4 20639
+#endif
+#define SEED_C2 3
+#define SEED_C3 269
+#define SEED_C5 26107
+
+#ifndef PERL_NO_DEV_RANDOM
+ int fd;
+#endif
+ U32 u;
+#ifdef VMS
+# include <starlet.h>
+ /* when[] = (low 32 bits, high 32 bits) of time since epoch
+ * in 100-ns units, typically incremented ever 10 ms. */
+ unsigned int when[2];
+#else
+# ifdef HAS_GETTIMEOFDAY
+ struct timeval when;
+# else
+ Time_t when;
+# endif
+#endif
+
+/* This test is an escape hatch, this symbol isn't set by Configure. */
+#ifndef PERL_NO_DEV_RANDOM
+#ifndef PERL_RANDOM_DEVICE
+ /* /dev/random isn't used by default because reads from it will block
+ * if there isn't enough entropy available. You can compile with
+ * PERL_RANDOM_DEVICE to it if you'd prefer Perl to block until there
+ * is enough real entropy to fill the seed. */
+# define PERL_RANDOM_DEVICE "/dev/urandom"
+#endif
+ fd = PerlLIO_open(PERL_RANDOM_DEVICE, 0);
+ if (fd != -1) {
+ if (PerlLIO_read(fd, (void*)&u, sizeof u) != sizeof u)
+ u = 0;
+ PerlLIO_close(fd);
+ if (u)
+ return u;
+ }
+#endif
+
+#ifdef VMS
+ _ckvmssts(sys$gettim(when));
+ u = (U32)SEED_C1 * when[0] + (U32)SEED_C2 * when[1];
+#else
+# ifdef HAS_GETTIMEOFDAY
+ PerlProc_gettimeofday(&when,NULL);
+ u = (U32)SEED_C1 * when.tv_sec + (U32)SEED_C2 * when.tv_usec;
+# else
+ (void)time(&when);
+ u = (U32)SEED_C1 * when;
+# endif
+#endif
+ u += SEED_C3 * (U32)PerlProc_getpid();
+ u += SEED_C4 * (U32)PTR2UV(PL_stack_sp);
+#ifndef PLAN9 /* XXX Plan9 assembler chokes on this; fix needed */
+ u += SEED_C5 * (U32)PTR2UV(&when);
+#endif
+ return u;
+}
+
+UV
+Perl_get_hash_seed(pTHX)
+{
+ const char *s = PerlEnv_getenv("PERL_HASH_SEED");
+ UV myseed = 0;
+
+ if (s)
+ while (isSPACE(*s)) s++;
+ if (s && isDIGIT(*s))
+ myseed = (UV)Atoul(s);
+ else
+#ifdef USE_HASH_SEED_EXPLICIT
+ if (s)
+#endif
+ {
+ /* Compute a random seed */
+ (void)seedDrand01((Rand_seed_t)seed());
+ myseed = (UV)(Drand01() * (NV)UV_MAX);
+#if RANDBITS < (UVSIZE * 8)
+ /* Since there are not enough randbits to to reach all
+ * the bits of a UV, the low bits might need extra
+ * help. Sum in another random number that will
+ * fill in the low bits. */
+ myseed +=
+ (UV)(Drand01() * (NV)((1 << ((UVSIZE * 8 - RANDBITS))) - 1));
+#endif /* RANDBITS < (UVSIZE * 8) */
+ if (myseed == 0) { /* Superparanoia. */
+ myseed = (UV)(Drand01() * (NV)UV_MAX); /* One more chance. */
+ if (myseed == 0)
+ Perl_croak(aTHX_ "Your random numbers are not that random");
+ }
+ }
+ PL_rehash_seed_set = TRUE;
+
+ return myseed;
+}
+
+#ifdef PERL_GLOBAL_STRUCT
+
+struct perl_vars *
+Perl_init_global_struct(pTHX)
+{
+ struct perl_vars *plvarsp = NULL;
+#ifdef PERL_GLOBAL_STRUCT
+# define PERL_GLOBAL_STRUCT_INIT
+# include "opcode.h" /* the ppaddr and check */
+ IV nppaddr = sizeof(Gppaddr)/sizeof(Perl_ppaddr_t);
+ IV ncheck = sizeof(Gcheck) /sizeof(Perl_check_t);
+# ifdef PERL_GLOBAL_STRUCT_PRIVATE
+ /* PerlMem_malloc() because can't use even safesysmalloc() this early. */
+ plvarsp = (struct perl_vars*)PerlMem_malloc(sizeof(struct perl_vars));
+ if (!plvarsp)
+ exit(1);
+# else
+ plvarsp = PL_VarsPtr;
+# endif /* PERL_GLOBAL_STRUCT_PRIVATE */
+# undef PERLVAR
+# undef PERLVARA
+# undef PERLVARI
+# undef PERLVARIC
+# undef PERLVARISC
+# define PERLVAR(var,type) /**/
+# define PERLVARA(var,n,type) /**/
+# define PERLVARI(var,type,init) plvarsp->var = init;
+# define PERLVARIC(var,type,init) plvarsp->var = init;
+# define PERLVARISC(var,init) Copy(init, plvarsp->var, sizeof(init), char);
+# include "perlvars.h"
+# undef PERLVAR
+# undef PERLVARA
+# undef PERLVARI
+# undef PERLVARIC
+# undef PERLVARISC
+# ifdef PERL_GLOBAL_STRUCT
+ plvarsp->Gppaddr = PerlMem_malloc(nppaddr * sizeof(Perl_ppaddr_t));
+ if (!plvarsp->Gppaddr)
+ exit(1);
+ plvarsp->Gcheck = PerlMem_malloc(ncheck * sizeof(Perl_check_t));
+ if (!plvarsp->Gcheck)
+ exit(1);
+ Copy(Gppaddr, plvarsp->Gppaddr, nppaddr, Perl_ppaddr_t);
+ Copy(Gcheck, plvarsp->Gcheck, ncheck, Perl_check_t);
+# endif
+# ifdef PERL_SET_VARS
+ PERL_SET_VARS(plvarsp);
+# endif
+# undef PERL_GLOBAL_STRUCT_INIT
+#endif
+ return plvarsp;
+}
+
+#endif /* PERL_GLOBAL_STRUCT */
+
+#ifdef PERL_GLOBAL_STRUCT
+
+void
+Perl_free_global_struct(pTHX_ struct perl_vars *plvarsp)
+{
+#ifdef PERL_GLOBAL_STRUCT
+# ifdef PERL_UNSET_VARS
+ PERL_UNSET_VARS(plvarsp);
+# endif
+ free(plvarsp->Gppaddr);
+ free(plvarsp->Gcheck);
+# ifdef PERL_GLOBAL_STRUCT_PRIVATE
+ free(plvarsp);
+# endif
+#endif
+}
+
+#endif /* PERL_GLOBAL_STRUCT */
+
+/*
+ * Local variables:
+ * c-indentation-style: bsd
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 noet:
+*/