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 + -
显示快捷键?