static void restore_magic _((void *p));
-static MGS *
-save_magic(sv)
+static void
+save_magic(mgs, sv)
+MGS* mgs;
SV* sv;
{
- MGS* mgs;
-
assert(SvMAGICAL(sv));
- mgs = (MGS*)safemalloc(sizeof(MGS));
mgs->mgs_sv = sv;
mgs->mgs_flags = SvMAGICAL(sv) | SvREADONLY(sv);
SAVEDESTRUCTOR(restore_magic, mgs);
SvMAGICAL_off(sv);
SvREADONLY_off(sv);
SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
-
- return mgs;
}
static void
restore_magic(p)
void* p;
{
- MGS *mgs = (MGS*)p;
+ MGS* mgs = (MGS*)p;
SV* sv = mgs->mgs_sv;
if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv))
if (SvGMAGICAL(sv))
SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK);
}
-
- Safefree(mgs);
}
mg_get(sv)
SV* sv;
{
- MGS* mgs;
+ MGS mgs;
MAGIC* mg;
MAGIC** mgp;
int mgp_valid = 0;
ENTER;
- mgs = save_magic(sv);
+ save_magic(&mgs, sv);
mgp = &SvMAGIC(sv);
while ((mg = *mgp) != 0) {
if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
(*vtbl->svt_get)(sv, mg);
/* Ignore this magic if it's been deleted */
- if ((mg == (mgp_valid ? *mgp : SvMAGIC(sv))) && (mg->mg_flags & MGf_GSKIP))
- mgs->mgs_flags = 0;
+ if ((mg == (mgp_valid ? *mgp : SvMAGIC(sv))) &&
+ (mg->mg_flags & MGf_GSKIP))
+ mgs.mgs_flags = 0;
}
/* Advance to next magic (complicated by possible deletion) */
if (mg == (mgp_valid ? *mgp : SvMAGIC(sv))) {
mg_set(sv)
SV* sv;
{
- MGS* mgs;
+ MGS mgs;
MAGIC* mg;
MAGIC* nextmg;
ENTER;
- mgs = save_magic(sv);
+ save_magic(&mgs, sv);
for (mg = SvMAGIC(sv); mg; mg = nextmg) {
MGVTBL* vtbl = mg->mg_virtual;
nextmg = mg->mg_moremagic; /* it may delete itself */
if (mg->mg_flags & MGf_GSKIP) {
mg->mg_flags &= ~MGf_GSKIP; /* setting requires another read */
- mgs->mgs_flags = 0;
+ mgs.mgs_flags = 0;
}
if (vtbl && vtbl->svt_set)
(*vtbl->svt_set)(sv, mg);
for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
MGVTBL* vtbl = mg->mg_virtual;
if (vtbl && vtbl->svt_len) {
+ MGS mgs;
+
ENTER;
- save_magic(sv);
+ save_magic(&mgs, sv);
/* omit MGf_GSKIP -- not changed here */
len = (*vtbl->svt_len)(sv, mg);
LEAVE;
mg_clear(sv)
SV* sv;
{
+ MGS mgs;
MAGIC* mg;
ENTER;
- save_magic(sv);
+ save_magic(&mgs, sv);
for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
MGVTBL* vtbl = mg->mg_virtual;
register I32 paren;
register char *s;
register I32 i;
+ register REGEXP *rx;
char *t;
switch (*mg->mg_ptr) {
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '&':
- if (curpm) {
+ if (curpm && (rx = curpm->op_pmregexp)) {
paren = atoi(mg->mg_ptr);
getparen:
- if (curpm->op_pmregexp &&
- paren <= curpm->op_pmregexp->nparens &&
- (s = curpm->op_pmregexp->startp[paren]) &&
- (t = curpm->op_pmregexp->endp[paren]) ) {
+ if (paren <= rx->nparens &&
+ (s = rx->startp[paren]) &&
+ (t = rx->endp[paren]))
+ {
i = t - s;
if (i >= 0)
return i;
return 0;
break;
case '+':
- if (curpm) {
- paren = curpm->op_pmregexp->lastparen;
- if (!paren)
- return 0;
- goto getparen;
+ if (curpm && (rx = curpm->op_pmregexp)) {
+ paren = rx->lastparen;
+ if (paren)
+ goto getparen;
}
return 0;
break;
case '`':
- if (curpm) {
- if (curpm->op_pmregexp &&
- (s = curpm->op_pmregexp->subbeg) ) {
- i = curpm->op_pmregexp->startp[0] - s;
+ if (curpm && (rx = curpm->op_pmregexp)) {
+ if ((s = rx->subbeg) && rx->startp[0]) {
+ i = rx->startp[0] - s;
if (i >= 0)
return i;
}
}
return 0;
case '\'':
- if (curpm) {
- if (curpm->op_pmregexp &&
- (s = curpm->op_pmregexp->endp[0]) ) {
- return (STRLEN) (curpm->op_pmregexp->subend - s);
+ if (curpm && (rx = curpm->op_pmregexp)) {
+ if (rx->subend && (s = rx->endp[0])) {
+ i = rx->subend - s;
+ if (i >= 0)
+ return 0;
}
}
return 0;
register I32 paren;
register char *s;
register I32 i;
+ register REGEXP *rx;
char *t;
switch (*mg->mg_ptr) {
break;
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '&':
- if (curpm) {
+ if (curpm && (rx = curpm->op_pmregexp)) {
paren = atoi(GvENAME((GV*)mg->mg_obj));
getparen:
- if (curpm->op_pmregexp &&
- paren <= curpm->op_pmregexp->nparens &&
- (s = curpm->op_pmregexp->startp[paren]) &&
- (t = curpm->op_pmregexp->endp[paren]) ) {
+ if (paren <= rx->nparens &&
+ (s = rx->startp[paren]) &&
+ (t = rx->endp[paren]))
+ {
i = t - s;
+ getrx:
if (i >= 0) {
- MAGIC *tmg;
+ bool was_tainted;
+ if (tainting) {
+ was_tainted = tainted;
+ tainted = FALSE;
+ }
sv_setpvn(sv,s,i);
- if (tainting && (tmg = mg_find(sv,'t')))
- tmg->mg_len = 0; /* guarantee $1 untainted */
+ if (tainting)
+ tainted = was_tainted || rx->exec_tainted;
break;
}
}
sv_setsv(sv,&sv_undef);
break;
case '+':
- if (curpm) {
- paren = curpm->op_pmregexp->lastparen;
+ if (curpm && (rx = curpm->op_pmregexp)) {
+ paren = rx->lastparen;
if (paren)
goto getparen;
}
sv_setsv(sv,&sv_undef);
break;
case '`':
- if (curpm) {
- if (curpm->op_pmregexp &&
- (s = curpm->op_pmregexp->subbeg) ) {
- i = curpm->op_pmregexp->startp[0] - s;
- if (i >= 0) {
- sv_setpvn(sv,s,i);
- break;
- }
+ if (curpm && (rx = curpm->op_pmregexp)) {
+ if ((s = rx->subbeg) && rx->startp[0]) {
+ i = rx->startp[0] - s;
+ goto getrx;
}
}
sv_setsv(sv,&sv_undef);
break;
case '\'':
- if (curpm) {
- if (curpm->op_pmregexp &&
- (s = curpm->op_pmregexp->endp[0]) ) {
- sv_setpvn(sv,s, curpm->op_pmregexp->subend - s);
- break;
+ if (curpm && (rx = curpm->op_pmregexp)) {
+ if (rx->subend && (s = rx->endp[0])) {
+ i = rx->subend - s;
+ goto getrx;
}
}
sv_setsv(sv,&sv_undef);
#endif
break;
case '?':
- sv_setiv(sv, (IV)statusvalue);
+ sv_setiv(sv, (IV)STATUS_CURRENT);
+#ifdef COMPLEX_STATUS
+ LvTARGOFF(sv) = statusvalue;
+ LvTARGLEN(sv) = statusvalue_vms;
+#endif
break;
case '^':
s = IoTOP_NAME(GvIOp(defoutgv));
return 0;
}
-#ifdef HAS_SIGACTION
-/* set up reliable signal() clone */
-
-typedef void (*Sigfunc) _((int));
-
-static
-Sigfunc rsignal(signo,handler)
-int signo;
-Sigfunc handler;
-{
- struct sigaction act,oact;
-
- act.sa_handler = handler;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
-#ifdef SA_RESTART
- act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */
-#endif
- if (sigaction(signo, &act, &oact) < 0)
- return(SIG_ERR);
- else
- return(oact.sa_handler);
-}
-
-#else
-
-/* ah well, so much for reliability */
-
-#define rsignal(x,y) signal(x,y)
-
-#endif
-
-static sig_trapped;
-static
-Signal_t
-sig_trap(signo)
-int signo;
-{
- sig_trapped++;
-}
int
magic_getsig(sv,mg)
SV* sv;
if(psig_ptr[i])
sv_setsv(sv,psig_ptr[i]);
else {
- void (*origsig) _((int));
- /* get signal state without losing signals */
- sig_trapped=0;
- origsig = rsignal(i,sig_trap);
- rsignal(i,origsig);
- if(sig_trapped)
- kill(getpid(),i);
+ Sighandler_t sigstate = rsignal_state(i);
+
/* cache state so we don't fetch it again */
- if(origsig == SIG_IGN)
+ if(sigstate == SIG_IGN)
sv_setpv(sv,"IGNORE");
else
sv_setsv(sv,&sv_undef);
warn("No such signal: SIG%s", s);
return 0;
}
- if(psig_ptr[i])
- SvREFCNT_dec(psig_ptr[i]);
+ SvREFCNT_dec(psig_name[i]);
+ SvREFCNT_dec(psig_ptr[i]);
psig_ptr[i] = SvREFCNT_inc(sv);
- if(psig_name[i])
- SvREFCNT_dec(psig_name[i]);
- psig_name[i] = newSVpv(s,strlen(s));
SvTEMP_off(sv); /* Make sure it doesn't go away on us */
+ psig_name[i] = newSVpv(s, strlen(s));
SvREADONLY_on(psig_name[i]);
}
if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) {
if (i)
- (void)rsignal(i,sighandler);
+ (void)rsignal(i, sighandler);
else
*svp = SvREFCNT_inc(sv);
return 0;
s = SvPV_force(sv,na);
if (strEQ(s,"IGNORE")) {
if (i)
- (void)rsignal(i,SIG_IGN);
+ (void)rsignal(i, SIG_IGN);
else
*svp = 0;
}
else if (strEQ(s,"DEFAULT") || !*s) {
if (i)
- (void)rsignal(i,SIG_DFL);
+ (void)rsignal(i, SIG_DFL);
else
*svp = 0;
}
sv_setpv(sv,tokenbuf);
}
if (i)
- (void)rsignal(i,sighandler);
+ (void)rsignal(i, sighandler);
else
*svp = SvREFCNT_inc(sv);
}
else if (pos > len)
pos = len;
mg->mg_len = pos;
+ mg->mg_flags &= ~MGf_MINMATCH;
return 0;
}
if (GvGP(sv))
gp_free((GV*)sv);
GvGP(sv) = gp_ref(GvGP(gv));
- if (!GvAV(gv))
- gv_AVadd(gv);
- if (!GvHV(gv))
- gv_HVadd(gv);
- if (!GvIOp(gv))
- GvIOp(gv) = newIO();
return 0;
}
SV* sv;
MAGIC* mg;
{
- if (mg->mg_len & 1)
- tainted = TRUE;
- else if (mg->mg_len & 2 && mg->mg_obj == sv) /* kludge */
- tainted = TRUE;
+ TAINT_IF((mg->mg_len & 1) ||
+ (mg->mg_len & 2) && mg->mg_obj == sv); /* kludge */
return 0;
}
}
int
+magic_getitervar(sv,mg)
+SV* sv;
+MAGIC* mg;
+{
+ SV *targ = Nullsv;
+ if (LvTARGLEN(sv)) {
+ AV* av = (AV*)LvTARG(sv);
+ if (LvTARGOFF(sv) <= AvFILL(av))
+ targ = AvARRAY(av)[LvTARGOFF(sv)];
+ }
+ else
+ targ = LvTARG(sv);
+ sv_setsv(sv, targ ? targ : &sv_undef);
+ return 0;
+}
+
+int
+magic_setitervar(sv,mg)
+SV* sv;
+MAGIC* mg;
+{
+ if (LvTARGLEN(sv))
+ vivify_itervar(sv);
+ if (LvTARG(sv))
+ sv_setsv(LvTARG(sv), sv);
+ return 0;
+}
+
+int
+magic_freeitervar(sv,mg)
+SV* sv;
+MAGIC* mg;
+{
+ SvREFCNT_dec(LvTARG(sv));
+ return 0;
+}
+
+void
+vivify_itervar(sv)
+SV* sv;
+{
+ AV* av;
+
+ if (!LvTARGLEN(sv))
+ return;
+ av = (AV*)LvTARG(sv);
+ if (LvTARGOFF(sv) <= AvFILL(av)) {
+ SV** svp = AvARRAY(av) + LvTARGOFF(sv);
+ LvTARG(sv) = newSVsv(*svp);
+ SvREFCNT_dec(*svp);
+ *svp = SvREFCNT_inc(LvTARG(sv));
+ }
+ else
+ LvTARG(sv) = Nullsv;
+ SvREFCNT_dec(av);
+ LvTARGLEN(sv) = 0;
+}
+
+int
magic_setmglob(sv,mg)
SV* sv;
MAGIC* mg;
}
int
+magic_setfm(sv,mg)
+SV* sv;
+MAGIC* mg;
+{
+ sv_unmagic(sv, 'f');
+ SvCOMPILED_off(sv);
+ return 0;
+}
+
+int
magic_setuvar(sv,mg)
SV* sv;
MAGIC* mg;
return 0;
}
+#ifdef USE_LOCALE_COLLATE
+int
+magic_setcollxfrm(sv,mg)
+SV* sv;
+MAGIC* mg;
+{
+ /*
+ * René Descartes said "I think not."
+ * and vanished with a faint plop.
+ */
+ if (mg->mg_ptr) {
+ Safefree(mg->mg_ptr);
+ mg->mg_ptr = NULL;
+ mg->mg_len = -1;
+ }
+ return 0;
+}
+#endif /* USE_LOCALE_COLLATE */
+
int
magic_set(sv,mg)
SV* sv;
#ifdef VMS
set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
#else
- SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),4); /* will anyone ever use this? */
+ /* will anyone ever use this? */
+ SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
#endif
break;
case '\006': /* ^F */
case '\\':
if (ors)
Safefree(ors);
- ors = savepv(SvPV(sv,orslen));
+ if (SvOK(sv) || SvGMAGICAL(sv))
+ ors = savepv(SvPV(sv,orslen));
+ else {
+ ors = Nullch;
+ orslen = 0;
+ }
break;
case ',':
if (ofs)
compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
break;
case '?':
- statusvalue = FIXSTATUS(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
+#ifdef COMPLEX_STATUS
+ if (localizing == 2) {
+ statusvalue = LvTARGOFF(sv);
+ statusvalue_vms = LvTARGLEN(sv);
+ }
+ else
+#endif
+#ifdef VMSISH_STATUS
+ if (VMSISH_STATUS)
+ STATUS_NATIVE_SET((U32)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)));
+ else
+#endif
+ STATUS_POSIX_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
break;
case '!':
- SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),SvIV(sv) == EVMSERR ? 4 : vaxc$errno); /* will anyone ever use this? */
+ SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),
+ (SvIV(sv) == EVMSERR) ? 4 : vaxc$errno);
break;
case '<':
uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
if (origargv[i] == s + 1)
s += strlen(++s); /* this one is ok too */
}
- if (origenviron[0] == s + 1) { /* can grab env area too? */
+ /* can grab env area too? */
+ if (origenviron && origenviron[0] == s + 1) {
my_setenv("NoNeSuCh", Nullch);
/* force copy of environment */
for (i = 0; origenviron[i]; i++)
SV *sv;
CV *cv;
AV *oldstack;
-
- if(!psig_ptr[sig])
- die("Signal SIG%s received, but no signal handler set.\n",
- sig_name[sig]);
+
+ if (!psig_ptr[sig])
+ die("Signal SIG%s received, but no signal handler set.\n",
+ sig_name[sig]);
cv = sv_2cv(psig_ptr[sig],&st,&gv,TRUE);
if (!cv || !CvROOT(cv)) {
if(psig_name[sig])
sv = SvREFCNT_inc(psig_name[sig]);
else {
- sv = sv_newmortal();
- sv_setpv(sv,sig_name[sig]);
+ sv = sv_newmortal();
+ sv_setpv(sv,sig_name[sig]);
}
PUSHMARK(sp);
PUSHs(sv);