#endif
+#if defined(HAS_FCNTL) && defined(F_SETFD) && !defined(FD_CLOEXEC)
+# define FD_CLOEXEC 1 /* NeXT needs this */
+#endif
+
/* paranoid version of system's malloc() */
/* NOTE: Do not call the next three routines directly. Use the macros
Malloc_t
Perl_safesysmalloc(MEM_SIZE size)
{
+ dTHX;
Malloc_t ptr;
#ifdef HAS_64K_LIMIT
if (size > 0xffff) {
- PerlIO_printf(PerlIO_stderr(), "Allocation too large: %lx\n", size) FLUSH;
- WITH_THX(my_exit(1));
+ PerlIO_printf(PerlIO_stderr(),
+ "Allocation too large: %lx\n", size) FLUSH;
+ my_exit(1);
}
#endif /* HAS_64K_LIMIT */
#ifdef DEBUGGING
Perl_croak_nocontext("panic: malloc");
#endif
ptr = PerlMem_malloc(size?size:1); /* malloc(0) is NASTY on our system */
-#if !(defined(I286) || defined(atarist))
- DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%x: (%05d) malloc %ld bytes\n",ptr,PL_an++,(long)size));
-#else
DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) malloc %ld bytes\n",ptr,PL_an++,(long)size));
-#endif
if (ptr != Nullch)
return ptr;
else if (PL_nomemok)
return Nullch;
else {
PerlIO_puts(PerlIO_stderr(),PL_no_mem) FLUSH;
- WITH_THX(my_exit(1));
+ my_exit(1);
return Nullch;
}
/*NOTREACHED*/
Malloc_t
Perl_safesysrealloc(Malloc_t where,MEM_SIZE size)
{
+ dTHX;
Malloc_t ptr;
#if !defined(STANDARD_C) && !defined(HAS_REALLOC_PROTOTYPE)
Malloc_t PerlMem_realloc();
if (size > 0xffff) {
PerlIO_printf(PerlIO_stderr(),
"Reallocation too large: %lx\n", size) FLUSH;
- WITH_THX(my_exit(1));
+ my_exit(1);
}
#endif /* HAS_64K_LIMIT */
if (!size) {
#endif
ptr = PerlMem_realloc(where,size);
-#if !(defined(I286) || defined(atarist))
- DEBUG_m( {
- PerlIO_printf(Perl_debug_log, "0x%x: (%05d) rfree\n",where,PL_an++);
- PerlIO_printf(Perl_debug_log, "0x%x: (%05d) realloc %ld bytes\n",ptr,PL_an++,(long)size);
- } )
-#else
- DEBUG_m( {
- PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) rfree\n",where,PL_an++);
- PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) realloc %ld bytes\n",ptr,PL_an++,(long)size);
- } )
-#endif
+ DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) rfree\n",where,PL_an++));
+ DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) realloc %ld bytes\n",ptr,PL_an++,(long)size));
if (ptr != Nullch)
return ptr;
return Nullch;
else {
PerlIO_puts(PerlIO_stderr(),PL_no_mem) FLUSH;
- WITH_THX(my_exit(1));
+ my_exit(1);
return Nullch;
}
/*NOTREACHED*/
Free_t
Perl_safesysfree(Malloc_t where)
{
-#if !(defined(I286) || defined(atarist))
- DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%x: (%05d) free\n",(char *) where,PL_an++));
-#else
+ dTHX;
DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) free\n",(char *) where,PL_an++));
-#endif
if (where) {
/*SUPPRESS 701*/
PerlMem_free(where);
Malloc_t
Perl_safesyscalloc(MEM_SIZE count, MEM_SIZE size)
{
+ dTHX;
Malloc_t ptr;
#ifdef HAS_64K_LIMIT
if (size * count > 0xffff) {
PerlIO_printf(PerlIO_stderr(),
"Allocation too large: %lx\n", size * count) FLUSH;
- WITH_THX(my_exit(1));
+ my_exit(1);
}
#endif /* HAS_64K_LIMIT */
#ifdef DEBUGGING
#endif
size *= count;
ptr = PerlMem_malloc(size?size:1); /* malloc(0) is NASTY on our system */
-#if !(defined(I286) || defined(atarist))
- DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%x: (%05d) calloc %ld x %ld bytes\n",ptr,PL_an++,(long)count,(long)size));
-#else
DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) calloc %ld x %ld bytes\n",ptr,PL_an++,(long)count,(long)size));
-#endif
if (ptr != Nullch) {
memset((void*)ptr, 0, size);
return ptr;
return Nullch;
else {
PerlIO_puts(PerlIO_stderr(),PL_no_mem) FLUSH;
- WITH_THX(my_exit(1));
+ my_exit(1);
return Nullch;
}
/*NOTREACHED*/
}
void
-perl_set_numeric_radix(void)
+Perl_set_numeric_radix(pTHX)
{
#ifdef USE_LOCALE_NUMERIC
# ifdef HAS_LOCALECONV
PL_numeric_name = savepv(newnum);
PL_numeric_standard = (strEQ(newnum, "C") || strEQ(newnum, "POSIX"));
PL_numeric_local = TRUE;
- perl_set_numeric_radix();
+ set_numeric_radix();
}
#endif /* USE_LOCALE_NUMERIC */
setlocale(LC_NUMERIC, PL_numeric_name);
PL_numeric_standard = FALSE;
PL_numeric_local = TRUE;
- perl_set_numeric_radix();
+ set_numeric_radix();
}
#endif /* USE_LOCALE_NUMERIC */
return sv;
}
-#ifdef PERL_IMPLICIT_CONTEXT
+#if defined(PERL_IMPLICIT_CONTEXT)
char *
Perl_form_nocontext(const char* pat, ...)
{
dTHX;
- SV *sv = mess_alloc();
+ char *retval;
va_list args;
va_start(args, pat);
- sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+ retval = vform(pat, &args);
va_end(args);
- return SvPVX(sv);
+ return retval;
}
-#endif
+#endif /* PERL_IMPLICIT_CONTEXT */
char *
Perl_form(pTHX_ const char* pat, ...)
{
- SV *sv = mess_alloc();
+ char *retval;
va_list args;
va_start(args, pat);
- sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*));
+ retval = vform(pat, &args);
va_end(args);
+ return retval;
+}
+
+char *
+Perl_vform(pTHX_ const char *pat, va_list *args)
+{
+ SV *sv = mess_alloc();
+ sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
return SvPVX(sv);
}
+#if defined(PERL_IMPLICIT_CONTEXT)
+SV *
+Perl_mess_nocontext(const char *pat, ...)
+{
+ dTHX;
+ SV *retval;
+ va_list args;
+ va_start(args, pat);
+ retval = vmess(pat, &args);
+ va_end(args);
+ return retval;
+}
+#endif /* PERL_IMPLICIT_CONTEXT */
+
SV *
-Perl_mess(pTHX_ const char *pat, va_list *args)
+Perl_mess(pTHX_ const char *pat, ...)
+{
+ SV *retval;
+ va_list args;
+ va_start(args, pat);
+ retval = vmess(pat, &args);
+ va_end(args);
+ return retval;
+}
+
+SV *
+Perl_vmess(pTHX_ const char *pat, va_list *args)
{
SV *sv = mess_alloc();
static char dgd[] = " during global destruction.\n";
sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
if (!SvCUR(sv) || *(SvEND(sv) - 1) != '\n') {
dTHR;
+#ifdef IV_IS_QUAD
+ if (PL_curcop->cop_line)
+ Perl_sv_catpvf(aTHX_ sv, " at %_ line %" PERL_PRId64,
+ GvSV(PL_curcop->cop_filegv), (IV)PL_curcop->cop_line);
+#else
if (PL_curcop->cop_line)
Perl_sv_catpvf(aTHX_ sv, " at %_ line %ld",
GvSV(PL_curcop->cop_filegv), (long)PL_curcop->cop_line);
+#endif
if (GvIO(PL_last_in_gv) && IoLINES(GvIOp(PL_last_in_gv))) {
bool line_mode = (RsSIMPLE(PL_rs) &&
SvCUR(PL_rs) == 1 && *SvPVX(PL_rs) == '\n');
+#ifdef IV_IS_QUAD
+ Perl_sv_catpvf(aTHX_ sv, ", <%s> %s %" PERL_PRId64,
+ PL_last_in_gv == PL_argvgv ? "" : GvNAME(PL_last_in_gv),
+ line_mode ? "line" : "chunk",
+ (IV)IoLINES(GvIOp(PL_last_in_gv)));
+#else
Perl_sv_catpvf(aTHX_ sv, ", <%s> %s %ld",
PL_last_in_gv == PL_argvgv ? "" : GvNAME(PL_last_in_gv),
line_mode ? "line" : "chunk",
(long)IoLINES(GvIOp(PL_last_in_gv)));
+#endif
}
+#ifdef USE_THREADS
+ if (thr->tid)
+ Perl_sv_catpvf(aTHX_ sv, " thread %ld", thr->tid);
+#endif
sv_catpv(sv, PL_dirty ? dgd : ".\n");
}
return sv;
}
-STATIC OP *
-S_do_die(pTHX_ const char* pat, va_list *args)
+OP *
+Perl_vdie(pTHX_ const char* pat, va_list *args)
{
dTHR;
char *message;
thr, PL_curstack, PL_mainstack));
if (pat) {
- msv = mess(pat, args);
- message = SvPV(msv,msglen);
+ msv = vmess(pat, args);
+ if (PL_errors && SvCUR(PL_errors)) {
+ sv_catsv(PL_errors, msv);
+ message = SvPV(PL_errors, msglen);
+ SvCUR_set(PL_errors, 0);
+ }
+ else
+ message = SvPV(msv,msglen);
}
else {
message = Nullch;
PUSHMARK(SP);
XPUSHs(msg);
PUTBACK;
- call_sv((SV*)cv, G_DISCARD);
+ /* HACK - REVISIT - avoid CATCH_SET(TRUE) in call_sv()
+ or we come back here due to a JMPENV_JMP() and do
+ a POPSTACK - but die_where() will have already done
+ one as it unwound - NI-S 1999/08/14 */
+ call_sv((SV*)cv, G_DISCARD|G_NOCATCH);
POPSTACK;
LEAVE;
}
return PL_restartop;
}
-#ifdef PERL_IMPLICIT_CONTEXT
+#if defined(PERL_IMPLICIT_CONTEXT)
OP *
Perl_die_nocontext(const char* pat, ...)
{
OP *o;
va_list args;
va_start(args, pat);
- o = do_die(aTHX_ pat, &args);
+ o = vdie(pat, &args);
va_end(args);
return o;
}
-#endif
+#endif /* PERL_IMPLICIT_CONTEXT */
OP *
Perl_die(pTHX_ const char* pat, ...)
OP *o;
va_list args;
va_start(args, pat);
- o = do_die(aTHX_ pat, &args);
+ o = vdie(pat, &args);
va_end(args);
return o;
}
-STATIC void
-S_do_croak(pTHX_ const char* pat, va_list *args)
+void
+Perl_vcroak(pTHX_ const char* pat, va_list *args)
{
dTHR;
char *message;
SV *msv;
STRLEN msglen;
- msv = mess(pat, args);
- message = SvPV(msv,msglen);
- DEBUG_S(PerlIO_printf(PerlIO_stderr(), "croak: 0x%lx %s", (unsigned long) thr, message));
+ msv = vmess(pat, args);
+ if (PL_errors && SvCUR(PL_errors)) {
+ sv_catsv(PL_errors, msv);
+ message = SvPV(PL_errors, msglen);
+ SvCUR_set(PL_errors, 0);
+ }
+ else
+ message = SvPV(msv,msglen);
+
+ DEBUG_S(PerlIO_printf(PerlIO_stderr(), "croak: 0x%lx %s",
+ (unsigned long) thr, message));
+
if (PL_diehook) {
/* sv_2cv might call Perl_croak() */
SV *olddiehook = PL_diehook;
my_failure_exit();
}
-#ifdef PERL_IMPLICIT_CONTEXT
+#if defined(PERL_IMPLICIT_CONTEXT)
void
Perl_croak_nocontext(const char *pat, ...)
{
dTHX;
va_list args;
va_start(args, pat);
- do_croak(pat, &args);
+ vcroak(pat, &args);
/* NOTREACHED */
va_end(args);
}
{
va_list args;
va_start(args, pat);
- do_croak(pat, &args);
+ vcroak(pat, &args);
/* NOTREACHED */
va_end(args);
}
-STATIC void
-S_do_warn(pTHX_ const char* pat, va_list *args)
+void
+Perl_vwarn(pTHX_ const char* pat, va_list *args)
{
char *message;
HV *stash;
SV *msv;
STRLEN msglen;
- msv = mess(pat, args);
+ msv = vmess(pat, args);
message = SvPV(msv, msglen);
if (PL_warnhook) {
(void)PerlIO_flush(PerlIO_stderr());
}
-#ifdef PERL_IMPLICIT_CONTEXT
+#if defined(PERL_IMPLICIT_CONTEXT)
void
Perl_warn_nocontext(const char *pat, ...)
{
dTHX;
va_list args;
va_start(args, pat);
- do_warn(pat, &args);
+ vwarn(pat, &args);
va_end(args);
}
#endif /* PERL_IMPLICIT_CONTEXT */
{
va_list args;
va_start(args, pat);
- do_warn(pat, &args);
+ vwarn(pat, &args);
+ va_end(args);
+}
+
+#if defined(PERL_IMPLICIT_CONTEXT)
+void
+Perl_warner_nocontext(U32 err, const char *pat, ...)
+{
+ dTHX;
+ va_list args;
+ va_start(args, pat);
+ vwarner(err, pat, &args);
va_end(args);
}
+#endif /* PERL_IMPLICIT_CONTEXT */
void
Perl_warner(pTHX_ U32 err, const char* pat,...)
{
- dTHR;
va_list args;
+ va_start(args, pat);
+ vwarner(err, pat, &args);
+ va_end(args);
+}
+
+void
+Perl_vwarner(pTHX_ U32 err, const char* pat, va_list* args)
+{
+ dTHR;
char *message;
HV *stash;
GV *gv;
SV *msv;
STRLEN msglen;
- va_start(args, pat);
- msv = mess(pat, &args);
+ msv = vmess(pat, args);
message = SvPV(msv, msglen);
- va_end(args);
if (ckDEAD(err)) {
#ifdef USE_THREADS
}
#ifndef VMS /* VMS' my_setenv() is in VMS.c */
-#if !defined(WIN32) && !defined(CYGWIN32)
+#if !defined(WIN32) && !defined(CYGWIN)
void
Perl_my_setenv(pTHX_ char *nam, char *val)
{
safesysfree(environ[i]);
environ[i] = (char*)safesysmalloc((strlen(nam)+strlen(val)+2) * sizeof(char));
-#ifndef MSDOS
(void)sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
-#else
- /* MS-DOS requires environment variable names to be in uppercase */
- /* [Tom Dinger, 27 August 1990: Well, it doesn't _require_ it, but
- * some utilities and applications may break because they only look
- * for upper case strings. (Fixed strupr() bug here.)]
- */
- strcpy(environ[i],nam); strupr(environ[i]);
- (void)sprintf(environ[i] + strlen(nam),"=%s",val);
-#endif /* MSDOS */
#else /* PERL_USE_SAFE_PUTENV */
char *new_env;
new_env = (char*)safesysmalloc((strlen(nam) + strlen(val) + 2) * sizeof(char));
-#ifndef MSDOS
(void)sprintf(new_env,"%s=%s",nam,val);/* all that work just for this */
-#else
- strcpy(new_env,nam); strupr(new_env);
- (void)sprintf(new_env + strlen(nam),"=%s",val);
-#endif
(void)putenv(new_env);
#endif /* PERL_USE_SAFE_PUTENV */
}
+#else /* WIN32 || CYGWIN */
+#if defined(CYGWIN)
+/*
+ * Save environ of perl.exe, currently Cygwin links in separate environ's
+ * for each exe/dll. Probably should be a member of impure_ptr.
+ */
+static char ***Perl_main_environ;
+
+EXTERN_C void
+Perl_my_setenv_init(char ***penviron)
+{
+ Perl_main_environ = penviron;
+}
+
+void
+my_setenv(char *nam, char *val)
+{
+ /* You can not directly manipulate the environ[] array because
+ * the routines do some additional work that syncs the Cygwin
+ * environment with the Windows environment.
+ */
+ char *oldstr = environ[setenv_getix(nam)];
+
+ if (!val) {
+ if (!oldstr)
+ return;
+ unsetenv(nam);
+ Safefree(oldstr);
+ return;
+ }
+ setenv(nam, val, 1);
+ environ = *Perl_main_environ; /* environ realloc can occur in setenv */
+ if(oldstr && environ[setenv_getix(nam)] != oldstr)
+ Safefree(oldstr);
+}
#else /* if WIN32 */
void
}
#endif /* WIN32 */
+#endif
I32
Perl_setenv_getix(pTHX_ char *nam)
{
int p[2];
register I32 This, that;
- register I32 pid;
+ register Pid_t pid;
SV *sv;
I32 doexec = strNE(cmd,"-");
I32 did_pipes = 0;
#endif /* defined OS2 */
/*SUPPRESS 560*/
if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
- sv_setiv(GvSV(tmpgv), (IV)getpid());
+ sv_setiv(GvSV(tmpgv), getpid());
PL_forkprocess = 0;
hv_clear(PL_pidstatus); /* we have no children */
return Nullfp;
break;
n += n1;
}
+ PerlLIO_close(pp[0]);
+ did_pipes = 0;
if (n) { /* Error */
if (n != sizeof(int))
Perl_croak(aTHX_ "panic: kid popen errno read");
- PerlLIO_close(pp[0]);
errno = errkid; /* Propagate errno from kid */
return Nullfp;
}
Sigsave_t hstat, istat, qstat;
int status;
SV **svp;
- int pid;
- int pid2;
+ Pid_t pid;
+ Pid_t pid2;
bool close_failed;
int saved_errno;
#ifdef VMS
#endif
svp = av_fetch(PL_fdpid,PerlIO_fileno(ptr),TRUE);
- pid = (int)SvIVX(*svp);
+ pid = SvIVX(*svp);
SvREFCNT_dec(*svp);
*svp = &PL_sv_undef;
#ifdef OS2
}
#endif /* !DOSISH */
-#if !defined(DOSISH) || defined(OS2) || defined(WIN32) || defined(CYGWIN32)
+#if !defined(DOSISH) || defined(OS2) || defined(WIN32)
I32
-Perl_wait4pid(pTHX_ int pid, int *statusp, int flags)
+Perl_wait4pid(pTHX_ Pid_t pid, int *statusp, int flags)
{
SV *sv;
SV** svp;
void
/*SUPPRESS 590*/
-Perl_pidgone(pTHX_ int pid, int status)
+Perl_pidgone(pTHX_ Pid_t pid, int status)
{
register SV *sv;
char spid[TYPE_CHARS(int)];
/* Needs work for PerlIO ! */
FILE *f = PerlIO_findFILE(ptr);
I32 result = pclose(f);
+#if defined(DJGPP)
+ result = (result << 8) & 0xff00;
+#endif
PerlIO_releaseFILE(ptr,f);
return result;
}
}
U32
-Perl_cast_ulong(pTHX_ double f)
+Perl_cast_ulong(pTHX_ NV f)
{
long along;
#endif
I32
-Perl_cast_i32(pTHX_ double f)
+Perl_cast_i32(pTHX_ NV f)
{
if (f >= I32_MAX)
return (I32) I32_MAX;
}
IV
-Perl_cast_iv(pTHX_ double f)
+Perl_cast_iv(pTHX_ NV f)
{
if (f >= IV_MAX) {
UV uv;
- if (f >= (double)UV_MAX)
+ if (f >= (NV)UV_MAX)
return (IV) UV_MAX;
uv = (UV) f;
return (IV)uv;
}
UV
-Perl_cast_uv(pTHX_ double f)
+Perl_cast_uv(pTHX_ NV f)
{
if (f >= MY_UV_MAX)
return (UV) MY_UV_MAX;
}
#endif /* !HAS_RENAME */
-UV
+NV
Perl_scan_bin(pTHX_ char *start, I32 len, I32 *retlen)
{
register char *s = start;
- register UV retval = 0;
- bool overflowed = FALSE;
- while (len && *s >= '0' && *s <= '1') {
- register UV n = retval << 1;
- if (!overflowed && (n >> 1) != retval) {
- Perl_warn(aTHX_ "Integer overflow in binary number");
- overflowed = TRUE;
- }
- retval = n | (*s++ - '0');
- len--;
- }
- if (len && (*s >= '2' && *s <= '9')) {
- dTHR;
- if (ckWARN(WARN_UNSAFE))
- Perl_warner(aTHX_ WARN_UNSAFE, "Illegal binary digit '%c' ignored", *s);
+ register NV rnv = 0.0;
+ register UV ruv = 0;
+ register bool seenb = FALSE;
+ register bool overflowed = FALSE;
+
+ for (; len-- && *s; s++) {
+ if (!(*s == '0' || *s == '1')) {
+ if (*s == '_')
+ continue; /* Note: does not check for __ and the like. */
+ if (seenb == FALSE && *s == 'b' && ruv == 0) {
+ /* Disallow 0bbb0b0bbb... */
+ seenb = TRUE;
+ continue;
+ }
+ else {
+ dTHR;
+ if (ckWARN(WARN_DIGIT))
+ Perl_warner(aTHX_ WARN_DIGIT,
+ "Illegal binary digit '%c' ignored", *s);
+ break;
+ }
+ }
+ if (!overflowed) {
+ register UV xuv = ruv << 1;
+
+ if ((xuv >> 1) != ruv) {
+ dTHR;
+ overflowed = TRUE;
+ rnv = (NV) ruv;
+ if (ckWARN_d(WARN_OVERFLOW))
+ Perl_warner(aTHX_ WARN_OVERFLOW,
+ "Integer overflow in binary number");
+ } else
+ ruv = xuv | (*s - '0');
+ }
+ if (overflowed) {
+ rnv *= 2;
+ /* If an NV has not enough bits in its mantissa to
+ * represent an UV this summing of small low-order numbers
+ * is a waste of time (because the NV cannot preserve
+ * the low-order bits anyway): we could just remember when
+ * did we overflow and in the end just multiply rnv by the
+ * right amount. */
+ rnv += (*s - '0');
+ }
+ }
+ if (!overflowed)
+ rnv = (NV) ruv;
+ if ( ( overflowed && rnv > 4294967295.0)
+#if UVSIZE > 4
+ || (!overflowed && ruv > 0xffffffff )
+#endif
+ ) {
+ dTHR;
+ if (ckWARN(WARN_PORTABLE))
+ Perl_warner(aTHX_ WARN_PORTABLE,
+ "Binary number > 0b11111111111111111111111111111111 non-portable");
}
*retlen = s - start;
- return retval;
+ return rnv;
}
-UV
+
+NV
Perl_scan_oct(pTHX_ char *start, I32 len, I32 *retlen)
{
register char *s = start;
- register UV retval = 0;
- bool overflowed = FALSE;
-
- while (len && *s >= '0' && *s <= '7') {
- register UV n = retval << 3;
- if (!overflowed && (n >> 3) != retval) {
- Perl_warn(aTHX_ "Integer overflow in octal number");
- overflowed = TRUE;
+ register NV rnv = 0.0;
+ register UV ruv = 0;
+ register bool overflowed = FALSE;
+
+ for (; len-- && *s; s++) {
+ if (!(*s >= '0' && *s <= '7')) {
+ if (*s == '_')
+ continue; /* Note: does not check for __ and the like. */
+ else {
+ /* Allow \octal to work the DWIM way (that is, stop scanning
+ * as soon as non-octal characters are seen, complain only iff
+ * someone seems to want to use the digits eight and nine). */
+ if (*s == '8' || *s == '9') {
+ dTHR;
+ if (ckWARN(WARN_DIGIT))
+ Perl_warner(aTHX_ WARN_DIGIT,
+ "Illegal octal digit '%c' ignored", *s);
+ }
+ break;
+ }
+ }
+ if (!overflowed) {
+ register UV xuv = ruv << 3;
+
+ if ((xuv >> 3) != ruv) {
+ dTHR;
+ overflowed = TRUE;
+ rnv = (NV) ruv;
+ if (ckWARN_d(WARN_OVERFLOW))
+ Perl_warner(aTHX_ WARN_OVERFLOW,
+ "Integer overflow in octal number");
+ } else
+ ruv = xuv | (*s - '0');
+ }
+ if (overflowed) {
+ rnv *= 8.0;
+ /* If an NV has not enough bits in its mantissa to
+ * represent an UV this summing of small low-order numbers
+ * is a waste of time (because the NV cannot preserve
+ * the low-order bits anyway): we could just remember when
+ * did we overflow and in the end just multiply rnv by the
+ * right amount of 8-tuples. */
+ rnv += (NV)(*s - '0');
}
- retval = n | (*s++ - '0');
- len--;
}
- if (len && (*s == '8' || *s == '9')) {
+ if (!overflowed)
+ rnv = (NV) ruv;
+ if ( ( overflowed && rnv > 4294967295.0)
+#if UVSIZE > 4
+ || (!overflowed && ruv > 0xffffffff )
+#endif
+ ) {
dTHR;
- if (ckWARN(WARN_OCTAL))
- Perl_warner(aTHX_ WARN_OCTAL, "Illegal octal digit '%c' ignored", *s);
+ if (ckWARN(WARN_PORTABLE))
+ Perl_warner(aTHX_ WARN_PORTABLE,
+ "Octal number > 037777777777 non-portable");
}
*retlen = s - start;
- return retval;
+ return rnv;
}
-UV
+NV
Perl_scan_hex(pTHX_ char *start, I32 len, I32 *retlen)
{
register char *s = start;
- register UV retval = 0;
- bool overflowed = FALSE;
- char *tmp = s;
- register UV n;
-
- while (len-- && *s) {
- tmp = strchr((char *) PL_hexdigit, *s++);
- if (!tmp) {
- if (*(s-1) == '_' || (*(s-1) == 'x' && retval == 0))
+ register NV rnv = 0.0;
+ register UV ruv = 0;
+ register bool seenx = FALSE;
+ register bool overflowed = FALSE;
+ char *hexdigit;
+
+ for (; len-- && *s; s++) {
+ hexdigit = strchr((char *) PL_hexdigit, *s);
+ if (!hexdigit) {
+ if (*s == '_')
+ continue; /* Note: does not check for __ and the like. */
+ if (seenx == FALSE && *s == 'x' && ruv == 0) {
+ /* Disallow 0xxx0x0xxx... */
+ seenx = TRUE;
continue;
+ }
else {
dTHR;
- --s;
- if (ckWARN(WARN_UNSAFE))
- Perl_warner(aTHX_ WARN_UNSAFE,"Illegal hex digit '%c' ignored", *s);
+ if (ckWARN(WARN_DIGIT))
+ Perl_warner(aTHX_ WARN_DIGIT,
+ "Illegal hexadecimal digit '%c' ignored", *s);
break;
}
}
- n = retval << 4;
- if (!overflowed && (n >> 4) != retval) {
- Perl_warn(aTHX_ "Integer overflow in hex number");
- overflowed = TRUE;
+ if (!overflowed) {
+ register UV xuv = ruv << 4;
+
+ if ((xuv >> 4) != ruv) {
+ dTHR;
+ overflowed = TRUE;
+ rnv = (NV) ruv;
+ if (ckWARN_d(WARN_OVERFLOW))
+ Perl_warner(aTHX_ WARN_OVERFLOW,
+ "Integer overflow in hexadecimal number");
+ } else
+ ruv = xuv | ((hexdigit - PL_hexdigit) & 15);
+ }
+ if (overflowed) {
+ rnv *= 16.0;
+ /* If an NV has not enough bits in its mantissa to
+ * represent an UV this summing of small low-order numbers
+ * is a waste of time (because the NV cannot preserve
+ * the low-order bits anyway): we could just remember when
+ * did we overflow and in the end just multiply rnv by the
+ * right amount of 16-tuples. */
+ rnv += (NV)((hexdigit - PL_hexdigit) & 15);
}
- retval = n | ((tmp - PL_hexdigit) & 15);
+ }
+ if (!overflowed)
+ rnv = (NV) ruv;
+ if ( ( overflowed && rnv > 4294967295.0)
+#if UVSIZE > 4
+ || (!overflowed && ruv > 0xffffffff )
+#endif
+ ) {
+ dTHR;
+ if (ckWARN(WARN_PORTABLE))
+ Perl_warner(aTHX_ WARN_PORTABLE,
+ "Hexadecimal number > 0xffffffff non-portable");
}
*retlen = s - start;
- return retval;
+ return rnv;
}
char*
struct perl_thread *
Perl_new_struct_thread(pTHX_ struct perl_thread *t)
{
-#ifndef PERL_IMPLICIT_CONTEXT
+#if !defined(PERL_IMPLICIT_CONTEXT)
struct perl_thread *thr;
#endif
SV *sv;
Zero(thr, 1, struct perl_thread);
#endif
- PL_protect = FUNC_NAME_TO_PTR(Perl_default_protect);
+ PL_protect = MEMBER_TO_FPTR(Perl_default_protect);
thr->oursv = sv;
init_stacks();
PL_curcop = &PL_compiling;
+ thr->interp = t->interp;
thr->cvcache = newHV();
thr->threadsv = newAV();
thr->specific = newAV();
PL_restartop = 0;
PL_statname = NEWSV(66,0);
+ PL_errors = newSVpvn("", 0);
PL_maxscream = -1;
- PL_regcompp = FUNC_NAME_TO_PTR(Perl_pregcomp);
- PL_regexecp = FUNC_NAME_TO_PTR(Perl_regexec_flags);
+ PL_regcompp = MEMBER_TO_FPTR(Perl_pregcomp);
+ PL_regexecp = MEMBER_TO_FPTR(Perl_regexec_flags);
+ PL_regint_start = MEMBER_TO_FPTR(Perl_re_intuit_start);
+ PL_regint_string = MEMBER_TO_FPTR(Perl_re_intuit_string);
+ PL_regfree = MEMBER_TO_FPTR(Perl_pregfree);
PL_regindent = 0;
PL_reginterp_cnt = 0;
PL_lastscream = Nullsv;
PL_screamnext = 0;
PL_reg_start_tmp = 0;
PL_reg_start_tmpl = 0;
+ PL_reg_poscache = Nullch;
/* parent thread's data needs to be locked while we make copy */
MUTEX_LOCK(&t->mutex);
* So it is in perl for (say) POSIX to use.
* Needed for SunOS with Sun's 'acc' for example.
*/
-double
+NV
Perl_huge(void)
{
return HUGE_VAL;
#endif
}
-double
-Perl_my_atof(const char* s) {
+NV
+Perl_my_atof(pTHX_ const char* s) {
#ifdef USE_LOCALE_NUMERIC
if ((PL_hints & HINT_LOCALE) && PL_numeric_local) {
- double x, y;
+ NV x, y;
- x = atof(s);
+ x = Perl_atof(s);
SET_NUMERIC_STANDARD();
- y = atof(s);
+ y = Perl_atof(s);
SET_NUMERIC_LOCAL();
if ((y < 0.0 && y < x) || (y > 0.0 && y > x))
return y;
return x;
- } else
- return atof(s);
+ }
+ else
+ return Perl_atof(s);
#else
- return atof(s);
+ return Perl_atof(s);
#endif
}