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);
22 static I32 needs_quote(const char *s, STRLEN len);
23 static SV *sv_x (pTHX_ SV *sv, const char *str, STRLEN len, I32 n);
24 static I32 DD_dump (pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval,
25 HV *seenhv, AV *postav, I32 *levelp, I32 indent,
26 SV *pad, SV *xpad, SV *apad, SV *sep, SV *pair,
27 SV *freezer, SV *toaster,
28 I32 purity, I32 deepcopy, I32 quotekeys, SV *bless,
29 I32 maxdepth, SV *sortkeys, int use_sparse_seen_hash);
32 #define HvNAME_get HvNAME
35 /* Perls 7 through portions of 15 used utf8_to_uvchr() which didn't have a
36 * length parameter. This wrongly allowed reading beyond the end of buffer
37 * given malformed input */
39 #if PERL_VERSION <= 6 /* Perl 5.6 and earlier */
42 # define UNI_TO_NATIVE(ch) (((ch) > 255) ? (ch) : ASCII_TO_NATIVE(ch))
44 # define UNI_TO_NATIVE(ch) (ch)
48 Perl_utf8_to_uvchr_buf(pTHX_ U8 *s, U8 *send, STRLEN *retlen)
50 const UV uv = utf8_to_uv(s, send - s, retlen,
51 ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
52 return UNI_TO_NATIVE(uv);
55 # if !defined(PERL_IMPLICIT_CONTEXT)
56 # define utf8_to_uvchr_buf Perl_utf8_to_uvchr_buf
58 # define utf8_to_uvchr_buf(a,b,c) Perl_utf8_to_uvchr_buf(aTHX_ a,b,c)
61 #endif /* PERL_VERSION <= 6 */
63 /* Perl 5.7 through part of 5.15 */
64 #if PERL_VERSION > 6 && PERL_VERSION <= 15 && ! defined(utf8_to_uvchr_buf)
67 Perl_utf8_to_uvchr_buf(pTHX_ U8 *s, U8 *send, STRLEN *retlen)
69 /* We have to discard <send> for these versions; hence can read off the
70 * end of the buffer if there is a malformation that indicates the
71 * character is longer than the space available */
73 const UV uv = utf8_to_uvchr(s, retlen);
74 return UNI_TO_NATIVE(uv);
77 # if !defined(PERL_IMPLICIT_CONTEXT)
78 # define utf8_to_uvchr_buf Perl_utf8_to_uvchr_buf
80 # define utf8_to_uvchr_buf(a,b,c) Perl_utf8_to_uvchr_buf(aTHX_ a,b,c)
83 #endif /* PERL_VERSION > 6 && <= 15 */
85 /* Changes in 5.7 series mean that now IOK is only set if scalar is
86 precisely integer but in 5.6 and earlier we need to do a more
89 #define DD_is_integer(sv) (SvIOK(sv) && (SvIsUV(val) ? SvUV(sv) == SvNV(sv) : SvIV(sv) == SvNV(sv)))
91 #define DD_is_integer(sv) SvIOK(sv)
94 /* does a string need to be protected? */
96 needs_quote(const char *s, STRLEN len)
98 const char *send = s+len;
110 if (!isWORDCHAR(*s)) {
122 /* count the number of "'"s and "\"s in string */
124 num_q(const char *s, STRLEN slen)
129 if (*s == '\'' || *s == '\\')
138 /* returns number of chars added to escape "'"s and "\"s in s */
139 /* slen number of characters in s will be escaped */
140 /* destination must be long enough for additional chars */
142 esc_q(char *d, const char *s, STRLEN slen)
162 esc_q_utf8(pTHX_ SV* sv, const char *src, STRLEN slen)
166 const char * const send = src + slen;
167 STRLEN j, cur = SvCUR(sv);
168 /* Could count 128-255 and 256+ in two variables, if we want to
169 be like &qquote and make a distinction. */
170 STRLEN grow = 0; /* bytes needed to represent chars 128+ */
171 /* STRLEN topbit_grow = 0; bytes needed to represent chars 128-255 */
172 STRLEN backslashes = 0;
173 STRLEN single_quotes = 0;
174 STRLEN qq_escapables = 0; /* " $ @ will need a \ in "" strings. */
178 /* this will need EBCDICification */
179 for (s = src; s < send; s += increment) {
180 const UV k = utf8_to_uvchr_buf((U8*)s, (U8*) send, NULL);
182 /* check for invalid utf8 */
183 increment = (k == 0 && *s != '\0') ? 1 : UTF8SKIP(s);
186 if (!isprint(k) || k > 256) {
190 /* 4: \x{} then count the number of hex digits. */
191 grow += 4 + (k <= 0xFF ? 2 : k <= 0xFFF ? 3 : k <= 0xFFFF ? 4 :
193 8 /* We may allocate a bit more than the minimum here. */
195 k <= 0xFFFFFFFF ? 8 : UVSIZE * 4
198 } else if (k == '\\') {
200 } else if (k == '\'') {
202 } else if (k == '"' || k == '$' || k == '@') {
209 /* We have something needing hex. 3 is ""\0 */
210 sv_grow(sv, cur + 3 + grow + 2*backslashes + single_quotes
211 + 2*qq_escapables + normal);
212 rstart = r = SvPVX(sv) + cur;
216 for (s = src; s < send; s += UTF8SKIP(s)) {
217 const UV k = utf8_to_uvchr_buf((U8*)s, (U8*) send, NULL);
219 if (k == '"' || k == '\\' || k == '$' || k == '@') {
225 if (isprint(k) && k < 256)
231 #if PERL_VERSION < 10
232 sprintf(r, "\\x{%"UVxf"}", k);
234 /* my_sprintf is not supported by ppport.h */
236 r = r + my_sprintf(r, "\\x{%"UVxf"}", k);
243 sv_grow(sv, cur + 3 + 2*backslashes + 2*single_quotes
244 + qq_escapables + normal);
245 rstart = r = SvPVX(sv) + cur;
247 for (s = src; s < send; s ++) {
249 if (k == '\'' || k == '\\')
257 SvCUR_set(sv, cur + j);
262 /* append a repeated string to an SV */
264 sv_x(pTHX_ SV *sv, const char *str, STRLEN len, I32 n)
267 sv = newSVpvn("", 0);
270 assert(SvTYPE(sv) >= SVt_PV);
274 SvGROW(sv, len*n + SvCUR(sv) + 1);
276 char * const start = SvPVX(sv) + SvCUR(sv);
277 SvCUR_set(sv, SvCUR(sv) + n);
284 sv_catpvn(sv, str, len);
292 * This ought to be split into smaller functions. (it is one long function since
293 * it exactly parallels the perl version, which was one long thing for
294 * efficiency raisins.) Ugggh!
297 DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv,
298 AV *postav, I32 *levelp, I32 indent, SV *pad, SV *xpad,
299 SV *apad, SV *sep, SV *pair, SV *freezer, SV *toaster, I32 purity,
300 I32 deepcopy, I32 quotekeys, SV *bless, I32 maxdepth, SV *sortkeys,
301 int use_sparse_seen_hash)
305 char *c, *r, *realpack;
306 #ifdef DD_USE_OLD_ID_FORMAT
310 char *const id = (char *)&id_buffer;
313 SV *sv, *ipad, *ival;
314 SV *blesspad = Nullsv;
315 AV *seenentry = NULL;
317 STRLEN inamelen, idlen = 0;
319 bool no_bless = 0; /* when a qr// is blessed into Regexp we dont want to bless it.
320 in later perls we should actually check the classname of the
321 engine. this gets tricky as it involves lexical issues that arent so
323 bool is_regex = 0; /* we are dumping a regex, we need to know this before we bless */
328 /* If the ouput buffer has less than some arbitrary amount of space
329 remaining, then enlarge it. For the test case (25M of output),
330 *1.1 was slower, *2.0 was the same, so the first guess of 1.5 is
331 deemed to be good enough. */
332 if (SvTYPE(retval) >= SVt_PV && (SvLEN(retval) - SvCUR(retval)) < 42) {
333 sv_grow(retval, SvCUR(retval) * 3 / 2);
336 realtype = SvTYPE(val);
342 /* If a freeze method is provided and the object has it, call
343 it. Warn on errors. */
344 if (SvOBJECT(SvRV(val)) && freezer &&
345 SvPOK(freezer) && SvCUR(freezer) &&
346 gv_fetchmeth(SvSTASH(SvRV(val)), SvPVX_const(freezer),
347 SvCUR(freezer), -1) != NULL)
349 dSP; ENTER; SAVETMPS; PUSHMARK(sp);
350 XPUSHs(val); PUTBACK;
351 i = perl_call_method(SvPVX_const(freezer), G_EVAL|G_VOID|G_DISCARD);
354 warn("WARNING(Freezer method call failed): %"SVf"", ERRSV);
355 PUTBACK; FREETMPS; LEAVE;
359 realtype = SvTYPE(ival);
360 #ifdef DD_USE_OLD_ID_FORMAT
361 idlen = my_snprintf(id, sizeof(id), "0x%"UVxf, PTR2UV(ival));
363 id_buffer = PTR2UV(ival);
364 idlen = sizeof(id_buffer);
367 realpack = HvNAME_get(SvSTASH(ival));
371 /* if it has a name, we need to either look it up, or keep a tab
372 * on it so we know when we hit it later
375 if ((svp = hv_fetch(seenhv, id, idlen, FALSE))
376 && (sv = *svp) && SvROK(sv) && (seenentry = (AV*)SvRV(sv)))
379 if ((svp = av_fetch(seenentry, 0, FALSE))
380 && (othername = *svp))
382 if (purity && *levelp > 0) {
385 if (realtype == SVt_PVHV)
386 sv_catpvn(retval, "{}", 2);
387 else if (realtype == SVt_PVAV)
388 sv_catpvn(retval, "[]", 2);
390 sv_catpvn(retval, "do{my $o}", 9);
391 postentry = newSVpvn(name, namelen);
392 sv_catpvn(postentry, " = ", 3);
393 sv_catsv(postentry, othername);
394 av_push(postav, postentry);
397 if (name[0] == '@' || name[0] == '%') {
398 if ((SvPVX_const(othername))[0] == '\\' &&
399 (SvPVX_const(othername))[1] == name[0]) {
400 sv_catpvn(retval, SvPVX_const(othername)+1,
404 sv_catpvn(retval, name, 1);
405 sv_catpvn(retval, "{", 1);
406 sv_catsv(retval, othername);
407 sv_catpvn(retval, "}", 1);
411 sv_catsv(retval, othername);
416 #ifdef DD_USE_OLD_ID_FORMAT
417 warn("ref name not found for %s", id);
419 warn("ref name not found for 0x%"UVxf, PTR2UV(ival));
424 else { /* store our name and continue */
426 if (name[0] == '@' || name[0] == '%') {
427 namesv = newSVpvn("\\", 1);
428 sv_catpvn(namesv, name, namelen);
430 else if (realtype == SVt_PVCV && name[0] == '*') {
431 namesv = newSVpvn("\\", 2);
432 sv_catpvn(namesv, name, namelen);
433 (SvPVX(namesv))[1] = '&';
436 namesv = newSVpvn(name, namelen);
438 av_push(seenentry, namesv);
439 (void)SvREFCNT_inc(val);
440 av_push(seenentry, val);
441 (void)hv_store(seenhv, id, idlen,
442 newRV_inc((SV*)seenentry), 0);
443 SvREFCNT_dec(seenentry);
446 /* regexps dont have to be blessed into package "Regexp"
447 * they can be blessed into any package.
450 if (realpack && *realpack == 'R' && strEQ(realpack, "Regexp"))
451 #elif PERL_VERSION < 11
452 if (realpack && realtype == SVt_PVMG && mg_find(ival, PERL_MAGIC_qr))
454 if (realpack && realtype == SVt_REGEXP)
458 if (strEQ(realpack, "Regexp"))
464 /* If purity is not set and maxdepth is set, then check depth:
465 * if we have reached maximum depth, return the string
466 * representation of the thing we are currently examining
467 * at this depth (i.e., 'Foo=ARRAY(0xdeadbeef)').
469 if (!purity && maxdepth > 0 && *levelp >= maxdepth) {
471 const char * const valstr = SvPV(val,vallen);
472 sv_catpvn(retval, "'", 1);
473 sv_catpvn(retval, valstr, vallen);
474 sv_catpvn(retval, "'", 1);
478 if (realpack && !no_bless) { /* we have a blessed ref */
480 const char * const blessstr = SvPV(bless, blesslen);
481 sv_catpvn(retval, blessstr, blesslen);
482 sv_catpvn(retval, "( ", 2);
485 apad = newSVsv(apad);
486 sv_x(aTHX_ apad, " ", 1, blesslen+2);
491 ipad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), *levelp);
496 const char *rval = SvPV(val, rlen);
497 const char * const rend = rval+rlen;
498 const char *slash = rval;
499 sv_catpvn(retval, "qr/", 3);
500 for (;slash < rend; slash++) {
501 if (*slash == '\\') { ++slash; continue; }
503 sv_catpvn(retval, rval, slash-rval);
504 sv_catpvn(retval, "\\/", 2);
505 rlen -= slash-rval+1;
509 sv_catpvn(retval, rval, rlen);
510 sv_catpvn(retval, "/", 1);
519 SV * const namesv = newSVpvn("${", 2);
520 sv_catpvn(namesv, name, namelen);
521 sv_catpvn(namesv, "}", 1);
522 if (realpack) { /* blessed */
523 sv_catpvn(retval, "do{\\(my $o = ", 13);
524 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
525 postav, levelp, indent, pad, xpad, apad, sep, pair,
526 freezer, toaster, purity, deepcopy, quotekeys, bless,
527 maxdepth, sortkeys, use_sparse_seen_hash);
528 sv_catpvn(retval, ")}", 2);
531 sv_catpvn(retval, "\\", 1);
532 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
533 postav, levelp, indent, pad, xpad, apad, sep, pair,
534 freezer, toaster, purity, deepcopy, quotekeys, bless,
535 maxdepth, sortkeys, use_sparse_seen_hash);
537 SvREFCNT_dec(namesv);
539 else if (realtype == SVt_PVGV) { /* glob ref */
540 SV * const namesv = newSVpvn("*{", 2);
541 sv_catpvn(namesv, name, namelen);
542 sv_catpvn(namesv, "}", 1);
543 sv_catpvn(retval, "\\", 1);
544 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
545 postav, levelp, indent, pad, xpad, apad, sep, pair,
546 freezer, toaster, purity, deepcopy, quotekeys, bless,
547 maxdepth, sortkeys, use_sparse_seen_hash);
548 SvREFCNT_dec(namesv);
550 else if (realtype == SVt_PVAV) {
553 const I32 ixmax = av_len((AV *)ival);
555 SV * const ixsv = newSViv(0);
556 /* allowing for a 24 char wide array index */
557 New(0, iname, namelen+28, char);
558 (void)strcpy(iname, name);
560 if (name[0] == '@') {
561 sv_catpvn(retval, "(", 1);
565 sv_catpvn(retval, "[", 1);
566 /* omit "->" in $foo{bar}->[0], but not in ${$foo}->[0] */
568 && name[namelen-1] != ']' && name[namelen-1] != '}'
569 && (namelen < 4 || (name[1] != '{' && name[2] != '{')))*/
571 && name[namelen-1] != ']' && name[namelen-1] != '}')
574 || (name[0] == '\\' && name[2] == '{'))))
576 iname[inamelen++] = '-'; iname[inamelen++] = '>';
577 iname[inamelen] = '\0';
580 if (iname[0] == '*' && iname[inamelen-1] == '}' && inamelen >= 8 &&
581 (instr(iname+inamelen-8, "{SCALAR}") ||
582 instr(iname+inamelen-7, "{ARRAY}") ||
583 instr(iname+inamelen-6, "{HASH}"))) {
584 iname[inamelen++] = '-'; iname[inamelen++] = '>';
586 iname[inamelen++] = '['; iname[inamelen] = '\0';
587 totpad = newSVsv(sep);
588 sv_catsv(totpad, pad);
589 sv_catsv(totpad, apad);
591 for (ix = 0; ix <= ixmax; ++ix) {
594 svp = av_fetch((AV*)ival, ix, FALSE);
602 #if PERL_VERSION < 10
603 (void) sprintf(iname+ilen, "%"IVdf, (IV)ix);
604 ilen = strlen(iname);
606 ilen = ilen + my_sprintf(iname+ilen, "%"IVdf, (IV)ix);
608 iname[ilen++] = ']'; iname[ilen] = '\0';
610 sv_catsv(retval, totpad);
611 sv_catsv(retval, ipad);
612 sv_catpvn(retval, "#", 1);
613 sv_catsv(retval, ixsv);
615 sv_catsv(retval, totpad);
616 sv_catsv(retval, ipad);
617 DD_dump(aTHX_ elem, iname, ilen, retval, seenhv, postav,
618 levelp, indent, pad, xpad, apad, sep, pair,
619 freezer, toaster, purity, deepcopy, quotekeys, bless,
620 maxdepth, sortkeys, use_sparse_seen_hash);
622 sv_catpvn(retval, ",", 1);
625 SV * const opad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), (*levelp)-1);
626 sv_catsv(retval, totpad);
627 sv_catsv(retval, opad);
631 sv_catpvn(retval, ")", 1);
633 sv_catpvn(retval, "]", 1);
635 SvREFCNT_dec(totpad);
638 else if (realtype == SVt_PVHV) {
639 SV *totpad, *newapad;
647 SV * const iname = newSVpvn(name, namelen);
648 if (name[0] == '%') {
649 sv_catpvn(retval, "(", 1);
650 (SvPVX(iname))[0] = '$';
653 sv_catpvn(retval, "{", 1);
654 /* omit "->" in $foo[0]->{bar}, but not in ${$foo}->{bar} */
656 && name[namelen-1] != ']' && name[namelen-1] != '}')
659 || (name[0] == '\\' && name[2] == '{'))))
661 sv_catpvn(iname, "->", 2);
664 if (name[0] == '*' && name[namelen-1] == '}' && namelen >= 8 &&
665 (instr(name+namelen-8, "{SCALAR}") ||
666 instr(name+namelen-7, "{ARRAY}") ||
667 instr(name+namelen-6, "{HASH}"))) {
668 sv_catpvn(iname, "->", 2);
670 sv_catpvn(iname, "{", 1);
671 totpad = newSVsv(sep);
672 sv_catsv(totpad, pad);
673 sv_catsv(totpad, apad);
675 /* If requested, get a sorted/filtered array of hash keys */
677 if (sortkeys == &PL_sv_yes) {
679 sortkeys = sv_2mortal(newSVpvn("Data::Dumper::_sortkeys", 23));
682 (void)hv_iterinit((HV*)ival);
683 while ((entry = hv_iternext((HV*)ival))) {
684 sv = hv_iterkeysv(entry);
685 (void)SvREFCNT_inc(sv);
688 # ifdef USE_LOCALE_NUMERIC
689 sortsv(AvARRAY(keys),
691 IN_LOCALE ? Perl_sv_cmp_locale : Perl_sv_cmp);
693 sortsv(AvARRAY(keys),
699 if (sortkeys != &PL_sv_yes) {
700 dSP; ENTER; SAVETMPS; PUSHMARK(sp);
701 XPUSHs(sv_2mortal(newRV_inc(ival))); PUTBACK;
702 i = perl_call_sv(sortkeys, G_SCALAR | G_EVAL);
706 if (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVAV))
707 keys = (AV*)SvREFCNT_inc(SvRV(sv));
710 warn("Sortkeys subroutine did not return ARRAYREF\n");
711 PUTBACK; FREETMPS; LEAVE;
714 sv_2mortal((SV*)keys);
717 (void)hv_iterinit((HV*)ival);
719 /* foreach (keys %hash) */
720 for (i = 0; 1; i++) {
722 char *nkey_buffer = NULL;
727 bool do_utf8 = FALSE;
730 if (!(keys && (I32)i <= av_len(keys))) break;
732 if (!(entry = hv_iternext((HV *)ival))) break;
736 sv_catpvn(retval, ",", 1);
740 svp = av_fetch(keys, i, FALSE);
741 keysv = svp ? *svp : sv_newmortal();
742 key = SvPV(keysv, keylen);
743 svp = hv_fetch((HV*)ival, key,
744 SvUTF8(keysv) ? -(I32)keylen : (I32)keylen, 0);
745 hval = svp ? *svp : sv_newmortal();
748 keysv = hv_iterkeysv(entry);
749 hval = hv_iterval((HV*)ival, entry);
752 key = SvPV(keysv, keylen);
753 do_utf8 = DO_UTF8(keysv);
756 sv_catsv(retval, totpad);
757 sv_catsv(retval, ipad);
758 /* old logic was first to check utf8 flag, and if utf8 always
759 call esc_q_utf8. This caused test to break under -Mutf8,
760 because there even strings like 'c' have utf8 flag on.
761 Hence with quotekeys == 0 the XS code would still '' quote
762 them based on flags, whereas the perl code would not,
764 The perl code is correct.
765 needs_quote() decides that anything that isn't a valid
766 perl identifier needs to be quoted, hence only correctly
767 formed strings with no characters outside [A-Za-z0-9_:]
768 won't need quoting. None of those characters are used in
769 the byte encoding of utf8, so anything with utf8
770 encoded characters in will need quoting. Hence strings
771 with utf8 encoded characters in will end up inside do_utf8
772 just like before, but now strings with utf8 flag set but
773 only ascii characters will end up in the unquoted section.
775 There should also be less tests for the (probably currently)
776 more common doesn't need quoting case.
777 The code is also smaller (22044 vs 22260) because I've been
778 able to pull the common logic out to both sides. */
779 if (quotekeys || needs_quote(key,keylen)) {
781 STRLEN ocur = SvCUR(retval);
782 nlen = esc_q_utf8(aTHX_ retval, key, klen);
783 nkey = SvPVX(retval) + ocur;
786 nticks = num_q(key, klen);
787 New(0, nkey_buffer, klen+nticks+3, char);
791 klen += esc_q(nkey+1, key, klen);
793 (void)Copy(key, nkey+1, klen, char);
797 sv_catpvn(retval, nkey, klen);
803 sv_catpvn(retval, nkey, klen);
805 sname = newSVsv(iname);
806 sv_catpvn(sname, nkey, nlen);
807 sv_catpvn(sname, "}", 1);
809 sv_catsv(retval, pair);
813 newapad = newSVsv(apad);
814 New(0, extra, klen+4+1, char);
815 while (elen < (klen+4))
818 sv_catpvn(newapad, extra, elen);
824 DD_dump(aTHX_ hval, SvPVX_const(sname), SvCUR(sname), retval, seenhv,
825 postav, levelp, indent, pad, xpad, newapad, sep, pair,
826 freezer, toaster, purity, deepcopy, quotekeys, bless,
827 maxdepth, sortkeys, use_sparse_seen_hash);
829 Safefree(nkey_buffer);
831 SvREFCNT_dec(newapad);
834 SV *opad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), *levelp-1);
835 sv_catsv(retval, totpad);
836 sv_catsv(retval, opad);
840 sv_catpvn(retval, ")", 1);
842 sv_catpvn(retval, "}", 1);
844 SvREFCNT_dec(totpad);
846 else if (realtype == SVt_PVCV) {
847 sv_catpvn(retval, "sub { \"DUMMY\" }", 15);
849 warn("Encountered CODE ref, using dummy placeholder");
852 warn("cannot handle ref type %d", (int)realtype);
855 if (realpack && !no_bless) { /* free blessed allocs */
863 sv_catpvn(retval, ", '", 3);
865 plen = strlen(realpack);
866 pticks = num_q(realpack, plen);
867 if (pticks) { /* needs escaping */
869 char *npack_buffer = NULL;
871 New(0, npack_buffer, plen+pticks+1, char);
872 npack = npack_buffer;
873 plen += esc_q(npack, realpack, plen);
876 sv_catpvn(retval, npack, plen);
877 Safefree(npack_buffer);
880 sv_catpvn(retval, realpack, strlen(realpack));
882 sv_catpvn(retval, "' )", 3);
883 if (toaster && SvPOK(toaster) && SvCUR(toaster)) {
884 sv_catpvn(retval, "->", 2);
885 sv_catsv(retval, toaster);
886 sv_catpvn(retval, "()", 2);
897 #ifdef DD_USE_OLD_ID_FORMAT
898 idlen = my_snprintf(id, sizeof(id), "0x%"UVxf, PTR2UV(val));
900 id_buffer = PTR2UV(val);
901 idlen = sizeof(id_buffer);
903 if ((svp = hv_fetch(seenhv, id, idlen, FALSE)) &&
904 (sv = *svp) && SvROK(sv) &&
905 (seenentry = (AV*)SvRV(sv)))
908 if ((svp = av_fetch(seenentry, 0, FALSE)) && (othername = *svp)
909 && (svp = av_fetch(seenentry, 2, FALSE)) && *svp && SvIV(*svp) > 0)
911 sv_catpvn(retval, "${", 2);
912 sv_catsv(retval, othername);
913 sv_catpvn(retval, "}", 1);
917 /* If we're allowed to keep only a sparse "seen" hash
918 * (IOW, the user does not expect it to contain everything
919 * after the dump, then only store in seen hash if the SV
920 * ref count is larger than 1. If it's 1, then we know that
921 * there is no other reference, duh. This is an optimization.
922 * Note that we'd have to check for weak-refs, too, but this is
923 * already the branch for non-refs only. */
924 else if (val != &PL_sv_undef && (!use_sparse_seen_hash || SvREFCNT(val) > 1)) {
925 SV * const namesv = newSVpvn("\\", 1);
926 sv_catpvn(namesv, name, namelen);
928 av_push(seenentry, namesv);
929 av_push(seenentry, newRV_inc(val));
930 (void)hv_store(seenhv, id, idlen, newRV_inc((SV*)seenentry), 0);
931 SvREFCNT_dec(seenentry);
935 if (DD_is_integer(val)) {
938 len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"UVuf, SvUV(val));
940 len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"IVdf, SvIV(val));
942 /* Need to check to see if this is a string such as " 0".
943 I'm assuming from sprintf isn't going to clash with utf8.
944 Is this valid on EBCDIC? */
946 const char * const pv = SvPV(val, pvlen);
947 if (pvlen != len || memNE(pv, tmpbuf, len))
948 goto integer_came_from_string;
951 /* Looks like we're on a 64 bit system. Make it a string so that
952 if a 32 bit system reads the number it will cope better. */
953 sv_catpvf(retval, "'%s'", tmpbuf);
955 sv_catpvn(retval, tmpbuf, len);
957 else if (realtype == SVt_PVGV) {/* GLOBs can end up with scribbly names */
959 if(i) ++c, --i; /* just get the name */
960 if (i >= 6 && strncmp(c, "main::", 6) == 0) {
963 if (i == 6 || (i == 7 && c[6] == '\0'))
969 if (needs_quote(c,i)) {
971 if (GvNAMEUTF8(val)) {
972 sv_grow(retval, SvCUR(retval)+2);
973 r = SvPVX(retval)+SvCUR(retval);
974 r[0] = '*'; r[1] = '{';
975 SvCUR_set(retval, SvCUR(retval)+2);
976 esc_q_utf8(aTHX_ retval, c, i);
977 sv_grow(retval, SvCUR(retval)+2);
978 r = SvPVX(retval)+SvCUR(retval);
979 r[0] = '}'; r[1] = '\0';
985 sv_grow(retval, SvCUR(retval)+6+2*i);
986 r = SvPVX(retval)+SvCUR(retval);
987 r[0] = '*'; r[1] = '{'; r[2] = '\'';
988 i += esc_q(r+3, c, i);
990 r[i++] = '\''; r[i++] = '}';
995 sv_grow(retval, SvCUR(retval)+i+2);
996 r = SvPVX(retval)+SvCUR(retval);
997 r[0] = '*'; strcpy(r+1, c);
1000 SvCUR_set(retval, SvCUR(retval)+i);
1003 static const char* const entries[] = { "{SCALAR}", "{ARRAY}", "{HASH}" };
1004 static const STRLEN sizes[] = { 8, 7, 6 };
1006 SV * const nname = newSVpvn("", 0);
1007 SV * const newapad = newSVpvn("", 0);
1008 GV * const gv = (GV*)val;
1011 for (j=0; j<3; j++) {
1012 e = ((j == 0) ? GvSV(gv) : (j == 1) ? (SV*)GvAV(gv) : (SV*)GvHV(gv));
1015 if (j == 0 && !SvOK(e))
1020 SV *postentry = newSVpvn(r,i);
1022 sv_setsv(nname, postentry);
1023 sv_catpvn(nname, entries[j], sizes[j]);
1024 sv_catpvn(postentry, " = ", 3);
1025 av_push(postav, postentry);
1028 SvCUR_set(newapad, 0);
1030 (void)sv_x(aTHX_ newapad, " ", 1, SvCUR(postentry));
1032 DD_dump(aTHX_ e, SvPVX_const(nname), SvCUR(nname), postentry,
1033 seenhv, postav, &nlevel, indent, pad, xpad,
1034 newapad, sep, pair, freezer, toaster, purity,
1035 deepcopy, quotekeys, bless, maxdepth,
1036 sortkeys, use_sparse_seen_hash);
1041 SvREFCNT_dec(newapad);
1042 SvREFCNT_dec(nname);
1045 else if (val == &PL_sv_undef || !SvOK(val)) {
1046 sv_catpvn(retval, "undef", 5);
1049 else if (SvMAGICAL(val) && (mg = mg_find(val, 'V'))) {
1050 # if !defined(PL_vtbl_vstring) && PERL_VERSION < 17
1051 SV * const vecsv = sv_newmortal();
1052 # if PERL_VERSION < 10
1053 scan_vstring(mg->mg_ptr, vecsv);
1055 scan_vstring(mg->mg_ptr, mg->mg_ptr + mg->mg_len, vecsv);
1057 if (!sv_eq(vecsv, val)) goto integer_came_from_string;
1059 sv_catpvn(retval, (const char *)mg->mg_ptr, mg->mg_len);
1063 integer_came_from_string:
1066 i += esc_q_utf8(aTHX_ retval, c, i);
1068 sv_grow(retval, SvCUR(retval)+3+2*i); /* 3: ""\0 */
1069 r = SvPVX(retval) + SvCUR(retval);
1071 i += esc_q(r+1, c, i);
1075 SvCUR_set(retval, SvCUR(retval)+i);
1082 (void)hv_delete(seenhv, id, idlen, G_DISCARD);
1083 else if (namelen && seenentry) {
1084 SV *mark = *av_fetch(seenentry, 2, TRUE);
1092 MODULE = Data::Dumper PACKAGE = Data::Dumper PREFIX = Data_Dumper_
1095 # This is the exact equivalent of Dump. Well, almost. The things that are
1096 # different as of now (due to Laziness):
1097 # * doesn't do double-quotes yet.
1101 Data_Dumper_Dumpxs(href, ...)
1107 SV *retval, *valstr;
1109 AV *postav, *todumpav, *namesav;
1111 I32 indent, terse, i, imax, postlen;
1113 SV *val, *name, *pad, *xpad, *apad, *sep, *pair, *varname;
1114 SV *freezer, *toaster, *bless, *sortkeys;
1115 I32 purity, deepcopy, quotekeys, maxdepth = 0;
1118 int use_sparse_seen_hash = 0;
1120 if (!SvROK(href)) { /* call new to get an object first */
1122 croak("Usage: Data::Dumper::Dumpxs(PACKAGE, VAL_ARY_REF, [NAME_ARY_REF])");
1128 EXTEND(SP, 3); /* 3 == max of all branches below */
1130 PUSHs(sv_2mortal(newSVsv(ST(1))));
1132 PUSHs(sv_2mortal(newSVsv(ST(2))));
1134 i = perl_call_method("new", G_SCALAR);
1137 href = newSVsv(POPs);
1143 (void)sv_2mortal(href);
1146 todumpav = namesav = NULL;
1148 val = pad = xpad = apad = sep = pair = varname
1149 = freezer = toaster = bless = sortkeys = &PL_sv_undef;
1150 name = sv_newmortal();
1152 terse = purity = deepcopy = 0;
1155 retval = newSVpvn("", 0);
1157 && (hv = (HV*)SvRV((SV*)href))
1158 && SvTYPE(hv) == SVt_PVHV) {
1160 if ((svp = hv_fetch(hv, "seen", 4, FALSE)) && SvROK(*svp))
1161 seenhv = (HV*)SvRV(*svp);
1163 use_sparse_seen_hash = 1;
1164 if ((svp = hv_fetch(hv, "noseen", 6, FALSE)))
1165 use_sparse_seen_hash = (SvOK(*svp) && SvIV(*svp) != 0);
1166 if ((svp = hv_fetch(hv, "todump", 6, FALSE)) && SvROK(*svp))
1167 todumpav = (AV*)SvRV(*svp);
1168 if ((svp = hv_fetch(hv, "names", 5, FALSE)) && SvROK(*svp))
1169 namesav = (AV*)SvRV(*svp);
1170 if ((svp = hv_fetch(hv, "indent", 6, FALSE)))
1171 indent = SvIV(*svp);
1172 if ((svp = hv_fetch(hv, "purity", 6, FALSE)))
1173 purity = SvIV(*svp);
1174 if ((svp = hv_fetch(hv, "terse", 5, FALSE)))
1175 terse = SvTRUE(*svp);
1176 #if 0 /* useqq currently unused */
1177 if ((svp = hv_fetch(hv, "useqq", 5, FALSE)))
1178 useqq = SvTRUE(*svp);
1180 if ((svp = hv_fetch(hv, "pad", 3, FALSE)))
1182 if ((svp = hv_fetch(hv, "xpad", 4, FALSE)))
1184 if ((svp = hv_fetch(hv, "apad", 4, FALSE)))
1186 if ((svp = hv_fetch(hv, "sep", 3, FALSE)))
1188 if ((svp = hv_fetch(hv, "pair", 4, FALSE)))
1190 if ((svp = hv_fetch(hv, "varname", 7, FALSE)))
1192 if ((svp = hv_fetch(hv, "freezer", 7, FALSE)))
1194 if ((svp = hv_fetch(hv, "toaster", 7, FALSE)))
1196 if ((svp = hv_fetch(hv, "deepcopy", 8, FALSE)))
1197 deepcopy = SvTRUE(*svp);
1198 if ((svp = hv_fetch(hv, "quotekeys", 9, FALSE)))
1199 quotekeys = SvTRUE(*svp);
1200 if ((svp = hv_fetch(hv, "bless", 5, FALSE)))
1202 if ((svp = hv_fetch(hv, "maxdepth", 8, FALSE)))
1203 maxdepth = SvIV(*svp);
1204 if ((svp = hv_fetch(hv, "sortkeys", 8, FALSE))) {
1206 if (! SvTRUE(sortkeys))
1208 else if (! (SvROK(sortkeys) &&
1209 SvTYPE(SvRV(sortkeys)) == SVt_PVCV) )
1211 /* flag to use qsortsv() for sorting hash keys */
1212 sortkeys = &PL_sv_yes;
1218 imax = av_len(todumpav);
1221 valstr = newSVpvn("",0);
1222 for (i = 0; i <= imax; ++i) {
1226 if ((svp = av_fetch(todumpav, i, FALSE)))
1230 if ((svp = av_fetch(namesav, i, TRUE))) {
1231 sv_setsv(name, *svp);
1232 if (SvOK(*svp) && !SvPOK(*svp))
1233 (void)SvPV_nolen_const(name);
1236 (void)SvOK_off(name);
1239 if ((SvPVX_const(name))[0] == '*') {
1241 switch (SvTYPE(SvRV(val))) {
1243 (SvPVX(name))[0] = '@';
1246 (SvPVX(name))[0] = '%';
1249 (SvPVX(name))[0] = '*';
1252 (SvPVX(name))[0] = '$';
1257 (SvPVX(name))[0] = '$';
1259 else if ((SvPVX_const(name))[0] != '$')
1260 sv_insert(name, 0, 0, "$", 1);
1264 sv_setpvn(name, "$", 1);
1265 sv_catsv(name, varname);
1266 nchars = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"IVdf, (IV)(i+1));
1267 sv_catpvn(name, tmpbuf, nchars);
1270 if (indent >= 2 && !terse) {
1271 SV * const tmpsv = sv_x(aTHX_ NULL, " ", 1, SvCUR(name)+3);
1272 newapad = newSVsv(apad);
1273 sv_catsv(newapad, tmpsv);
1274 SvREFCNT_dec(tmpsv);
1280 DD_dump(aTHX_ val, SvPVX_const(name), SvCUR(name), valstr, seenhv,
1281 postav, &level, indent, pad, xpad, newapad, sep, pair,
1282 freezer, toaster, purity, deepcopy, quotekeys,
1283 bless, maxdepth, sortkeys, use_sparse_seen_hash);
1286 if (indent >= 2 && !terse)
1287 SvREFCNT_dec(newapad);
1289 postlen = av_len(postav);
1290 if (postlen >= 0 || !terse) {
1291 sv_insert(valstr, 0, 0, " = ", 3);
1292 sv_insert(valstr, 0, 0, SvPVX_const(name), SvCUR(name));
1293 sv_catpvn(valstr, ";", 1);
1295 sv_catsv(retval, pad);
1296 sv_catsv(retval, valstr);
1297 sv_catsv(retval, sep);
1300 sv_catsv(retval, pad);
1301 for (i = 0; i <= postlen; ++i) {
1303 svp = av_fetch(postav, i, FALSE);
1304 if (svp && (elem = *svp)) {
1305 sv_catsv(retval, elem);
1307 sv_catpvn(retval, ";", 1);
1308 sv_catsv(retval, sep);
1309 sv_catsv(retval, pad);
1313 sv_catpvn(retval, ";", 1);
1314 sv_catsv(retval, sep);
1316 sv_setpvn(valstr, "", 0);
1317 if (gimme == G_ARRAY) {
1318 XPUSHs(sv_2mortal(retval));
1319 if (i < imax) /* not the last time thro ? */
1320 retval = newSVpvn("",0);
1323 SvREFCNT_dec(postav);
1324 SvREFCNT_dec(valstr);
1327 croak("Call to new() method failed to return HASH ref");
1328 if (gimme == G_SCALAR)
1329 XPUSHs(sv_2mortal(retval));
1333 Data_Dumper__vstring(sv)
1341 SvMAGICAL(sv) && (mg = mg_find(sv, 'V'))
1342 ? newSVpvn((const char *)mg->mg_ptr, mg->mg_len)
1345 RETVAL = &PL_sv_undef;