1 #define PERL_NO_GET_CONTEXT
6 # define NEED_my_snprintf
7 # define NEED_sv_2pv_flags
12 # define DD_USE_OLD_ID_FORMAT
15 static I32 num_q (const char *s, STRLEN slen);
16 static I32 esc_q (char *dest, const char *src, STRLEN slen);
17 static I32 esc_q_utf8 (pTHX_ SV *sv, const char *src, STRLEN slen);
18 static I32 needs_quote(const char *s, STRLEN len);
19 static SV *sv_x (pTHX_ SV *sv, const char *str, STRLEN len, I32 n);
20 static I32 DD_dump (pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval,
21 HV *seenhv, AV *postav, I32 *levelp, I32 indent,
22 SV *pad, SV *xpad, SV *apad, SV *sep, SV *pair,
23 SV *freezer, SV *toaster,
24 I32 purity, I32 deepcopy, I32 quotekeys, SV *bless,
25 I32 maxdepth, SV *sortkeys, int use_sparse_seen_hash);
28 #define HvNAME_get HvNAME
31 /* Perls 7 through portions of 15 used utf8_to_uvchr() which didn't have a
32 * length parameter. This wrongly allowed reading beyond the end of buffer
33 * given malformed input */
35 #if PERL_VERSION <= 6 /* Perl 5.6 and earlier */
38 # define UNI_TO_NATIVE(ch) (((ch) > 255) ? (ch) : ASCII_TO_NATIVE(ch))
40 # define UNI_TO_NATIVE(ch) (ch)
44 Perl_utf8_to_uvchr_buf(pTHX_ U8 *s, U8 *send, STRLEN *retlen)
46 const UV uv = utf8_to_uv(s, send - s, retlen,
47 ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
48 return UNI_TO_NATIVE(uv);
51 # if !defined(PERL_IMPLICIT_CONTEXT)
52 # define utf8_to_uvchr_buf Perl_utf8_to_uvchr_buf
54 # define utf8_to_uvchr_buf(a,b,c) Perl_utf8_to_uvchr_buf(aTHX_ a,b,c)
57 #endif /* PERL_VERSION <= 6 */
59 /* Perl 5.7 through part of 5.15 */
60 #if PERL_VERSION > 6 && PERL_VERSION <= 15 && ! defined(utf8_to_uvchr_buf)
63 Perl_utf8_to_uvchr_buf(pTHX_ U8 *s, U8 *send, STRLEN *retlen)
65 /* We have to discard <send> for these versions; hence can read off the
66 * end of the buffer if there is a malformation that indicates the
67 * character is longer than the space available */
69 const UV uv = utf8_to_uvchr(s, retlen);
70 return UNI_TO_NATIVE(uv);
73 # if !defined(PERL_IMPLICIT_CONTEXT)
74 # define utf8_to_uvchr_buf Perl_utf8_to_uvchr_buf
76 # define utf8_to_uvchr_buf(a,b,c) Perl_utf8_to_uvchr_buf(aTHX_ a,b,c)
79 #endif /* PERL_VERSION > 6 && <= 15 */
81 /* Changes in 5.7 series mean that now IOK is only set if scalar is
82 precisely integer but in 5.6 and earlier we need to do a more
85 #define DD_is_integer(sv) (SvIOK(sv) && (SvIsUV(val) ? SvUV(sv) == SvNV(sv) : SvIV(sv) == SvNV(sv)))
87 #define DD_is_integer(sv) SvIOK(sv)
90 /* does a string need to be protected? */
92 needs_quote(const char *s, STRLEN len)
94 const char *send = s+len;
106 if (!isWORDCHAR(*s)) {
118 /* count the number of "'"s and "\"s in string */
120 num_q(const char *s, STRLEN slen)
125 if (*s == '\'' || *s == '\\')
134 /* returns number of chars added to escape "'"s and "\"s in s */
135 /* slen number of characters in s will be escaped */
136 /* destination must be long enough for additional chars */
138 esc_q(char *d, const char *s, STRLEN slen)
158 esc_q_utf8(pTHX_ SV* sv, const char *src, STRLEN slen)
162 const char * const send = src + slen;
163 STRLEN j, cur = SvCUR(sv);
164 /* Could count 128-255 and 256+ in two variables, if we want to
165 be like &qquote and make a distinction. */
166 STRLEN grow = 0; /* bytes needed to represent chars 128+ */
167 /* STRLEN topbit_grow = 0; bytes needed to represent chars 128-255 */
168 STRLEN backslashes = 0;
169 STRLEN single_quotes = 0;
170 STRLEN qq_escapables = 0; /* " $ @ will need a \ in "" strings. */
174 /* this will need EBCDICification */
175 for (s = src; s < send; s += increment) {
176 const UV k = utf8_to_uvchr_buf((U8*)s, (U8*) send, NULL);
178 /* check for invalid utf8 */
179 increment = (k == 0 && *s != '\0') ? 1 : UTF8SKIP(s);
182 if (!isprint(k) || k > 256) {
186 /* 4: \x{} then count the number of hex digits. */
187 grow += 4 + (k <= 0xFF ? 2 : k <= 0xFFF ? 3 : k <= 0xFFFF ? 4 :
189 8 /* We may allocate a bit more than the minimum here. */
191 k <= 0xFFFFFFFF ? 8 : UVSIZE * 4
194 } else if (k == '\\') {
196 } else if (k == '\'') {
198 } else if (k == '"' || k == '$' || k == '@') {
205 /* We have something needing hex. 3 is ""\0 */
206 sv_grow(sv, cur + 3 + grow + 2*backslashes + single_quotes
207 + 2*qq_escapables + normal);
208 rstart = r = SvPVX(sv) + cur;
212 for (s = src; s < send; s += UTF8SKIP(s)) {
213 const UV k = utf8_to_uvchr_buf((U8*)s, (U8*) send, NULL);
215 if (k == '"' || k == '\\' || k == '$' || k == '@') {
221 if (isprint(k) && k < 256)
227 #if PERL_VERSION < 10
228 sprintf(r, "\\x{%"UVxf"}", k);
230 /* my_sprintf is not supported by ppport.h */
232 r = r + my_sprintf(r, "\\x{%"UVxf"}", k);
239 sv_grow(sv, cur + 3 + 2*backslashes + 2*single_quotes
240 + qq_escapables + normal);
241 rstart = r = SvPVX(sv) + cur;
243 for (s = src; s < send; s ++) {
245 if (k == '\'' || k == '\\')
253 SvCUR_set(sv, cur + j);
258 /* append a repeated string to an SV */
260 sv_x(pTHX_ SV *sv, const char *str, STRLEN len, I32 n)
263 sv = newSVpvn("", 0);
266 assert(SvTYPE(sv) >= SVt_PV);
270 SvGROW(sv, len*n + SvCUR(sv) + 1);
272 char * const start = SvPVX(sv) + SvCUR(sv);
273 SvCUR_set(sv, SvCUR(sv) + n);
280 sv_catpvn(sv, str, len);
288 * This ought to be split into smaller functions. (it is one long function since
289 * it exactly parallels the perl version, which was one long thing for
290 * efficiency raisins.) Ugggh!
293 DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv,
294 AV *postav, I32 *levelp, I32 indent, SV *pad, SV *xpad,
295 SV *apad, SV *sep, SV *pair, SV *freezer, SV *toaster, I32 purity,
296 I32 deepcopy, I32 quotekeys, SV *bless, I32 maxdepth, SV *sortkeys,
297 int use_sparse_seen_hash)
301 char *c, *r, *realpack;
302 #ifdef DD_USE_OLD_ID_FORMAT
306 char *const id = (char *)&id_buffer;
309 SV *sv, *ipad, *ival;
310 SV *blesspad = Nullsv;
311 AV *seenentry = NULL;
313 STRLEN inamelen, idlen = 0;
315 bool no_bless = 0; /* when a qr// is blessed into Regexp we dont want to bless it.
316 in later perls we should actually check the classname of the
317 engine. this gets tricky as it involves lexical issues that arent so
319 bool is_regex = 0; /* we are dumping a regex, we need to know this before we bless */
324 /* If the ouput buffer has less than some arbitrary amount of space
325 remaining, then enlarge it. For the test case (25M of output),
326 *1.1 was slower, *2.0 was the same, so the first guess of 1.5 is
327 deemed to be good enough. */
328 if (SvTYPE(retval) >= SVt_PV && (SvLEN(retval) - SvCUR(retval)) < 42) {
329 sv_grow(retval, SvCUR(retval) * 3 / 2);
332 realtype = SvTYPE(val);
338 /* If a freeze method is provided and the object has it, call
339 it. Warn on errors. */
340 if (SvOBJECT(SvRV(val)) && freezer &&
341 SvPOK(freezer) && SvCUR(freezer) &&
342 gv_fetchmeth(SvSTASH(SvRV(val)), SvPVX_const(freezer),
343 SvCUR(freezer), -1) != NULL)
345 dSP; ENTER; SAVETMPS; PUSHMARK(sp);
346 XPUSHs(val); PUTBACK;
347 i = perl_call_method(SvPVX_const(freezer), G_EVAL|G_VOID);
350 warn("WARNING(Freezer method call failed): %"SVf"", ERRSV);
351 PUTBACK; FREETMPS; LEAVE;
355 realtype = SvTYPE(ival);
356 #ifdef DD_USE_OLD_ID_FORMAT
357 idlen = my_snprintf(id, sizeof(id), "0x%"UVxf, PTR2UV(ival));
359 id_buffer = PTR2UV(ival);
360 idlen = sizeof(id_buffer);
363 realpack = HvNAME_get(SvSTASH(ival));
367 /* if it has a name, we need to either look it up, or keep a tab
368 * on it so we know when we hit it later
371 if ((svp = hv_fetch(seenhv, id, idlen, FALSE))
372 && (sv = *svp) && SvROK(sv) && (seenentry = (AV*)SvRV(sv)))
375 if ((svp = av_fetch(seenentry, 0, FALSE))
376 && (othername = *svp))
378 if (purity && *levelp > 0) {
381 if (realtype == SVt_PVHV)
382 sv_catpvn(retval, "{}", 2);
383 else if (realtype == SVt_PVAV)
384 sv_catpvn(retval, "[]", 2);
386 sv_catpvn(retval, "do{my $o}", 9);
387 postentry = newSVpvn(name, namelen);
388 sv_catpvn(postentry, " = ", 3);
389 sv_catsv(postentry, othername);
390 av_push(postav, postentry);
393 if (name[0] == '@' || name[0] == '%') {
394 if ((SvPVX_const(othername))[0] == '\\' &&
395 (SvPVX_const(othername))[1] == name[0]) {
396 sv_catpvn(retval, SvPVX_const(othername)+1,
400 sv_catpvn(retval, name, 1);
401 sv_catpvn(retval, "{", 1);
402 sv_catsv(retval, othername);
403 sv_catpvn(retval, "}", 1);
407 sv_catsv(retval, othername);
412 #ifdef DD_USE_OLD_ID_FORMAT
413 warn("ref name not found for %s", id);
415 warn("ref name not found for 0x%"UVxf, PTR2UV(ival));
420 else { /* store our name and continue */
422 if (name[0] == '@' || name[0] == '%') {
423 namesv = newSVpvn("\\", 1);
424 sv_catpvn(namesv, name, namelen);
426 else if (realtype == SVt_PVCV && name[0] == '*') {
427 namesv = newSVpvn("\\", 2);
428 sv_catpvn(namesv, name, namelen);
429 (SvPVX(namesv))[1] = '&';
432 namesv = newSVpvn(name, namelen);
434 av_push(seenentry, namesv);
435 (void)SvREFCNT_inc(val);
436 av_push(seenentry, val);
437 (void)hv_store(seenhv, id, idlen,
438 newRV_inc((SV*)seenentry), 0);
439 SvREFCNT_dec(seenentry);
442 /* regexps dont have to be blessed into package "Regexp"
443 * they can be blessed into any package.
446 if (realpack && *realpack == 'R' && strEQ(realpack, "Regexp"))
447 #elif PERL_VERSION < 11
448 if (realpack && realtype == SVt_PVMG && mg_find(ival, PERL_MAGIC_qr))
450 if (realpack && realtype == SVt_REGEXP)
454 if (strEQ(realpack, "Regexp"))
460 /* If purity is not set and maxdepth is set, then check depth:
461 * if we have reached maximum depth, return the string
462 * representation of the thing we are currently examining
463 * at this depth (i.e., 'Foo=ARRAY(0xdeadbeef)').
465 if (!purity && maxdepth > 0 && *levelp >= maxdepth) {
467 const char * const valstr = SvPV(val,vallen);
468 sv_catpvn(retval, "'", 1);
469 sv_catpvn(retval, valstr, vallen);
470 sv_catpvn(retval, "'", 1);
474 if (realpack && !no_bless) { /* we have a blessed ref */
476 const char * const blessstr = SvPV(bless, blesslen);
477 sv_catpvn(retval, blessstr, blesslen);
478 sv_catpvn(retval, "( ", 2);
481 apad = newSVsv(apad);
482 sv_x(aTHX_ apad, " ", 1, blesslen+2);
487 ipad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), *levelp);
492 const char *rval = SvPV(val, rlen);
493 const char * const rend = rval+rlen;
494 const char *slash = rval;
495 sv_catpvn(retval, "qr/", 3);
496 for (;slash < rend; slash++) {
497 if (*slash == '\\') { ++slash; continue; }
499 sv_catpvn(retval, rval, slash-rval);
500 sv_catpvn(retval, "\\/", 2);
501 rlen -= slash-rval+1;
505 sv_catpvn(retval, rval, rlen);
506 sv_catpvn(retval, "/", 1);
515 SV * const namesv = newSVpvn("${", 2);
516 sv_catpvn(namesv, name, namelen);
517 sv_catpvn(namesv, "}", 1);
518 if (realpack) { /* blessed */
519 sv_catpvn(retval, "do{\\(my $o = ", 13);
520 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
521 postav, levelp, indent, pad, xpad, apad, sep, pair,
522 freezer, toaster, purity, deepcopy, quotekeys, bless,
523 maxdepth, sortkeys, use_sparse_seen_hash);
524 sv_catpvn(retval, ")}", 2);
527 sv_catpvn(retval, "\\", 1);
528 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
529 postav, levelp, indent, pad, xpad, apad, sep, pair,
530 freezer, toaster, purity, deepcopy, quotekeys, bless,
531 maxdepth, sortkeys, use_sparse_seen_hash);
533 SvREFCNT_dec(namesv);
535 else if (realtype == SVt_PVGV) { /* glob ref */
536 SV * const namesv = newSVpvn("*{", 2);
537 sv_catpvn(namesv, name, namelen);
538 sv_catpvn(namesv, "}", 1);
539 sv_catpvn(retval, "\\", 1);
540 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
541 postav, levelp, indent, pad, xpad, apad, sep, pair,
542 freezer, toaster, purity, deepcopy, quotekeys, bless,
543 maxdepth, sortkeys, use_sparse_seen_hash);
544 SvREFCNT_dec(namesv);
546 else if (realtype == SVt_PVAV) {
549 const I32 ixmax = av_len((AV *)ival);
551 SV * const ixsv = newSViv(0);
552 /* allowing for a 24 char wide array index */
553 New(0, iname, namelen+28, char);
554 (void)strcpy(iname, name);
556 if (name[0] == '@') {
557 sv_catpvn(retval, "(", 1);
561 sv_catpvn(retval, "[", 1);
562 /* omit "->" in $foo{bar}->[0], but not in ${$foo}->[0] */
564 && name[namelen-1] != ']' && name[namelen-1] != '}'
565 && (namelen < 4 || (name[1] != '{' && name[2] != '{')))*/
567 && name[namelen-1] != ']' && name[namelen-1] != '}')
570 || (name[0] == '\\' && name[2] == '{'))))
572 iname[inamelen++] = '-'; iname[inamelen++] = '>';
573 iname[inamelen] = '\0';
576 if (iname[0] == '*' && iname[inamelen-1] == '}' && inamelen >= 8 &&
577 (instr(iname+inamelen-8, "{SCALAR}") ||
578 instr(iname+inamelen-7, "{ARRAY}") ||
579 instr(iname+inamelen-6, "{HASH}"))) {
580 iname[inamelen++] = '-'; iname[inamelen++] = '>';
582 iname[inamelen++] = '['; iname[inamelen] = '\0';
583 totpad = newSVsv(sep);
584 sv_catsv(totpad, pad);
585 sv_catsv(totpad, apad);
587 for (ix = 0; ix <= ixmax; ++ix) {
590 svp = av_fetch((AV*)ival, ix, FALSE);
598 #if PERL_VERSION < 10
599 (void) sprintf(iname+ilen, "%"IVdf, (IV)ix);
600 ilen = strlen(iname);
602 ilen = ilen + my_sprintf(iname+ilen, "%"IVdf, (IV)ix);
604 iname[ilen++] = ']'; iname[ilen] = '\0';
606 sv_catsv(retval, totpad);
607 sv_catsv(retval, ipad);
608 sv_catpvn(retval, "#", 1);
609 sv_catsv(retval, ixsv);
611 sv_catsv(retval, totpad);
612 sv_catsv(retval, ipad);
613 DD_dump(aTHX_ elem, iname, ilen, retval, seenhv, postav,
614 levelp, indent, pad, xpad, apad, sep, pair,
615 freezer, toaster, purity, deepcopy, quotekeys, bless,
616 maxdepth, sortkeys, use_sparse_seen_hash);
618 sv_catpvn(retval, ",", 1);
621 SV * const opad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), (*levelp)-1);
622 sv_catsv(retval, totpad);
623 sv_catsv(retval, opad);
627 sv_catpvn(retval, ")", 1);
629 sv_catpvn(retval, "]", 1);
631 SvREFCNT_dec(totpad);
634 else if (realtype == SVt_PVHV) {
635 SV *totpad, *newapad;
643 SV * const iname = newSVpvn(name, namelen);
644 if (name[0] == '%') {
645 sv_catpvn(retval, "(", 1);
646 (SvPVX(iname))[0] = '$';
649 sv_catpvn(retval, "{", 1);
650 /* omit "->" in $foo[0]->{bar}, but not in ${$foo}->{bar} */
652 && name[namelen-1] != ']' && name[namelen-1] != '}')
655 || (name[0] == '\\' && name[2] == '{'))))
657 sv_catpvn(iname, "->", 2);
660 if (name[0] == '*' && name[namelen-1] == '}' && namelen >= 8 &&
661 (instr(name+namelen-8, "{SCALAR}") ||
662 instr(name+namelen-7, "{ARRAY}") ||
663 instr(name+namelen-6, "{HASH}"))) {
664 sv_catpvn(iname, "->", 2);
666 sv_catpvn(iname, "{", 1);
667 totpad = newSVsv(sep);
668 sv_catsv(totpad, pad);
669 sv_catsv(totpad, apad);
671 /* If requested, get a sorted/filtered array of hash keys */
673 if (sortkeys == &PL_sv_yes) {
675 sortkeys = sv_2mortal(newSVpvn("Data::Dumper::_sortkeys", 23));
678 (void)hv_iterinit((HV*)ival);
679 while ((entry = hv_iternext((HV*)ival))) {
680 sv = hv_iterkeysv(entry);
681 (void)SvREFCNT_inc(sv);
684 # ifdef USE_LOCALE_NUMERIC
685 sortsv(AvARRAY(keys),
687 IN_LOCALE ? Perl_sv_cmp_locale : Perl_sv_cmp);
689 sortsv(AvARRAY(keys),
695 if (sortkeys != &PL_sv_yes) {
696 dSP; ENTER; SAVETMPS; PUSHMARK(sp);
697 XPUSHs(sv_2mortal(newRV_inc(ival))); PUTBACK;
698 i = perl_call_sv(sortkeys, G_SCALAR | G_EVAL);
702 if (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVAV))
703 keys = (AV*)SvREFCNT_inc(SvRV(sv));
706 warn("Sortkeys subroutine did not return ARRAYREF\n");
707 PUTBACK; FREETMPS; LEAVE;
710 sv_2mortal((SV*)keys);
713 (void)hv_iterinit((HV*)ival);
715 /* foreach (keys %hash) */
716 for (i = 0; 1; i++) {
718 char *nkey_buffer = NULL;
723 bool do_utf8 = FALSE;
726 if (!(keys && (I32)i <= av_len(keys))) break;
728 if (!(entry = hv_iternext((HV *)ival))) break;
732 sv_catpvn(retval, ",", 1);
736 svp = av_fetch(keys, i, FALSE);
737 keysv = svp ? *svp : sv_newmortal();
738 key = SvPV(keysv, keylen);
739 svp = hv_fetch((HV*)ival, key,
740 SvUTF8(keysv) ? -(I32)keylen : (I32)keylen, 0);
741 hval = svp ? *svp : sv_newmortal();
744 keysv = hv_iterkeysv(entry);
745 hval = hv_iterval((HV*)ival, entry);
748 key = SvPV(keysv, keylen);
749 do_utf8 = DO_UTF8(keysv);
752 sv_catsv(retval, totpad);
753 sv_catsv(retval, ipad);
754 /* old logic was first to check utf8 flag, and if utf8 always
755 call esc_q_utf8. This caused test to break under -Mutf8,
756 because there even strings like 'c' have utf8 flag on.
757 Hence with quotekeys == 0 the XS code would still '' quote
758 them based on flags, whereas the perl code would not,
760 The perl code is correct.
761 needs_quote() decides that anything that isn't a valid
762 perl identifier needs to be quoted, hence only correctly
763 formed strings with no characters outside [A-Za-z0-9_:]
764 won't need quoting. None of those characters are used in
765 the byte encoding of utf8, so anything with utf8
766 encoded characters in will need quoting. Hence strings
767 with utf8 encoded characters in will end up inside do_utf8
768 just like before, but now strings with utf8 flag set but
769 only ascii characters will end up in the unquoted section.
771 There should also be less tests for the (probably currently)
772 more common doesn't need quoting case.
773 The code is also smaller (22044 vs 22260) because I've been
774 able to pull the common logic out to both sides. */
775 if (quotekeys || needs_quote(key,keylen)) {
777 STRLEN ocur = SvCUR(retval);
778 nlen = esc_q_utf8(aTHX_ retval, key, klen);
779 nkey = SvPVX(retval) + ocur;
782 nticks = num_q(key, klen);
783 New(0, nkey_buffer, klen+nticks+3, char);
787 klen += esc_q(nkey+1, key, klen);
789 (void)Copy(key, nkey+1, klen, char);
793 sv_catpvn(retval, nkey, klen);
799 sv_catpvn(retval, nkey, klen);
801 sname = newSVsv(iname);
802 sv_catpvn(sname, nkey, nlen);
803 sv_catpvn(sname, "}", 1);
805 sv_catsv(retval, pair);
809 newapad = newSVsv(apad);
810 New(0, extra, klen+4+1, char);
811 while (elen < (klen+4))
814 sv_catpvn(newapad, extra, elen);
820 DD_dump(aTHX_ hval, SvPVX_const(sname), SvCUR(sname), retval, seenhv,
821 postav, levelp, indent, pad, xpad, newapad, sep, pair,
822 freezer, toaster, purity, deepcopy, quotekeys, bless,
823 maxdepth, sortkeys, use_sparse_seen_hash);
825 Safefree(nkey_buffer);
827 SvREFCNT_dec(newapad);
830 SV *opad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), *levelp-1);
831 sv_catsv(retval, totpad);
832 sv_catsv(retval, opad);
836 sv_catpvn(retval, ")", 1);
838 sv_catpvn(retval, "}", 1);
840 SvREFCNT_dec(totpad);
842 else if (realtype == SVt_PVCV) {
843 sv_catpvn(retval, "sub { \"DUMMY\" }", 15);
845 warn("Encountered CODE ref, using dummy placeholder");
848 warn("cannot handle ref type %d", (int)realtype);
851 if (realpack && !no_bless) { /* free blessed allocs */
859 sv_catpvn(retval, ", '", 3);
861 plen = strlen(realpack);
862 pticks = num_q(realpack, plen);
863 if (pticks) { /* needs escaping */
865 char *npack_buffer = NULL;
867 New(0, npack_buffer, plen+pticks+1, char);
868 npack = npack_buffer;
869 plen += esc_q(npack, realpack, plen);
872 sv_catpvn(retval, npack, plen);
873 Safefree(npack_buffer);
876 sv_catpvn(retval, realpack, strlen(realpack));
878 sv_catpvn(retval, "' )", 3);
879 if (toaster && SvPOK(toaster) && SvCUR(toaster)) {
880 sv_catpvn(retval, "->", 2);
881 sv_catsv(retval, toaster);
882 sv_catpvn(retval, "()", 2);
893 #ifdef DD_USE_OLD_ID_FORMAT
894 idlen = my_snprintf(id, sizeof(id), "0x%"UVxf, PTR2UV(val));
896 id_buffer = PTR2UV(val);
897 idlen = sizeof(id_buffer);
899 if ((svp = hv_fetch(seenhv, id, idlen, FALSE)) &&
900 (sv = *svp) && SvROK(sv) &&
901 (seenentry = (AV*)SvRV(sv)))
904 if ((svp = av_fetch(seenentry, 0, FALSE)) && (othername = *svp)
905 && (svp = av_fetch(seenentry, 2, FALSE)) && *svp && SvIV(*svp) > 0)
907 sv_catpvn(retval, "${", 2);
908 sv_catsv(retval, othername);
909 sv_catpvn(retval, "}", 1);
913 /* If we're allowed to keep only a sparse "seen" hash
914 * (IOW, the user does not expect it to contain everything
915 * after the dump, then only store in seen hash if the SV
916 * ref count is larger than 1. If it's 1, then we know that
917 * there is no other reference, duh. This is an optimization.
918 * Note that we'd have to check for weak-refs, too, but this is
919 * already the branch for non-refs only. */
920 else if (val != &PL_sv_undef && (!use_sparse_seen_hash || SvREFCNT(val) > 1)) {
921 SV * const namesv = newSVpvn("\\", 1);
922 sv_catpvn(namesv, name, namelen);
924 av_push(seenentry, namesv);
925 av_push(seenentry, newRV_inc(val));
926 (void)hv_store(seenhv, id, idlen, newRV_inc((SV*)seenentry), 0);
927 SvREFCNT_dec(seenentry);
931 if (DD_is_integer(val)) {
934 len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"UVuf, SvUV(val));
936 len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"IVdf, SvIV(val));
938 /* Need to check to see if this is a string such as " 0".
939 I'm assuming from sprintf isn't going to clash with utf8.
940 Is this valid on EBCDIC? */
942 const char * const pv = SvPV(val, pvlen);
943 if (pvlen != len || memNE(pv, tmpbuf, len))
944 goto integer_came_from_string;
947 /* Looks like we're on a 64 bit system. Make it a string so that
948 if a 32 bit system reads the number it will cope better. */
949 sv_catpvf(retval, "'%s'", tmpbuf);
951 sv_catpvn(retval, tmpbuf, len);
953 else if (realtype == SVt_PVGV) {/* GLOBs can end up with scribbly names */
955 if(i) ++c, --i; /* just get the name */
956 if (i >= 6 && strncmp(c, "main::", 6) == 0) {
959 if (i == 6 || (i == 7 && c[6] == '\0'))
965 if (needs_quote(c,i)) {
967 if (GvNAMEUTF8(val)) {
968 sv_grow(retval, SvCUR(retval)+2);
969 r = SvPVX(retval)+SvCUR(retval);
970 r[0] = '*'; r[1] = '{';
971 SvCUR_set(retval, SvCUR(retval)+2);
972 esc_q_utf8(aTHX_ retval, c, i);
973 sv_grow(retval, SvCUR(retval)+2);
974 r = SvPVX(retval)+SvCUR(retval);
975 r[0] = '}'; r[1] = '\0';
981 sv_grow(retval, SvCUR(retval)+6+2*i);
982 r = SvPVX(retval)+SvCUR(retval);
983 r[0] = '*'; r[1] = '{'; r[2] = '\'';
984 i += esc_q(r+3, c, i);
986 r[i++] = '\''; r[i++] = '}';
991 sv_grow(retval, SvCUR(retval)+i+2);
992 r = SvPVX(retval)+SvCUR(retval);
993 r[0] = '*'; strcpy(r+1, c);
996 SvCUR_set(retval, SvCUR(retval)+i);
999 static const char* const entries[] = { "{SCALAR}", "{ARRAY}", "{HASH}" };
1000 static const STRLEN sizes[] = { 8, 7, 6 };
1002 SV * const nname = newSVpvn("", 0);
1003 SV * const newapad = newSVpvn("", 0);
1004 GV * const gv = (GV*)val;
1007 for (j=0; j<3; j++) {
1008 e = ((j == 0) ? GvSV(gv) : (j == 1) ? (SV*)GvAV(gv) : (SV*)GvHV(gv));
1011 if (j == 0 && !SvOK(e))
1016 SV *postentry = newSVpvn(r,i);
1018 sv_setsv(nname, postentry);
1019 sv_catpvn(nname, entries[j], sizes[j]);
1020 sv_catpvn(postentry, " = ", 3);
1021 av_push(postav, postentry);
1024 SvCUR_set(newapad, 0);
1026 (void)sv_x(aTHX_ newapad, " ", 1, SvCUR(postentry));
1028 DD_dump(aTHX_ e, SvPVX_const(nname), SvCUR(nname), postentry,
1029 seenhv, postav, &nlevel, indent, pad, xpad,
1030 newapad, sep, pair, freezer, toaster, purity,
1031 deepcopy, quotekeys, bless, maxdepth,
1032 sortkeys, use_sparse_seen_hash);
1037 SvREFCNT_dec(newapad);
1038 SvREFCNT_dec(nname);
1041 else if (val == &PL_sv_undef || !SvOK(val)) {
1042 sv_catpvn(retval, "undef", 5);
1045 else if (SvMAGICAL(val) && (mg = mg_find(val, 'V'))) {
1046 # if !defined(PL_vtbl_vstring) && PERL_VERSION < 17
1047 SV * const vecsv = sv_newmortal();
1048 # if PERL_VERSION < 10
1049 scan_vstring(mg->mg_ptr, vecsv);
1051 scan_vstring(mg->mg_ptr, mg->mg_ptr + mg->mg_len, vecsv);
1053 if (!sv_eq(vecsv, val)) goto integer_came_from_string;
1055 sv_catpvn(retval, (const char *)mg->mg_ptr, mg->mg_len);
1059 integer_came_from_string:
1062 i += esc_q_utf8(aTHX_ retval, c, i);
1064 sv_grow(retval, SvCUR(retval)+3+2*i); /* 3: ""\0 */
1065 r = SvPVX(retval) + SvCUR(retval);
1067 i += esc_q(r+1, c, i);
1071 SvCUR_set(retval, SvCUR(retval)+i);
1078 (void)hv_delete(seenhv, id, idlen, G_DISCARD);
1079 else if (namelen && seenentry) {
1080 SV *mark = *av_fetch(seenentry, 2, TRUE);
1088 MODULE = Data::Dumper PACKAGE = Data::Dumper PREFIX = Data_Dumper_
1091 # This is the exact equivalent of Dump. Well, almost. The things that are
1092 # different as of now (due to Laziness):
1093 # * doesn't do double-quotes yet.
1097 Data_Dumper_Dumpxs(href, ...)
1103 SV *retval, *valstr;
1105 AV *postav, *todumpav, *namesav;
1107 I32 indent, terse, i, imax, postlen;
1109 SV *val, *name, *pad, *xpad, *apad, *sep, *pair, *varname;
1110 SV *freezer, *toaster, *bless, *sortkeys;
1111 I32 purity, deepcopy, quotekeys, maxdepth = 0;
1114 int use_sparse_seen_hash = 0;
1116 if (!SvROK(href)) { /* call new to get an object first */
1118 croak("Usage: Data::Dumper::Dumpxs(PACKAGE, VAL_ARY_REF, [NAME_ARY_REF])");
1124 EXTEND(SP, 3); /* 3 == max of all branches below */
1126 PUSHs(sv_2mortal(newSVsv(ST(1))));
1128 PUSHs(sv_2mortal(newSVsv(ST(2))));
1130 i = perl_call_method("new", G_SCALAR);
1133 href = newSVsv(POPs);
1139 (void)sv_2mortal(href);
1142 todumpav = namesav = NULL;
1144 val = pad = xpad = apad = sep = pair = varname
1145 = freezer = toaster = bless = sortkeys = &PL_sv_undef;
1146 name = sv_newmortal();
1148 terse = purity = deepcopy = 0;
1151 retval = newSVpvn("", 0);
1153 && (hv = (HV*)SvRV((SV*)href))
1154 && SvTYPE(hv) == SVt_PVHV) {
1156 if ((svp = hv_fetch(hv, "seen", 4, FALSE)) && SvROK(*svp))
1157 seenhv = (HV*)SvRV(*svp);
1159 use_sparse_seen_hash = 1;
1160 if ((svp = hv_fetch(hv, "noseen", 6, FALSE)))
1161 use_sparse_seen_hash = (SvOK(*svp) && SvIV(*svp) != 0);
1162 if ((svp = hv_fetch(hv, "todump", 6, FALSE)) && SvROK(*svp))
1163 todumpav = (AV*)SvRV(*svp);
1164 if ((svp = hv_fetch(hv, "names", 5, FALSE)) && SvROK(*svp))
1165 namesav = (AV*)SvRV(*svp);
1166 if ((svp = hv_fetch(hv, "indent", 6, FALSE)))
1167 indent = SvIV(*svp);
1168 if ((svp = hv_fetch(hv, "purity", 6, FALSE)))
1169 purity = SvIV(*svp);
1170 if ((svp = hv_fetch(hv, "terse", 5, FALSE)))
1171 terse = SvTRUE(*svp);
1172 #if 0 /* useqq currently unused */
1173 if ((svp = hv_fetch(hv, "useqq", 5, FALSE)))
1174 useqq = SvTRUE(*svp);
1176 if ((svp = hv_fetch(hv, "pad", 3, FALSE)))
1178 if ((svp = hv_fetch(hv, "xpad", 4, FALSE)))
1180 if ((svp = hv_fetch(hv, "apad", 4, FALSE)))
1182 if ((svp = hv_fetch(hv, "sep", 3, FALSE)))
1184 if ((svp = hv_fetch(hv, "pair", 4, FALSE)))
1186 if ((svp = hv_fetch(hv, "varname", 7, FALSE)))
1188 if ((svp = hv_fetch(hv, "freezer", 7, FALSE)))
1190 if ((svp = hv_fetch(hv, "toaster", 7, FALSE)))
1192 if ((svp = hv_fetch(hv, "deepcopy", 8, FALSE)))
1193 deepcopy = SvTRUE(*svp);
1194 if ((svp = hv_fetch(hv, "quotekeys", 9, FALSE)))
1195 quotekeys = SvTRUE(*svp);
1196 if ((svp = hv_fetch(hv, "bless", 5, FALSE)))
1198 if ((svp = hv_fetch(hv, "maxdepth", 8, FALSE)))
1199 maxdepth = SvIV(*svp);
1200 if ((svp = hv_fetch(hv, "sortkeys", 8, FALSE))) {
1202 if (! SvTRUE(sortkeys))
1204 else if (! (SvROK(sortkeys) &&
1205 SvTYPE(SvRV(sortkeys)) == SVt_PVCV) )
1207 /* flag to use qsortsv() for sorting hash keys */
1208 sortkeys = &PL_sv_yes;
1214 imax = av_len(todumpav);
1217 valstr = newSVpvn("",0);
1218 for (i = 0; i <= imax; ++i) {
1222 if ((svp = av_fetch(todumpav, i, FALSE)))
1226 if ((svp = av_fetch(namesav, i, TRUE))) {
1227 sv_setsv(name, *svp);
1228 if (SvOK(*svp) && !SvPOK(*svp))
1229 (void)SvPV_nolen_const(name);
1232 (void)SvOK_off(name);
1235 if ((SvPVX_const(name))[0] == '*') {
1237 switch (SvTYPE(SvRV(val))) {
1239 (SvPVX(name))[0] = '@';
1242 (SvPVX(name))[0] = '%';
1245 (SvPVX(name))[0] = '*';
1248 (SvPVX(name))[0] = '$';
1253 (SvPVX(name))[0] = '$';
1255 else if ((SvPVX_const(name))[0] != '$')
1256 sv_insert(name, 0, 0, "$", 1);
1260 sv_setpvn(name, "$", 1);
1261 sv_catsv(name, varname);
1262 nchars = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"IVdf, (IV)(i+1));
1263 sv_catpvn(name, tmpbuf, nchars);
1266 if (indent >= 2 && !terse) {
1267 SV * const tmpsv = sv_x(aTHX_ NULL, " ", 1, SvCUR(name)+3);
1268 newapad = newSVsv(apad);
1269 sv_catsv(newapad, tmpsv);
1270 SvREFCNT_dec(tmpsv);
1276 DD_dump(aTHX_ val, SvPVX_const(name), SvCUR(name), valstr, seenhv,
1277 postav, &level, indent, pad, xpad, newapad, sep, pair,
1278 freezer, toaster, purity, deepcopy, quotekeys,
1279 bless, maxdepth, sortkeys, use_sparse_seen_hash);
1282 if (indent >= 2 && !terse)
1283 SvREFCNT_dec(newapad);
1285 postlen = av_len(postav);
1286 if (postlen >= 0 || !terse) {
1287 sv_insert(valstr, 0, 0, " = ", 3);
1288 sv_insert(valstr, 0, 0, SvPVX_const(name), SvCUR(name));
1289 sv_catpvn(valstr, ";", 1);
1291 sv_catsv(retval, pad);
1292 sv_catsv(retval, valstr);
1293 sv_catsv(retval, sep);
1296 sv_catsv(retval, pad);
1297 for (i = 0; i <= postlen; ++i) {
1299 svp = av_fetch(postav, i, FALSE);
1300 if (svp && (elem = *svp)) {
1301 sv_catsv(retval, elem);
1303 sv_catpvn(retval, ";", 1);
1304 sv_catsv(retval, sep);
1305 sv_catsv(retval, pad);
1309 sv_catpvn(retval, ";", 1);
1310 sv_catsv(retval, sep);
1312 sv_setpvn(valstr, "", 0);
1313 if (gimme == G_ARRAY) {
1314 XPUSHs(sv_2mortal(retval));
1315 if (i < imax) /* not the last time thro ? */
1316 retval = newSVpvn("",0);
1319 SvREFCNT_dec(postav);
1320 SvREFCNT_dec(valstr);
1323 croak("Call to new() method failed to return HASH ref");
1324 if (gimme == G_SCALAR)
1325 XPUSHs(sv_2mortal(retval));
1329 Data_Dumper__vstring(sv)
1337 SvMAGICAL(sv) && (mg = mg_find(sv, 'V'))
1338 ? newSVpvn((const char *)mg->mg_ptr, mg->mg_len)
1341 RETVAL = &PL_sv_undef;