/* util.c
*
- * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- * 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, by Larry Wall and others
+ * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*/
/*
- * "Very useful, no doubt, that was to Saruman; yet it seems that he was
- * not content." --Gandalf
+ * 'Very useful, no doubt, that was to Saruman; yet it seems that he was
+ * not content.' --Gandalf to Pippin
+ *
+ * [p.598 of _The Lord of the Rings_, III/xi: "The PalantÃr"]
*/
/* This file contains assorted utility routines.
ptr = (Malloc_t)PerlMem_realloc(where,size);
PERL_ALLOC_CHECK(ptr);
- DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) rfree\n",PTR2UV(where),(long)PL_an++));
- DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) realloc %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)size));
-
- if (ptr != NULL) {
+ /* MUST do this fixup first, before doing ANYTHING else, as anything else
+ might allocate memory/free/move memory, and until we do the fixup, it
+ may well be chasing (and writing to) free memory. */
#ifdef PERL_TRACK_MEMPOOL
+ if (ptr != NULL) {
struct perl_memory_debug_header *const header
= (struct perl_memory_debug_header *)ptr;
header->prev->next = header;
ptr = (Malloc_t)((char*)ptr+sTHX);
+ }
#endif
+
+ /* In particular, must do that fixup above before logging anything via
+ *printf(), as it can reallocate memory, which can cause SEGVs. */
+
+ DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) rfree\n",PTR2UV(where),(long)PL_an++));
+ DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) realloc %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)size));
+
+
+ if (ptr != NULL) {
return ptr;
}
else if (PL_nomemok)
if (size && (count <= MEM_SIZE_MAX / size))
total_size = size * count;
else
- Perl_croak_nocontext(PL_memory_wrap);
+ Perl_croak_nocontext("%s", PL_memory_wrap);
#ifdef PERL_TRACK_MEMPOOL
if (sTHX <= MEM_SIZE_MAX - (MEM_SIZE)total_size)
total_size += sTHX;
else
- Perl_croak_nocontext(PL_memory_wrap);
+ Perl_croak_nocontext("%s", PL_memory_wrap);
#endif
#ifdef HAS_64K_LIMIT
if (total_size > 0xffff) {
register I32 tolen;
PERL_UNUSED_CONTEXT;
+ PERL_ARGS_ASSERT_DELIMCPY;
+
for (tolen = 0; from < fromend; from++, tolen++) {
if (*from == '\\') {
if (from[1] != delim) {
register I32 first;
PERL_UNUSED_CONTEXT;
+ PERL_ARGS_ASSERT_INSTR;
+
if (!little)
return (char*)big;
first = *little++;
char *
Perl_ninstr(pTHX_ const char *big, const char *bigend, const char *little, const char *lend)
{
+ PERL_ARGS_ASSERT_NINSTR;
PERL_UNUSED_CONTEXT;
if (little >= lend)
return (char*)big;
{
- char first = *little++;
+ const char first = *little;
const char *s, *x;
- bigend -= lend - little;
+ bigend -= lend - little++;
OUTER:
while (big <= bigend) {
if (*big++ == first) {
register const char * const littleend = lend;
PERL_UNUSED_CONTEXT;
+ PERL_ARGS_ASSERT_RNINSTR;
+
if (little >= littleend)
return (char*)bigend;
bigbeg = big;
U32 rarest = 0;
U32 frequency = 256;
+ PERL_ARGS_ASSERT_FBM_COMPILE;
+
if (flags & FBMcf_TAIL) {
MAGIC * const mg = SvUTF8(sv) && SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_utf8) : NULL;
sv_catpvs(sv, "\n"); /* Taken into account in fbm_instr() */
register STRLEN littlelen = l;
register const I32 multiline = flags & FBMrf_MULTILINE;
+ PERL_ARGS_ASSERT_FBM_INSTR;
+
if ((STRLEN)(bigend - big) < littlelen) {
if ( SvTAIL(littlestr)
&& ((STRLEN)(bigend - big) == littlelen - 1)
register const unsigned char *littleend;
I32 found = 0;
+ PERL_ARGS_ASSERT_SCREAMINSTR;
+
assert(SvTYPE(littlestr) == SVt_PVGV);
assert(SvVALID(littlestr));
register const U8 *b = (const U8 *)s2;
PERL_UNUSED_CONTEXT;
+ PERL_ARGS_ASSERT_IBCMP;
+
while (len--) {
if (*a != *b && *a != PL_fold[*b])
return 1;
register const U8 *b = (const U8 *)s2;
PERL_UNUSED_CONTEXT;
+ PERL_ARGS_ASSERT_IBCMP_LOCALE;
+
while (len--) {
if (*a != *b && *a != PL_fold_locale[*b])
return 1;
Perl_savesharedpvn(pTHX_ const char *const pv, const STRLEN len)
{
char *const newaddr = (char*)PerlMemShared_malloc(len + 1);
- assert(pv);
+
+ PERL_ARGS_ASSERT_SAVESHAREDPVN;
+
if (!newaddr) {
return write_no_mem();
}
const char * const pv = SvPV_const(sv, len);
register char *newaddr;
+ PERL_ARGS_ASSERT_SAVESVPV;
+
++len;
Newx(newaddr,len,char);
return (char *) CopyD(pv,newaddr,len,char);
XPVMG *any;
if (!PL_dirty)
- return sv_2mortal(newSVpvs(""));
+ return newSVpvs_flags("", SVs_TEMP);
if (PL_mess_sv)
return PL_mess_sv;
dTHX;
char *retval;
va_list args;
+ PERL_ARGS_ASSERT_FORM_NOCONTEXT;
va_start(args, pat);
retval = vform(pat, &args);
va_end(args);
{
char *retval;
va_list args;
+ PERL_ARGS_ASSERT_FORM;
va_start(args, pat);
retval = vform(pat, &args);
va_end(args);
Perl_vform(pTHX_ const char *pat, va_list *args)
{
SV * const sv = mess_alloc();
+ PERL_ARGS_ASSERT_VFORM;
sv_vsetpvfn(sv, pat, strlen(pat), args, NULL, 0, NULL);
return SvPVX(sv);
}
dTHX;
SV *retval;
va_list args;
+ PERL_ARGS_ASSERT_MESS_NOCONTEXT;
va_start(args, pat);
retval = vmess(pat, &args);
va_end(args);
{
SV *retval;
va_list args;
+ PERL_ARGS_ASSERT_MESS;
va_start(args, pat);
retval = vmess(pat, &args);
va_end(args);
dVAR;
/* Look for PL_op starting from o. cop is the last COP we've seen. */
+ PERL_ARGS_ASSERT_CLOSEST_COP;
+
if (!o || o == PL_op)
return cop;
dVAR;
SV * const sv = mess_alloc();
+ PERL_ARGS_ASSERT_VMESS;
+
sv_vsetpvfn(sv, pat, strlen(pat), args, NULL, 0, NULL);
if (!SvCUR(sv) || *(SvEND(sv) - 1) != '\n') {
/*
IO *io;
MAGIC *mg;
+ PERL_ARGS_ASSERT_WRITE_TO_STDERR;
+
if (PL_stderrgv && SvREFCNT(PL_stderrgv)
&& (io = GvIO(PL_stderrgv))
- && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)))
+ && (mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar)))
{
dSP;
ENTER;
PUSHMARK(SP);
EXTEND(SP,2);
- PUSHs(SvTIED_obj((SV*)io, mg));
- PUSHs(sv_2mortal(newSVpvn(message, msglen)));
+ PUSHs(SvTIED_obj(MUTABLE_SV(io), mg));
+ mPUSHp(message, msglen);
PUTBACK;
call_method("PRINT", G_SCALAR);
else {
#ifdef USE_SFIO
/* SFIO can really mess with your errno */
- const int e = errno;
+ dSAVED_ERRNO;
#endif
PerlIO * const serr = Perl_error_log;
PERL_WRITE_MSG_TO_CONSOLE(serr, message, msglen);
(void)PerlIO_flush(serr);
#ifdef USE_SFIO
- errno = e;
+ RESTORE_ERRNO;
#endif
}
}
*hook = NULL;
}
if (warn || message) {
- msg = newSVpvn(message, msglen);
- SvFLAGS(msg) |= utf8;
+ msg = newSVpvn_flags(message, msglen, utf8);
SvREADONLY_on(msg);
SAVEFREESV(msg);
}
PUSHMARK(SP);
XPUSHs(msg);
PUTBACK;
- call_sv((SV*)cv, G_DISCARD);
+ call_sv(MUTABLE_SV(cv), G_DISCARD);
POPSTACK;
LEAVE;
return TRUE;
message = NULL;
}
- DEBUG_S(PerlIO_printf(Perl_debug_log,
- "%p: die/croak: message = %s\ndiehook = %p\n",
- (void*)thr, message, (void*)PL_diehook));
if (PL_diehook) {
S_vdie_common(aTHX_ message, *msglen, *utf8, FALSE);
}
return message;
}
-OP *
-Perl_vdie(pTHX_ const char* pat, va_list *args)
+static OP *
+S_vdie(pTHX_ const char* pat, va_list *args)
{
dVAR;
const char *message;
STRLEN msglen;
I32 utf8 = 0;
- DEBUG_S(PerlIO_printf(Perl_debug_log,
- "%p: die: curstack = %p, mainstack = %p\n",
- (void*)thr, (void*)PL_curstack, (void*)PL_mainstack));
-
message = vdie_croak_common(pat, args, &msglen, &utf8);
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",
- (void*)thr, (void*)PL_restartop, was_in_eval, (void*)PL_top_env));
if ((!PL_restartop && was_in_eval) || PL_top_env->je_prev)
JMPENV_JUMP(3);
return PL_restartop;
dTHX;
OP *o;
va_list args;
+ PERL_ARGS_ASSERT_DIE_NOCONTEXT;
va_start(args, pat);
o = vdie(pat, &args);
va_end(args);
const I32 utf8 = SvUTF8(msv);
const char * const message = SvPV_const(msv, msglen);
+ PERL_ARGS_ASSERT_VWARN;
+
if (PL_warnhook) {
if (vdie_common(message, msglen, utf8, TRUE))
return;
{
dTHX;
va_list args;
+ PERL_ARGS_ASSERT_WARN_NOCONTEXT;
va_start(args, pat);
vwarn(pat, &args);
va_end(args);
Perl_warn(pTHX_ const char *pat, ...)
{
va_list args;
+ PERL_ARGS_ASSERT_WARN;
va_start(args, pat);
vwarn(pat, &args);
va_end(args);
{
dTHX;
va_list args;
+ PERL_ARGS_ASSERT_WARNER_NOCONTEXT;
va_start(args, pat);
vwarner(err, pat, &args);
va_end(args);
Perl_warner(pTHX_ U32 err, const char* pat,...)
{
va_list args;
+ PERL_ARGS_ASSERT_WARNER;
va_start(args, pat);
vwarner(err, pat, &args);
va_end(args);
Perl_vwarner(pTHX_ U32 err, const char* pat, va_list* args)
{
dVAR;
+ PERL_ARGS_ASSERT_VWARNER;
if (PL_warnhook == PERL_WARNHOOK_FATAL || ckDEAD(err)) {
SV * const msv = vmess(pat, args);
STRLEN msglen;
STRLEN size) {
const MEM_SIZE len_wanted = sizeof(STRLEN) + size;
PERL_UNUSED_CONTEXT;
+ PERL_ARGS_ASSERT_NEW_WARNINGS_BITFIELD;
buffer = (STRLEN*)
(specialWARN(buffer) ?
#ifndef PERL_USE_SAFE_PUTENV
if (!PL_use_safe_putenv) {
/* most putenv()s leak, so we manipulate environ directly */
- register I32 i=setenv_getix(nam); /* where does it go? */
+ register I32 i;
+ register const I32 len = strlen(nam);
int nlen, vlen;
+ /* where does it go? */
+ for (i = 0; environ[i]; i++) {
+ if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
+ break;
+ }
+
if (environ == PL_origenviron) { /* need we copy environment? */
I32 j;
I32 max;
#endif /* WIN32 || NETWARE */
-#ifndef PERL_MICRO
-I32
-Perl_setenv_getix(pTHX_ const char *nam)
-{
- register I32 i;
- register const I32 len = strlen(nam);
- PERL_UNUSED_CONTEXT;
-
- for (i = 0; environ[i]; i++) {
- if (
-#ifdef WIN32
- strnicmp(environ[i],nam,len) == 0
-#else
- strnEQ(environ[i],nam,len)
-#endif
- && environ[i][len] == '=')
- break; /* strnEQ must come first to avoid */
- } /* potential SEGV's */
- return i;
-}
-#endif /* !PERL_MICRO */
-
#endif /* !VMS && !EPOC*/
#ifdef UNLINK_ALL_VERSIONS
{
I32 retries = 0;
+ PERL_ARGS_ASSERT_UNLNK;
+
while (PerlLIO_unlink(f) >= 0)
retries++;
return retries ? 0 : -1;
{
char * const retval = to;
+ PERL_ARGS_ASSERT_MY_BCOPY;
+
if (from - to >= 0) {
while (len--)
*to++ = *from++;
{
char * const retval = loc;
+ PERL_ARGS_ASSERT_MY_MEMSET;
+
while (len--)
*loc++ = ch;
return retval;
{
char * const retval = loc;
+ PERL_ARGS_ASSERT_MY_BZERO;
+
while (len--)
*loc++ = 0;
return retval;
register const U8 *b = (const U8 *)s2;
register I32 tmp;
+ PERL_ARGS_ASSERT_MY_MEMCMP;
+
while (len--) {
if ((tmp = *a++ - *b++))
return tmp;
register char *e = s + (n-1);
register char tc;
+ PERL_ARGS_ASSERT_MY_SWABN;
+
for (n /= 2; n > 0; s++, e--, n--) {
tc = *s;
*s = *e;
}
PerlIO *
-Perl_my_popen_list(pTHX_ char *mode, int n, SV **args)
+Perl_my_popen_list(pTHX_ const char *mode, int n, SV **args)
{
#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(OS2) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC) && !defined(MACOS_TRADITIONAL) && !defined(NETWARE) && !defined(__LIBCATAMOUNT__)
dVAR;
I32 did_pipes = 0;
int pp[2];
+ PERL_ARGS_ASSERT_MY_POPEN_LIST;
+
PERL_FLUSHALL_FOR_CHILD;
This = (*mode == 'w');
that = !This;
return PerlIO_fdopen(p[This], mode);
#else
# ifdef OS2 /* Same, without fork()ing and all extra overhead... */
- return my_syspopen4(aTHX_ Nullch, mode, n, args);
+ return my_syspopen4(aTHX_ NULL, mode, n, args);
# else
Perl_croak(aTHX_ "List form of piped open not implemented");
return (PerlIO *) NULL;
I32 did_pipes = 0;
int pp[2];
+ PERL_ARGS_ASSERT_MY_POPEN;
+
PERL_FLUSHALL_FOR_CHILD;
#ifdef OS2
if (doexec) {
PerlIO *
Perl_my_popen(pTHX_ const char *cmd, const char *mode)
{
+ PERL_ARGS_ASSERT_MY_POPEN;
PERL_FLUSHALL_FOR_CHILD;
/* Call system's popen() to get a FILE *, then import it.
used 0 for 2nd parameter to PerlIO_importFILE;
#ifdef DUMP_FDS
void
-Perl_dump_fds(pTHX_ char *s)
+Perl_dump_fds(pTHX_ const char *const s)
{
int fd;
Stat_t tmpstatbuf;
+ PERL_ARGS_ASSERT_DUMP_FDS;
+
PerlIO_printf(Perl_debug_log,"%s", s);
for (fd = 0; fd < 32; fd++) {
if (PerlLIO_fstat(fd,&tmpstatbuf) >= 0)
dVAR;
struct sigaction act;
+ PERL_ARGS_ASSERT_RSIGNAL_SAVE;
+
#ifdef USE_ITHREADS
/* only "parent" interpreter can diddle signals */
if (PL_curinterp != aTHX)
Pid_t pid;
Pid_t pid2;
bool close_failed;
- int saved_errno = 0;
-#ifdef WIN32
- int saved_win32_errno;
-#endif
+ dSAVEDERRNO;
LOCK_FDPID_MUTEX;
svp = av_fetch(PL_fdpid,PerlIO_fileno(ptr),TRUE);
return my_syspclose(ptr);
}
#endif
- if ((close_failed = (PerlIO_close(ptr) == EOF))) {
- saved_errno = errno;
-#ifdef WIN32
- saved_win32_errno = GetLastError();
-#endif
- }
+ close_failed = (PerlIO_close(ptr) == EOF);
+ SAVE_ERRNO;
#ifdef UTS
if(PerlProc_kill(pid, 0) < 0) { return(pid); } /* HOM 12/23/91 */
#endif
rsignal_restore(SIGQUIT, &qstat);
#endif
if (close_failed) {
- SETERRNO(saved_errno, 0);
+ RESTORE_ERRNO;
return -1;
}
return(pid2 < 0 ? pid2 : status == 0 ? 0 : (errno = 0, status));
{
dVAR;
I32 result = 0;
+ PERL_ARGS_ASSERT_WAIT4PID;
if (!pid)
return -1;
#ifdef PERL_USES_PL_PIDSTATUS
#endif
if (result < 0 && errno == EINTR) {
PERL_ASYNC_CHECK();
+ errno = EINTR; /* reset in case a signal handler changed $! */
}
return result;
}
#ifdef PERL_USES_PL_PIDSTATUS
void
-Perl_pidgone(pTHX_ Pid_t pid, int status)
+S_pidgone(pTHX_ Pid_t pid, int status)
{
register SV *sv;
register const char * const frombase = from;
PERL_UNUSED_CONTEXT;
+ PERL_ARGS_ASSERT_REPEATCPY;
+
if (len == 1) {
register const char c = *from;
while (count-- > 0)
Stat_t tmpstatbuf2;
SV * const tmpsv = sv_newmortal();
+ PERL_ARGS_ASSERT_SAME_DIRENT;
+
if (fa)
fa++;
else
if (strNE(a,b))
return FALSE;
if (fa == a)
- sv_setpvn(tmpsv, ".", 1);
+ sv_setpvs(tmpsv, ".");
else
sv_setpvn(tmpsv, a, fa - a);
if (PerlLIO_stat(SvPVX_const(tmpsv), &tmpstatbuf1) < 0)
return FALSE;
if (fb == b)
- sv_setpvn(tmpsv, ".", 1);
+ sv_setpvs(tmpsv, ".");
else
sv_setpvn(tmpsv, b, fb - b);
if (PerlLIO_stat(SvPVX_const(tmpsv), &tmpstatbuf2) < 0)
# define MAX_EXT_LEN 0
#endif
+ PERL_ARGS_ASSERT_FIND_SCRIPT;
+
/*
* If dosearch is true and if scriptname does not contain path
* delimiters, search the PATH for scriptname.
Perl_set_context(void *t)
{
dVAR;
+ PERL_ARGS_ASSERT_SET_CONTEXT;
#if defined(USE_ITHREADS)
# ifdef I_MACH_CTHREADS
cthread_set_data(cthread_self(), t);
{
char * const env_trans = PerlEnv_getenv(env_elem);
PERL_UNUSED_CONTEXT;
+ PERL_ARGS_ASSERT_GETENV_LEN;
if (env_trans)
*len = strlen(env_trans);
return env_trans;
#ifdef HAS_TM_TM_ZONE
Time_t now;
const struct tm* my_tm;
+ PERL_ARGS_ASSERT_INIT_TM;
(void)time(&now);
my_tm = localtime(&now);
if (my_tm)
Copy(my_tm, ptm, 1, struct tm);
#else
+ PERL_ARGS_ASSERT_INIT_TM;
PERL_UNUSED_ARG(ptm);
#endif
}
int odd_cent, odd_year;
PERL_UNUSED_CONTEXT;
+ PERL_ARGS_ASSERT_MINI_MKTIME;
+
#define DAYS_PER_YEAR 365
#define DAYS_PER_QYEAR (4*DAYS_PER_YEAR+1)
#define DAYS_PER_CENT (25*DAYS_PER_QYEAR-1)
struct tm mytm;
int len;
+ PERL_ARGS_ASSERT_MY_STRFTIME;
+
init_tm(&mytm); /* XXX workaround - see init_tm() above */
mytm.tm_sec = sec;
mytm.tm_min = min;
SvTAINTED_on(sv);
#endif
+ PERL_ARGS_ASSERT_GETCWD_SV;
+
#ifdef HAS_GETCWD
{
char buf[MAXPATHLEN];
bool vinf = FALSE;
AV * const av = newAV();
SV * const hv = newSVrv(rv, "version"); /* create an SV and upgrade the RV */
- (void)sv_upgrade(hv, SVt_PVHV); /* needs to be an HV type */
-#ifndef NODEFAULT_SHAREKEYS
- HvSHAREKEYS_on(hv); /* key-sharing on by default */
-#endif
+ PERL_ARGS_ASSERT_SCAN_VERSION;
+
+ (void)sv_upgrade(hv, SVt_PVHV); /* needs to be an HV type */
while (isSPACE(*s)) /* leading whitespace is OK */
s++;
pos = s;
if ( qv )
- (void)hv_stores((HV *)hv, "qv", newSViv(qv));
+ (void)hv_stores(MUTABLE_HV(hv), "qv", newSViv(qv));
if ( alpha )
- (void)hv_stores((HV *)hv, "alpha", newSViv(alpha));
+ (void)hv_stores(MUTABLE_HV(hv), "alpha", newSViv(alpha));
if ( !qv && width < 3 )
- (void)hv_stores((HV *)hv, "width", newSViv(width));
+ (void)hv_stores(MUTABLE_HV(hv), "width", newSViv(width));
while (isDIGIT(*pos))
pos++;
Compiler in question is:
gcc version 3.3 20030304 (Apple Computer, Inc. build 1640)
for ( len = 2 - len; len > 0; len-- )
- av_push((AV *)sv, newSViv(0));
+ av_push(MUTABLE_AV(sv), newSViv(0));
*/
len = 2 - len;
while (len-- > 0)
/* need to save off the current version string for later */
if ( vinf ) {
SV * orig = newSVpvn("v.Inf", sizeof("v.Inf")-1);
- (void)hv_stores((HV *)hv, "original", orig);
- (void)hv_stores((HV *)hv, "vinf", newSViv(1));
+ (void)hv_stores(MUTABLE_HV(hv), "original", orig);
+ (void)hv_stores(MUTABLE_HV(hv), "vinf", newSViv(1));
}
else if ( s > start ) {
SV * orig = newSVpvn(start,s-start);
/* need to insert a v to be consistent */
sv_insert(orig, 0, 0, "v", 1);
}
- (void)hv_stores((HV *)hv, "original", orig);
+ (void)hv_stores(MUTABLE_HV(hv), "original", orig);
}
else {
- (void)hv_stores((HV *)hv, "original", newSVpvn("0",1));
+ (void)hv_stores(MUTABLE_HV(hv), "original", newSVpvs("0"));
av_push(av, newSViv(0));
}
/* And finally, store the AV in the hash */
- (void)hv_stores((HV *)hv, "version", newRV_noinc((SV *)av));
+ (void)hv_stores(MUTABLE_HV(hv), "version", newRV_noinc(MUTABLE_SV(av)));
/* fix RT#19517 - special case 'undef' as string */
if ( *s == 'u' && strEQ(s,"undef") ) {
{
dVAR;
SV * const rv = newSV(0);
+ PERL_ARGS_ASSERT_NEW_VERSION;
if ( sv_derived_from(ver,"version") ) /* can just copy directly */
{
I32 key;
/* This will get reblessed later if a derived class*/
SV * const hv = newSVrv(rv, "version");
(void)sv_upgrade(hv, SVt_PVHV); /* needs to be an HV type */
-#ifndef NODEFAULT_SHAREKEYS
- HvSHAREKEYS_on(hv); /* key-sharing on by default */
-#endif
if ( SvROK(ver) )
ver = SvRV(ver);
/* Begin copying all of the elements */
- if ( hv_exists((HV *)ver, "qv", 2) )
- (void)hv_stores((HV *)hv, "qv", newSViv(1));
+ if ( hv_exists(MUTABLE_HV(ver), "qv", 2) )
+ (void)hv_stores(MUTABLE_HV(hv), "qv", newSViv(1));
- if ( hv_exists((HV *)ver, "alpha", 5) )
- (void)hv_stores((HV *)hv, "alpha", newSViv(1));
+ if ( hv_exists(MUTABLE_HV(ver), "alpha", 5) )
+ (void)hv_stores(MUTABLE_HV(hv), "alpha", newSViv(1));
- if ( hv_exists((HV*)ver, "width", 5 ) )
+ if ( hv_exists(MUTABLE_HV(ver), "width", 5 ) )
{
- const I32 width = SvIV(*hv_fetchs((HV*)ver, "width", FALSE));
- (void)hv_stores((HV *)hv, "width", newSViv(width));
+ const I32 width = SvIV(*hv_fetchs(MUTABLE_HV(ver), "width", FALSE));
+ (void)hv_stores(MUTABLE_HV(hv), "width", newSViv(width));
}
- if ( hv_exists((HV*)ver, "original", 8 ) )
+ if ( hv_exists(MUTABLE_HV(ver), "original", 8 ) )
{
- SV * pv = *hv_fetchs((HV*)ver, "original", FALSE);
- (void)hv_stores((HV *)hv, "original", newSVsv(pv));
+ SV * pv = *hv_fetchs(MUTABLE_HV(ver), "original", FALSE);
+ (void)hv_stores(MUTABLE_HV(hv), "original", newSVsv(pv));
}
- sav = (AV *)SvRV(*hv_fetchs((HV*)ver, "version", FALSE));
+ sav = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(ver), "version", FALSE)));
/* This will get reblessed later if a derived class*/
for ( key = 0; key <= av_len(sav); key++ )
{
av_push(av, newSViv(rev));
}
- (void)hv_stores((HV *)hv, "version", newRV_noinc((SV *)av));
+ (void)hv_stores(MUTABLE_HV(hv), "version", newRV_noinc(MUTABLE_SV(av)));
return rv;
}
#ifdef SvVOK
const MAGIC *mg;
#endif
+ PERL_ARGS_ASSERT_UPG_VERSION;
+
if ( SvNOK(ver) && !( SvPOK(ver) && sv_len(ver) == 3 ) )
{
/* may get too much accuracy */
Perl_vverify(pTHX_ SV *vs)
{
SV *sv;
+
+ PERL_ARGS_ASSERT_VVERIFY;
+
if ( SvROK(vs) )
vs = SvRV(vs);
/* see if the appropriate elements exist */
if ( SvTYPE(vs) == SVt_PVHV
- && hv_exists((HV*)vs, "version", 7)
- && (sv = SvRV(*hv_fetchs((HV*)vs, "version", FALSE)))
+ && hv_exists(MUTABLE_HV(vs), "version", 7)
+ && (sv = SvRV(*hv_fetchs(MUTABLE_HV(vs), "version", FALSE)))
&& SvTYPE(sv) == SVt_PVAV )
return TRUE;
else
bool alpha = FALSE;
SV * const sv = newSV(0);
AV *av;
+
+ PERL_ARGS_ASSERT_VNUMIFY;
+
if ( SvROK(vs) )
vs = SvRV(vs);
Perl_croak(aTHX_ "Invalid version object");
/* see if various flags exist */
- if ( hv_exists((HV*)vs, "alpha", 5 ) )
+ if ( hv_exists(MUTABLE_HV(vs), "alpha", 5 ) )
alpha = TRUE;
- if ( hv_exists((HV*)vs, "width", 5 ) )
- width = SvIV(*hv_fetchs((HV*)vs, "width", FALSE));
+ if ( hv_exists(MUTABLE_HV(vs), "width", 5 ) )
+ width = SvIV(*hv_fetchs(MUTABLE_HV(vs), "width", FALSE));
else
width = 3;
/* attempt to retrieve the version array */
- if ( !(av = (AV *)SvRV(*hv_fetchs((HV*)vs, "version", FALSE)) ) ) {
+ if ( !(av = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(vs), "version", FALSE))) ) ) {
sv_catpvs(sv,"0");
return sv;
}
bool alpha = FALSE;
SV * const sv = newSV(0);
AV *av;
+
+ PERL_ARGS_ASSERT_VNORMAL;
+
if ( SvROK(vs) )
vs = SvRV(vs);
if ( !vverify(vs) )
Perl_croak(aTHX_ "Invalid version object");
- if ( hv_exists((HV*)vs, "alpha", 5 ) )
+ if ( hv_exists(MUTABLE_HV(vs), "alpha", 5 ) )
alpha = TRUE;
- av = (AV *)SvRV(*hv_fetchs((HV*)vs, "version", FALSE));
+ av = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(vs), "version", FALSE)));
len = av_len(av);
if ( len == -1 )
SV *
Perl_vstringify(pTHX_ SV *vs)
{
- SV *pv;
+ PERL_ARGS_ASSERT_VSTRINGIFY;
+
if ( SvROK(vs) )
vs = SvRV(vs);
-
+
if ( !vverify(vs) )
Perl_croak(aTHX_ "Invalid version object");
- pv = *hv_fetchs((HV*)vs, "original", FALSE);
- if ( SvPOK(pv) )
- return newSVsv(pv);
- else
- return &PL_sv_undef;
+ if (hv_exists(MUTABLE_HV(vs), "original", sizeof("original") - 1)) {
+ SV *pv;
+ pv = *hv_fetchs(MUTABLE_HV(vs), "original", FALSE);
+ if ( SvPOK(pv) )
+ return newSVsv(pv);
+ else
+ return &PL_sv_undef;
+ }
+ else {
+ if ( hv_exists(MUTABLE_HV(vs), "qv", 2) )
+ return vnormal(vs);
+ else
+ return vnumify(vs);
+ }
}
/*
I32 left = 0;
I32 right = 0;
AV *lav, *rav;
+
+ PERL_ARGS_ASSERT_VCMP;
+
if ( SvROK(lhv) )
lhv = SvRV(lhv);
if ( SvROK(rhv) )
Perl_croak(aTHX_ "Invalid version object");
/* get the left hand term */
- lav = (AV *)SvRV(*hv_fetchs((HV*)lhv, "version", FALSE));
- if ( hv_exists((HV*)lhv, "alpha", 5 ) )
+ lav = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(lhv), "version", FALSE)));
+ if ( hv_exists(MUTABLE_HV(lhv), "alpha", 5 ) )
lalpha = TRUE;
/* and the right hand term */
- rav = (AV *)SvRV(*hv_fetchs((HV*)rhv, "version", FALSE));
- if ( hv_exists((HV*)rhv, "alpha", 5 ) )
+ rav = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(rhv), "version", FALSE)));
+ if ( hv_exists(MUTABLE_HV(rhv), "alpha", 5 ) )
ralpha = TRUE;
l = av_len(lav);
errno = ECONNABORTED;
tidy_up_and_fail:
{
- const int save_errno = errno;
+ dSAVE_ERRNO;
if (sockets[0] != -1)
PerlLIO_close(sockets[0]);
if (sockets[1] != -1)
PerlLIO_close(sockets[1]);
- errno = save_errno;
+ RESTORE_ERRNO;
return -1;
}
}
#endif
tidy_up_and_fail:
{
- const int save_errno = errno;
+ dSAVE_ERRNO;
if (listener != -1)
PerlLIO_close(listener);
if (connector != -1)
PerlLIO_close(connector);
if (acceptor != -1)
PerlLIO_close(acceptor);
- errno = save_errno;
+ RESTORE_ERRNO;
return -1;
}
}
const char *p = *popt;
U32 opt = 0;
+ PERL_ARGS_ASSERT_PARSE_UNICODE_OPTS;
+
if (*p) {
if (isDIGIT(*p)) {
opt = (U32) atoi(p);
const char * const stashpv = CopSTASHPV(c);
const char * const name = HvNAME_get(hv);
PERL_UNUSED_CONTEXT;
+ PERL_ARGS_ASSERT_STASHPV_HVNAME_MATCH;
if (stashpv == name)
return TRUE;
void
Perl_free_global_struct(pTHX_ struct perl_vars *plvarsp)
{
+ PERL_ARGS_ASSERT_FREE_GLOBAL_STRUCT;
# ifdef PERL_GLOBAL_STRUCT
# ifdef PERL_UNSET_VARS
PERL_UNSET_VARS(plvarsp);
* PERL_MEM_LOG: the Perl_mem_log_..() will be compiled.
*
* PERL_MEM_LOG_ENV: if defined, during run time the environment
- * variable PERL_MEM_LOG will be consulted, and if the integer value
- * of that is true, the logging will happen. (The default is to
- * always log if the PERL_MEM_LOG define was in effect.)
+ * variables PERL_MEM_LOG and PERL_SV_LOG will be consulted, and
+ * if the integer value of that is true, the logging will happen.
+ * (The default is to always log if the PERL_MEM_LOG define was
+ * in effect.)
+ *
+ * PERL_MEM_LOG_TIMESTAMP: if defined, a timestamp will be logged
+ * before every memory logging entry. This can be turned off at run
+ * time by setting the environment variable PERL_MEM_LOG_TIMESTAMP
+ * to zero.
*/
/*
# define PERL_MEM_LOG_FD 2 /* If STDERR is too boring for you. */
#endif
-Malloc_t
-Perl_mem_log_alloc(const UV n, const UV typesize, const char *typename, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname)
-{
#ifdef PERL_MEM_LOG_STDERR
+
+# ifdef DEBUG_LEAKING_SCALARS
+# define SV_LOG_SERIAL_FMT " [%lu]"
+# define _SV_LOG_SERIAL_ARG(sv) , (unsigned long) (sv)->sv_debug_serial
+# else
+# define SV_LOG_SERIAL_FMT
+# define _SV_LOG_SERIAL_ARG(sv)
+# endif
+
+static void
+S_mem_log_common(enum mem_log_type mlt, const UV n, const UV typesize, const char *type_name, const SV *sv, Malloc_t oldalloc, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname)
+{
# if defined(PERL_MEM_LOG_ENV) || defined(PERL_MEM_LOG_ENV_FD)
- char *s;
+ const char *s;
# endif
+
+ PERL_ARGS_ASSERT_MEM_LOG_COMMON;
+
# ifdef PERL_MEM_LOG_ENV
- s = getenv("PERL_MEM_LOG");
+ s = PerlEnv_getenv(mlt < MLT_NEW_SV ? "PERL_MEM_LOG" : "PERL_SV_LOG");
if (s ? atoi(s) : 0)
# endif
{
* so we'll use stdio and low-level IO instead. */
char buf[PERL_MEM_LOG_SPRINTF_BUF_SIZE];
# ifdef PERL_MEM_LOG_TIMESTAMP
- struct timeval tv;
# ifdef HAS_GETTIMEOFDAY
+# define MEM_LOG_TIME_FMT "%10d.%06d: "
+# define MEM_LOG_TIME_ARG (int)tv.tv_sec, (int)tv.tv_usec
+ struct timeval tv;
gettimeofday(&tv, 0);
+# else
+# define MEM_LOG_TIME_FMT "%10d: "
+# define MEM_LOG_TIME_ARG (int)when
+ Time_t when;
+ (void)time(&when);
# endif
/* If there are other OS specific ways of hires time than
* gettimeofday() (see ext/Time/HiRes), the easiest way is
* timeval. */
# endif
{
- const STRLEN len =
- my_snprintf(buf,
- sizeof(buf),
-# ifdef PERL_MEM_LOG_TIMESTAMP
- "%10d.%06d: "
+ int fd = PERL_MEM_LOG_FD;
+ STRLEN len;
+
+# ifdef PERL_MEM_LOG_ENV_FD
+ if ((s = PerlEnv_getenv("PERL_MEM_LOG_FD"))) {
+ fd = atoi(s);
+ }
# endif
- "alloc: %s:%d:%s: %"IVdf" %"UVuf
- " %s = %"IVdf": %"UVxf"\n",
-# ifdef PERL_MEM_LOG_TIMESTAMP
- (int)tv.tv_sec, (int)tv.tv_usec,
+# ifdef PERL_MEM_LOG_TIMESTAMP
+ s = PerlEnv_getenv("PERL_MEM_LOG_TIMESTAMP");
+ if (!s || atoi(s)) {
+ len = my_snprintf(buf, sizeof(buf),
+ MEM_LOG_TIME_FMT, MEM_LOG_TIME_ARG);
+ PerlLIO_write(fd, buf, len);
+ }
# endif
- filename, linenumber, funcname, n, typesize,
- typename, n * typesize, PTR2UV(newalloc));
-# ifdef PERL_MEM_LOG_ENV_FD
- s = PerlEnv_getenv("PERL_MEM_LOG_FD");
- PerlLIO_write(s ? atoi(s) : PERL_MEM_LOG_FD, buf, len);
-# else
- PerlLIO_write(PERL_MEM_LOG_FD, buf, len);
-#endif
+ switch (mlt) {
+ case MLT_ALLOC:
+ len = my_snprintf(buf, sizeof(buf),
+ "alloc: %s:%d:%s: %"IVdf" %"UVuf
+ " %s = %"IVdf": %"UVxf"\n",
+ filename, linenumber, funcname, n, typesize,
+ type_name, n * typesize, PTR2UV(newalloc));
+ break;
+ case MLT_REALLOC:
+ len = my_snprintf(buf, sizeof(buf),
+ "realloc: %s:%d:%s: %"IVdf" %"UVuf
+ " %s = %"IVdf": %"UVxf" -> %"UVxf"\n",
+ filename, linenumber, funcname, n, typesize,
+ type_name, n * typesize, PTR2UV(oldalloc),
+ PTR2UV(newalloc));
+ break;
+ case MLT_FREE:
+ len = my_snprintf(buf, sizeof(buf),
+ "free: %s:%d:%s: %"UVxf"\n",
+ filename, linenumber, funcname,
+ PTR2UV(oldalloc));
+ break;
+ case MLT_NEW_SV:
+ case MLT_DEL_SV:
+ len = my_snprintf(buf, sizeof(buf),
+ "%s_SV: %s:%d:%s: %"UVxf SV_LOG_SERIAL_FMT "\n",
+ mlt == MLT_NEW_SV ? "new" : "del",
+ filename, linenumber, funcname,
+ PTR2UV(sv) _SV_LOG_SERIAL_ARG(sv));
+ break;
+ }
+ PerlLIO_write(fd, buf, len);
}
}
+}
+#endif
+
+Malloc_t
+Perl_mem_log_alloc(const UV n, const UV typesize, const char *type_name, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname)
+{
+#ifdef PERL_MEM_LOG_STDERR
+ mem_log_common(MLT_ALLOC, n, typesize, type_name, NULL, NULL, newalloc, filename, linenumber, funcname);
#endif
return newalloc;
}
Malloc_t
-Perl_mem_log_realloc(const UV n, const UV typesize, const char *typename, Malloc_t oldalloc, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname)
+Perl_mem_log_realloc(const UV n, const UV typesize, const char *type_name, Malloc_t oldalloc, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname)
{
#ifdef PERL_MEM_LOG_STDERR
-# if defined(PERL_MEM_LOG_ENV) || defined(PERL_MEM_LOG_ENV_FD)
- char *s;
-# endif
-# ifdef PERL_MEM_LOG_ENV
- s = PerlEnv_getenv("PERL_MEM_LOG");
- if (s ? atoi(s) : 0)
-# endif
- {
- /* We can't use SVs or PerlIO for obvious reasons,
- * so we'll use stdio and low-level IO instead. */
- char buf[PERL_MEM_LOG_SPRINTF_BUF_SIZE];
-# ifdef PERL_MEM_LOG_TIMESTAMP
- struct timeval tv;
- gettimeofday(&tv, 0);
-# endif
- {
- const STRLEN len =
- my_snprintf(buf,
- sizeof(buf),
-# ifdef PERL_MEM_LOG_TIMESTAMP
- "%10d.%06d: "
-# endif
- "realloc: %s:%d:%s: %"IVdf" %"UVuf
- " %s = %"IVdf": %"UVxf" -> %"UVxf"\n",
-# ifdef PERL_MEM_LOG_TIMESTAMP
- (int)tv.tv_sec, (int)tv.tv_usec,
-# endif
- filename, linenumber, funcname, n, typesize,
- typename, n * typesize, PTR2UV(oldalloc),
- PTR2UV(newalloc));
-# ifdef PERL_MEM_LOG_ENV_FD
- s = PerlEnv_getenv("PERL_MEM_LOG_FD");
- PerlLIO_write(s ? atoi(s) : PERL_MEM_LOG_FD, buf, len);
-# else
- PerlLIO_write(PERL_MEM_LOG_FD, buf, len);
-# endif
- }
- }
+ mem_log_common(MLT_REALLOC, n, typesize, type_name, NULL, oldalloc, newalloc, filename, linenumber, funcname);
#endif
return newalloc;
}
Perl_mem_log_free(Malloc_t oldalloc, const char *filename, const int linenumber, const char *funcname)
{
#ifdef PERL_MEM_LOG_STDERR
-# if defined(PERL_MEM_LOG_ENV) || defined(PERL_MEM_LOG_ENV_FD)
- char *s;
-# endif
-# ifdef PERL_MEM_LOG_ENV
- s = PerlEnv_getenv("PERL_MEM_LOG");
- if (s ? atoi(s) : 0)
-# endif
- {
- /* We can't use SVs or PerlIO for obvious reasons,
- * so we'll use stdio and low-level IO instead. */
- char buf[PERL_MEM_LOG_SPRINTF_BUF_SIZE];
-# ifdef PERL_MEM_LOG_TIMESTAMP
- struct timeval tv;
- gettimeofday(&tv, 0);
-# endif
- {
- const STRLEN len =
- my_snprintf(buf,
- sizeof(buf),
-# ifdef PERL_MEM_LOG_TIMESTAMP
- "%10d.%06d: "
-# endif
- "free: %s:%d:%s: %"UVxf"\n",
-# ifdef PERL_MEM_LOG_TIMESTAMP
- (int)tv.tv_sec, (int)tv.tv_usec,
-# endif
- filename, linenumber, funcname,
- PTR2UV(oldalloc));
-# ifdef PERL_MEM_LOG_ENV_FD
- s = PerlEnv_getenv("PERL_MEM_LOG_FD");
- PerlLIO_write(s ? atoi(s) : PERL_MEM_LOG_FD, buf, len);
-# else
- PerlLIO_write(PERL_MEM_LOG_FD, buf, len);
-# endif
- }
- }
+ mem_log_common(MLT_FREE, 0, 0, "", NULL, oldalloc, NULL, filename, linenumber, funcname);
#endif
return oldalloc;
}
+void
+Perl_mem_log_new_sv(const SV *sv, const char *filename, const int linenumber, const char *funcname)
+{
+#ifdef PERL_MEM_LOG_STDERR
+ mem_log_common(MLT_NEW_SV, 0, 0, "", sv, NULL, NULL, filename, linenumber, funcname);
+#endif
+}
+
+void
+Perl_mem_log_del_sv(const SV *sv, const char *filename, const int linenumber, const char *funcname)
+{
+#ifdef PERL_MEM_LOG_STDERR
+ mem_log_common(MLT_DEL_SV, 0, 0, "", sv, NULL, NULL, filename, linenumber, funcname);
+#endif
+}
+
#endif /* PERL_MEM_LOG */
/*
Perl_my_sprintf(char *buffer, const char* pat, ...)
{
va_list args;
+ PERL_ARGS_ASSERT_MY_SPRINTF;
va_start(args, pat);
vsprintf(buffer, pat, args);
va_end(args);
dTHX;
int retval;
va_list ap;
+ PERL_ARGS_ASSERT_MY_SNPRINTF;
va_start(ap, format);
#ifdef HAS_VSNPRINTF
retval = vsnprintf(buffer, len, format, ap);
int retval;
#ifdef NEED_VA_COPY
va_list apc;
+
+ PERL_ARGS_ASSERT_MY_VSNPRINTF;
+
Perl_va_copy(ap, apc);
# ifdef HAS_VSNPRINTF
retval = vsnprintf(buffer, len, format, apc);
{
dVAR;
void *p;
+ PERL_ARGS_ASSERT_MY_CXT_INIT;
if (*index == -1) {
/* this module hasn't been allocated an index yet */
MUTEX_LOCK(&PL_my_ctx_mutex);
dVAR;
int index;
+ PERL_ARGS_ASSERT_MY_CXT_INDEX;
+
for (index = 0; index < PL_my_cxt_index; index++) {
const char *key = PL_my_cxt_keys[index];
/* try direct pointer compare first - there are chances to success,
void *p;
int index;
+ PERL_ARGS_ASSERT_MY_CXT_INIT;
+
index = Perl_my_cxt_index(aTHX_ my_cxt_key);
if (index == -1) {
/* this module hasn't been allocated an index yet */
* it's for informational purposes only.
*/
+ PERL_ARGS_ASSERT_GET_DB_SUB;
+
save_item(dbsv);
if (!PERLDB_SUB_NN) {
GV * const gv = CvGV(cv);
if ( svp && ((CvFLAGS(cv) & (CVf_ANON | CVf_CLONED))
|| strEQ(GvNAME(gv), "END")
|| ((GvCV(gv) != cv) && /* Could be imported, and old sub redefined. */
- !( (SvTYPE(*svp) == SVt_PVGV) && (GvCV((GV*)*svp) == cv) )))) {
+ !( (SvTYPE(*svp) == SVt_PVGV)
+ && (GvCV((const GV *)*svp) == cv) )))) {
/* Use GV from the stack as a fallback. */
/* GV is potentially non-unique, or contain different CV. */
- SV * const tmp = newRV((SV*)cv);
+ SV * const tmp = newRV(MUTABLE_SV(cv));
sv_setsv(dbsv, tmp);
SvREFCNT_dec(tmp);
}
REGEXP *
Perl_get_re_arg(pTHX_ SV *sv) {
SV *tmpsv;
- MAGIC *mg;
if (sv) {
if (SvMAGICAL(sv))
mg_get(sv);
if (SvROK(sv) &&
- (tmpsv = (SV*)SvRV(sv)) && /* assign deliberate */
- SvTYPE(tmpsv) == SVt_PVMG &&
- (mg = mg_find(tmpsv, PERL_MAGIC_qr))) /* assign deliberate */
+ (tmpsv = MUTABLE_SV(SvRV(sv))) && /* assign deliberate */
+ SvTYPE(tmpsv) == SVt_REGEXP)
{
- return (REGEXP *)mg->mg_obj;
+ return (REGEXP*) tmpsv;
}
}