#include "perl.h"
#ifndef PERL_MICRO
-#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
#include <signal.h>
-#endif
-
#ifndef SIG_ERR
# define SIG_ERR ((Sighandler_t) -1)
#endif
else if (PL_nomemok)
return Nullch;
else {
- PerlIO_puts(Perl_error_log,PL_no_mem) FLUSH;
+ /* Can't use PerlIO to write as it allocates memory */
+ PerlLIO_write(PerlIO_fileno(Perl_error_log),
+ PL_no_mem, strlen(PL_no_mem));
my_exit(1);
return Nullch;
}
else if (PL_nomemok)
return Nullch;
else {
- PerlIO_puts(Perl_error_log,PL_no_mem) FLUSH;
+ /* Can't use PerlIO to write as it allocates memory */
+ PerlLIO_write(PerlIO_fileno(Perl_error_log),
+ PL_no_mem, strlen(PL_no_mem));
my_exit(1);
return Nullch;
}
else if (PL_nomemok)
return Nullch;
else {
- PerlIO_puts(Perl_error_log,PL_no_mem) FLUSH;
+ /* Can't use PerlIO to write as it allocates memory */
+ PerlLIO_write(PerlIO_fileno(Perl_error_log),
+ PL_no_mem, strlen(PL_no_mem));
my_exit(1);
return Nullch;
}
CV *cv;
SV *msv;
STRLEN msglen;
+ I32 utf8 = 0;
DEBUG_S(PerlIO_printf(Perl_debug_log,
"%p: die: curstack = %p, mainstack = %p\n",
}
else
message = SvPV(msv,msglen);
+ utf8 = SvUTF8(msv);
}
else {
message = Nullch;
save_re_context();
if (message) {
msg = newSVpvn(message, msglen);
+ SvFLAGS(msg) |= utf8;
SvREADONLY_on(msg);
SAVEFREESV(msg);
}
}
PL_restartop = die_where(message, msglen);
+ SvFLAGS(ERRSV) |= utf8;
DEBUG_S(PerlIO_printf(Perl_debug_log,
"%p: die: restartop = %p, was_in_eval = %d, top_env = %p\n",
thr, PL_restartop, was_in_eval, PL_top_env));
CV *cv;
SV *msv;
STRLEN msglen;
+ I32 utf8 = 0;
if (pat) {
msv = vmess(pat, args);
}
else
message = SvPV(msv,msglen);
+ utf8 = SvUTF8(msv);
}
else {
message = Nullch;
save_re_context();
if (message) {
msg = newSVpvn(message, msglen);
+ SvFLAGS(msg) |= utf8;
SvREADONLY_on(msg);
SAVEFREESV(msg);
}
}
if (PL_in_eval) {
PL_restartop = die_where(message, msglen);
+ SvFLAGS(ERRSV) |= utf8;
JMPENV_JUMP(3);
}
else if (!message)
CV *cv;
SV *msv;
STRLEN msglen;
+ I32 utf8 = 0;
msv = vmess(pat, args);
+ utf8 = SvUTF8(msv);
message = SvPV(msv, msglen);
if (PL_warnhook) {
ENTER;
save_re_context();
msg = newSVpvn(message, msglen);
+ SvFLAGS(msg) |= utf8;
SvREADONLY_on(msg);
SAVEFREESV(msg);
CV *cv;
SV *msv;
STRLEN msglen;
+ I32 utf8 = 0;
msv = vmess(pat, args);
message = SvPV(msv, msglen);
+ utf8 = SvUTF8(msv);
if (ckDEAD(err)) {
if (PL_diehook) {
ENTER;
save_re_context();
msg = newSVpvn(message, msglen);
+ SvFLAGS(msg) |= utf8;
SvREADONLY_on(msg);
SAVEFREESV(msg);
}
if (PL_in_eval) {
PL_restartop = die_where(message, msglen);
+ SvFLAGS(ERRSV) |= utf8;
JMPENV_JUMP(3);
}
write_to_stderr(message, msglen);
ENTER;
save_re_context();
msg = newSVpvn(message, msglen);
+ SvFLAGS(msg) |= utf8;
SvREADONLY_on(msg);
SAVEFREESV(msg);
#endif /* WIN32 || NETWARE */
+#ifndef PERL_MICRO
I32
Perl_setenv_getix(pTHX_ char *nam)
{
} /* potential SEGV's */
return i;
}
+#endif /* !PERL_MICRO */
#endif /* !VMS && !EPOC*/
}
/*
-=head1 SV Manipulation Functions
-
-=for apidoc scan_vstring
-
-Returns a pointer to the next character after the parsed
-vstring, as well as updating the passed in sv.
-
-Function must be called like
-
- sv = NEWSV(92,5);
- s = scan_vstring(s,sv);
-
-The sv should already be large enough to store the vstring
-passed in, for performance reasons.
-
-=cut
-*/
-
-char *
-Perl_scan_vstring(pTHX_ char *s, SV *sv)
-{
- char *pos = s;
- char *start = s;
- if (*pos == 'v') pos++; /* get past 'v' */
- while (isDIGIT(*pos) || *pos == '_')
- pos++;
- if (!isALPHA(*pos)) {
- UV rev;
- U8 tmpbuf[UTF8_MAXLEN+1];
- U8 *tmpend;
-
- if (*s == 'v') s++; /* get past 'v' */
-
- sv_setpvn(sv, "", 0);
-
- for (;;) {
- rev = 0;
- {
- /* this is atoi() that tolerates underscores */
- char *end = pos;
- UV mult = 1;
- while (--end >= s) {
- UV orev;
- if (*end == '_')
- continue;
- orev = rev;
- rev += (*end - '0') * mult;
- mult *= 10;
- if (orev > rev && ckWARN_d(WARN_OVERFLOW))
- Perl_warner(aTHX_ packWARN(WARN_OVERFLOW),
- "Integer overflow in decimal number");
- }
- }
-#ifdef EBCDIC
- if (rev > 0x7FFFFFFF)
- Perl_croak(aTHX_ "In EBCDIC the v-string components cannot exceed 2147483647");
-#endif
- /* Append native character for the rev point */
- tmpend = uvchr_to_utf8(tmpbuf, rev);
- sv_catpvn(sv, (const char*)tmpbuf, tmpend - tmpbuf);
- if (!UNI_IS_INVARIANT(NATIVE_TO_UNI(rev)))
- SvUTF8_on(sv);
- if (*pos == '.' && isDIGIT(pos[1]))
- s = ++pos;
- else {
- s = pos;
- break;
- }
- while (isDIGIT(*pos) || *pos == '_')
- pos++;
- }
- SvPOK_on(sv);
- sv_magic(sv,NULL,PERL_MAGIC_vstring,(const char*)start, pos-start);
- SvRMAGICAL_on(sv);
- }
- return s;
-}
-
-/*
=for apidoc scan_version
Returns a pointer to the next character after the parsed
Function must be called with an already existing SV like
- sv = NEWSV(92,0);
- s = scan_version(s,sv);
+ sv = newSV(0);
+ s = scan_version(s,SV *sv, bool qv);
Performs some preprocessing to the string to ensure that
it has the correct characteristics of a version. Flags the
object if it contains an underscore (which denotes this
-is a beta version).
+is a alpha version). The boolean qv denotes that the version
+should be interpreted as if it had multiple decimals, even if
+it doesn't.
=cut
*/
char *
-Perl_scan_version(pTHX_ char *s, SV *rv)
+Perl_scan_version(pTHX_ char *s, SV *rv, bool qv)
{
const char *start = s;
char *pos = s;
}
pos = s;
- if (*pos == 'v') pos++; /* get past 'v' */
+ if (*pos == 'v') {
+ pos++; /* get past 'v' */
+ qv = 1; /* force quoted version processing */
+ }
while (isDIGIT(*pos))
pos++;
if (!isALPHA(*pos)) {
I32 mult = 1;
I32 orev;
if ( s < pos && s > start && *(s-1) == '_' ) {
- mult *= -1; /* beta version */
+ mult *= -1; /* alpha version */
}
/* the following if() will only be true after the decimal
* point of a version originally created with a bare
* floating point number, i.e. not quoted in any way
*/
- if ( s > start+1 && saw_period == 1 && !saw_under ) {
+ if ( !qv && s > start+1 && saw_period == 1 && !saw_under ) {
mult = 100;
while ( s < end ) {
orev = rev;
Perl_new_version(pTHX_ SV *ver)
{
SV *rv = newSV(0);
- char *version;
- if ( SvNOK(ver) ) /* may get too much accuracy */
- {
- char tbuf[64];
- sprintf(tbuf,"%.9"NVgf, SvNVX(ver));
- version = savepv(tbuf);
- }
#ifdef SvVOK
- else if ( SvVOK(ver) ) { /* already a v-string */
+ if ( SvVOK(ver) ) { /* already a v-string */
+ char *version;
MAGIC* mg = mg_find(ver,PERL_MAGIC_vstring);
version = savepvn( (const char*)mg->mg_ptr,mg->mg_len );
+ sv_setpv(rv,version);
+ Safefree(version);
}
+ else {
#endif
- else /* must be a string or something like a string */
- {
- version = (char *)SvPV(ver,PL_na);
+ sv_setsv(rv,ver); /* make a duplicate */
+#ifdef SvVOK
}
- version = scan_version(version,rv);
+#endif
+ upg_version(rv);
return rv;
}
SV *
Perl_upg_version(pTHX_ SV *ver)
{
- char *version = savepvn(SvPVX(ver),SvCUR(ver));
+ char *version;
+ bool qv = 0;
+
+ if ( SvNOK(ver) ) /* may get too much accuracy */
+ {
+ char tbuf[64];
+ sprintf(tbuf,"%.9"NVgf, SvNVX(ver));
+ version = savepv(tbuf);
+ }
#ifdef SvVOK
- if ( SvVOK(ver) ) { /* already a v-string */
+ else if ( SvVOK(ver) ) { /* already a v-string */
MAGIC* mg = mg_find(ver,PERL_MAGIC_vstring);
version = savepvn( (const char*)mg->mg_ptr,mg->mg_len );
+ qv = 1;
}
#endif
- version = scan_version(version,ver);
+ else /* must be a string or something like a string */
+ {
+ STRLEN n_a;
+ version = savepv(SvPV(ver,n_a));
+ }
+ (void)scan_version(version, ver, qv);
+ Safefree(version);
return ver;
}
Perl_vnumify(pTHX_ SV *vs)
{
I32 i, len, digit;
- SV *sv = NEWSV(92,0);
+ SV *sv = newSV(0);
if ( SvROK(vs) )
vs = SvRV(vs);
len = av_len((AV *)vs);
Perl_vstringify(pTHX_ SV *vs)
{
I32 i, len, digit;
- SV *sv = NEWSV(92,0);
+ SV *sv = newSV(0);
if ( SvROK(vs) )
vs = SvRV(vs);
len = av_len((AV *)vs);
else
Perl_sv_catpvf(aTHX_ sv,".%"IVdf,(IV)digit);
}
- if ( len == 0 )
- Perl_sv_catpv(aTHX_ sv,".0");
+
+ if ( len <= 2 ) { /* short version, must be at least three */
+ for ( len = 2 - len; len != 0; len-- )
+ Perl_sv_catpv(aTHX_ sv,".0");
+ }
+
return sv;
}
{
I32 left = SvIV(*av_fetch((AV *)lsv,i,0));
I32 right = SvIV(*av_fetch((AV *)rsv,i,0));
- bool lbeta = left < 0 ? 1 : 0;
- bool rbeta = right < 0 ? 1 : 0;
- left = PERL_ABS(left);
- right = PERL_ABS(right);
- if ( left < right || (left == right && lbeta && !rbeta) )
+ bool lalpha = left < 0 ? 1 : 0;
+ bool ralpha = right < 0 ? 1 : 0;
+ left = abs(left);
+ right = abs(right);
+ if ( left < right || (left == right && lalpha && !ralpha) )
retval = -1;
- if ( left > right || (left == right && rbeta && !lbeta) )
+ if ( left > right || (left == right && ralpha && !lalpha) )
retval = +1;
i++;
}
- if ( l != r && retval == 0 ) /* possible match except for trailing 0 */
+ if ( l != r && retval == 0 ) /* possible match except for trailing 0's */
{
- if ( !( l < r && r-l == 1 && SvIV(*av_fetch((AV *)rsv,r,0)) == 0 ) &&
- !( l-r == 1 && SvIV(*av_fetch((AV *)lsv,l,0)) == 0 ) )
+ if ( l < r )
{
- retval = l < r ? -1 : +1; /* not a match after all */
+ while ( i <= r && retval == 0 )
+ {
+ if ( SvIV(*av_fetch((AV *)rsv,i,0)) != 0 )
+ retval = -1; /* not a match after all */
+ i++;
+ }
+ }
+ else
+ {
+ while ( i <= l && retval == 0 )
+ {
+ if ( SvIV(*av_fetch((AV *)lsv,i,0)) != 0 )
+ retval = +1; /* not a match after all */
+ i++;
+ }
}
}
return retval;
return u;
}
+UV
+Perl_get_hash_seed(pTHX)
+{
+ 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;
+}