X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=mg.c;h=923915dd0151376f7e72cd9a9ff34d76e6d533c3;hb=240263869b859eb47916a5c595018abdc313547e;hp=0ea35601344c612692517e2f8cff6cd583ea5598;hpb=57b2e4523f4df782c055782388ac1aacff9603ef;p=p5sagit%2Fp5-mst-13.2.git diff --git a/mg.c b/mg.c index 0ea3560..923915d 100644 --- a/mg.c +++ b/mg.c @@ -1,6 +1,6 @@ /* mg.c * - * Copyright (c) 1991-1999, Larry Wall + * Copyright (c) 1991-2000, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -60,6 +60,14 @@ S_save_magic(pTHX_ I32 mgs_ix, SV *sv) SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT; } +/* +=for apidoc mg_magical + +Turns on the magical status of an SV. See C. + +=cut +*/ + void Perl_mg_magical(pTHX_ SV *sv) { @@ -77,6 +85,14 @@ Perl_mg_magical(pTHX_ SV *sv) } } +/* +=for apidoc mg_get + +Do magic after a value is retrieved from the SV. See C. + +=cut +*/ + int Perl_mg_get(pTHX_ SV *sv) { @@ -112,6 +128,14 @@ Perl_mg_get(pTHX_ SV *sv) return 0; } +/* +=for apidoc mg_set + +Do magic after a value is assigned to the SV. See C. + +=cut +*/ + int Perl_mg_set(pTHX_ SV *sv) { @@ -138,6 +162,14 @@ Perl_mg_set(pTHX_ SV *sv) return 0; } +/* +=for apidoc mg_length + +Report on the SV's length. See C. + +=cut +*/ + U32 Perl_mg_length(pTHX_ SV *sv) { @@ -196,6 +228,14 @@ Perl_mg_size(pTHX_ SV *sv) return 0; } +/* +=for apidoc mg_clear + +Clear something magical that the SV represents. See C. + +=cut +*/ + int Perl_mg_clear(pTHX_ SV *sv) { @@ -217,6 +257,14 @@ Perl_mg_clear(pTHX_ SV *sv) return 0; } +/* +=for apidoc mg_find + +Finds the magic pointer for type matching the SV. See C. + +=cut +*/ + MAGIC* Perl_mg_find(pTHX_ SV *sv, int type) { @@ -228,6 +276,14 @@ Perl_mg_find(pTHX_ SV *sv, int type) return 0; } +/* +=for apidoc mg_copy + +Copies the magic from one SV to another. See C. + +=cut +*/ + int Perl_mg_copy(pTHX_ SV *sv, SV *nsv, const char *key, I32 klen) { @@ -236,7 +292,8 @@ Perl_mg_copy(pTHX_ SV *sv, SV *nsv, const char *key, I32 klen) for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) { if (isUPPER(mg->mg_type)) { sv_magic(nsv, - mg->mg_type == 'P' ? SvTIED_obj(sv, mg) : mg->mg_obj, + mg->mg_type == 'P' ? SvTIED_obj(sv, mg) : + (mg->mg_type == 'D' && mg->mg_obj) ? sv : mg->mg_obj, toLOWER(mg->mg_type), key, klen); count++; } @@ -244,6 +301,14 @@ Perl_mg_copy(pTHX_ SV *sv, SV *nsv, const char *key, I32 klen) return count; } +/* +=for apidoc mg_free + +Free any magic storage used by the SV. See C. + +=cut +*/ + int Perl_mg_free(pTHX_ SV *sv) { @@ -275,10 +340,7 @@ U32 Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg) { dTHR; - register char *s; - register I32 i; register REGEXP *rx; - char *t; if (PL_curpm && (rx = PL_curpm->op_pmregexp)) { if (mg->mg_obj) /* @+ */ @@ -318,21 +380,28 @@ Perl_magic_regdatum_get(pTHX_ SV *sv, MAGIC *mg) return 0; } +int +Perl_magic_regdatum_set(pTHX_ SV *sv, MAGIC *mg) +{ + dTHR; + Perl_croak(aTHX_ PL_no_modify); + /* NOT REACHED */ + return 0; +} + U32 Perl_magic_len(pTHX_ SV *sv, MAGIC *mg) { dTHR; register I32 paren; - register char *s; register I32 i; register REGEXP *rx; - char *t; + I32 s1, t1; switch (*mg->mg_ptr) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '&': if (PL_curpm && (rx = PL_curpm->op_pmregexp)) { - I32 s1, t1; paren = atoi(mg->mg_ptr); getparen: @@ -341,6 +410,16 @@ Perl_magic_len(pTHX_ SV *sv, MAGIC *mg) (t1 = rx->endp[paren]) != -1) { i = t1 - s1; + getlen: + if (i > 0 && (PL_curpm->op_pmdynflags & PMdf_UTF8) && !IN_BYTE) { + char *s = rx->subbeg + s1; + char *send = rx->subbeg + t1; + i = 0; + while (s < send) { + s += UTF8SKIP(s); + i++; + } + } if (i >= 0) return i; } @@ -357,8 +436,11 @@ Perl_magic_len(pTHX_ SV *sv, MAGIC *mg) if (PL_curpm && (rx = PL_curpm->op_pmregexp)) { if (rx->startp[0] != -1) { i = rx->startp[0]; - if (i >= 0) - return i; + if (i > 0) { + s1 = 0; + t1 = i; + goto getlen; + } } } return 0; @@ -366,8 +448,11 @@ Perl_magic_len(pTHX_ SV *sv, MAGIC *mg) if (PL_curpm && (rx = PL_curpm->op_pmregexp)) { if (rx->endp[0] != -1) { i = rx->sublen - rx->endp[0]; - if (i >= 0) - return i; + if (i > 0) { + s1 = rx->endp[0]; + t1 = rx->sublen; + goto getlen; + } } } return 0; @@ -394,7 +479,6 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) register char *s; register I32 i; register REGEXP *rx; - char *t; switch (*mg->mg_ptr) { case '\001': /* ^A */ @@ -406,14 +490,17 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) case '\004': /* ^D */ sv_setiv(sv, (IV)(PL_debug & 32767)); +#if defined(YYDEBUG) && defined(DEBUGGING) + PL_yydebug = (PL_debug & 1); +#endif break; case '\005': /* ^E */ #ifdef MACOS_TRADITIONAL { char msg[256]; - sv_setnv(sv,(double)gLastMacOSErr); - sv_setpv(sv, gLastMacOSErr ? GetSysErrText(gLastMacOSErr, msg) : ""); + sv_setnv(sv,(double)gMacPerl_OSErr); + sv_setpv(sv, gMacPerl_OSErr ? GetSysErrText(gMacPerl_OSErr, msg) : ""); } #else #ifdef VMS @@ -486,11 +573,9 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) { dTHR; if (PL_lex_state != LEX_NOTPARSING) - SvOK_off(sv); + (void)SvOK_off(sv); else if (PL_in_eval) - sv_setiv(sv, 1); - else - sv_setiv(sv, 0); + sv_setiv(sv, PL_in_eval & ~(EVAL_INREQUIRE)); } break; case '\024': /* ^T */ @@ -500,22 +585,25 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) sv_setiv(sv, (IV)PL_basetime); #endif break; - case '\027': /* ^W & $^Warnings*/ + case '\027': /* ^W & $^WARNING_BITS & ^WIDE_SYSTEM_CALLS */ if (*(mg->mg_ptr+1) == '\0') sv_setiv(sv, (IV)((PL_dowarn & G_WARN_ON) ? TRUE : FALSE)); - else if (strEQ(mg->mg_ptr, "\027arnings")) { - if (PL_compiling.cop_warnings == WARN_NONE || - PL_compiling.cop_warnings == WARN_STD) + else if (strEQ(mg->mg_ptr, "\027ARNING_BITS")) { + if (PL_compiling.cop_warnings == pWARN_NONE || + PL_compiling.cop_warnings == pWARN_STD) { sv_setpvn(sv, WARN_NONEstring, WARNsize) ; } - else if (PL_compiling.cop_warnings == WARN_ALL) { + else if (PL_compiling.cop_warnings == pWARN_ALL) { sv_setpvn(sv, WARN_ALLstring, WARNsize) ; } else { sv_setsv(sv, PL_compiling.cop_warnings); } + SvPOK_only(sv); } + else if (strEQ(mg->mg_ptr, "\027IDE_SYSTEM_CALLS")) + sv_setiv(sv, (IV)PL_widesyscalls); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '&': @@ -534,6 +622,9 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) { i = t1 - s1; s = rx->subbeg + s1; + if (!rx->subbeg) + break; + getrx: if (i >= 0) { bool was_tainted; @@ -542,6 +633,10 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) PL_tainted = FALSE; } sv_setpvn(sv, s, i); + if ((PL_curpm->op_pmdynflags & PMdf_UTF8) && !IN_BYTE) + SvUTF8_on(sv); + else + SvUTF8_off(sv); if (PL_tainting) PL_tainted = (was_tainted || RX_MATCH_TAINTED(rx)); break; @@ -665,11 +760,15 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) break; case '(': sv_setiv(sv, (IV)PL_gid); +#ifdef HAS_GETGROUPS Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, PL_gid); +#endif goto add_groups; case ')': sv_setiv(sv, (IV)PL_egid); +#ifdef HAS_GETGROUPS Perl_sv_setpvf(aTHX_ sv, "%"Gid_t_f, PL_egid); +#endif add_groups: #ifdef HAS_GETGROUPS { @@ -679,7 +778,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) Perl_sv_catpvf(aTHX_ sv, " %"Gid_t_f, gary[i]); } #endif - SvIOK_on(sv); /* what a wonderful hack! */ + (void)SvIOK_on(sv); /* what a wonderful hack! */ break; case '*': break; @@ -802,7 +901,7 @@ Perl_magic_set_all_env(pTHX_ SV *sv, MAGIC *mg) STRLEN n_a; magic_clear_all_env(sv,mg); hv_iterinit((HV*)sv); - while (entry = hv_iternext((HV*)sv)) { + while ((entry = hv_iternext((HV*)sv))) { I32 keylen; my_setenv(hv_iterkey(entry, &keylen), SvPV(hv_iterval((HV*)sv, entry), n_a)); @@ -815,7 +914,7 @@ Perl_magic_set_all_env(pTHX_ SV *sv, MAGIC *mg) int Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg) { -#if defined(VMS) +#if defined(VMS) || defined(EPOC) Perl_die(aTHX_ "Can't make list assignment to %%ENV on this system"); #else # ifdef PERL_IMPLICIT_SYS @@ -837,11 +936,6 @@ Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg) cur += len+1; } FreeEnvironmentStrings(envv); -# else -# ifdef CYGWIN - I32 i; - for (i = 0; environ[i]; i++) - Safefree(environ[i]); # else # ifndef PERL_USE_SAFE_PUTENV I32 i; @@ -852,7 +946,6 @@ Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg) for (i = 0; environ[i]; i++) safesysfree(environ[i]); # endif /* PERL_USE_SAFE_PUTENV */ -# endif /* CYGWIN */ environ[0] = Nullch; @@ -862,6 +955,7 @@ Perl_magic_clear_all_env(pTHX_ SV *sv, MAGIC *mg) return 0; } +#ifndef PERL_MICRO int Perl_magic_getsig(pTHX_ SV *sv, MAGIC *mg) { @@ -932,7 +1026,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) else { i = whichsig(s); /* ...no, a brick */ if (!i) { - if (ckWARN(WARN_SIGNAL) || strEQ(s,"ALARM")) + if (ckWARN(WARN_SIGNAL)) Perl_warner(aTHX_ WARN_SIGNAL, "No such signal: SIG%s", s); return 0; } @@ -978,6 +1072,7 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) } return 0; } +#endif /* !PERL_MICRO */ int Perl_magic_setisa(pTHX_ SV *sv, MAGIC *mg) @@ -1008,7 +1103,7 @@ Perl_magic_getnkeys(pTHX_ SV *sv, MAGIC *mg) i = HvKEYS(hv); else { /*SUPPRESS 560*/ - while (entry = hv_iternext(hv)) { + while ((entry = hv_iternext(hv))) { i++; } } @@ -1184,8 +1279,6 @@ Perl_magic_setdbline(pTHX_ SV *sv, MAGIC *mg) atoi(MgPV(mg,n_a)), FALSE); if (svp && SvIOKp(*svp) && (o = INT2PTR(OP*,SvIVX(*svp)))) o->op_private = i; - else if (ckWARN_d(WARN_INTERNAL)) - Perl_warner(aTHX_ WARN_INTERNAL, "Can't break at that line\n"); return 0; } @@ -1215,7 +1308,7 @@ Perl_magic_getpos(pTHX_ SV *sv, MAGIC *mg) if (mg && mg->mg_len >= 0) { dTHR; I32 i = mg->mg_len; - if (IN_UTF8) + if (DO_UTF8(lsv)) sv_pos_b2u(lsv, &i); sv_setiv(sv, i + PL_curcop->cop_arybase); return 0; @@ -1231,7 +1324,7 @@ Perl_magic_setpos(pTHX_ SV *sv, MAGIC *mg) SV* lsv = LvTARG(sv); SSize_t pos; STRLEN len; - STRLEN ulen; + STRLEN ulen = 0; dTHR; mg = 0; @@ -1252,12 +1345,10 @@ Perl_magic_setpos(pTHX_ SV *sv, MAGIC *mg) pos = SvIV(sv) - PL_curcop->cop_arybase; - if (IN_UTF8) { + if (DO_UTF8(lsv)) { ulen = sv_len_utf8(lsv); if (ulen) len = ulen; - else - ulen = 0; } if (pos < 0) { @@ -1328,6 +1419,8 @@ Perl_magic_getsubstr(pTHX_ SV *sv, MAGIC *mg) if (rem + offs > len) rem = len - offs; sv_setpvn(sv, tmps + offs, (STRLEN)rem); + if (DO_UTF8(lsv)) + SvUTF8_on(sv); return 0; } @@ -1345,7 +1438,7 @@ Perl_magic_gettaint(pTHX_ SV *sv, MAGIC *mg) { dTHR; TAINT_IF((mg->mg_len & 1) || - (mg->mg_len & 2) && mg->mg_obj == sv); /* kludge */ + ((mg->mg_len & 2) && mg->mg_obj == sv)); /* kludge */ return 0; } @@ -1372,7 +1465,7 @@ Perl_magic_getvec(pTHX_ SV *sv, MAGIC *mg) SV *lsv = LvTARG(sv); if (!lsv) { - SvOK_off(sv); + (void)SvOK_off(sv); return 0; } @@ -1495,7 +1588,7 @@ Perl_magic_killbackrefs(pTHX_ SV *sv, MAGIC *mg) Perl_croak(aTHX_ "panic: magic_killbackrefs"); /* XXX Should we check that it hasn't changed? */ SvRV(svp[i]) = 0; - SvOK_off(svp[i]); + (void)SvOK_off(svp[i]); SvWEAKREF_off(svp[i]); svp[i] = &PL_sv_undef; } @@ -1584,7 +1677,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) break; case '\005': /* ^E */ #ifdef MACOS_TRADITIONAL - gLastMacOSErr = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv); + gMacPerl_OSErr = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv); #else # ifdef VMS set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); @@ -1634,7 +1727,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) PL_basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); #endif break; - case '\027': /* ^W & $^Warnings */ + case '\027': /* ^W & $^WARNING_BITS & ^WIDE_SYSTEM_CALLS */ if (*(mg->mg_ptr+1) == '\0') { if ( ! (PL_dowarn & G_WARN_ALL_MASK)) { i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv); @@ -1642,24 +1735,42 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) | (i ? G_WARN_ON : G_WARN_OFF) ; } } - else if (strEQ(mg->mg_ptr, "\027arnings")) { + else if (strEQ(mg->mg_ptr, "\027ARNING_BITS")) { if ( ! (PL_dowarn & G_WARN_ALL_MASK)) { - if (memEQ(SvPVX(sv), WARN_ALLstring, WARNsize)) { - PL_compiling.cop_warnings = WARN_ALL; - PL_dowarn |= G_WARN_ONCE ; - } - else if (memEQ(SvPVX(sv), WARN_NONEstring, WARNsize)) - PL_compiling.cop_warnings = WARN_NONE; - else { - if (specialWARN(PL_compiling.cop_warnings)) - PL_compiling.cop_warnings = newSVsv(sv) ; - else - sv_setsv(PL_compiling.cop_warnings, sv); - if (isWARN_on(PL_compiling.cop_warnings, WARN_ONCE)) + if (!SvPOK(sv) && PL_localizing) { + sv_setpvn(sv, WARN_NONEstring, WARNsize); + PL_compiling.cop_warnings = pWARN_NONE; + break; + } + { + STRLEN len, i; + int accumulate = 0 ; + int any_fatals = 0 ; + char * ptr = (char*)SvPV(sv, len) ; + for (i = 0 ; i < len ; ++i) { + accumulate |= ptr[i] ; + any_fatals |= (ptr[i] & 0xAA) ; + } + if (!accumulate) + PL_compiling.cop_warnings = pWARN_NONE; + else if (isWARN_on(sv, WARN_ALL) && !any_fatals) { + PL_compiling.cop_warnings = pWARN_ALL; PL_dowarn |= G_WARN_ONCE ; - } + } + else { + if (specialWARN(PL_compiling.cop_warnings)) + PL_compiling.cop_warnings = newSVsv(sv) ; + else + sv_setsv(PL_compiling.cop_warnings, sv); + if (isWARN_on(PL_compiling.cop_warnings, WARN_ONCE)) + PL_dowarn |= G_WARN_ONCE ; + } + + } } } + else if (strEQ(mg->mg_ptr, "\027IDE_SYSTEM_CALLS")) + PL_widesyscalls = SvTRUE(sv); break; case '.': if (PL_localizing) { @@ -1894,6 +2005,30 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg) break; #ifndef MACOS_TRADITIONAL case '0': +#ifdef HAS_SETPROCTITLE + /* The BSDs don't show the argv[] in ps(1) output, they + * show a string from the process struct and provide + * the setproctitle() routine to manipulate that. */ + { + s = SvPV(sv, len); +# if __FreeBSD_version >= 410001 + /* The leading "-" removes the "perl: " prefix, + * but not the "(perl) suffix from the ps(1) + * output, because that's what ps(1) shows if the + * argv[] is modified. */ + setproctitle("-%s", s, len + 1); +# else /* old FreeBSDs, NetBSD, OpenBSD, anyBSD */ + /* This doesn't really work if you assume that + * $0 = 'foobar'; will wipe out 'perl' from the $0 + * because in ps(1) output the result will be like + * sprintf("perl: %s (perl)", s) + * I guess this is a security feature: + * one (a user process) cannot get rid of the original name. + * --jhi */ + setproctitle("%s", s); +# endif + } +#endif if (!PL_origalen) { s = PL_origargv[0]; s += strlen(s); @@ -2000,7 +2135,11 @@ static SV* sig_sv; Signal_t Perl_sighandler(int sig) { +#if defined(WIN32) && defined(PERL_IMPLICIT_CONTEXT) + dTHXoa(PL_curinterp); /* fake TLS, because signals don't do TLS */ +#else dTHX; +#endif dSP; GV *gv = Nullgv; HV *st; @@ -2008,8 +2147,12 @@ Perl_sighandler(int sig) CV *cv = Nullcv; OP *myop = PL_op; U32 flags = 0; - I32 o_save_i = PL_savestack_ix, type; + I32 o_save_i = PL_savestack_ix; XPV *tXpv = PL_Xpv; + +#if defined(WIN32) && defined(PERL_IMPLICIT_CONTEXT) + PERL_SET_THX(aTHXo); /* fake TLS, see above */ +#endif if (PL_savestack_ix + 15 <= PL_savestack_max) flags |= 1; @@ -2098,7 +2241,7 @@ static void restore_magic(pTHXo_ void *p) { dTHR; - MGS* mgs = SSPTR((I32)p, MGS*); + MGS* mgs = SSPTR(PTR2IV(p), MGS*); SV* sv = mgs->mgs_sv; if (!sv)