1 #define PERL_NO_GET_CONTEXT
6 static I32 num_q (const char *s, STRLEN slen);
7 static I32 esc_q (char *dest, const char *src, STRLEN slen);
8 static I32 esc_q_utf8 (pTHX_ SV *sv, const char *src, STRLEN slen);
9 static I32 needs_quote(register const char *s);
10 static SV *sv_x (pTHX_ SV *sv, const char *str, STRLEN len, I32 n);
11 static I32 DD_dump (pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval,
12 HV *seenhv, AV *postav, I32 *levelp, I32 indent,
13 SV *pad, SV *xpad, SV *apad, SV *sep, SV *pair,
14 SV *freezer, SV *toaster,
15 I32 purity, I32 deepcopy, I32 quotekeys, SV *bless,
16 I32 maxdepth, SV *sortkeys);
19 #define HvNAME_get HvNAME
22 #if PERL_VERSION <= 6 /* Perl 5.6 and earlier */
25 # define UNI_TO_NATIVE(ch) (((ch) > 255) ? (ch) : ASCII_TO_NATIVE(ch))
27 # define UNI_TO_NATIVE(ch) (ch)
31 Perl_utf8_to_uvchr(pTHX_ U8 *s, STRLEN *retlen)
33 const UV uv = utf8_to_uv(s, UTF8_MAXLEN, retlen,
34 ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
35 return UNI_TO_NATIVE(uv);
38 # if !defined(PERL_IMPLICIT_CONTEXT)
39 # define utf8_to_uvchr Perl_utf8_to_uvchr
41 # define utf8_to_uvchr(a,b) Perl_utf8_to_uvchr(aTHX_ a,b)
44 #endif /* PERL_VERSION <= 6 */
46 /* Changes in 5.7 series mean that now IOK is only set if scalar is
47 precisely integer but in 5.6 and earlier we need to do a more
50 #define DD_is_integer(sv) (SvIOK(sv) && (SvIsUV(val) ? SvUV(sv) == SvNV(sv) : SvIV(sv) == SvNV(sv)))
52 #define DD_is_integer(sv) SvIOK(sv)
55 /* does a string need to be protected? */
57 needs_quote(register const char *s)
82 /* count the number of "'"s and "\"s in string */
84 num_q(register const char *s, register STRLEN slen)
89 if (*s == '\'' || *s == '\\')
98 /* returns number of chars added to escape "'"s and "\"s in s */
99 /* slen number of characters in s will be escaped */
100 /* destination must be long enough for additional chars */
102 esc_q(register char *d, register const char *s, register STRLEN slen)
104 register I32 ret = 0;
122 esc_q_utf8(pTHX_ SV* sv, register const char *src, register STRLEN slen)
126 const char * const send = src + slen;
127 STRLEN j, cur = SvCUR(sv);
128 /* Could count 128-255 and 256+ in two variables, if we want to
129 be like &qquote and make a distinction. */
130 STRLEN grow = 0; /* bytes needed to represent chars 128+ */
131 /* STRLEN topbit_grow = 0; bytes needed to represent chars 128-255 */
132 STRLEN backslashes = 0;
133 STRLEN single_quotes = 0;
134 STRLEN qq_escapables = 0; /* " $ @ will need a \ in "" strings. */
137 /* this will need EBCDICification */
138 for (s = src; s < send; s += UTF8SKIP(s)) {
139 const UV k = utf8_to_uvchr((U8*)s, NULL);
142 /* 4: \x{} then count the number of hex digits. */
143 grow += 4 + (k <= 0xFF ? 2 : k <= 0xFFF ? 3 : k <= 0xFFFF ? 4 :
145 8 /* We may allocate a bit more than the minimum here. */
147 k <= 0xFFFFFFFF ? 8 : UVSIZE * 4
150 } else if (k == '\\') {
152 } else if (k == '\'') {
154 } else if (k == '"' || k == '$' || k == '@') {
161 /* We have something needing hex. 3 is ""\0 */
162 sv_grow(sv, cur + 3 + grow + 2*backslashes + single_quotes
163 + 2*qq_escapables + normal);
164 rstart = r = SvPVX(sv) + cur;
168 for (s = src; s < send; s += UTF8SKIP(s)) {
169 const UV k = utf8_to_uvchr((U8*)s, NULL);
171 if (k == '"' || k == '\\' || k == '$' || k == '@') {
178 /* The return value of sprintf() is unportable.
179 * In modern systems it returns (int) the number of characters,
180 * but in older systems it might return (char*) the original
181 * buffer, or it might even be (void). The easiest portable
182 * thing to do is probably use sprintf() in void context and
183 * then strlen(buffer) for the length. The more proper way
184 * would of course be to figure out the prototype of sprintf.
186 sprintf(r, "\\x{%"UVxf"}", k);
193 sv_grow(sv, cur + 3 + 2*backslashes + 2*single_quotes
194 + qq_escapables + normal);
195 rstart = r = SvPVX(sv) + cur;
197 for (s = src; s < send; s ++) {
199 if (k == '\'' || k == '\\')
207 SvCUR_set(sv, cur + j);
212 /* append a repeated string to an SV */
214 sv_x(pTHX_ SV *sv, const char *str, STRLEN len, I32 n)
217 sv = newSVpvn("", 0);
220 assert(SvTYPE(sv) >= SVt_PV);
224 SvGROW(sv, len*n + SvCUR(sv) + 1);
226 char * const start = SvPVX(sv) + SvCUR(sv);
227 SvCUR_set(sv, SvCUR(sv) + n);
234 sv_catpvn(sv, str, len);
242 * This ought to be split into smaller functions. (it is one long function since
243 * it exactly parallels the perl version, which was one long thing for
244 * efficiency raisins.) Ugggh!
247 DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv,
248 AV *postav, I32 *levelp, I32 indent, SV *pad, SV *xpad,
249 SV *apad, SV *sep, SV *pair, SV *freezer, SV *toaster, I32 purity,
250 I32 deepcopy, I32 quotekeys, SV *bless, I32 maxdepth, SV *sortkeys)
254 char *c, *r, *realpack, id[128];
256 SV *sv, *ipad, *ival;
257 SV *blesspad = Nullsv;
258 AV *seenentry = NULL;
260 STRLEN inamelen, idlen = 0;
266 realtype = SvTYPE(val);
272 /* If a freeze method is provided and the object has it, call
273 it. Warn on errors. */
274 if (SvOBJECT(SvRV(val)) && freezer &&
275 SvPOK(freezer) && SvCUR(freezer) &&
276 gv_fetchmeth(SvSTASH(SvRV(val)), SvPVX_const(freezer),
277 SvCUR(freezer), -1) != NULL)
279 dSP; ENTER; SAVETMPS; PUSHMARK(sp);
280 XPUSHs(val); PUTBACK;
281 i = perl_call_method(SvPVX_const(freezer), G_EVAL|G_VOID);
284 warn("WARNING(Freezer method call failed): %"SVf"", ERRSV);
285 PUTBACK; FREETMPS; LEAVE;
289 realtype = SvTYPE(ival);
290 (void) sprintf(id, "0x%"UVxf, PTR2UV(ival));
293 realpack = HvNAME_get(SvSTASH(ival));
297 /* if it has a name, we need to either look it up, or keep a tab
298 * on it so we know when we hit it later
301 if ((svp = hv_fetch(seenhv, id, idlen, FALSE))
302 && (sv = *svp) && SvROK(sv) && (seenentry = (AV*)SvRV(sv)))
305 if ((svp = av_fetch(seenentry, 0, FALSE))
306 && (othername = *svp))
308 if (purity && *levelp > 0) {
311 if (realtype == SVt_PVHV)
312 sv_catpvn(retval, "{}", 2);
313 else if (realtype == SVt_PVAV)
314 sv_catpvn(retval, "[]", 2);
316 sv_catpvn(retval, "do{my $o}", 9);
317 postentry = newSVpvn(name, namelen);
318 sv_catpvn(postentry, " = ", 3);
319 sv_catsv(postentry, othername);
320 av_push(postav, postentry);
323 if (name[0] == '@' || name[0] == '%') {
324 if ((SvPVX_const(othername))[0] == '\\' &&
325 (SvPVX_const(othername))[1] == name[0]) {
326 sv_catpvn(retval, SvPVX_const(othername)+1,
330 sv_catpvn(retval, name, 1);
331 sv_catpvn(retval, "{", 1);
332 sv_catsv(retval, othername);
333 sv_catpvn(retval, "}", 1);
337 sv_catsv(retval, othername);
342 warn("ref name not found for %s", id);
346 else { /* store our name and continue */
348 if (name[0] == '@' || name[0] == '%') {
349 namesv = newSVpvn("\\", 1);
350 sv_catpvn(namesv, name, namelen);
352 else if (realtype == SVt_PVCV && name[0] == '*') {
353 namesv = newSVpvn("\\", 2);
354 sv_catpvn(namesv, name, namelen);
355 (SvPVX(namesv))[1] = '&';
358 namesv = newSVpvn(name, namelen);
360 av_push(seenentry, namesv);
361 (void)SvREFCNT_inc(val);
362 av_push(seenentry, val);
363 (void)hv_store(seenhv, id, strlen(id),
364 newRV_inc((SV*)seenentry), 0);
365 SvREFCNT_dec(seenentry);
369 if (realpack && *realpack == 'R' && strEQ(realpack, "Regexp")) {
371 const char *rval = SvPV(val, rlen);
372 const char *slash = strchr(rval, '/');
373 sv_catpvn(retval, "qr/", 3);
375 sv_catpvn(retval, rval, slash-rval);
376 sv_catpvn(retval, "\\/", 2);
377 rlen -= slash-rval+1;
379 slash = strchr(rval, '/');
381 sv_catpvn(retval, rval, rlen);
382 sv_catpvn(retval, "/", 1);
386 /* If purity is not set and maxdepth is set, then check depth:
387 * if we have reached maximum depth, return the string
388 * representation of the thing we are currently examining
389 * at this depth (i.e., 'Foo=ARRAY(0xdeadbeef)').
391 if (!purity && maxdepth > 0 && *levelp >= maxdepth) {
393 const char * const valstr = SvPV(val,vallen);
394 sv_catpvn(retval, "'", 1);
395 sv_catpvn(retval, valstr, vallen);
396 sv_catpvn(retval, "'", 1);
400 if (realpack) { /* we have a blessed ref */
402 const char * const blessstr = SvPV(bless, blesslen);
403 sv_catpvn(retval, blessstr, blesslen);
404 sv_catpvn(retval, "( ", 2);
407 apad = newSVsv(apad);
408 sv_x(aTHX_ apad, " ", 1, blesslen+2);
413 ipad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), *levelp);
415 if (realtype <= SVt_PVBM) { /* scalar ref */
416 SV * const namesv = newSVpvn("${", 2);
417 sv_catpvn(namesv, name, namelen);
418 sv_catpvn(namesv, "}", 1);
419 if (realpack) { /* blessed */
420 sv_catpvn(retval, "do{\\(my $o = ", 13);
421 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
422 postav, levelp, indent, pad, xpad, apad, sep, pair,
423 freezer, toaster, purity, deepcopy, quotekeys, bless,
425 sv_catpvn(retval, ")}", 2);
428 sv_catpvn(retval, "\\", 1);
429 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
430 postav, levelp, indent, pad, xpad, apad, sep, pair,
431 freezer, toaster, purity, deepcopy, quotekeys, bless,
434 SvREFCNT_dec(namesv);
436 else if (realtype == SVt_PVGV) { /* glob ref */
437 SV * const namesv = newSVpvn("*{", 2);
438 sv_catpvn(namesv, name, namelen);
439 sv_catpvn(namesv, "}", 1);
440 sv_catpvn(retval, "\\", 1);
441 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
442 postav, levelp, indent, pad, xpad, apad, sep, pair,
443 freezer, toaster, purity, deepcopy, quotekeys, bless,
445 SvREFCNT_dec(namesv);
447 else if (realtype == SVt_PVAV) {
450 const I32 ixmax = av_len((AV *)ival);
452 SV * const ixsv = newSViv(0);
453 /* allowing for a 24 char wide array index */
454 New(0, iname, namelen+28, char);
455 (void)strcpy(iname, name);
457 if (name[0] == '@') {
458 sv_catpvn(retval, "(", 1);
462 sv_catpvn(retval, "[", 1);
463 /* omit "->" in $foo{bar}->[0], but not in ${$foo}->[0] */
465 && name[namelen-1] != ']' && name[namelen-1] != '}'
466 && (namelen < 4 || (name[1] != '{' && name[2] != '{')))*/
468 && name[namelen-1] != ']' && name[namelen-1] != '}')
471 || (name[0] == '\\' && name[2] == '{'))))
473 iname[inamelen++] = '-'; iname[inamelen++] = '>';
474 iname[inamelen] = '\0';
477 if (iname[0] == '*' && iname[inamelen-1] == '}' && inamelen >= 8 &&
478 (instr(iname+inamelen-8, "{SCALAR}") ||
479 instr(iname+inamelen-7, "{ARRAY}") ||
480 instr(iname+inamelen-6, "{HASH}"))) {
481 iname[inamelen++] = '-'; iname[inamelen++] = '>';
483 iname[inamelen++] = '['; iname[inamelen] = '\0';
484 totpad = newSVsv(sep);
485 sv_catsv(totpad, pad);
486 sv_catsv(totpad, apad);
488 for (ix = 0; ix <= ixmax; ++ix) {
491 svp = av_fetch((AV*)ival, ix, FALSE);
499 (void) sprintf(iname+ilen, "%"IVdf, (IV)ix);
500 ilen = strlen(iname);
501 iname[ilen++] = ']'; iname[ilen] = '\0';
503 sv_catsv(retval, totpad);
504 sv_catsv(retval, ipad);
505 sv_catpvn(retval, "#", 1);
506 sv_catsv(retval, ixsv);
508 sv_catsv(retval, totpad);
509 sv_catsv(retval, ipad);
510 DD_dump(aTHX_ elem, iname, ilen, retval, seenhv, postav,
511 levelp, indent, pad, xpad, apad, sep, pair,
512 freezer, toaster, purity, deepcopy, quotekeys, bless,
515 sv_catpvn(retval, ",", 1);
518 SV * const opad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), (*levelp)-1);
519 sv_catsv(retval, totpad);
520 sv_catsv(retval, opad);
524 sv_catpvn(retval, ")", 1);
526 sv_catpvn(retval, "]", 1);
528 SvREFCNT_dec(totpad);
531 else if (realtype == SVt_PVHV) {
532 SV *totpad, *newapad;
540 SV * const iname = newSVpvn(name, namelen);
541 if (name[0] == '%') {
542 sv_catpvn(retval, "(", 1);
543 (SvPVX(iname))[0] = '$';
546 sv_catpvn(retval, "{", 1);
547 /* omit "->" in $foo[0]->{bar}, but not in ${$foo}->{bar} */
549 && name[namelen-1] != ']' && name[namelen-1] != '}')
552 || (name[0] == '\\' && name[2] == '{'))))
554 sv_catpvn(iname, "->", 2);
557 if (name[0] == '*' && name[namelen-1] == '}' && namelen >= 8 &&
558 (instr(name+namelen-8, "{SCALAR}") ||
559 instr(name+namelen-7, "{ARRAY}") ||
560 instr(name+namelen-6, "{HASH}"))) {
561 sv_catpvn(iname, "->", 2);
563 sv_catpvn(iname, "{", 1);
564 totpad = newSVsv(sep);
565 sv_catsv(totpad, pad);
566 sv_catsv(totpad, apad);
568 /* If requested, get a sorted/filtered array of hash keys */
570 if (sortkeys == &PL_sv_yes) {
572 sortkeys = sv_2mortal(newSVpvn("Data::Dumper::_sortkeys", 23));
575 (void)hv_iterinit((HV*)ival);
576 while ((entry = hv_iternext((HV*)ival))) {
577 sv = hv_iterkeysv(entry);
581 # ifdef USE_LOCALE_NUMERIC
582 sortsv(AvARRAY(keys),
584 IN_LOCALE ? Perl_sv_cmp_locale : Perl_sv_cmp);
586 sortsv(AvARRAY(keys),
592 if (sortkeys != &PL_sv_yes) {
593 dSP; ENTER; SAVETMPS; PUSHMARK(sp);
594 XPUSHs(sv_2mortal(newRV_inc(ival))); PUTBACK;
595 i = perl_call_sv(sortkeys, G_SCALAR | G_EVAL);
599 if (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVAV))
600 keys = (AV*)SvREFCNT_inc(SvRV(sv));
603 warn("Sortkeys subroutine did not return ARRAYREF\n");
604 PUTBACK; FREETMPS; LEAVE;
607 sv_2mortal((SV*)keys);
610 (void)hv_iterinit((HV*)ival);
612 /* foreach (keys %hash) */
613 for (i = 0; 1; i++) {
615 char *nkey_buffer = NULL;
620 bool do_utf8 = FALSE;
623 if (!(keys && (I32)i <= av_len(keys))) break;
625 if (!(entry = hv_iternext((HV *)ival))) break;
629 sv_catpvn(retval, ",", 1);
633 svp = av_fetch(keys, i, FALSE);
634 keysv = svp ? *svp : sv_mortalcopy(&PL_sv_undef);
635 key = SvPV(keysv, keylen);
636 svp = hv_fetch((HV*)ival, key,
637 SvUTF8(keysv) ? -(I32)keylen : keylen, 0);
638 hval = svp ? *svp : sv_mortalcopy(&PL_sv_undef);
641 keysv = hv_iterkeysv(entry);
642 hval = hv_iterval((HV*)ival, entry);
645 do_utf8 = DO_UTF8(keysv);
646 key = SvPV(keysv, keylen);
649 sv_catsv(retval, totpad);
650 sv_catsv(retval, ipad);
651 /* old logic was first to check utf8 flag, and if utf8 always
652 call esc_q_utf8. This caused test to break under -Mutf8,
653 because there even strings like 'c' have utf8 flag on.
654 Hence with quotekeys == 0 the XS code would still '' quote
655 them based on flags, whereas the perl code would not,
657 The perl code is correct.
658 needs_quote() decides that anything that isn't a valid
659 perl identifier needs to be quoted, hence only correctly
660 formed strings with no characters outside [A-Za-z0-9_:]
661 won't need quoting. None of those characters are used in
662 the byte encoding of utf8, so anything with utf8
663 encoded characters in will need quoting. Hence strings
664 with utf8 encoded characters in will end up inside do_utf8
665 just like before, but now strings with utf8 flag set but
666 only ascii characters will end up in the unquoted section.
668 There should also be less tests for the (probably currently)
669 more common doesn't need quoting case.
670 The code is also smaller (22044 vs 22260) because I've been
671 able to pull the common logic out to both sides. */
672 if (quotekeys || needs_quote(key)) {
674 STRLEN ocur = SvCUR(retval);
675 nlen = esc_q_utf8(aTHX_ retval, key, klen);
676 nkey = SvPVX(retval) + ocur;
679 nticks = num_q(key, klen);
680 New(0, nkey_buffer, klen+nticks+3, char);
684 klen += esc_q(nkey+1, key, klen);
686 (void)Copy(key, nkey+1, klen, char);
690 sv_catpvn(retval, nkey, klen);
696 sv_catpvn(retval, nkey, klen);
698 sname = newSVsv(iname);
699 sv_catpvn(sname, nkey, nlen);
700 sv_catpvn(sname, "}", 1);
702 sv_catsv(retval, pair);
706 newapad = newSVsv(apad);
707 New(0, extra, klen+4+1, char);
708 while (elen < (klen+4))
711 sv_catpvn(newapad, extra, elen);
717 DD_dump(aTHX_ hval, SvPVX_const(sname), SvCUR(sname), retval, seenhv,
718 postav, levelp, indent, pad, xpad, newapad, sep, pair,
719 freezer, toaster, purity, deepcopy, quotekeys, bless,
722 Safefree(nkey_buffer);
724 SvREFCNT_dec(newapad);
727 SV *opad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), *levelp-1);
728 sv_catsv(retval, totpad);
729 sv_catsv(retval, opad);
733 sv_catpvn(retval, ")", 1);
735 sv_catpvn(retval, "}", 1);
737 SvREFCNT_dec(totpad);
739 else if (realtype == SVt_PVCV) {
740 sv_catpvn(retval, "sub { \"DUMMY\" }", 15);
742 warn("Encountered CODE ref, using dummy placeholder");
745 warn("cannot handle ref type %ld", realtype);
748 if (realpack) { /* free blessed allocs */
753 sv_catpvn(retval, ", '", 3);
754 sv_catpvn(retval, realpack, strlen(realpack));
755 sv_catpvn(retval, "' )", 3);
756 if (toaster && SvPOK(toaster) && SvCUR(toaster)) {
757 sv_catpvn(retval, "->", 2);
758 sv_catsv(retval, toaster);
759 sv_catpvn(retval, "()", 2);
769 (void) sprintf(id, "0x%"UVxf, PTR2UV(val));
770 if ((svp = hv_fetch(seenhv, id, (idlen = strlen(id)), FALSE)) &&
771 (sv = *svp) && SvROK(sv) &&
772 (seenentry = (AV*)SvRV(sv)))
775 if ((svp = av_fetch(seenentry, 0, FALSE)) && (othername = *svp)
776 && (svp = av_fetch(seenentry, 2, FALSE)) && *svp && SvIV(*svp) > 0)
778 sv_catpvn(retval, "${", 2);
779 sv_catsv(retval, othername);
780 sv_catpvn(retval, "}", 1);
784 else if (val != &PL_sv_undef) {
785 SV * const namesv = newSVpvn("\\", 1);
786 sv_catpvn(namesv, name, namelen);
788 av_push(seenentry, namesv);
789 av_push(seenentry, newRV_inc(val));
790 (void)hv_store(seenhv, id, strlen(id), newRV_inc((SV*)seenentry), 0);
791 SvREFCNT_dec(seenentry);
795 if (DD_is_integer(val)) {
798 (void) sprintf(tmpbuf, "%"UVuf, SvUV(val));
800 (void) sprintf(tmpbuf, "%"IVdf, SvIV(val));
801 len = strlen(tmpbuf);
803 /* Need to check to see if this is a string such as " 0".
804 I'm assuming from sprintf isn't going to clash with utf8.
805 Is this valid on EBCDIC? */
807 const char * const pv = SvPV(val, pvlen);
808 if (pvlen != len || memNE(pv, tmpbuf, len))
809 goto integer_came_from_string;
812 /* Looks like we're on a 64 bit system. Make it a string so that
813 if a 32 bit system reads the number it will cope better. */
814 sv_catpvf(retval, "'%s'", tmpbuf);
816 sv_catpvn(retval, tmpbuf, len);
818 else if (realtype == SVt_PVGV) {/* GLOBs can end up with scribbly names */
820 ++c; --i; /* just get the name */
821 if (i >= 6 && strncmp(c, "main::", 6) == 0) {
825 if (needs_quote(c)) {
826 sv_grow(retval, SvCUR(retval)+6+2*i);
827 r = SvPVX(retval)+SvCUR(retval);
828 r[0] = '*'; r[1] = '{'; r[2] = '\'';
829 i += esc_q(r+3, c, i);
831 r[i++] = '\''; r[i++] = '}';
835 sv_grow(retval, SvCUR(retval)+i+2);
836 r = SvPVX(retval)+SvCUR(retval);
837 r[0] = '*'; strcpy(r+1, c);
840 SvCUR_set(retval, SvCUR(retval)+i);
843 static const char* const entries[] = { "{SCALAR}", "{ARRAY}", "{HASH}" };
844 static const STRLEN sizes[] = { 8, 7, 6 };
846 SV * const nname = newSVpvn("", 0);
847 SV * const newapad = newSVpvn("", 0);
848 GV * const gv = (GV*)val;
851 for (j=0; j<3; j++) {
852 e = ((j == 0) ? GvSV(gv) : (j == 1) ? (SV*)GvAV(gv) : (SV*)GvHV(gv));
855 if (j == 0 && !SvOK(e))
860 SV *postentry = newSVpvn(r,i);
862 sv_setsv(nname, postentry);
863 sv_catpvn(nname, entries[j], sizes[j]);
864 sv_catpvn(postentry, " = ", 3);
865 av_push(postav, postentry);
868 SvCUR_set(newapad, 0);
870 (void)sv_x(aTHX_ newapad, " ", 1, SvCUR(postentry));
872 DD_dump(aTHX_ e, SvPVX_const(nname), SvCUR(nname), postentry,
873 seenhv, postav, &nlevel, indent, pad, xpad,
874 newapad, sep, pair, freezer, toaster, purity,
875 deepcopy, quotekeys, bless, maxdepth,
881 SvREFCNT_dec(newapad);
885 else if (val == &PL_sv_undef || !SvOK(val)) {
886 sv_catpvn(retval, "undef", 5);
889 integer_came_from_string:
892 i += esc_q_utf8(aTHX_ retval, c, i);
894 sv_grow(retval, SvCUR(retval)+3+2*i); /* 3: ""\0 */
895 r = SvPVX(retval) + SvCUR(retval);
897 i += esc_q(r+1, c, i);
901 SvCUR_set(retval, SvCUR(retval)+i);
908 (void)hv_delete(seenhv, id, idlen, G_DISCARD);
909 else if (namelen && seenentry) {
910 SV *mark = *av_fetch(seenentry, 2, TRUE);
918 MODULE = Data::Dumper PACKAGE = Data::Dumper PREFIX = Data_Dumper_
921 # This is the exact equivalent of Dump. Well, almost. The things that are
922 # different as of now (due to Laziness):
923 # * doesnt do double-quotes yet.
927 Data_Dumper_Dumpxs(href, ...)
935 AV *postav, *todumpav, *namesav;
937 I32 indent, terse, i, imax, postlen;
939 SV *val, *name, *pad, *xpad, *apad, *sep, *pair, *varname;
940 SV *freezer, *toaster, *bless, *sortkeys;
941 I32 purity, deepcopy, quotekeys, maxdepth = 0;
945 if (!SvROK(href)) { /* call new to get an object first */
947 croak("Usage: Data::Dumper::Dumpxs(PACKAGE, VAL_ARY_REF, [NAME_ARY_REF])");
954 XPUSHs(sv_2mortal(newSVsv(ST(1))));
956 XPUSHs(sv_2mortal(newSVsv(ST(2))));
958 i = perl_call_method("new", G_SCALAR);
961 href = newSVsv(POPs);
967 (void)sv_2mortal(href);
970 todumpav = namesav = NULL;
972 val = pad = xpad = apad = sep = pair = varname
973 = freezer = toaster = bless = sortkeys = &PL_sv_undef;
974 name = sv_newmortal();
976 terse = purity = deepcopy = 0;
979 retval = newSVpvn("", 0);
981 && (hv = (HV*)SvRV((SV*)href))
982 && SvTYPE(hv) == SVt_PVHV) {
984 if ((svp = hv_fetch(hv, "seen", 4, FALSE)) && SvROK(*svp))
985 seenhv = (HV*)SvRV(*svp);
986 if ((svp = hv_fetch(hv, "todump", 6, FALSE)) && SvROK(*svp))
987 todumpav = (AV*)SvRV(*svp);
988 if ((svp = hv_fetch(hv, "names", 5, FALSE)) && SvROK(*svp))
989 namesav = (AV*)SvRV(*svp);
990 if ((svp = hv_fetch(hv, "indent", 6, FALSE)))
992 if ((svp = hv_fetch(hv, "purity", 6, FALSE)))
994 if ((svp = hv_fetch(hv, "terse", 5, FALSE)))
995 terse = SvTRUE(*svp);
996 #if 0 /* useqq currently unused */
997 if ((svp = hv_fetch(hv, "useqq", 5, FALSE)))
998 useqq = SvTRUE(*svp);
1000 if ((svp = hv_fetch(hv, "pad", 3, FALSE)))
1002 if ((svp = hv_fetch(hv, "xpad", 4, FALSE)))
1004 if ((svp = hv_fetch(hv, "apad", 4, FALSE)))
1006 if ((svp = hv_fetch(hv, "sep", 3, FALSE)))
1008 if ((svp = hv_fetch(hv, "pair", 4, FALSE)))
1010 if ((svp = hv_fetch(hv, "varname", 7, FALSE)))
1012 if ((svp = hv_fetch(hv, "freezer", 7, FALSE)))
1014 if ((svp = hv_fetch(hv, "toaster", 7, FALSE)))
1016 if ((svp = hv_fetch(hv, "deepcopy", 8, FALSE)))
1017 deepcopy = SvTRUE(*svp);
1018 if ((svp = hv_fetch(hv, "quotekeys", 9, FALSE)))
1019 quotekeys = SvTRUE(*svp);
1020 if ((svp = hv_fetch(hv, "bless", 5, FALSE)))
1022 if ((svp = hv_fetch(hv, "maxdepth", 8, FALSE)))
1023 maxdepth = SvIV(*svp);
1024 if ((svp = hv_fetch(hv, "sortkeys", 8, FALSE))) {
1026 if (! SvTRUE(sortkeys))
1028 else if (! (SvROK(sortkeys) &&
1029 SvTYPE(SvRV(sortkeys)) == SVt_PVCV) )
1031 /* flag to use qsortsv() for sorting hash keys */
1032 sortkeys = &PL_sv_yes;
1038 imax = av_len(todumpav);
1041 valstr = newSVpvn("",0);
1042 for (i = 0; i <= imax; ++i) {
1046 if ((svp = av_fetch(todumpav, i, FALSE)))
1050 if ((svp = av_fetch(namesav, i, TRUE))) {
1051 sv_setsv(name, *svp);
1052 if (SvOK(*svp) && !SvPOK(*svp))
1053 (void)SvPV_nolen_const(name);
1056 (void)SvOK_off(name);
1059 if ((SvPVX_const(name))[0] == '*') {
1061 switch (SvTYPE(SvRV(val))) {
1063 (SvPVX(name))[0] = '@';
1066 (SvPVX(name))[0] = '%';
1069 (SvPVX(name))[0] = '*';
1072 (SvPVX(name))[0] = '$';
1077 (SvPVX(name))[0] = '$';
1079 else if ((SvPVX_const(name))[0] != '$')
1080 sv_insert(name, 0, 0, "$", 1);
1084 sv_setpvn(name, "$", 1);
1085 sv_catsv(name, varname);
1086 (void) sprintf(tmpbuf, "%"IVdf, (IV)(i+1));
1087 nchars = strlen(tmpbuf);
1088 sv_catpvn(name, tmpbuf, nchars);
1092 SV * const tmpsv = sv_x(aTHX_ NULL, " ", 1, SvCUR(name)+3);
1093 newapad = newSVsv(apad);
1094 sv_catsv(newapad, tmpsv);
1095 SvREFCNT_dec(tmpsv);
1100 DD_dump(aTHX_ val, SvPVX_const(name), SvCUR(name), valstr, seenhv,
1101 postav, &level, indent, pad, xpad, newapad, sep, pair,
1102 freezer, toaster, purity, deepcopy, quotekeys,
1103 bless, maxdepth, sortkeys);
1106 SvREFCNT_dec(newapad);
1108 postlen = av_len(postav);
1109 if (postlen >= 0 || !terse) {
1110 sv_insert(valstr, 0, 0, " = ", 3);
1111 sv_insert(valstr, 0, 0, SvPVX_const(name), SvCUR(name));
1112 sv_catpvn(valstr, ";", 1);
1114 sv_catsv(retval, pad);
1115 sv_catsv(retval, valstr);
1116 sv_catsv(retval, sep);
1119 sv_catsv(retval, pad);
1120 for (i = 0; i <= postlen; ++i) {
1122 svp = av_fetch(postav, i, FALSE);
1123 if (svp && (elem = *svp)) {
1124 sv_catsv(retval, elem);
1126 sv_catpvn(retval, ";", 1);
1127 sv_catsv(retval, sep);
1128 sv_catsv(retval, pad);
1132 sv_catpvn(retval, ";", 1);
1133 sv_catsv(retval, sep);
1135 sv_setpvn(valstr, "", 0);
1136 if (gimme == G_ARRAY) {
1137 XPUSHs(sv_2mortal(retval));
1138 if (i < imax) /* not the last time thro ? */
1139 retval = newSVpvn("",0);
1142 SvREFCNT_dec(postav);
1143 SvREFCNT_dec(valstr);
1146 croak("Call to new() method failed to return HASH ref");
1147 if (gimme == G_SCALAR)
1148 XPUSHs(sv_2mortal(retval));