dumper.xs
来自「source of perl for linux application,」· XS 代码 · 共 1,207 行 · 第 1/3 页
XS
1,207 行
sv_catpvn(retval, realpack, strlen(realpack)); } sv_catpvn(retval, "' )", 3); if (toaster && SvPOK(toaster) && SvCUR(toaster)) { sv_catpvn(retval, "->", 2); sv_catsv(retval, toaster); sv_catpvn(retval, "()", 2); } } SvREFCNT_dec(ipad); (*levelp)--; } else { STRLEN i; if (namelen) {#ifdef DD_USE_OLD_ID_FORMAT idlen = my_snprintf(id, sizeof(id), "0x%"UVxf, PTR2UV(val));#else id_buffer = PTR2UV(val); idlen = sizeof(id_buffer);#endif if ((svp = hv_fetch(seenhv, id, idlen, FALSE)) && (sv = *svp) && SvROK(sv) && (seenentry = (AV*)SvRV(sv))) { SV *othername; if ((svp = av_fetch(seenentry, 0, FALSE)) && (othername = *svp) && (svp = av_fetch(seenentry, 2, FALSE)) && *svp && SvIV(*svp) > 0) { sv_catpvn(retval, "${", 2); sv_catsv(retval, othername); sv_catpvn(retval, "}", 1); return 1; } } else if (val != &PL_sv_undef) { SV * const namesv = newSVpvn("\\", 1); sv_catpvn(namesv, name, namelen); seenentry = newAV(); av_push(seenentry, namesv); av_push(seenentry, newRV_inc(val)); (void)hv_store(seenhv, id, idlen, newRV_inc((SV*)seenentry), 0); SvREFCNT_dec(seenentry); } } if (DD_is_integer(val)) { STRLEN len; if (SvIsUV(val)) len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"UVuf, SvUV(val)); else len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"IVdf, SvIV(val)); if (SvPOK(val)) { /* Need to check to see if this is a string such as " 0". I'm assuming from sprintf isn't going to clash with utf8. Is this valid on EBCDIC? */ STRLEN pvlen; const char * const pv = SvPV(val, pvlen); if (pvlen != len || memNE(pv, tmpbuf, len)) goto integer_came_from_string; } if (len > 10) { /* Looks like we're on a 64 bit system. Make it a string so that if a 32 bit system reads the number it will cope better. */ sv_catpvf(retval, "'%s'", tmpbuf); } else sv_catpvn(retval, tmpbuf, len); } else if (realtype == SVt_PVGV) {/* GLOBs can end up with scribbly names */ c = SvPV(val, i); ++c; --i; /* just get the name */ if (i >= 6 && strncmp(c, "main::", 6) == 0) { c += 4; i -= 4; } if (needs_quote(c)) { sv_grow(retval, SvCUR(retval)+6+2*i); r = SvPVX(retval)+SvCUR(retval); r[0] = '*'; r[1] = '{'; r[2] = '\''; i += esc_q(r+3, c, i); i += 3; r[i++] = '\''; r[i++] = '}'; r[i] = '\0'; } else { sv_grow(retval, SvCUR(retval)+i+2); r = SvPVX(retval)+SvCUR(retval); r[0] = '*'; strcpy(r+1, c); i++; } SvCUR_set(retval, SvCUR(retval)+i); if (purity) { static const char* const entries[] = { "{SCALAR}", "{ARRAY}", "{HASH}" }; static const STRLEN sizes[] = { 8, 7, 6 }; SV *e; SV * const nname = newSVpvn("", 0); SV * const newapad = newSVpvn("", 0); GV * const gv = (GV*)val; I32 j; for (j=0; j<3; j++) { e = ((j == 0) ? GvSV(gv) : (j == 1) ? (SV*)GvAV(gv) : (SV*)GvHV(gv)); if (!e) continue; if (j == 0 && !SvOK(e)) continue; { I32 nlevel = 0; SV *postentry = newSVpvn(r,i); sv_setsv(nname, postentry); sv_catpvn(nname, entries[j], sizes[j]); sv_catpvn(postentry, " = ", 3); av_push(postav, postentry); e = newRV_inc(e); SvCUR_set(newapad, 0); if (indent >= 2) (void)sv_x(aTHX_ newapad, " ", 1, SvCUR(postentry)); DD_dump(aTHX_ e, SvPVX_const(nname), SvCUR(nname), postentry, seenhv, postav, &nlevel, indent, pad, xpad, newapad, sep, pair, freezer, toaster, purity, deepcopy, quotekeys, bless, maxdepth, sortkeys); SvREFCNT_dec(e); } } SvREFCNT_dec(newapad); SvREFCNT_dec(nname); } } else if (val == &PL_sv_undef || !SvOK(val)) { sv_catpvn(retval, "undef", 5); } else { integer_came_from_string: c = SvPV(val, i); if (DO_UTF8(val)) i += esc_q_utf8(aTHX_ retval, c, i); else { sv_grow(retval, SvCUR(retval)+3+2*i); /* 3: ""\0 */ r = SvPVX(retval) + SvCUR(retval); r[0] = '\''; i += esc_q(r+1, c, i); ++i; r[i++] = '\''; r[i] = '\0'; SvCUR_set(retval, SvCUR(retval)+i); } } } if (idlen) { if (deepcopy) (void)hv_delete(seenhv, id, idlen, G_DISCARD); else if (namelen && seenentry) { SV *mark = *av_fetch(seenentry, 2, TRUE); sv_setiv(mark,1); } } return 1;}MODULE = Data::Dumper PACKAGE = Data::Dumper PREFIX = Data_Dumper_## This is the exact equivalent of Dump. Well, almost. The things that are# different as of now (due to Laziness):# * doesnt do double-quotes yet.#voidData_Dumper_Dumpxs(href, ...) SV *href; PROTOTYPE: $;$$ PPCODE: { HV *hv; SV *retval, *valstr; HV *seenhv = NULL; AV *postav, *todumpav, *namesav; I32 level = 0; I32 indent, terse, i, imax, postlen; SV **svp; SV *val, *name, *pad, *xpad, *apad, *sep, *pair, *varname; SV *freezer, *toaster, *bless, *sortkeys; I32 purity, deepcopy, quotekeys, maxdepth = 0; char tmpbuf[1024]; I32 gimme = GIMME; if (!SvROK(href)) { /* call new to get an object first */ if (items < 2) croak("Usage: Data::Dumper::Dumpxs(PACKAGE, VAL_ARY_REF, [NAME_ARY_REF])"); ENTER; SAVETMPS; PUSHMARK(sp); XPUSHs(href); XPUSHs(sv_2mortal(newSVsv(ST(1)))); if (items >= 3) XPUSHs(sv_2mortal(newSVsv(ST(2)))); PUTBACK; i = perl_call_method("new", G_SCALAR); SPAGAIN; if (i) href = newSVsv(POPs); PUTBACK; FREETMPS; LEAVE; if (i) (void)sv_2mortal(href); } todumpav = namesav = NULL; seenhv = NULL; val = pad = xpad = apad = sep = pair = varname = freezer = toaster = bless = sortkeys = &PL_sv_undef; name = sv_newmortal(); indent = 2; terse = purity = deepcopy = 0; quotekeys = 1; retval = newSVpvn("", 0); if (SvROK(href) && (hv = (HV*)SvRV((SV*)href)) && SvTYPE(hv) == SVt_PVHV) { if ((svp = hv_fetch(hv, "seen", 4, FALSE)) && SvROK(*svp)) seenhv = (HV*)SvRV(*svp); if ((svp = hv_fetch(hv, "todump", 6, FALSE)) && SvROK(*svp)) todumpav = (AV*)SvRV(*svp); if ((svp = hv_fetch(hv, "names", 5, FALSE)) && SvROK(*svp)) namesav = (AV*)SvRV(*svp); if ((svp = hv_fetch(hv, "indent", 6, FALSE))) indent = SvIV(*svp); if ((svp = hv_fetch(hv, "purity", 6, FALSE))) purity = SvIV(*svp); if ((svp = hv_fetch(hv, "terse", 5, FALSE))) terse = SvTRUE(*svp);#if 0 /* useqq currently unused */ if ((svp = hv_fetch(hv, "useqq", 5, FALSE))) useqq = SvTRUE(*svp);#endif if ((svp = hv_fetch(hv, "pad", 3, FALSE))) pad = *svp; if ((svp = hv_fetch(hv, "xpad", 4, FALSE))) xpad = *svp; if ((svp = hv_fetch(hv, "apad", 4, FALSE))) apad = *svp; if ((svp = hv_fetch(hv, "sep", 3, FALSE))) sep = *svp; if ((svp = hv_fetch(hv, "pair", 4, FALSE))) pair = *svp; if ((svp = hv_fetch(hv, "varname", 7, FALSE))) varname = *svp; if ((svp = hv_fetch(hv, "freezer", 7, FALSE))) freezer = *svp; if ((svp = hv_fetch(hv, "toaster", 7, FALSE))) toaster = *svp; if ((svp = hv_fetch(hv, "deepcopy", 8, FALSE))) deepcopy = SvTRUE(*svp); if ((svp = hv_fetch(hv, "quotekeys", 9, FALSE))) quotekeys = SvTRUE(*svp); if ((svp = hv_fetch(hv, "bless", 5, FALSE))) bless = *svp; if ((svp = hv_fetch(hv, "maxdepth", 8, FALSE))) maxdepth = SvIV(*svp); if ((svp = hv_fetch(hv, "sortkeys", 8, FALSE))) { sortkeys = *svp; if (! SvTRUE(sortkeys)) sortkeys = NULL; else if (! (SvROK(sortkeys) && SvTYPE(SvRV(sortkeys)) == SVt_PVCV) ) { /* flag to use qsortsv() for sorting hash keys */ sortkeys = &PL_sv_yes; } } postav = newAV(); if (todumpav) imax = av_len(todumpav); else imax = -1; valstr = newSVpvn("",0); for (i = 0; i <= imax; ++i) { SV *newapad; av_clear(postav); if ((svp = av_fetch(todumpav, i, FALSE))) val = *svp; else val = &PL_sv_undef; if ((svp = av_fetch(namesav, i, TRUE))) { sv_setsv(name, *svp); if (SvOK(*svp) && !SvPOK(*svp)) (void)SvPV_nolen_const(name); } else (void)SvOK_off(name); if (SvPOK(name)) { if ((SvPVX_const(name))[0] == '*') { if (SvROK(val)) { switch (SvTYPE(SvRV(val))) { case SVt_PVAV: (SvPVX(name))[0] = '@'; break; case SVt_PVHV: (SvPVX(name))[0] = '%'; break; case SVt_PVCV: (SvPVX(name))[0] = '*'; break; default: (SvPVX(name))[0] = '$'; break; } } else (SvPVX(name))[0] = '$'; } else if ((SvPVX_const(name))[0] != '$') sv_insert(name, 0, 0, "$", 1); } else { STRLEN nchars; sv_setpvn(name, "$", 1); sv_catsv(name, varname); nchars = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"IVdf, (IV)(i+1)); sv_catpvn(name, tmpbuf, nchars); } if (indent >= 2) { SV * const tmpsv = sv_x(aTHX_ NULL, " ", 1, SvCUR(name)+3); newapad = newSVsv(apad); sv_catsv(newapad, tmpsv); SvREFCNT_dec(tmpsv); } else newapad = apad; DD_dump(aTHX_ val, SvPVX_const(name), SvCUR(name), valstr, seenhv, postav, &level, indent, pad, xpad, newapad, sep, pair, freezer, toaster, purity, deepcopy, quotekeys, bless, maxdepth, sortkeys); if (indent >= 2) SvREFCNT_dec(newapad); postlen = av_len(postav); if (postlen >= 0 || !terse) { sv_insert(valstr, 0, 0, " = ", 3); sv_insert(valstr, 0, 0, SvPVX_const(name), SvCUR(name)); sv_catpvn(valstr, ";", 1); } sv_catsv(retval, pad); sv_catsv(retval, valstr); sv_catsv(retval, sep); if (postlen >= 0) { I32 i; sv_catsv(retval, pad); for (i = 0; i <= postlen; ++i) { SV *elem; svp = av_fetch(postav, i, FALSE); if (svp && (elem = *svp)) { sv_catsv(retval, elem); if (i < postlen) { sv_catpvn(retval, ";", 1); sv_catsv(retval, sep); sv_catsv(retval, pad); } } } sv_catpvn(retval, ";", 1); sv_catsv(retval, sep); } sv_setpvn(valstr, "", 0); if (gimme == G_ARRAY) { XPUSHs(sv_2mortal(retval)); if (i < imax) /* not the last time thro ? */ retval = newSVpvn("",0); } } SvREFCNT_dec(postav); SvREFCNT_dec(valstr); } else croak("Call to new() method failed to return HASH ref"); if (gimme == G_SCALAR) XPUSHs(sv_2mortal(retval)); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?