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(register 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);
28 #define HvNAME_get HvNAME
31 #if PERL_VERSION <= 6 /* Perl 5.6 and earlier */
34 # define UNI_TO_NATIVE(ch) (((ch) > 255) ? (ch) : ASCII_TO_NATIVE(ch))
36 # define UNI_TO_NATIVE(ch) (ch)
40 Perl_utf8_to_uvchr_buf(pTHX_ U8 *s, U8 *send, STRLEN *retlen)
42 const UV uv = utf8_to_uv(s, send - s, retlen,
43 ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
44 return UNI_TO_NATIVE(uv);
47 # if !defined(PERL_IMPLICIT_CONTEXT)
48 # define utf8_to_uvchr_buf Perl_utf8_to_uvchr_buf
50 # define utf8_to_uvchr_buf(a,b) Perl_utf8_to_uvchr_buf(aTHX_ a,b)
53 #endif /* PERL_VERSION <= 6 */
55 /* Changes in 5.7 series mean that now IOK is only set if scalar is
56 precisely integer but in 5.6 and earlier we need to do a more
59 #define DD_is_integer(sv) (SvIOK(sv) && (SvIsUV(val) ? SvUV(sv) == SvNV(sv) : SvIV(sv) == SvNV(sv)))
61 #define DD_is_integer(sv) SvIOK(sv)
64 /* does a string need to be protected? */
66 needs_quote(register const char *s, STRLEN len)
68 const char *send = s+len;
92 /* count the number of "'"s and "\"s in string */
94 num_q(register const char *s, register STRLEN slen)
99 if (*s == '\'' || *s == '\\')
108 /* returns number of chars added to escape "'"s and "\"s in s */
109 /* slen number of characters in s will be escaped */
110 /* destination must be long enough for additional chars */
112 esc_q(register char *d, register const char *s, register STRLEN slen)
114 register I32 ret = 0;
132 esc_q_utf8(pTHX_ SV* sv, register const char *src, register STRLEN slen)
136 const char * const send = src + slen;
137 STRLEN j, cur = SvCUR(sv);
138 /* Could count 128-255 and 256+ in two variables, if we want to
139 be like &qquote and make a distinction. */
140 STRLEN grow = 0; /* bytes needed to represent chars 128+ */
141 /* STRLEN topbit_grow = 0; bytes needed to represent chars 128-255 */
142 STRLEN backslashes = 0;
143 STRLEN single_quotes = 0;
144 STRLEN qq_escapables = 0; /* " $ @ will need a \ in "" strings. */
148 /* this will need EBCDICification */
149 for (s = src; s < send; s += increment) {
150 const UV k = utf8_to_uvchr_buf((U8*)s, (U8*) send, NULL);
152 /* check for invalid utf8 */
153 increment = (k == 0 && *s != '\0') ? 1 : UTF8SKIP(s);
156 if (!isprint(k) || k > 256) {
160 /* 4: \x{} then count the number of hex digits. */
161 grow += 4 + (k <= 0xFF ? 2 : k <= 0xFFF ? 3 : k <= 0xFFFF ? 4 :
163 8 /* We may allocate a bit more than the minimum here. */
165 k <= 0xFFFFFFFF ? 8 : UVSIZE * 4
168 } else if (k == '\\') {
170 } else if (k == '\'') {
172 } else if (k == '"' || k == '$' || k == '@') {
179 /* We have something needing hex. 3 is ""\0 */
180 sv_grow(sv, cur + 3 + grow + 2*backslashes + single_quotes
181 + 2*qq_escapables + normal);
182 rstart = r = SvPVX(sv) + cur;
186 for (s = src; s < send; s += UTF8SKIP(s)) {
187 const UV k = utf8_to_uvchr_buf((U8*)s, (U8*) send, NULL);
189 if (k == '"' || k == '\\' || k == '$' || k == '@') {
195 if (isprint(k) && k < 256)
201 #if PERL_VERSION < 10
202 sprintf(r, "\\x{%"UVxf"}", k);
204 /* my_sprintf is not supported by ppport.h */
206 r = r + my_sprintf(r, "\\x{%"UVxf"}", k);
213 sv_grow(sv, cur + 3 + 2*backslashes + 2*single_quotes
214 + qq_escapables + normal);
215 rstart = r = SvPVX(sv) + cur;
217 for (s = src; s < send; s ++) {
219 if (k == '\'' || k == '\\')
227 SvCUR_set(sv, cur + j);
232 /* append a repeated string to an SV */
234 sv_x(pTHX_ SV *sv, const char *str, STRLEN len, I32 n)
237 sv = newSVpvn("", 0);
240 assert(SvTYPE(sv) >= SVt_PV);
244 SvGROW(sv, len*n + SvCUR(sv) + 1);
246 char * const start = SvPVX(sv) + SvCUR(sv);
247 SvCUR_set(sv, SvCUR(sv) + n);
254 sv_catpvn(sv, str, len);
262 * This ought to be split into smaller functions. (it is one long function since
263 * it exactly parallels the perl version, which was one long thing for
264 * efficiency raisins.) Ugggh!
267 DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv,
268 AV *postav, I32 *levelp, I32 indent, SV *pad, SV *xpad,
269 SV *apad, SV *sep, SV *pair, SV *freezer, SV *toaster, I32 purity,
270 I32 deepcopy, I32 quotekeys, SV *bless, I32 maxdepth, SV *sortkeys)
274 char *c, *r, *realpack;
275 #ifdef DD_USE_OLD_ID_FORMAT
279 char *const id = (char *)&id_buffer;
282 SV *sv, *ipad, *ival;
283 SV *blesspad = Nullsv;
284 AV *seenentry = NULL;
286 STRLEN inamelen, idlen = 0;
288 bool no_bless = 0; /* when a qr// is blessed into Regexp we dont want to bless it.
289 in later perls we should actually check the classname of the
290 engine. this gets tricky as it involves lexical issues that arent so
292 bool is_regex = 0; /* we are dumping a regex, we need to know this before we bless */
297 /* If the ouput buffer has less than some arbitrary amount of space
298 remaining, then enlarge it. For the test case (25M of output),
299 *1.1 was slower, *2.0 was the same, so the first guess of 1.5 is
300 deemed to be good enough. */
301 if (SvTYPE(retval) >= SVt_PV && (SvLEN(retval) - SvCUR(retval)) < 42) {
302 sv_grow(retval, SvCUR(retval) * 3 / 2);
305 realtype = SvTYPE(val);
311 /* If a freeze method is provided and the object has it, call
312 it. Warn on errors. */
313 if (SvOBJECT(SvRV(val)) && freezer &&
314 SvPOK(freezer) && SvCUR(freezer) &&
315 gv_fetchmeth(SvSTASH(SvRV(val)), SvPVX_const(freezer),
316 SvCUR(freezer), -1) != NULL)
318 dSP; ENTER; SAVETMPS; PUSHMARK(sp);
319 XPUSHs(val); PUTBACK;
320 i = perl_call_method(SvPVX_const(freezer), G_EVAL|G_VOID);
323 warn("WARNING(Freezer method call failed): %"SVf"", ERRSV);
324 PUTBACK; FREETMPS; LEAVE;
328 realtype = SvTYPE(ival);
329 #ifdef DD_USE_OLD_ID_FORMAT
330 idlen = my_snprintf(id, sizeof(id), "0x%"UVxf, PTR2UV(ival));
332 id_buffer = PTR2UV(ival);
333 idlen = sizeof(id_buffer);
336 realpack = HvNAME_get(SvSTASH(ival));
340 /* if it has a name, we need to either look it up, or keep a tab
341 * on it so we know when we hit it later
344 if ((svp = hv_fetch(seenhv, id, idlen, FALSE))
345 && (sv = *svp) && SvROK(sv) && (seenentry = (AV*)SvRV(sv)))
348 if ((svp = av_fetch(seenentry, 0, FALSE))
349 && (othername = *svp))
351 if (purity && *levelp > 0) {
354 if (realtype == SVt_PVHV)
355 sv_catpvn(retval, "{}", 2);
356 else if (realtype == SVt_PVAV)
357 sv_catpvn(retval, "[]", 2);
359 sv_catpvn(retval, "do{my $o}", 9);
360 postentry = newSVpvn(name, namelen);
361 sv_catpvn(postentry, " = ", 3);
362 sv_catsv(postentry, othername);
363 av_push(postav, postentry);
366 if (name[0] == '@' || name[0] == '%') {
367 if ((SvPVX_const(othername))[0] == '\\' &&
368 (SvPVX_const(othername))[1] == name[0]) {
369 sv_catpvn(retval, SvPVX_const(othername)+1,
373 sv_catpvn(retval, name, 1);
374 sv_catpvn(retval, "{", 1);
375 sv_catsv(retval, othername);
376 sv_catpvn(retval, "}", 1);
380 sv_catsv(retval, othername);
385 #ifdef DD_USE_OLD_ID_FORMAT
386 warn("ref name not found for %s", id);
388 warn("ref name not found for 0x%"UVxf, PTR2UV(ival));
393 else { /* store our name and continue */
395 if (name[0] == '@' || name[0] == '%') {
396 namesv = newSVpvn("\\", 1);
397 sv_catpvn(namesv, name, namelen);
399 else if (realtype == SVt_PVCV && name[0] == '*') {
400 namesv = newSVpvn("\\", 2);
401 sv_catpvn(namesv, name, namelen);
402 (SvPVX(namesv))[1] = '&';
405 namesv = newSVpvn(name, namelen);
407 av_push(seenentry, namesv);
408 (void)SvREFCNT_inc(val);
409 av_push(seenentry, val);
410 (void)hv_store(seenhv, id, idlen,
411 newRV_inc((SV*)seenentry), 0);
412 SvREFCNT_dec(seenentry);
415 /* regexps dont have to be blessed into package "Regexp"
416 * they can be blessed into any package.
419 if (realpack && *realpack == 'R' && strEQ(realpack, "Regexp"))
420 #elif PERL_VERSION < 11
421 if (realpack && realtype == SVt_PVMG && mg_find(ival, PERL_MAGIC_qr))
423 if (realpack && realtype == SVt_REGEXP)
427 if (strEQ(realpack, "Regexp"))
433 /* If purity is not set and maxdepth is set, then check depth:
434 * if we have reached maximum depth, return the string
435 * representation of the thing we are currently examining
436 * at this depth (i.e., 'Foo=ARRAY(0xdeadbeef)').
438 if (!purity && maxdepth > 0 && *levelp >= maxdepth) {
440 const char * const valstr = SvPV(val,vallen);
441 sv_catpvn(retval, "'", 1);
442 sv_catpvn(retval, valstr, vallen);
443 sv_catpvn(retval, "'", 1);
447 if (realpack && !no_bless) { /* we have a blessed ref */
449 const char * const blessstr = SvPV(bless, blesslen);
450 sv_catpvn(retval, blessstr, blesslen);
451 sv_catpvn(retval, "( ", 2);
454 apad = newSVsv(apad);
455 sv_x(aTHX_ apad, " ", 1, blesslen+2);
460 ipad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), *levelp);
465 const char *rval = SvPV(val, rlen);
466 const char * const rend = rval+rlen;
467 const char *slash = rval;
468 sv_catpvn(retval, "qr/", 3);
469 for (;slash < rend; slash++) {
470 if (*slash == '\\') { ++slash; continue; }
472 sv_catpvn(retval, rval, slash-rval);
473 sv_catpvn(retval, "\\/", 2);
474 rlen -= slash-rval+1;
478 sv_catpvn(retval, rval, rlen);
479 sv_catpvn(retval, "/", 1);
488 SV * const namesv = newSVpvn("${", 2);
489 sv_catpvn(namesv, name, namelen);
490 sv_catpvn(namesv, "}", 1);
491 if (realpack) { /* blessed */
492 sv_catpvn(retval, "do{\\(my $o = ", 13);
493 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
494 postav, levelp, indent, pad, xpad, apad, sep, pair,
495 freezer, toaster, purity, deepcopy, quotekeys, bless,
497 sv_catpvn(retval, ")}", 2);
500 sv_catpvn(retval, "\\", 1);
501 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
502 postav, levelp, indent, pad, xpad, apad, sep, pair,
503 freezer, toaster, purity, deepcopy, quotekeys, bless,
506 SvREFCNT_dec(namesv);
508 else if (realtype == SVt_PVGV) { /* glob ref */
509 SV * const namesv = newSVpvn("*{", 2);
510 sv_catpvn(namesv, name, namelen);
511 sv_catpvn(namesv, "}", 1);
512 sv_catpvn(retval, "\\", 1);
513 DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv,
514 postav, levelp, indent, pad, xpad, apad, sep, pair,
515 freezer, toaster, purity, deepcopy, quotekeys, bless,
517 SvREFCNT_dec(namesv);
519 else if (realtype == SVt_PVAV) {
522 const I32 ixmax = av_len((AV *)ival);
524 SV * const ixsv = newSViv(0);
525 /* allowing for a 24 char wide array index */
526 New(0, iname, namelen+28, char);
527 (void)strcpy(iname, name);
529 if (name[0] == '@') {
530 sv_catpvn(retval, "(", 1);
534 sv_catpvn(retval, "[", 1);
535 /* omit "->" in $foo{bar}->[0], but not in ${$foo}->[0] */
537 && name[namelen-1] != ']' && name[namelen-1] != '}'
538 && (namelen < 4 || (name[1] != '{' && name[2] != '{')))*/
540 && name[namelen-1] != ']' && name[namelen-1] != '}')
543 || (name[0] == '\\' && name[2] == '{'))))
545 iname[inamelen++] = '-'; iname[inamelen++] = '>';
546 iname[inamelen] = '\0';
549 if (iname[0] == '*' && iname[inamelen-1] == '}' && inamelen >= 8 &&
550 (instr(iname+inamelen-8, "{SCALAR}") ||
551 instr(iname+inamelen-7, "{ARRAY}") ||
552 instr(iname+inamelen-6, "{HASH}"))) {
553 iname[inamelen++] = '-'; iname[inamelen++] = '>';
555 iname[inamelen++] = '['; iname[inamelen] = '\0';
556 totpad = newSVsv(sep);
557 sv_catsv(totpad, pad);
558 sv_catsv(totpad, apad);
560 for (ix = 0; ix <= ixmax; ++ix) {
563 svp = av_fetch((AV*)ival, ix, FALSE);
571 #if PERL_VERSION < 10
572 (void) sprintf(iname+ilen, "%"IVdf, (IV)ix);
573 ilen = strlen(iname);
575 ilen = ilen + my_sprintf(iname+ilen, "%"IVdf, (IV)ix);
577 iname[ilen++] = ']'; iname[ilen] = '\0';
579 sv_catsv(retval, totpad);
580 sv_catsv(retval, ipad);
581 sv_catpvn(retval, "#", 1);
582 sv_catsv(retval, ixsv);
584 sv_catsv(retval, totpad);
585 sv_catsv(retval, ipad);
586 DD_dump(aTHX_ elem, iname, ilen, retval, seenhv, postav,
587 levelp, indent, pad, xpad, apad, sep, pair,
588 freezer, toaster, purity, deepcopy, quotekeys, bless,
591 sv_catpvn(retval, ",", 1);
594 SV * const opad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), (*levelp)-1);
595 sv_catsv(retval, totpad);
596 sv_catsv(retval, opad);
600 sv_catpvn(retval, ")", 1);
602 sv_catpvn(retval, "]", 1);
604 SvREFCNT_dec(totpad);
607 else if (realtype == SVt_PVHV) {
608 SV *totpad, *newapad;
616 SV * const iname = newSVpvn(name, namelen);
617 if (name[0] == '%') {
618 sv_catpvn(retval, "(", 1);
619 (SvPVX(iname))[0] = '$';
622 sv_catpvn(retval, "{", 1);
623 /* omit "->" in $foo[0]->{bar}, but not in ${$foo}->{bar} */
625 && name[namelen-1] != ']' && name[namelen-1] != '}')
628 || (name[0] == '\\' && name[2] == '{'))))
630 sv_catpvn(iname, "->", 2);
633 if (name[0] == '*' && name[namelen-1] == '}' && namelen >= 8 &&
634 (instr(name+namelen-8, "{SCALAR}") ||
635 instr(name+namelen-7, "{ARRAY}") ||
636 instr(name+namelen-6, "{HASH}"))) {
637 sv_catpvn(iname, "->", 2);
639 sv_catpvn(iname, "{", 1);
640 totpad = newSVsv(sep);
641 sv_catsv(totpad, pad);
642 sv_catsv(totpad, apad);
644 /* If requested, get a sorted/filtered array of hash keys */
646 if (sortkeys == &PL_sv_yes) {
648 sortkeys = sv_2mortal(newSVpvn("Data::Dumper::_sortkeys", 23));
651 (void)hv_iterinit((HV*)ival);
652 while ((entry = hv_iternext((HV*)ival))) {
653 sv = hv_iterkeysv(entry);
654 (void)SvREFCNT_inc(sv);
657 # ifdef USE_LOCALE_NUMERIC
658 sortsv(AvARRAY(keys),
660 IN_LOCALE ? Perl_sv_cmp_locale : Perl_sv_cmp);
662 sortsv(AvARRAY(keys),
668 if (sortkeys != &PL_sv_yes) {
669 dSP; ENTER; SAVETMPS; PUSHMARK(sp);
670 XPUSHs(sv_2mortal(newRV_inc(ival))); PUTBACK;
671 i = perl_call_sv(sortkeys, G_SCALAR | G_EVAL);
675 if (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVAV))
676 keys = (AV*)SvREFCNT_inc(SvRV(sv));
679 warn("Sortkeys subroutine did not return ARRAYREF\n");
680 PUTBACK; FREETMPS; LEAVE;
683 sv_2mortal((SV*)keys);
686 (void)hv_iterinit((HV*)ival);
688 /* foreach (keys %hash) */
689 for (i = 0; 1; i++) {
691 char *nkey_buffer = NULL;
696 bool do_utf8 = FALSE;
699 if (!(keys && (I32)i <= av_len(keys))) break;
701 if (!(entry = hv_iternext((HV *)ival))) break;
705 sv_catpvn(retval, ",", 1);
709 svp = av_fetch(keys, i, FALSE);
710 keysv = svp ? *svp : sv_newmortal();
711 key = SvPV(keysv, keylen);
712 svp = hv_fetch((HV*)ival, key,
713 SvUTF8(keysv) ? -(I32)keylen : (I32)keylen, 0);
714 hval = svp ? *svp : sv_newmortal();
717 keysv = hv_iterkeysv(entry);
718 hval = hv_iterval((HV*)ival, entry);
721 key = SvPV(keysv, keylen);
722 do_utf8 = DO_UTF8(keysv);
725 sv_catsv(retval, totpad);
726 sv_catsv(retval, ipad);
727 /* old logic was first to check utf8 flag, and if utf8 always
728 call esc_q_utf8. This caused test to break under -Mutf8,
729 because there even strings like 'c' have utf8 flag on.
730 Hence with quotekeys == 0 the XS code would still '' quote
731 them based on flags, whereas the perl code would not,
733 The perl code is correct.
734 needs_quote() decides that anything that isn't a valid
735 perl identifier needs to be quoted, hence only correctly
736 formed strings with no characters outside [A-Za-z0-9_:]
737 won't need quoting. None of those characters are used in
738 the byte encoding of utf8, so anything with utf8
739 encoded characters in will need quoting. Hence strings
740 with utf8 encoded characters in will end up inside do_utf8
741 just like before, but now strings with utf8 flag set but
742 only ascii characters will end up in the unquoted section.
744 There should also be less tests for the (probably currently)
745 more common doesn't need quoting case.
746 The code is also smaller (22044 vs 22260) because I've been
747 able to pull the common logic out to both sides. */
748 if (quotekeys || needs_quote(key,keylen)) {
750 STRLEN ocur = SvCUR(retval);
751 nlen = esc_q_utf8(aTHX_ retval, key, klen);
752 nkey = SvPVX(retval) + ocur;
755 nticks = num_q(key, klen);
756 New(0, nkey_buffer, klen+nticks+3, char);
760 klen += esc_q(nkey+1, key, klen);
762 (void)Copy(key, nkey+1, klen, char);
766 sv_catpvn(retval, nkey, klen);
772 sv_catpvn(retval, nkey, klen);
774 sname = newSVsv(iname);
775 sv_catpvn(sname, nkey, nlen);
776 sv_catpvn(sname, "}", 1);
778 sv_catsv(retval, pair);
782 newapad = newSVsv(apad);
783 New(0, extra, klen+4+1, char);
784 while (elen < (klen+4))
787 sv_catpvn(newapad, extra, elen);
793 DD_dump(aTHX_ hval, SvPVX_const(sname), SvCUR(sname), retval, seenhv,
794 postav, levelp, indent, pad, xpad, newapad, sep, pair,
795 freezer, toaster, purity, deepcopy, quotekeys, bless,
798 Safefree(nkey_buffer);
800 SvREFCNT_dec(newapad);
803 SV *opad = sv_x(aTHX_ Nullsv, SvPVX_const(xpad), SvCUR(xpad), *levelp-1);
804 sv_catsv(retval, totpad);
805 sv_catsv(retval, opad);
809 sv_catpvn(retval, ")", 1);
811 sv_catpvn(retval, "}", 1);
813 SvREFCNT_dec(totpad);
815 else if (realtype == SVt_PVCV) {
816 sv_catpvn(retval, "sub { \"DUMMY\" }", 15);
818 warn("Encountered CODE ref, using dummy placeholder");
821 warn("cannot handle ref type %d", (int)realtype);
824 if (realpack && !no_bless) { /* free blessed allocs */
832 sv_catpvn(retval, ", '", 3);
834 plen = strlen(realpack);
835 pticks = num_q(realpack, plen);
836 if (pticks) { /* needs escaping */
838 char *npack_buffer = NULL;
840 New(0, npack_buffer, plen+pticks+1, char);
841 npack = npack_buffer;
842 plen += esc_q(npack, realpack, plen);
845 sv_catpvn(retval, npack, plen);
846 Safefree(npack_buffer);
849 sv_catpvn(retval, realpack, strlen(realpack));
851 sv_catpvn(retval, "' )", 3);
852 if (toaster && SvPOK(toaster) && SvCUR(toaster)) {
853 sv_catpvn(retval, "->", 2);
854 sv_catsv(retval, toaster);
855 sv_catpvn(retval, "()", 2);
866 #ifdef DD_USE_OLD_ID_FORMAT
867 idlen = my_snprintf(id, sizeof(id), "0x%"UVxf, PTR2UV(val));
869 id_buffer = PTR2UV(val);
870 idlen = sizeof(id_buffer);
872 if ((svp = hv_fetch(seenhv, id, idlen, FALSE)) &&
873 (sv = *svp) && SvROK(sv) &&
874 (seenentry = (AV*)SvRV(sv)))
877 if ((svp = av_fetch(seenentry, 0, FALSE)) && (othername = *svp)
878 && (svp = av_fetch(seenentry, 2, FALSE)) && *svp && SvIV(*svp) > 0)
880 sv_catpvn(retval, "${", 2);
881 sv_catsv(retval, othername);
882 sv_catpvn(retval, "}", 1);
886 else if (val != &PL_sv_undef) {
887 SV * const namesv = newSVpvn("\\", 1);
888 sv_catpvn(namesv, name, namelen);
890 av_push(seenentry, namesv);
891 av_push(seenentry, newRV_inc(val));
892 (void)hv_store(seenhv, id, idlen, newRV_inc((SV*)seenentry), 0);
893 SvREFCNT_dec(seenentry);
897 if (DD_is_integer(val)) {
900 len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"UVuf, SvUV(val));
902 len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"IVdf, SvIV(val));
904 /* Need to check to see if this is a string such as " 0".
905 I'm assuming from sprintf isn't going to clash with utf8.
906 Is this valid on EBCDIC? */
908 const char * const pv = SvPV(val, pvlen);
909 if (pvlen != len || memNE(pv, tmpbuf, len))
910 goto integer_came_from_string;
913 /* Looks like we're on a 64 bit system. Make it a string so that
914 if a 32 bit system reads the number it will cope better. */
915 sv_catpvf(retval, "'%s'", tmpbuf);
917 sv_catpvn(retval, tmpbuf, len);
919 else if (realtype == SVt_PVGV) {/* GLOBs can end up with scribbly names */
921 if(i) ++c, --i; /* just get the name */
922 if (i >= 6 && strncmp(c, "main::", 6) == 0) {
925 if (i == 6 || (i == 7 && c[6] == '\0'))
931 if (needs_quote(c,i)) {
933 if (GvNAMEUTF8(val)) {
934 sv_grow(retval, SvCUR(retval)+2);
935 r = SvPVX(retval)+SvCUR(retval);
936 r[0] = '*'; r[1] = '{';
937 SvCUR_set(retval, SvCUR(retval)+2);
938 esc_q_utf8(aTHX_ retval, c, i);
939 sv_grow(retval, SvCUR(retval)+2);
940 r = SvPVX(retval)+SvCUR(retval);
941 r[0] = '}'; r[1] = '\0';
947 sv_grow(retval, SvCUR(retval)+6+2*i);
948 r = SvPVX(retval)+SvCUR(retval);
949 r[0] = '*'; r[1] = '{'; r[2] = '\'';
950 i += esc_q(r+3, c, i);
952 r[i++] = '\''; r[i++] = '}';
957 sv_grow(retval, SvCUR(retval)+i+2);
958 r = SvPVX(retval)+SvCUR(retval);
959 r[0] = '*'; strcpy(r+1, c);
962 SvCUR_set(retval, SvCUR(retval)+i);
965 static const char* const entries[] = { "{SCALAR}", "{ARRAY}", "{HASH}" };
966 static const STRLEN sizes[] = { 8, 7, 6 };
968 SV * const nname = newSVpvn("", 0);
969 SV * const newapad = newSVpvn("", 0);
970 GV * const gv = (GV*)val;
973 for (j=0; j<3; j++) {
974 e = ((j == 0) ? GvSV(gv) : (j == 1) ? (SV*)GvAV(gv) : (SV*)GvHV(gv));
977 if (j == 0 && !SvOK(e))
982 SV *postentry = newSVpvn(r,i);
984 sv_setsv(nname, postentry);
985 sv_catpvn(nname, entries[j], sizes[j]);
986 sv_catpvn(postentry, " = ", 3);
987 av_push(postav, postentry);
990 SvCUR_set(newapad, 0);
992 (void)sv_x(aTHX_ newapad, " ", 1, SvCUR(postentry));
994 DD_dump(aTHX_ e, SvPVX_const(nname), SvCUR(nname), postentry,
995 seenhv, postav, &nlevel, indent, pad, xpad,
996 newapad, sep, pair, freezer, toaster, purity,
997 deepcopy, quotekeys, bless, maxdepth,
1003 SvREFCNT_dec(newapad);
1004 SvREFCNT_dec(nname);
1007 else if (val == &PL_sv_undef || !SvOK(val)) {
1008 sv_catpvn(retval, "undef", 5);
1011 else if (SvMAGICAL(val) && (mg = mg_find(val, 'V'))) {
1012 # ifndef PL_vtbl_vstring && PERL_VERSION < 17
1013 SV * const vecsv = sv_newmortal();
1014 # if PERL_VERSION < 10
1015 scan_vstring(mg->mg_ptr, vecsv);
1017 scan_vstring(mg->mg_ptr, mg->mg_ptr + mg->mg_len, vecsv);
1019 if (!sv_eq(vecsv, val)) goto integer_came_from_string;
1021 sv_catpvn(retval, (const char *)mg->mg_ptr, mg->mg_len);
1025 integer_came_from_string:
1028 i += esc_q_utf8(aTHX_ retval, c, i);
1030 sv_grow(retval, SvCUR(retval)+3+2*i); /* 3: ""\0 */
1031 r = SvPVX(retval) + SvCUR(retval);
1033 i += esc_q(r+1, c, i);
1037 SvCUR_set(retval, SvCUR(retval)+i);
1044 (void)hv_delete(seenhv, id, idlen, G_DISCARD);
1045 else if (namelen && seenentry) {
1046 SV *mark = *av_fetch(seenentry, 2, TRUE);
1054 MODULE = Data::Dumper PACKAGE = Data::Dumper PREFIX = Data_Dumper_
1057 # This is the exact equivalent of Dump. Well, almost. The things that are
1058 # different as of now (due to Laziness):
1059 # * doesn't do double-quotes yet.
1063 Data_Dumper_Dumpxs(href, ...)
1069 SV *retval, *valstr;
1071 AV *postav, *todumpav, *namesav;
1073 I32 indent, terse, i, imax, postlen;
1075 SV *val, *name, *pad, *xpad, *apad, *sep, *pair, *varname;
1076 SV *freezer, *toaster, *bless, *sortkeys;
1077 I32 purity, deepcopy, quotekeys, maxdepth = 0;
1081 if (!SvROK(href)) { /* call new to get an object first */
1083 croak("Usage: Data::Dumper::Dumpxs(PACKAGE, VAL_ARY_REF, [NAME_ARY_REF])");
1090 XPUSHs(sv_2mortal(newSVsv(ST(1))));
1092 XPUSHs(sv_2mortal(newSVsv(ST(2))));
1094 i = perl_call_method("new", G_SCALAR);
1097 href = newSVsv(POPs);
1103 (void)sv_2mortal(href);
1106 todumpav = namesav = NULL;
1108 val = pad = xpad = apad = sep = pair = varname
1109 = freezer = toaster = bless = sortkeys = &PL_sv_undef;
1110 name = sv_newmortal();
1112 terse = purity = deepcopy = 0;
1115 retval = newSVpvn("", 0);
1117 && (hv = (HV*)SvRV((SV*)href))
1118 && SvTYPE(hv) == SVt_PVHV) {
1120 if ((svp = hv_fetch(hv, "seen", 4, FALSE)) && SvROK(*svp))
1121 seenhv = (HV*)SvRV(*svp);
1122 if ((svp = hv_fetch(hv, "todump", 6, FALSE)) && SvROK(*svp))
1123 todumpav = (AV*)SvRV(*svp);
1124 if ((svp = hv_fetch(hv, "names", 5, FALSE)) && SvROK(*svp))
1125 namesav = (AV*)SvRV(*svp);
1126 if ((svp = hv_fetch(hv, "indent", 6, FALSE)))
1127 indent = SvIV(*svp);
1128 if ((svp = hv_fetch(hv, "purity", 6, FALSE)))
1129 purity = SvIV(*svp);
1130 if ((svp = hv_fetch(hv, "terse", 5, FALSE)))
1131 terse = SvTRUE(*svp);
1132 #if 0 /* useqq currently unused */
1133 if ((svp = hv_fetch(hv, "useqq", 5, FALSE)))
1134 useqq = SvTRUE(*svp);
1136 if ((svp = hv_fetch(hv, "pad", 3, FALSE)))
1138 if ((svp = hv_fetch(hv, "xpad", 4, FALSE)))
1140 if ((svp = hv_fetch(hv, "apad", 4, FALSE)))
1142 if ((svp = hv_fetch(hv, "sep", 3, FALSE)))
1144 if ((svp = hv_fetch(hv, "pair", 4, FALSE)))
1146 if ((svp = hv_fetch(hv, "varname", 7, FALSE)))
1148 if ((svp = hv_fetch(hv, "freezer", 7, FALSE)))
1150 if ((svp = hv_fetch(hv, "toaster", 7, FALSE)))
1152 if ((svp = hv_fetch(hv, "deepcopy", 8, FALSE)))
1153 deepcopy = SvTRUE(*svp);
1154 if ((svp = hv_fetch(hv, "quotekeys", 9, FALSE)))
1155 quotekeys = SvTRUE(*svp);
1156 if ((svp = hv_fetch(hv, "bless", 5, FALSE)))
1158 if ((svp = hv_fetch(hv, "maxdepth", 8, FALSE)))
1159 maxdepth = SvIV(*svp);
1160 if ((svp = hv_fetch(hv, "sortkeys", 8, FALSE))) {
1162 if (! SvTRUE(sortkeys))
1164 else if (! (SvROK(sortkeys) &&
1165 SvTYPE(SvRV(sortkeys)) == SVt_PVCV) )
1167 /* flag to use qsortsv() for sorting hash keys */
1168 sortkeys = &PL_sv_yes;
1174 imax = av_len(todumpav);
1177 valstr = newSVpvn("",0);
1178 for (i = 0; i <= imax; ++i) {
1182 if ((svp = av_fetch(todumpav, i, FALSE)))
1186 if ((svp = av_fetch(namesav, i, TRUE))) {
1187 sv_setsv(name, *svp);
1188 if (SvOK(*svp) && !SvPOK(*svp))
1189 (void)SvPV_nolen_const(name);
1192 (void)SvOK_off(name);
1195 if ((SvPVX_const(name))[0] == '*') {
1197 switch (SvTYPE(SvRV(val))) {
1199 (SvPVX(name))[0] = '@';
1202 (SvPVX(name))[0] = '%';
1205 (SvPVX(name))[0] = '*';
1208 (SvPVX(name))[0] = '$';
1213 (SvPVX(name))[0] = '$';
1215 else if ((SvPVX_const(name))[0] != '$')
1216 sv_insert(name, 0, 0, "$", 1);
1220 sv_setpvn(name, "$", 1);
1221 sv_catsv(name, varname);
1222 nchars = my_snprintf(tmpbuf, sizeof(tmpbuf), "%"IVdf, (IV)(i+1));
1223 sv_catpvn(name, tmpbuf, nchars);
1226 if (indent >= 2 && !terse) {
1227 SV * const tmpsv = sv_x(aTHX_ NULL, " ", 1, SvCUR(name)+3);
1228 newapad = newSVsv(apad);
1229 sv_catsv(newapad, tmpsv);
1230 SvREFCNT_dec(tmpsv);
1236 DD_dump(aTHX_ val, SvPVX_const(name), SvCUR(name), valstr, seenhv,
1237 postav, &level, indent, pad, xpad, newapad, sep, pair,
1238 freezer, toaster, purity, deepcopy, quotekeys,
1239 bless, maxdepth, sortkeys);
1242 if (indent >= 2 && !terse)
1243 SvREFCNT_dec(newapad);
1245 postlen = av_len(postav);
1246 if (postlen >= 0 || !terse) {
1247 sv_insert(valstr, 0, 0, " = ", 3);
1248 sv_insert(valstr, 0, 0, SvPVX_const(name), SvCUR(name));
1249 sv_catpvn(valstr, ";", 1);
1251 sv_catsv(retval, pad);
1252 sv_catsv(retval, valstr);
1253 sv_catsv(retval, sep);
1256 sv_catsv(retval, pad);
1257 for (i = 0; i <= postlen; ++i) {
1259 svp = av_fetch(postav, i, FALSE);
1260 if (svp && (elem = *svp)) {
1261 sv_catsv(retval, elem);
1263 sv_catpvn(retval, ";", 1);
1264 sv_catsv(retval, sep);
1265 sv_catsv(retval, pad);
1269 sv_catpvn(retval, ";", 1);
1270 sv_catsv(retval, sep);
1272 sv_setpvn(valstr, "", 0);
1273 if (gimme == G_ARRAY) {
1274 XPUSHs(sv_2mortal(retval));
1275 if (i < imax) /* not the last time thro ? */
1276 retval = newSVpvn("",0);
1279 SvREFCNT_dec(postav);
1280 SvREFCNT_dec(valstr);
1283 croak("Call to new() method failed to return HASH ref");
1284 if (gimme == G_SCALAR)
1285 XPUSHs(sv_2mortal(retval));
1289 Data_Dumper__vstring(sv)
1297 SvMAGICAL(sv) && (mg = mg_find(sv, 'V'))
1298 ? newSVpvn((const char *)mg->mg_ptr, mg->mg_len)
1301 RETVAL = &PL_sv_undef;