1 #define PERL_NO_GET_CONTEXT
7 static I32 num_q (const char *s, STRLEN slen);
8 static I32 esc_q (char *dest, const char *src, STRLEN slen);
9 static I32 esc_q_utf8 (pTHX_ SV *sv, const char *src, STRLEN slen);
10 static I32 needs_quote(register const char *s);
11 static SV *sv_x (pTHX_ SV *sv, const char *str, STRLEN len, I32 n);
12 static I32 DD_dump (pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval,
13 HV *seenhv, AV *postav, I32 *levelp, I32 indent,
14 SV *pad, SV *xpad, SV *apad, SV *sep, SV *pair,
15 SV *freezer, SV *toaster,
16 I32 purity, I32 deepcopy, I32 quotekeys, SV *bless,
17 I32 maxdepth, SV *sortkeys);
20 #define HvNAME_get HvNAME
23 #if PERL_VERSION <= 6 /* Perl 5.6 and earlier */
26 # define UNI_TO_NATIVE(ch) (((ch) > 255) ? (ch) : ASCII_TO_NATIVE(ch))
28 # define UNI_TO_NATIVE(ch) (ch)
32 Perl_utf8_to_uvchr(pTHX_ U8 *s, STRLEN *retlen)
34 const UV uv = utf8_to_uv(s, UTF8_MAXLEN, retlen,
35 ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
36 return UNI_TO_NATIVE(uv);
39 # if !defined(PERL_IMPLICIT_CONTEXT)
40 # define utf8_to_uvchr Perl_utf8_to_uvchr
42 # define utf8_to_uvchr(a,b) Perl_utf8_to_uvchr(aTHX_ a,b)
45 #endif /* PERL_VERSION <= 6 */
47 /* Changes in 5.7 series mean that now IOK is only set if scalar is
48 precisely integer but in 5.6 and earlier we need to do a more
51 #define DD_is_integer(sv) (SvIOK(sv) && (SvIsUV(val) ? SvUV(sv) == SvNV(sv) : SvIV(sv) == SvNV(sv)))
53 #define DD_is_integer(sv) SvIOK(sv)
56 /* does a string need to be protected? */
58 needs_quote(register const char *s)
83 /* count the number of "'"s and "\"s in string */
85 num_q(register const char *s, register STRLEN slen)
90 if (*s == '\'' || *s == '\\')
99 /* returns number of chars added to escape "'"s and "\"s in s */
100 /* slen number of characters in s will be escaped */
101 /* destination must be long enough for additional chars */
103 esc_q(register char *d, register const char *s, register STRLEN slen)
105 register I32 ret = 0;
123 esc_q_utf8(pTHX_ SV* sv, register const char *src, register STRLEN slen)
127 const char * const send = src + slen;
128 STRLEN j, cur = SvCUR(sv);
129 /* Could count 128-255 and 256+ in two variables, if we want to
130 be like &qquote and make a distinction. */
131 STRLEN grow = 0; /* bytes needed to represent chars 128+ */
132 /* STRLEN topbit_grow = 0; bytes needed to represent chars 128-255 */
133 STRLEN backslashes = 0;
134 STRLEN single_quotes = 0;
135 STRLEN qq_escapables = 0; /* " $ @ will need a \ in "" strings. */
138 /* this will need EBCDICification */
139 for (s = src; s < send; s += UTF8SKIP(s)) {
140 const UV k = utf8_to_uvchr((U8*)s, NULL);
143 if (!isprint(k) || k > 256) {
147 /* 4: \x{} then count the number of hex digits. */
148 grow += 4 + (k <= 0xFF ? 2 : k <= 0xFFF ? 3 : k <= 0xFFFF ? 4 :
150 8 /* We may allocate a bit more than the minimum here. */
152 k <= 0xFFFFFFFF ? 8 : UVSIZE * 4
155 } else if (k == '\\') {
157 } else if (k == '\'') {
159 } else if (k == '"' || k == '$' || k == '@') {
166 /* We have something needing hex. 3 is ""\0 */
167 sv_grow(sv, cur + 3 + grow + 2*backslashes + single_quotes
168 + 2*qq_escapables + normal);
169 rstart = r = SvPVX(sv) + cur;
173 for (s = src; s < send; s += UTF8SKIP(s)) {
174 const UV k = utf8_to_uvchr((U8*)s, NULL);
176 if (k == '"' || k == '\\' || k == '$' || k == '@') {
182 if (isprint(k) && k < 256)
188 r = r + my_sprintf(r, "\\x{%"UVxf"}", k);
194 sv_grow(sv, cur + 3 + 2*backslashes + 2*single_quotes
195 + qq_escapables + normal);
196 rstart = r = SvPVX(sv) + cur;
198 for (s = src; s < send; s ++) {
200 if (k == '\'' || k == '\\')
208 SvCUR_set(sv, cur + j);
213 /* append a repeated string to an SV */
215 sv_x(pTHX_ SV *sv, const char *str, STRLEN len, I32 n)
218 sv = newSVpvn("", 0);
221 assert(SvTYPE(sv) >= SVt_PV);
225 SvGROW(sv, len*n + SvCUR(sv) + 1);
227 char * const start = SvPVX(sv) + SvCUR(sv);
228 SvCUR_set(sv, SvCUR(sv) + n);
235 sv_catpvn(sv, str, len);
243 * This ought to be split into smaller functions. (it is one long function since
244 * it exactly parallels the perl version, which was one long thing for
245 * efficiency raisins.) Ugggh!
248 DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv,
249 AV *postav, I32 *levelp, I32 indent, SV *pad, SV *xpad,
250 SV *apad, SV *sep, SV *pair, SV *freezer, SV *toaster, I32 purity,
251 I32 deepcopy, I32 quotekeys, SV *bless, I32 maxdepth, SV *sortkeys)
255 char *c, *r, *realpack, id[128];
257 SV *sv, *ipad, *ival;
258 SV *blesspad = Nullsv;
259 AV *seenentry = NULL;
261 STRLEN inamelen, idlen = 0;
267 realtype = SvTYPE(val);
273 /* If a freeze method is provided and the object has it, call
274 it. Warn on errors. */
275 if (SvOBJECT(SvRV(val)) && freezer &&
276 SvPOK(freezer) && SvCUR(freezer) &&
277 gv_fetchmeth(SvSTASH(SvRV(val)), SvPVX_const(freezer),
278 SvCUR(freezer), -1) != NULL)
280 dSP; ENTER; SAVETMPS; PUSHMARK(sp);
281 XPUSHs(val); PUTBACK;
282 i = perl_call_method(SvPVX_const(freezer), G_EVAL|G_VOID);
285 warn("WARNING(Freezer method call failed): %"SVf"", ERRSV);
286 PUTBACK; FREETMPS; LEAVE;
290 realtype = SvTYPE(ival);
291 idlen = my_snprintf(id, sizeof(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, idlen,
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 ilen = ilen + my_sprintf(iname+ilen, "%"IVdf, (IV)ix);
500 iname[ilen++] = ']'; iname[ilen] = '\0';
502 sv_catsv(retval, totpad);
503 sv_catsv(retval, ipad);
504 sv_catpvn(retval, "#", 1);
505 sv_catsv(retval, ixsv);
507 sv_catsv(retval, totpad);
508 sv_catsv(retval, ipad);
509 DD_dump(aTHX_ elem, iname, ilen, retval, seenhv, postav,
510 levelp, indent, pad, xpad, apad, sep, pair,
511 freezer, toaster, purity, deepcopy, quotekeys, bless,
514 sv_catpvn(retval, ",", 1);
517 SV * const opad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), (*levelp)-1);
518 sv_catsv(retval, totpad);
519 sv_catsv(retval, opad);
523 sv_catpvn(retval, ")", 1);
525 sv_catpvn(retval, "]", 1);
527 SvREFCNT_dec(totpad);
530 else if (realtype == SVt_PVHV) {
531 SV *totpad, *newapad;
539 SV * const iname = newSVpvn(name, namelen);
540 if (name[0] == '%') {
541 sv_catpvn(retval, "(", 1);
542 (SvPVX(iname))[0] = '$';
545 sv_catpvn(retval, "{", 1);
546 /* omit "->" in $foo[0]->{bar}, but not in ${$foo}->{bar} */
548 && name[namelen-1] != ']' && name[namelen-1] != '}')
551 || (name[0] == '\\' && name[2] == '{'))))
553 sv_catpvn(iname, "->", 2);
556 if (name[0] == '*' && name[namelen-1] == '}' && namelen >= 8 &&
557 (instr(name+namelen-8, "{SCALAR}") ||
558 instr(name+namelen-7, "{ARRAY}") ||
559 instr(name+namelen-6, "{HASH}"))) {
560 sv_catpvn(iname, "->", 2);
562 sv_catpvn(iname, "{", 1);
563 totpad = newSVsv(sep);
564 sv_catsv(totpad, pad);
565 sv_catsv(totpad, apad);
567 /* If requested, get a sorted/filtered array of hash keys */
569 if (sortkeys == &PL_sv_yes) {
571 sortkeys = sv_2mortal(newSVpvn("Data::Dumper::_sortkeys", 23));
574 (void)hv_iterinit((HV*)ival);
575 while ((entry = hv_iternext((HV*)ival))) {
576 sv = hv_iterkeysv(entry);
580 # ifdef USE_LOCALE_NUMERIC
581 sortsv(AvARRAY(keys),
583 IN_LOCALE ? Perl_sv_cmp_locale : Perl_sv_cmp);
585 sortsv(AvARRAY(keys),
591 if (sortkeys != &PL_sv_yes) {
592 dSP; ENTER; SAVETMPS; PUSHMARK(sp);
593 XPUSHs(sv_2mortal(newRV_inc(ival))); PUTBACK;
594 i = perl_call_sv(sortkeys, G_SCALAR | G_EVAL);
598 if (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVAV))
599 keys = (AV*)SvREFCNT_inc(SvRV(sv));
602 warn("Sortkeys subroutine did not return ARRAYREF\n");
603 PUTBACK; FREETMPS; LEAVE;
606 sv_2mortal((SV*)keys);
609 (void)hv_iterinit((HV*)ival);
611 /* foreach (keys %hash) */
612 for (i = 0; 1; i++) {
614 char *nkey_buffer = NULL;
619 bool do_utf8 = FALSE;
622 if (!(keys && (I32)i <= av_len(keys))) break;
624 if (!(entry = hv_iternext((HV *)ival))) break;
628 sv_catpvn(retval, ",", 1);
632 svp = av_fetch(keys, i, FALSE);
633 keysv = svp ? *svp : sv_mortalcopy(&PL_sv_undef);
634 key = SvPV(keysv, keylen);
635 svp = hv_fetch((HV*)ival, key,
636 SvUTF8(keysv) ? -(I32)keylen : keylen, 0);
637 hval = svp ? *svp : sv_mortalcopy(&PL_sv_undef);
640 keysv = hv_iterkeysv(entry);
641 hval = hv_iterval((HV*)ival, entry);
644 key = SvPV(keysv, keylen);
645 do_utf8 = DO_UTF8(keysv);
648 sv_catsv(retval, totpad);
649 sv_catsv(retval, ipad);
650 /* old logic was first to check utf8 flag, and if utf8 always
651 call esc_q_utf8. This caused test to break under -Mutf8,
652 because there even strings like 'c' have utf8 flag on.
653 Hence with quotekeys == 0 the XS code would still '' quote
654 them based on flags, whereas the perl code would not,
656 The perl code is correct.
657 needs_quote() decides that anything that isn't a valid
658 perl identifier needs to be quoted, hence only correctly
659 formed strings with no characters outside [A-Za-z0-9_:]
660 won't need quoting. None of those characters are used in
661 the byte encoding of utf8, so anything with utf8
662 encoded characters in will need quoting. Hence strings
663 with utf8 encoded characters in will end up inside do_utf8
664 just like before, but now strings with utf8 flag set but
665 only ascii characters will end up in the unquoted section.
667 There should also be less tests for the (probably currently)
668 more common doesn't need quoting case.
669 The code is also smaller (22044 vs 22260) because I've been
670 able to pull the common logic out to both sides. */
671 if (quotekeys || needs_quote(key)) {
673 STRLEN ocur = SvCUR(retval);
674 nlen = esc_q_utf8(aTHX_ retval, key, klen);
675 nkey = SvPVX(retval) + ocur;
678 nticks = num_q(key, klen);
679 New(0, nkey_buffer, klen+nticks+3, char);
683 klen += esc_q(nkey+1, key, klen);
685 (void)Copy(key, nkey+1, klen, char);
689 sv_catpvn(retval, nkey, klen);
695 sv_catpvn(retval, nkey, klen);
697 sname = newSVsv(iname);
698 sv_catpvn(sname, nkey, nlen);
699 sv_catpvn(sname, "}", 1);
701 sv_catsv(retval, pair);
705 newapad = newSVsv(apad);
706 New(0, extra, klen+4+1, char);
707 while (elen < (klen+4))
710 sv_catpvn(newapad, extra, elen);
716 DD_dump(aTHX_ hval, SvPVX_const(sname), SvCUR(sname), retval, seenhv,
717 postav, levelp, indent, pad, xpad, newapad, sep, pair,
718 freezer, toaster, purity, deepcopy, quotekeys, bless,
721 Safefree(nkey_buffer);
723 SvREFCNT_dec(newapad);
726 SV *opad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), *levelp-1);
727 sv_catsv(retval, totpad);
728 sv_catsv(retval, opad);
732 sv_catpvn(retval, ")", 1);
734 sv_catpvn(retval, "}", 1);
736 SvREFCNT_dec(totpad);
738 else if (realtype == SVt_PVCV) {
739 sv_catpvn(retval, "sub { \"DUMMY\" }", 15);
741 warn("Encountered CODE ref, using dummy placeholder");
744 warn("cannot handle ref type %ld", realtype);
747 if (realpack) { /* free blessed allocs */
752 sv_catpvn(retval, ", '", 3);
753 sv_catpvn(retval, realpack, strlen(realpack));
754 sv_catpvn(retval, "' )", 3);
755 if (toaster && SvPOK(toaster) && SvCUR(toaster)) {
756 sv_catpvn(retval, "->", 2);
757 sv_catsv(retval, toaster);
758 sv_catpvn(retval, "()", 2);
768 idlen = my_snprintf(id, sizeof(id), "0x%"UVxf, PTR2UV(val));
769 if ((svp = hv_fetch(seenhv, id, idlen, FALSE)) &&
770 (sv = *svp) && SvROK(sv) &&
771 (seenentry = (AV*)SvRV(sv)))
774 if ((svp = av_fetch(seenentry, 0, FALSE)) && (othername = *svp)
775 && (svp = av_fetch(seenentry, 2, FALSE)) && *svp && SvIV(*svp) > 0)
777 sv_catpvn(retval, "${", 2);
778 sv_catsv(retval, othername);
779 sv_catpvn(retval, "}", 1);
783 else if (val != &PL_sv_undef) {
784 SV * const namesv = newSVpvn("\\", 1);
785 sv_catpvn(namesv, name, namelen);
787 av_push(seenentry, namesv);
788 av_push(seenentry, newRV_inc(val));
789 (void)hv_store(seenhv, id, idlen, newRV_inc((SV*)seenentry), 0);
790 SvREFCNT_dec(seenentry);
794 if (DD_is_integer(val)) {
797 len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"UVuf, SvUV(val));
799 len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"IVdf, SvIV(val));
801 /* Need to check to see if this is a string such as " 0".
802 I'm assuming from sprintf isn't going to clash with utf8.
803 Is this valid on EBCDIC? */
805 const char * const pv = SvPV(val, pvlen);
806 if (pvlen != len || memNE(pv, tmpbuf, len))
807 goto integer_came_from_string;
810 /* Looks like we're on a 64 bit system. Make it a string so that
811 if a 32 bit system reads the number it will cope better. */
812 sv_catpvf(retval, "'%s'", tmpbuf);
814 sv_catpvn(retval, tmpbuf, len);
816 else if (realtype == SVt_PVGV) {/* GLOBs can end up with scribbly names */
818 ++c; --i; /* just get the name */
819 if (i >= 6 && strncmp(c, "main::", 6) == 0) {
823 if (needs_quote(c)) {
824 sv_grow(retval, SvCUR(retval)+6+2*i);
825 r = SvPVX(retval)+SvCUR(retval);
826 r[0] = '*'; r[1] = '{'; r[2] = '\'';
827 i += esc_q(r+3, c, i);
829 r[i++] = '\''; r[i++] = '}';
833 sv_grow(retval, SvCUR(retval)+i+2);
834 r = SvPVX(retval)+SvCUR(retval);
835 r[0] = '*'; strcpy(r+1, c);
838 SvCUR_set(retval, SvCUR(retval)+i);
841 static const char* const entries[] = { "{SCALAR}", "{ARRAY}", "{HASH}" };
842 static const STRLEN sizes[] = { 8, 7, 6 };
844 SV * const nname = newSVpvn("", 0);
845 SV * const newapad = newSVpvn("", 0);
846 GV * const gv = (GV*)val;
849 for (j=0; j<3; j++) {
850 e = ((j == 0) ? GvSV(gv) : (j == 1) ? (SV*)GvAV(gv) : (SV*)GvHV(gv));
853 if (j == 0 && !SvOK(e))
858 SV *postentry = newSVpvn(r,i);
860 sv_setsv(nname, postentry);
861 sv_catpvn(nname, entries[j], sizes[j]);
862 sv_catpvn(postentry, " = ", 3);
863 av_push(postav, postentry);
866 SvCUR_set(newapad, 0);
868 (void)sv_x(aTHX_ newapad, " ", 1, SvCUR(postentry));
870 DD_dump(aTHX_ e, SvPVX_const(nname), SvCUR(nname), postentry,
871 seenhv, postav, &nlevel, indent, pad, xpad,
872 newapad, sep, pair, freezer, toaster, purity,
873 deepcopy, quotekeys, bless, maxdepth,
879 SvREFCNT_dec(newapad);
883 else if (val == &PL_sv_undef || !SvOK(val)) {
884 sv_catpvn(retval, "undef", 5);
887 integer_came_from_string:
890 i += esc_q_utf8(aTHX_ retval, c, i);
892 sv_grow(retval, SvCUR(retval)+3+2*i); /* 3: ""\0 */
893 r = SvPVX(retval) + SvCUR(retval);
895 i += esc_q(r+1, c, i);
899 SvCUR_set(retval, SvCUR(retval)+i);
906 (void)hv_delete(seenhv, id, idlen, G_DISCARD);
907 else if (namelen && seenentry) {
908 SV *mark = *av_fetch(seenentry, 2, TRUE);
916 MODULE = Data::Dumper PACKAGE = Data::Dumper PREFIX = Data_Dumper_
919 # This is the exact equivalent of Dump. Well, almost. The things that are
920 # different as of now (due to Laziness):
921 # * doesnt do double-quotes yet.
925 Data_Dumper_Dumpxs(href, ...)
933 AV *postav, *todumpav, *namesav;
935 I32 indent, terse, i, imax, postlen;
937 SV *val, *name, *pad, *xpad, *apad, *sep, *pair, *varname;
938 SV *freezer, *toaster, *bless, *sortkeys;
939 I32 purity, deepcopy, quotekeys, maxdepth = 0;
943 if (!SvROK(href)) { /* call new to get an object first */
945 croak("Usage: Data::Dumper::Dumpxs(PACKAGE, VAL_ARY_REF, [NAME_ARY_REF])");
952 XPUSHs(sv_2mortal(newSVsv(ST(1))));
954 XPUSHs(sv_2mortal(newSVsv(ST(2))));
956 i = perl_call_method("new", G_SCALAR);
959 href = newSVsv(POPs);
965 (void)sv_2mortal(href);
968 todumpav = namesav = NULL;
970 val = pad = xpad = apad = sep = pair = varname
971 = freezer = toaster = bless = sortkeys = &PL_sv_undef;
972 name = sv_newmortal();
974 terse = purity = deepcopy = 0;
977 retval = newSVpvn("", 0);
979 && (hv = (HV*)SvRV((SV*)href))
980 && SvTYPE(hv) == SVt_PVHV) {
982 if ((svp = hv_fetch(hv, "seen", 4, FALSE)) && SvROK(*svp))
983 seenhv = (HV*)SvRV(*svp);
984 if ((svp = hv_fetch(hv, "todump", 6, FALSE)) && SvROK(*svp))
985 todumpav = (AV*)SvRV(*svp);
986 if ((svp = hv_fetch(hv, "names", 5, FALSE)) && SvROK(*svp))
987 namesav = (AV*)SvRV(*svp);
988 if ((svp = hv_fetch(hv, "indent", 6, FALSE)))
990 if ((svp = hv_fetch(hv, "purity", 6, FALSE)))
992 if ((svp = hv_fetch(hv, "terse", 5, FALSE)))
993 terse = SvTRUE(*svp);
994 #if 0 /* useqq currently unused */
995 if ((svp = hv_fetch(hv, "useqq", 5, FALSE)))
996 useqq = SvTRUE(*svp);
998 if ((svp = hv_fetch(hv, "pad", 3, FALSE)))
1000 if ((svp = hv_fetch(hv, "xpad", 4, FALSE)))
1002 if ((svp = hv_fetch(hv, "apad", 4, FALSE)))
1004 if ((svp = hv_fetch(hv, "sep", 3, FALSE)))
1006 if ((svp = hv_fetch(hv, "pair", 4, FALSE)))
1008 if ((svp = hv_fetch(hv, "varname", 7, FALSE)))
1010 if ((svp = hv_fetch(hv, "freezer", 7, FALSE)))
1012 if ((svp = hv_fetch(hv, "toaster", 7, FALSE)))
1014 if ((svp = hv_fetch(hv, "deepcopy", 8, FALSE)))
1015 deepcopy = SvTRUE(*svp);
1016 if ((svp = hv_fetch(hv, "quotekeys", 9, FALSE)))
1017 quotekeys = SvTRUE(*svp);
1018 if ((svp = hv_fetch(hv, "bless", 5, FALSE)))
1020 if ((svp = hv_fetch(hv, "maxdepth", 8, FALSE)))
1021 maxdepth = SvIV(*svp);
1022 if ((svp = hv_fetch(hv, "sortkeys", 8, FALSE))) {
1024 if (! SvTRUE(sortkeys))
1026 else if (! (SvROK(sortkeys) &&
1027 SvTYPE(SvRV(sortkeys)) == SVt_PVCV) )
1029 /* flag to use qsortsv() for sorting hash keys */
1030 sortkeys = &PL_sv_yes;
1036 imax = av_len(todumpav);
1039 valstr = newSVpvn("",0);
1040 for (i = 0; i <= imax; ++i) {
1044 if ((svp = av_fetch(todumpav, i, FALSE)))
1048 if ((svp = av_fetch(namesav, i, TRUE))) {
1049 sv_setsv(name, *svp);
1050 if (SvOK(*svp) && !SvPOK(*svp))
1051 (void)SvPV_nolen_const(name);
1054 (void)SvOK_off(name);
1057 if ((SvPVX_const(name))[0] == '*') {
1059 switch (SvTYPE(SvRV(val))) {
1061 (SvPVX(name))[0] = '@';
1064 (SvPVX(name))[0] = '%';
1067 (SvPVX(name))[0] = '*';
1070 (SvPVX(name))[0] = '$';
1075 (SvPVX(name))[0] = '$';
1077 else if ((SvPVX_const(name))[0] != '$')
1078 sv_insert(name, 0, 0, "$", 1);
1082 sv_setpvn(name, "$", 1);
1083 sv_catsv(name, varname);
1084 nchars = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"IVdf, (IV)(i+1));
1085 sv_catpvn(name, tmpbuf, nchars);
1089 SV * const tmpsv = sv_x(aTHX_ NULL, " ", 1, SvCUR(name)+3);
1090 newapad = newSVsv(apad);
1091 sv_catsv(newapad, tmpsv);
1092 SvREFCNT_dec(tmpsv);
1097 DD_dump(aTHX_ val, SvPVX_const(name), SvCUR(name), valstr, seenhv,
1098 postav, &level, indent, pad, xpad, newapad, sep, pair,
1099 freezer, toaster, purity, deepcopy, quotekeys,
1100 bless, maxdepth, sortkeys);
1103 SvREFCNT_dec(newapad);
1105 postlen = av_len(postav);
1106 if (postlen >= 0 || !terse) {
1107 sv_insert(valstr, 0, 0, " = ", 3);
1108 sv_insert(valstr, 0, 0, SvPVX_const(name), SvCUR(name));
1109 sv_catpvn(valstr, ";", 1);
1111 sv_catsv(retval, pad);
1112 sv_catsv(retval, valstr);
1113 sv_catsv(retval, sep);
1116 sv_catsv(retval, pad);
1117 for (i = 0; i <= postlen; ++i) {
1119 svp = av_fetch(postav, i, FALSE);
1120 if (svp && (elem = *svp)) {
1121 sv_catsv(retval, elem);
1123 sv_catpvn(retval, ";", 1);
1124 sv_catsv(retval, sep);
1125 sv_catsv(retval, pad);
1129 sv_catpvn(retval, ";", 1);
1130 sv_catsv(retval, sep);
1132 sv_setpvn(valstr, "", 0);
1133 if (gimme == G_ARRAY) {
1134 XPUSHs(sv_2mortal(retval));
1135 if (i < imax) /* not the last time thro ? */
1136 retval = newSVpvn("",0);
1139 SvREFCNT_dec(postav);
1140 SvREFCNT_dec(valstr);
1143 croak("Call to new() method failed to return HASH ref");
1144 if (gimme == G_SCALAR)
1145 XPUSHs(sv_2mortal(retval));