1 #define PERL_NO_GET_CONTEXT
6 # define NEED_my_snprintf
7 # define NEED_sv_2pv_flags
12 # define DD_USE_OLD_ID_FORMAT
16 # define isWORDCHAR(c) isALNUM(c)
19 static I32 num_q (const char *s, STRLEN slen);
20 static I32 esc_q (char *dest, const char *src, STRLEN slen);
21 static I32 esc_q_utf8 (pTHX_ SV *sv, const char *src, STRLEN slen, I32 do_utf8, I32 useqq);
22 static bool globname_needs_quote(const char *s, STRLEN len);
23 static bool key_needs_quote(const char *s, STRLEN len);
24 static bool safe_decimal_number(const char *p, STRLEN len);
25 static SV *sv_x (pTHX_ SV *sv, const char *str, STRLEN len, I32 n);
26 static I32 DD_dump (pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval,
27 HV *seenhv, AV *postav, I32 *levelp, I32 indent,
28 SV *pad, SV *xpad, SV *apad, SV *sep, SV *pair,
29 SV *freezer, SV *toaster,
30 I32 purity, I32 deepcopy, I32 quotekeys, SV *bless,
31 I32 maxdepth, SV *sortkeys, int use_sparse_seen_hash, I32 useqq);
34 #define HvNAME_get HvNAME
37 /* Perls 7 through portions of 15 used utf8_to_uvchr() which didn't have a
38 * length parameter. This wrongly allowed reading beyond the end of buffer
39 * given malformed input */
41 #if PERL_VERSION <= 6 /* Perl 5.6 and earlier */
44 # define UNI_TO_NATIVE(ch) (((ch) > 255) ? (ch) : ASCII_TO_NATIVE(ch))
46 # define UNI_TO_NATIVE(ch) (ch)
50 Perl_utf8_to_uvchr_buf(pTHX_ U8 *s, U8 *send, STRLEN *retlen)
52 const UV uv = utf8_to_uv(s, send - s, retlen,
53 ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
54 return UNI_TO_NATIVE(uv);
57 # if !defined(PERL_IMPLICIT_CONTEXT)
58 # define utf8_to_uvchr_buf Perl_utf8_to_uvchr_buf
60 # define utf8_to_uvchr_buf(a,b,c) Perl_utf8_to_uvchr_buf(aTHX_ a,b,c)
63 #endif /* PERL_VERSION <= 6 */
65 /* Perl 5.7 through part of 5.15 */
66 #if PERL_VERSION > 6 && PERL_VERSION <= 15 && ! defined(utf8_to_uvchr_buf)
69 Perl_utf8_to_uvchr_buf(pTHX_ U8 *s, U8 *send, STRLEN *retlen)
71 /* We have to discard <send> for these versions; hence can read off the
72 * end of the buffer if there is a malformation that indicates the
73 * character is longer than the space available */
75 const UV uv = utf8_to_uvchr(s, retlen);
76 return UNI_TO_NATIVE(uv);
79 # if !defined(PERL_IMPLICIT_CONTEXT)
80 # define utf8_to_uvchr_buf Perl_utf8_to_uvchr_buf
82 # define utf8_to_uvchr_buf(a,b,c) Perl_utf8_to_uvchr_buf(aTHX_ a,b,c)
85 #endif /* PERL_VERSION > 6 && <= 15 */
87 /* Changes in 5.7 series mean that now IOK is only set if scalar is
88 precisely integer but in 5.6 and earlier we need to do a more
91 #define DD_is_integer(sv) (SvIOK(sv) && (SvIsUV(val) ? SvUV(sv) == SvNV(sv) : SvIV(sv) == SvNV(sv)))
93 #define DD_is_integer(sv) SvIOK(sv)
96 /* does a glob name need to be protected? */
98 globname_needs_quote(const char *s, STRLEN len)
100 const char *send = s+len;
112 if (!isWORDCHAR(*s)) {
125 /* does a hash key need to be quoted (to the left of => ).
126 Previously this used (globname_)needs_quote() which accepted strings
127 like '::foo', but these aren't safe as unquoted keys under strict.
130 key_needs_quote(const char *s, STRLEN len) {
131 const char *send = s+len;
133 if (safe_decimal_number(s, len)) {
136 else if (isIDFIRST(*s)) {
147 /* Check that the SV can be represented as a simple decimal integer.
149 * The perl code does this by matching against /^(?:0|-?[1-9]\d{0,8})\z/
152 safe_decimal_number(const char *p, STRLEN len) {
153 if (len == 1 && *p == '0')
156 if (len && *p == '-') {
161 if (len == 0 || *p < '1' || *p > '9')
171 /* the perl code checks /\d/ but we don't want unicode digits here */
172 if (*p < '0' || *p > '9')
180 /* count the number of "'"s and "\"s in string */
182 num_q(const char *s, STRLEN slen)
187 if (*s == '\'' || *s == '\\')
196 /* returns number of chars added to escape "'"s and "\"s in s */
197 /* slen number of characters in s will be escaped */
198 /* destination must be long enough for additional chars */
200 esc_q(char *d, const char *s, STRLEN slen)
219 /* this function is also misused for implementing $Useqq */
221 esc_q_utf8(pTHX_ SV* sv, const char *src, STRLEN slen, I32 do_utf8, I32 useqq)
225 const char * const send = src + slen;
226 STRLEN j, cur = SvCUR(sv);
227 /* Could count 128-255 and 256+ in two variables, if we want to
228 be like &qquote and make a distinction. */
229 STRLEN grow = 0; /* bytes needed to represent chars 128+ */
230 /* STRLEN topbit_grow = 0; bytes needed to represent chars 128-255 */
231 STRLEN backslashes = 0;
232 STRLEN single_quotes = 0;
233 STRLEN qq_escapables = 0; /* " $ @ will need a \ in "" strings. */
238 /* this will need EBCDICification */
239 for (s = src; s < send; do_utf8 ? s += increment : s++) {
240 const UV k = do_utf8 ? utf8_to_uvchr_buf((U8*)s, (U8*) send, NULL) : *(U8*)s;
242 /* check for invalid utf8 */
243 increment = (k == 0 && *s != '\0') ? 1 : UTF8SKIP(s);
245 /* this is only used to check if the next character is an
246 * ASCII digit, which are invariant, so if the following collects
247 * a UTF-8 start byte it does no harm
249 next = (s + increment >= send ) ? 0 : *(U8*)(s+increment);
252 if (!isprint(k) || k > 256) {
256 /* 4: \x{} then count the number of hex digits. */
257 grow += 4 + (k <= 0xFF ? 2 : k <= 0xFFF ? 3 : k <= 0xFFFF ? 4 :
259 8 /* We may allocate a bit more than the minimum here. */
261 k <= 0xFFFFFFFF ? 8 : UVSIZE * 4
266 /* we can't use the short form like '\0' if followed by a digit */
267 (((k >= 7 && k <= 10) || k == 12 || k == 13 || k == 27)
268 || (k < 8 && (next < '0' || next > '9')))) {
270 } else if (useqq && k <= 31 && (next < '0' || next > '9')) {
272 } else if (useqq && (k <= 31 || k >= 127)) {
275 } else if (k == '\\') {
277 } else if (k == '\'') {
279 } else if (k == '"' || k == '$' || k == '@') {
286 /* We have something needing hex. 3 is ""\0 */
287 sv_grow(sv, cur + 3 + grow + 2*backslashes + single_quotes
288 + 2*qq_escapables + normal);
289 rstart = r = SvPVX(sv) + cur;
293 for (s = src; s < send; do_utf8 ? s += UTF8SKIP(s) : s++) {
294 const UV k = do_utf8 ? utf8_to_uvchr_buf((U8*)s, (U8*) send, NULL) : *(U8*)s;
296 if (k == '"' || k == '\\' || k == '$' || k == '@') {
302 if (isprint(k) && k < 256)
304 if (useqq && (k <= 31 || k == 127 || (!do_utf8 && k > 127))) {
309 case 7: *r++ = 'a'; break;
310 case 8: *r++ = 'b'; break;
311 case 9: *r++ = 't'; break;
312 case 10: *r++ = 'n'; break;
313 case 12: *r++ = 'f'; break;
314 case 13: *r++ = 'r'; break;
315 case 27: *r++ = 'e'; break;
317 increment = (k == 0 && *s != '\0') ? 1 : UTF8SKIP(s);
319 /* only ASCII digits matter here, which are invariant,
320 * since we only encode characters \377 and under, or
321 * \x177 and under for a unicode string
323 next = (s+increment < send) ? *(U8*)(s+increment) : 0;
324 next_is_digit = next >= '0' && next <= '9';
327 * r = r + my_sprintf(r, "%o", k);
329 if (k <= 7 && !next_is_digit) {
330 *r++ = (char)k + '0';
331 } else if (k <= 63 && !next_is_digit) {
332 *r++ = (char)(k>>3) + '0';
333 *r++ = (char)(k&7) + '0';
335 *r++ = (char)(k>>6) + '0';
336 *r++ = (char)((k&63)>>3) + '0';
337 *r++ = (char)(k&7) + '0';
345 #if PERL_VERSION < 10
346 sprintf(r, "\\x{%"UVxf"}", k);
348 /* my_sprintf is not supported by ppport.h */
350 r = r + my_sprintf(r, "\\x{%"UVxf"}", k);
357 sv_grow(sv, cur + 3 + 2*backslashes + 2*single_quotes
358 + qq_escapables + normal);
359 rstart = r = SvPVX(sv) + cur;
361 for (s = src; s < send; s ++) {
363 if (k == '\'' || k == '\\')
371 SvCUR_set(sv, cur + j);
376 /* append a repeated string to an SV */
378 sv_x(pTHX_ SV *sv, const char *str, STRLEN len, I32 n)
381 sv = newSVpvn("", 0);
384 assert(SvTYPE(sv) >= SVt_PV);
388 SvGROW(sv, len*n + SvCUR(sv) + 1);
390 char * const start = SvPVX(sv) + SvCUR(sv);
391 SvCUR_set(sv, SvCUR(sv) + n);
398 sv_catpvn(sv, str, len);
406 * This ought to be split into smaller functions. (it is one long function since
407 * it exactly parallels the perl version, which was one long thing for
408 * efficiency raisins.) Ugggh!
411 DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv,
412 AV *postav, I32 *levelp, I32 indent, SV *pad, SV *xpad,
413 SV *apad, SV *sep, SV *pair, SV *freezer, SV *toaster, I32 purity,
414 I32 deepcopy, I32 quotekeys, SV *bless, I32 maxdepth, SV *sortkeys,
415 int use_sparse_seen_hash, I32 useqq)
419 char *c, *r, *realpack;
420 #ifdef DD_USE_OLD_ID_FORMAT
424 char *const id = (char *)&id_buffer;
427 SV *sv, *ipad, *ival;
428 SV *blesspad = Nullsv;
429 AV *seenentry = NULL;
431 STRLEN inamelen, idlen = 0;
433 bool no_bless = 0; /* when a qr// is blessed into Regexp we dont want to bless it.
434 in later perls we should actually check the classname of the
435 engine. this gets tricky as it involves lexical issues that arent so
437 bool is_regex = 0; /* we are dumping a regex, we need to know this before we bless */
442 /* If the ouput buffer has less than some arbitrary amount of space
443 remaining, then enlarge it. For the test case (25M of output),
444 *1.1 was slower, *2.0 was the same, so the first guess of 1.5 is
445 deemed to be good enough. */
446 if (SvTYPE(retval) >= SVt_PV && (SvLEN(retval) - SvCUR(retval)) < 42) {
447 sv_grow(retval, SvCUR(retval) * 3 / 2);
450 realtype = SvTYPE(val);
456 /* If a freeze method is provided and the object has it, call
457 it. Warn on errors. */
458 if (SvOBJECT(SvRV(val)) && freezer &&
459 SvPOK(freezer) && SvCUR(freezer) &&
460 gv_fetchmeth(SvSTASH(SvRV(val)), SvPVX_const(freezer),
461 SvCUR(freezer), -1) != NULL)
463 dSP; ENTER; SAVETMPS; PUSHMARK(sp);
464 XPUSHs(val); PUTBACK;
465 i = perl_call_method(SvPVX_const(freezer), G_EVAL|G_VOID|G_DISCARD);
468 warn("WARNING(Freezer method call failed): %"SVf"", ERRSV);
469 PUTBACK; FREETMPS; LEAVE;
473 realtype = SvTYPE(ival);
474 #ifdef DD_USE_OLD_ID_FORMAT
475 idlen = my_snprintf(id, sizeof(id), "0x%"UVxf, PTR2UV(ival));
477 id_buffer = PTR2UV(ival);
478 idlen = sizeof(id_buffer);
481 realpack = HvNAME_get(SvSTASH(ival));
485 /* if it has a name, we need to either look it up, or keep a tab
486 * on it so we know when we hit it later
489 if ((svp = hv_fetch(seenhv, id, idlen, FALSE))
490 && (sv = *svp) && SvROK(sv) && (seenentry = (AV*)SvRV(sv)))
493 if ((svp = av_fetch(seenentry, 0, FALSE))
494 && (othername = *svp))
496 if (purity && *levelp > 0) {
499 if (realtype == SVt_PVHV)
500 sv_catpvn(retval, "{}", 2);
501 else if (realtype == SVt_PVAV)
502 sv_catpvn(retval, "[]", 2);
504 sv_catpvn(retval, "do{my $o}", 9);
505 postentry = newSVpvn(name, namelen);
506 sv_catpvn(postentry, " = ", 3);
507 sv_catsv(postentry, othername);
508 av_push(postav, postentry);
511 if (name[0] == '@' || name[0] == '%') {
512 if ((SvPVX_const(othername))[0] == '\\' &&
513 (SvPVX_const(othername))[1] == name[0]) {
514 sv_catpvn(retval, SvPVX_const(othername)+1,
518 sv_catpvn(retval, name, 1);
519 sv_catpvn(retval, "{", 1);
520 sv_catsv(retval, othername);
521 sv_catpvn(retval, "}", 1);
525 sv_catsv(retval, othername);
530 #ifdef DD_USE_OLD_ID_FORMAT
531 warn("ref name not found for %s", id);
533 warn("ref name not found for 0x%"UVxf, PTR2UV(ival));
538 else { /* store our name and continue */
540 if (name[0] == '@' || name[0] == '%') {
541 namesv = newSVpvn("\\", 1);
542 sv_catpvn(namesv, name, namelen);
544 else if (realtype == SVt_PVCV && name[0] == '*') {
545 namesv = newSVpvn("\\", 2);
546 sv_catpvn(namesv, name, namelen);
547 (SvPVX(namesv))[1] = '&';
550 namesv = newSVpvn(name, namelen);
552 av_push(seenentry, namesv);
553 (void)SvREFCNT_inc(val);
554 av_push(seenentry, val);
555 (void)hv_store(seenhv, id, idlen,
556 newRV_inc((SV*)seenentry), 0);
557 SvREFCNT_dec(seenentry);
560 /* regexps dont have to be blessed into package "Regexp"
561 * they can be blessed into any package.
564 if (realpack && *realpack == 'R' && strEQ(realpack, "Regexp"))
565 #elif PERL_VERSION < 11
566 if (realpack && realtype == SVt_PVMG && mg_find(ival, PERL_MAGIC_qr))
568 if (realpack && realtype == SVt_REGEXP)
572 if (strEQ(realpack, "Regexp"))
578 /* If purity is not set and maxdepth is set, then check depth:
579 * if we have reached maximum depth, return the string
580 * representation of the thing we are currently examining
581 * at this depth (i.e., 'Foo=ARRAY(0xdeadbeef)').
583 if (!purity && maxdepth > 0 && *levelp >= maxdepth) {
585 const char * const valstr = SvPV(val,vallen);
586 sv_catpvn(retval, "'", 1);
587 sv_catpvn(retval, valstr, vallen);
588 sv_catpvn(retval, "'", 1);
592 if (realpack && !no_bless) { /* we have a blessed ref */
594 const char * const blessstr = SvPV(bless, blesslen);
595 sv_catpvn(retval, blessstr, blesslen);
596 sv_catpvn(retval, "( ", 2);
599 apad = newSVsv(apad);
600 sv_x(aTHX_ apad, " ", 1, blesslen+2);
605 ipad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), *levelp);
610 SV *sv_pattern = NULL;
617 if ((re_pattern_cv = get_cv("re::regexp_pattern", 0))) {
625 count = call_sv((SV*)re_pattern_cv, G_ARRAY);
630 SvREFCNT_inc(sv_flags);
631 SvREFCNT_inc(sv_pattern);
637 sv_2mortal(sv_pattern);
638 sv_2mortal(sv_flags);
644 rval = SvPV(sv_pattern, rlen);
647 sv_catpvn(retval, "qr/", 3);
648 for (;slash < rend; slash++) {
649 if (*slash == '\\') { ++slash; continue; }
651 sv_catpvn(retval, rval, slash-rval);
652 sv_catpvn(retval, "\\/", 2);
653 rlen -= slash-rval+1;
657 sv_catpvn(retval, rval, rlen);
658 sv_catpvn(retval, "/", 1);
660 sv_catsv(retval, sv_flags);
669 SV * const namesv = newSVpvn("${", 2);
670 sv_catpvn(namesv, name, namelen);
671 sv_catpvn(namesv, "}", 1);
672 if (realpack) { /* blessed */
673 sv_catpvn(retval, "do{\\(my $o = ", 13);
674 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
675 postav, levelp, indent, pad, xpad, apad, sep, pair,
676 freezer, toaster, purity, deepcopy, quotekeys, bless,
677 maxdepth, sortkeys, use_sparse_seen_hash, useqq);
678 sv_catpvn(retval, ")}", 2);
681 sv_catpvn(retval, "\\", 1);
682 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
683 postav, levelp, indent, pad, xpad, apad, sep, pair,
684 freezer, toaster, purity, deepcopy, quotekeys, bless,
685 maxdepth, sortkeys, use_sparse_seen_hash, useqq);
687 SvREFCNT_dec(namesv);
689 else if (realtype == SVt_PVGV) { /* glob ref */
690 SV * const namesv = newSVpvn("*{", 2);
691 sv_catpvn(namesv, name, namelen);
692 sv_catpvn(namesv, "}", 1);
693 sv_catpvn(retval, "\\", 1);
694 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
695 postav, levelp, indent, pad, xpad, apad, sep, pair,
696 freezer, toaster, purity, deepcopy, quotekeys, bless,
697 maxdepth, sortkeys, use_sparse_seen_hash, useqq);
698 SvREFCNT_dec(namesv);
700 else if (realtype == SVt_PVAV) {
703 const SSize_t ixmax = av_len((AV *)ival);
705 SV * const ixsv = newSViv(0);
706 /* allowing for a 24 char wide array index */
707 New(0, iname, namelen+28, char);
708 (void)strcpy(iname, name);
710 if (name[0] == '@') {
711 sv_catpvn(retval, "(", 1);
715 sv_catpvn(retval, "[", 1);
716 /* omit "->" in $foo{bar}->[0], but not in ${$foo}->[0] */
718 && name[namelen-1] != ']' && name[namelen-1] != '}'
719 && (namelen < 4 || (name[1] != '{' && name[2] != '{')))*/
721 && name[namelen-1] != ']' && name[namelen-1] != '}')
724 || (name[0] == '\\' && name[2] == '{'))))
726 iname[inamelen++] = '-'; iname[inamelen++] = '>';
727 iname[inamelen] = '\0';
730 if (iname[0] == '*' && iname[inamelen-1] == '}' && inamelen >= 8 &&
731 (instr(iname+inamelen-8, "{SCALAR}") ||
732 instr(iname+inamelen-7, "{ARRAY}") ||
733 instr(iname+inamelen-6, "{HASH}"))) {
734 iname[inamelen++] = '-'; iname[inamelen++] = '>';
736 iname[inamelen++] = '['; iname[inamelen] = '\0';
737 totpad = newSVsv(sep);
738 sv_catsv(totpad, pad);
739 sv_catsv(totpad, apad);
741 for (ix = 0; ix <= ixmax; ++ix) {
744 svp = av_fetch((AV*)ival, ix, FALSE);
752 #if PERL_VERSION < 10
753 (void) sprintf(iname+ilen, "%"IVdf, (IV)ix);
754 ilen = strlen(iname);
756 ilen = ilen + my_sprintf(iname+ilen, "%"IVdf, (IV)ix);
758 iname[ilen++] = ']'; iname[ilen] = '\0';
760 sv_catsv(retval, totpad);
761 sv_catsv(retval, ipad);
762 sv_catpvn(retval, "#", 1);
763 sv_catsv(retval, ixsv);
765 sv_catsv(retval, totpad);
766 sv_catsv(retval, ipad);
767 DD_dump(aTHX_ elem, iname, ilen, retval, seenhv, postav,
768 levelp, indent, pad, xpad, apad, sep, pair,
769 freezer, toaster, purity, deepcopy, quotekeys, bless,
770 maxdepth, sortkeys, use_sparse_seen_hash, useqq);
772 sv_catpvn(retval, ",", 1);
775 SV * const opad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), (*levelp)-1);
776 sv_catsv(retval, totpad);
777 sv_catsv(retval, opad);
781 sv_catpvn(retval, ")", 1);
783 sv_catpvn(retval, "]", 1);
785 SvREFCNT_dec(totpad);
788 else if (realtype == SVt_PVHV) {
789 SV *totpad, *newapad;
797 SV * const iname = newSVpvn(name, namelen);
798 if (name[0] == '%') {
799 sv_catpvn(retval, "(", 1);
800 (SvPVX(iname))[0] = '$';
803 sv_catpvn(retval, "{", 1);
804 /* omit "->" in $foo[0]->{bar}, but not in ${$foo}->{bar} */
806 && name[namelen-1] != ']' && name[namelen-1] != '}')
809 || (name[0] == '\\' && name[2] == '{'))))
811 sv_catpvn(iname, "->", 2);
814 if (name[0] == '*' && name[namelen-1] == '}' && namelen >= 8 &&
815 (instr(name+namelen-8, "{SCALAR}") ||
816 instr(name+namelen-7, "{ARRAY}") ||
817 instr(name+namelen-6, "{HASH}"))) {
818 sv_catpvn(iname, "->", 2);
820 sv_catpvn(iname, "{", 1);
821 totpad = newSVsv(sep);
822 sv_catsv(totpad, pad);
823 sv_catsv(totpad, apad);
825 /* If requested, get a sorted/filtered array of hash keys */
827 if (sortkeys == &PL_sv_yes) {
829 sortkeys = sv_2mortal(newSVpvn("Data::Dumper::_sortkeys", 23));
832 (void)hv_iterinit((HV*)ival);
833 while ((entry = hv_iternext((HV*)ival))) {
834 sv = hv_iterkeysv(entry);
835 (void)SvREFCNT_inc(sv);
838 # ifdef USE_LOCALE_NUMERIC
839 sortsv(AvARRAY(keys),
841 IN_LOCALE ? Perl_sv_cmp_locale : Perl_sv_cmp);
843 sortsv(AvARRAY(keys),
849 if (sortkeys != &PL_sv_yes) {
850 dSP; ENTER; SAVETMPS; PUSHMARK(sp);
851 XPUSHs(sv_2mortal(newRV_inc(ival))); PUTBACK;
852 i = perl_call_sv(sortkeys, G_SCALAR | G_EVAL);
856 if (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVAV))
857 keys = (AV*)SvREFCNT_inc(SvRV(sv));
860 warn("Sortkeys subroutine did not return ARRAYREF\n");
861 PUTBACK; FREETMPS; LEAVE;
864 sv_2mortal((SV*)keys);
867 (void)hv_iterinit((HV*)ival);
869 /* foreach (keys %hash) */
870 for (i = 0; 1; i++) {
872 char *nkey_buffer = NULL;
877 bool do_utf8 = FALSE;
880 if (!(keys && (SSize_t)i <= av_len(keys))) break;
882 if (!(entry = hv_iternext((HV *)ival))) break;
886 sv_catpvn(retval, ",", 1);
890 svp = av_fetch(keys, i, FALSE);
891 keysv = svp ? *svp : sv_newmortal();
892 key = SvPV(keysv, keylen);
893 svp = hv_fetch((HV*)ival, key,
894 SvUTF8(keysv) ? -(I32)keylen : (I32)keylen, 0);
895 hval = svp ? *svp : sv_newmortal();
898 keysv = hv_iterkeysv(entry);
899 hval = hv_iterval((HV*)ival, entry);
902 key = SvPV(keysv, keylen);
903 do_utf8 = DO_UTF8(keysv);
906 sv_catsv(retval, totpad);
907 sv_catsv(retval, ipad);
909 old logic was first to check utf8 flag, and if utf8 always
910 call esc_q_utf8. This caused test to break under -Mutf8,
911 because there even strings like 'c' have utf8 flag on.
912 Hence with quotekeys == 0 the XS code would still '' quote
913 them based on flags, whereas the perl code would not,
916 The old logic checked that the string was a valid
917 perl glob name (foo::bar), which isn't safe under
918 strict, and differs from the perl code which only
919 accepts simple identifiers.
921 With the fix for [perl #120384] I chose to make
922 their handling of key quoting compatible between XS
925 if (quotekeys || key_needs_quote(key,keylen)) {
926 if (do_utf8 || useqq) {
927 STRLEN ocur = SvCUR(retval);
928 nlen = esc_q_utf8(aTHX_ retval, key, klen, do_utf8, useqq);
929 nkey = SvPVX(retval) + ocur;
932 nticks = num_q(key, klen);
933 New(0, nkey_buffer, klen+nticks+3, char);
937 klen += esc_q(nkey+1, key, klen);
939 (void)Copy(key, nkey+1, klen, char);
943 sv_catpvn(retval, nkey, klen);
949 sv_catpvn(retval, nkey, klen);
951 sname = newSVsv(iname);
952 sv_catpvn(sname, nkey, nlen);
953 sv_catpvn(sname, "}", 1);
955 sv_catsv(retval, pair);
959 newapad = newSVsv(apad);
960 New(0, extra, klen+4+1, char);
961 while (elen < (klen+4))
964 sv_catpvn(newapad, extra, elen);
970 DD_dump(aTHX_ hval, SvPVX_const(sname), SvCUR(sname), retval, seenhv,
971 postav, levelp, indent, pad, xpad, newapad, sep, pair,
972 freezer, toaster, purity, deepcopy, quotekeys, bless,
973 maxdepth, sortkeys, use_sparse_seen_hash, useqq);
975 Safefree(nkey_buffer);
977 SvREFCNT_dec(newapad);
980 SV *opad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), *levelp-1);
981 sv_catsv(retval, totpad);
982 sv_catsv(retval, opad);
986 sv_catpvn(retval, ")", 1);
988 sv_catpvn(retval, "}", 1);
990 SvREFCNT_dec(totpad);
992 else if (realtype == SVt_PVCV) {
993 sv_catpvn(retval, "sub { \"DUMMY\" }", 15);
995 warn("Encountered CODE ref, using dummy placeholder");
998 warn("cannot handle ref type %d", (int)realtype);
1001 if (realpack && !no_bless) { /* free blessed allocs */
1009 sv_catpvn(retval, ", '", 3);
1011 plen = strlen(realpack);
1012 pticks = num_q(realpack, plen);
1013 if (pticks) { /* needs escaping */
1015 char *npack_buffer = NULL;
1017 New(0, npack_buffer, plen+pticks+1, char);
1018 npack = npack_buffer;
1019 plen += esc_q(npack, realpack, plen);
1022 sv_catpvn(retval, npack, plen);
1023 Safefree(npack_buffer);
1026 sv_catpvn(retval, realpack, strlen(realpack));
1028 sv_catpvn(retval, "' )", 3);
1029 if (toaster && SvPOK(toaster) && SvCUR(toaster)) {
1030 sv_catpvn(retval, "->", 2);
1031 sv_catsv(retval, toaster);
1032 sv_catpvn(retval, "()", 2);
1043 #ifdef DD_USE_OLD_ID_FORMAT
1044 idlen = my_snprintf(id, sizeof(id), "0x%"UVxf, PTR2UV(val));
1046 id_buffer = PTR2UV(val);
1047 idlen = sizeof(id_buffer);
1049 if ((svp = hv_fetch(seenhv, id, idlen, FALSE)) &&
1050 (sv = *svp) && SvROK(sv) &&
1051 (seenentry = (AV*)SvRV(sv)))
1054 if ((svp = av_fetch(seenentry, 0, FALSE)) && (othername = *svp)
1055 && (svp = av_fetch(seenentry, 2, FALSE)) && *svp && SvIV(*svp) > 0)
1057 sv_catpvn(retval, "${", 2);
1058 sv_catsv(retval, othername);
1059 sv_catpvn(retval, "}", 1);
1063 /* If we're allowed to keep only a sparse "seen" hash
1064 * (IOW, the user does not expect it to contain everything
1065 * after the dump, then only store in seen hash if the SV
1066 * ref count is larger than 1. If it's 1, then we know that
1067 * there is no other reference, duh. This is an optimization.
1068 * Note that we'd have to check for weak-refs, too, but this is
1069 * already the branch for non-refs only. */
1070 else if (val != &PL_sv_undef && (!use_sparse_seen_hash || SvREFCNT(val) > 1)) {
1071 SV * const namesv = newSVpvn("\\", 1);
1072 sv_catpvn(namesv, name, namelen);
1073 seenentry = newAV();
1074 av_push(seenentry, namesv);
1075 av_push(seenentry, newRV_inc(val));
1076 (void)hv_store(seenhv, id, idlen, newRV_inc((SV*)seenentry), 0);
1077 SvREFCNT_dec(seenentry);
1081 if (DD_is_integer(val)) {
1084 len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"UVuf, SvUV(val));
1086 len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"IVdf, SvIV(val));
1088 /* Need to check to see if this is a string such as " 0".
1089 I'm assuming from sprintf isn't going to clash with utf8.
1090 Is this valid on EBCDIC? */
1092 const char * const pv = SvPV(val, pvlen);
1093 if (pvlen != len || memNE(pv, tmpbuf, len))
1094 goto integer_came_from_string;
1097 /* Looks like we're on a 64 bit system. Make it a string so that
1098 if a 32 bit system reads the number it will cope better. */
1099 sv_catpvf(retval, "'%s'", tmpbuf);
1101 sv_catpvn(retval, tmpbuf, len);
1103 else if (realtype == SVt_PVGV) {/* GLOBs can end up with scribbly names */
1105 if(i) ++c, --i; /* just get the name */
1106 if (i >= 6 && strncmp(c, "main::", 6) == 0) {
1108 #if PERL_VERSION < 7
1109 if (i == 6 || (i == 7 && c[6] == '\0'))
1115 if (globname_needs_quote(c,i)) {
1117 if (GvNAMEUTF8(val)) {
1118 sv_grow(retval, SvCUR(retval)+2);
1119 r = SvPVX(retval)+SvCUR(retval);
1120 r[0] = '*'; r[1] = '{';
1121 SvCUR_set(retval, SvCUR(retval)+2);
1122 esc_q_utf8(aTHX_ retval, c, i, 1, useqq);
1123 sv_grow(retval, SvCUR(retval)+2);
1124 r = SvPVX(retval)+SvCUR(retval);
1125 r[0] = '}'; r[1] = '\0';
1131 sv_grow(retval, SvCUR(retval)+6+2*i);
1132 r = SvPVX(retval)+SvCUR(retval);
1133 r[0] = '*'; r[1] = '{'; r[2] = '\'';
1134 i += esc_q(r+3, c, i);
1136 r[i++] = '\''; r[i++] = '}';
1141 sv_grow(retval, SvCUR(retval)+i+2);
1142 r = SvPVX(retval)+SvCUR(retval);
1143 r[0] = '*'; strcpy(r+1, c);
1146 SvCUR_set(retval, SvCUR(retval)+i);
1149 static const char* const entries[] = { "{SCALAR}", "{ARRAY}", "{HASH}" };
1150 static const STRLEN sizes[] = { 8, 7, 6 };
1152 SV * const nname = newSVpvn("", 0);
1153 SV * const newapad = newSVpvn("", 0);
1154 GV * const gv = (GV*)val;
1157 for (j=0; j<3; j++) {
1158 e = ((j == 0) ? GvSV(gv) : (j == 1) ? (SV*)GvAV(gv) : (SV*)GvHV(gv));
1161 if (j == 0 && !SvOK(e))
1166 SV *postentry = newSVpvn(r,i);
1168 sv_setsv(nname, postentry);
1169 sv_catpvn(nname, entries[j], sizes[j]);
1170 sv_catpvn(postentry, " = ", 3);
1171 av_push(postav, postentry);
1174 SvCUR_set(newapad, 0);
1176 (void)sv_x(aTHX_ newapad, " ", 1, SvCUR(postentry));
1178 DD_dump(aTHX_ e, SvPVX_const(nname), SvCUR(nname), postentry,
1179 seenhv, postav, &nlevel, indent, pad, xpad,
1180 newapad, sep, pair, freezer, toaster, purity,
1181 deepcopy, quotekeys, bless, maxdepth,
1182 sortkeys, use_sparse_seen_hash, useqq);
1187 SvREFCNT_dec(newapad);
1188 SvREFCNT_dec(nname);
1191 else if (val == &PL_sv_undef || !SvOK(val)) {
1192 sv_catpvn(retval, "undef", 5);
1195 else if (SvMAGICAL(val) && (mg = mg_find(val, 'V'))) {
1196 # if !defined(PL_vtbl_vstring) && PERL_VERSION < 17
1197 SV * const vecsv = sv_newmortal();
1198 # if PERL_VERSION < 10
1199 scan_vstring(mg->mg_ptr, vecsv);
1201 scan_vstring(mg->mg_ptr, mg->mg_ptr + mg->mg_len, vecsv);
1203 if (!sv_eq(vecsv, val)) goto integer_came_from_string;
1205 sv_catpvn(retval, (const char *)mg->mg_ptr, mg->mg_len);
1210 integer_came_from_string:
1212 /* the pure perl and XS non-qq outputs have historically been
1213 * different in this case, but for useqq, let's try to match
1214 * the pure perl code.
1217 if (useqq && safe_decimal_number(c, i)) {
1218 sv_catsv(retval, val);
1220 else if (DO_UTF8(val) || useqq)
1221 i += esc_q_utf8(aTHX_ retval, c, i, DO_UTF8(val), useqq);
1223 sv_grow(retval, SvCUR(retval)+3+2*i); /* 3: ""\0 */
1224 r = SvPVX(retval) + SvCUR(retval);
1226 i += esc_q(r+1, c, i);
1230 SvCUR_set(retval, SvCUR(retval)+i);
1237 (void)hv_delete(seenhv, id, idlen, G_DISCARD);
1238 else if (namelen && seenentry) {
1239 SV *mark = *av_fetch(seenentry, 2, TRUE);
1247 MODULE = Data::Dumper PACKAGE = Data::Dumper PREFIX = Data_Dumper_
1250 # This is the exact equivalent of Dump. Well, almost. The things that are
1251 # different as of now (due to Laziness):
1252 # * doesn't deparse yet.
1256 Data_Dumper_Dumpxs(href, ...)
1262 SV *retval, *valstr;
1264 AV *postav, *todumpav, *namesav;
1266 I32 indent, terse, useqq;
1267 SSize_t i, imax, postlen;
1269 SV *val, *name, *pad, *xpad, *apad, *sep, *pair, *varname;
1270 SV *freezer, *toaster, *bless, *sortkeys;
1271 I32 purity, deepcopy, quotekeys, maxdepth = 0;
1274 int use_sparse_seen_hash = 0;
1276 if (!SvROK(href)) { /* call new to get an object first */
1278 croak("Usage: Data::Dumper::Dumpxs(PACKAGE, VAL_ARY_REF, [NAME_ARY_REF])");
1284 EXTEND(SP, 3); /* 3 == max of all branches below */
1286 PUSHs(sv_2mortal(newSVsv(ST(1))));
1288 PUSHs(sv_2mortal(newSVsv(ST(2))));
1290 i = perl_call_method("new", G_SCALAR);
1293 href = newSVsv(POPs);
1299 (void)sv_2mortal(href);
1302 todumpav = namesav = NULL;
1304 val = pad = xpad = apad = sep = pair = varname
1305 = freezer = toaster = bless = sortkeys = &PL_sv_undef;
1306 name = sv_newmortal();
1308 terse = purity = deepcopy = useqq = 0;
1311 retval = newSVpvn("", 0);
1313 && (hv = (HV*)SvRV((SV*)href))
1314 && SvTYPE(hv) == SVt_PVHV) {
1316 if ((svp = hv_fetch(hv, "seen", 4, FALSE)) && SvROK(*svp))
1317 seenhv = (HV*)SvRV(*svp);
1319 use_sparse_seen_hash = 1;
1320 if ((svp = hv_fetch(hv, "noseen", 6, FALSE)))
1321 use_sparse_seen_hash = (SvOK(*svp) && SvIV(*svp) != 0);
1322 if ((svp = hv_fetch(hv, "todump", 6, FALSE)) && SvROK(*svp))
1323 todumpav = (AV*)SvRV(*svp);
1324 if ((svp = hv_fetch(hv, "names", 5, FALSE)) && SvROK(*svp))
1325 namesav = (AV*)SvRV(*svp);
1326 if ((svp = hv_fetch(hv, "indent", 6, FALSE)))
1327 indent = SvIV(*svp);
1328 if ((svp = hv_fetch(hv, "purity", 6, FALSE)))
1329 purity = SvIV(*svp);
1330 if ((svp = hv_fetch(hv, "terse", 5, FALSE)))
1331 terse = SvTRUE(*svp);
1332 if ((svp = hv_fetch(hv, "useqq", 5, FALSE)))
1333 useqq = SvTRUE(*svp);
1334 if ((svp = hv_fetch(hv, "pad", 3, FALSE)))
1336 if ((svp = hv_fetch(hv, "xpad", 4, FALSE)))
1338 if ((svp = hv_fetch(hv, "apad", 4, FALSE)))
1340 if ((svp = hv_fetch(hv, "sep", 3, FALSE)))
1342 if ((svp = hv_fetch(hv, "pair", 4, FALSE)))
1344 if ((svp = hv_fetch(hv, "varname", 7, FALSE)))
1346 if ((svp = hv_fetch(hv, "freezer", 7, FALSE)))
1348 if ((svp = hv_fetch(hv, "toaster", 7, FALSE)))
1350 if ((svp = hv_fetch(hv, "deepcopy", 8, FALSE)))
1351 deepcopy = SvTRUE(*svp);
1352 if ((svp = hv_fetch(hv, "quotekeys", 9, FALSE)))
1353 quotekeys = SvTRUE(*svp);
1354 if ((svp = hv_fetch(hv, "bless", 5, FALSE)))
1356 if ((svp = hv_fetch(hv, "maxdepth", 8, FALSE)))
1357 maxdepth = SvIV(*svp);
1358 if ((svp = hv_fetch(hv, "sortkeys", 8, FALSE))) {
1360 if (! SvTRUE(sortkeys))
1362 else if (! (SvROK(sortkeys) &&
1363 SvTYPE(SvRV(sortkeys)) == SVt_PVCV) )
1365 /* flag to use qsortsv() for sorting hash keys */
1366 sortkeys = &PL_sv_yes;
1372 imax = av_len(todumpav);
1375 valstr = newSVpvn("",0);
1376 for (i = 0; i <= imax; ++i) {
1380 if ((svp = av_fetch(todumpav, i, FALSE)))
1384 if ((svp = av_fetch(namesav, i, TRUE))) {
1385 sv_setsv(name, *svp);
1386 if (SvOK(*svp) && !SvPOK(*svp))
1387 (void)SvPV_nolen_const(name);
1390 (void)SvOK_off(name);
1393 if ((SvPVX_const(name))[0] == '*') {
1395 switch (SvTYPE(SvRV(val))) {
1397 (SvPVX(name))[0] = '@';
1400 (SvPVX(name))[0] = '%';
1403 (SvPVX(name))[0] = '*';
1406 (SvPVX(name))[0] = '$';
1411 (SvPVX(name))[0] = '$';
1413 else if ((SvPVX_const(name))[0] != '$')
1414 sv_insert(name, 0, 0, "$", 1);
1418 sv_setpvn(name, "$", 1);
1419 sv_catsv(name, varname);
1420 nchars = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"IVdf, (IV)(i+1));
1421 sv_catpvn(name, tmpbuf, nchars);
1424 if (indent >= 2 && !terse) {
1425 SV * const tmpsv = sv_x(aTHX_ NULL, " ", 1, SvCUR(name)+3);
1426 newapad = newSVsv(apad);
1427 sv_catsv(newapad, tmpsv);
1428 SvREFCNT_dec(tmpsv);
1434 DD_dump(aTHX_ val, SvPVX_const(name), SvCUR(name), valstr, seenhv,
1435 postav, &level, indent, pad, xpad, newapad, sep, pair,
1436 freezer, toaster, purity, deepcopy, quotekeys,
1437 bless, maxdepth, sortkeys, use_sparse_seen_hash, useqq);
1440 if (indent >= 2 && !terse)
1441 SvREFCNT_dec(newapad);
1443 postlen = av_len(postav);
1444 if (postlen >= 0 || !terse) {
1445 sv_insert(valstr, 0, 0, " = ", 3);
1446 sv_insert(valstr, 0, 0, SvPVX_const(name), SvCUR(name));
1447 sv_catpvn(valstr, ";", 1);
1449 sv_catsv(retval, pad);
1450 sv_catsv(retval, valstr);
1451 sv_catsv(retval, sep);
1454 sv_catsv(retval, pad);
1455 for (i = 0; i <= postlen; ++i) {
1457 svp = av_fetch(postav, i, FALSE);
1458 if (svp && (elem = *svp)) {
1459 sv_catsv(retval, elem);
1461 sv_catpvn(retval, ";", 1);
1462 sv_catsv(retval, sep);
1463 sv_catsv(retval, pad);
1467 sv_catpvn(retval, ";", 1);
1468 sv_catsv(retval, sep);
1470 sv_setpvn(valstr, "", 0);
1471 if (gimme == G_ARRAY) {
1472 XPUSHs(sv_2mortal(retval));
1473 if (i < imax) /* not the last time thro ? */
1474 retval = newSVpvn("",0);
1477 SvREFCNT_dec(postav);
1478 SvREFCNT_dec(valstr);
1481 croak("Call to new() method failed to return HASH ref");
1482 if (gimme == G_SCALAR)
1483 XPUSHs(sv_2mortal(retval));
1487 Data_Dumper__vstring(sv)
1495 SvMAGICAL(sv) && (mg = mg_find(sv, 'V'))
1496 ? newSVpvn((const char *)mg->mg_ptr, mg->mg_len)
1499 RETVAL = &PL_sv_undef;