line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#define PERL_NO_GET_CONTEXT |
2
|
|
|
|
|
|
|
#include "EXTERN.h" |
3
|
|
|
|
|
|
|
#include "perl.h" |
4
|
|
|
|
|
|
|
#include "XSUB.h" |
5
|
|
|
|
|
|
|
#ifdef USE_PPPORT_H |
6
|
|
|
|
|
|
|
# define NEED_my_snprintf |
7
|
|
|
|
|
|
|
# define NEED_my_sprintf |
8
|
|
|
|
|
|
|
# define NEED_sv_2pv_flags |
9
|
|
|
|
|
|
|
# define NEED_utf8_to_uvchr_buf |
10
|
|
|
|
|
|
|
# include "ppport.h" |
11
|
|
|
|
|
|
|
#endif |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
#ifndef strlcpy |
14
|
|
|
|
|
|
|
# ifdef my_strlcpy |
15
|
|
|
|
|
|
|
# define strlcpy(d,s,l) my_strlcpy(d,s,l) |
16
|
|
|
|
|
|
|
# else |
17
|
|
|
|
|
|
|
# define strlcpy(d,s,l) strcpy(d,s) |
18
|
|
|
|
|
|
|
# endif |
19
|
|
|
|
|
|
|
#endif |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
/* These definitions are ASCII only. But the pure-perl .pm avoids |
22
|
|
|
|
|
|
|
* calling this .xs file for releases where they aren't defined */ |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
#ifndef ESC_NATIVE /* \e */ |
25
|
|
|
|
|
|
|
# define ESC_NATIVE LATIN1_TO_NATIVE(27) |
26
|
|
|
|
|
|
|
#endif |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
/* SvPVCLEAR only from perl 5.25.6 */ |
29
|
|
|
|
|
|
|
#ifndef SvPVCLEAR |
30
|
|
|
|
|
|
|
# define SvPVCLEAR(sv) sv_setpvs((sv), "") |
31
|
|
|
|
|
|
|
#endif |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
#ifndef memBEGINs |
34
|
|
|
|
|
|
|
# define memBEGINs(s1, l, s2) \ |
35
|
|
|
|
|
|
|
( (l) >= sizeof(s2) - 1 \ |
36
|
|
|
|
|
|
|
&& memEQ(s1, "" s2 "", sizeof(s2)-1)) |
37
|
|
|
|
|
|
|
#endif |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
/* This struct contains almost all the user's desired configuration, and it |
40
|
|
|
|
|
|
|
* is treated as mostly constant (except for maxrecursed) by the recursive |
41
|
|
|
|
|
|
|
* function. This arrangement has the advantage of needing less memory |
42
|
|
|
|
|
|
|
* than passing all of them on the stack all the time (as was the case in |
43
|
|
|
|
|
|
|
* an earlier implementation). */ |
44
|
|
|
|
|
|
|
typedef struct { |
45
|
|
|
|
|
|
|
SV *pad; |
46
|
|
|
|
|
|
|
SV *xpad; |
47
|
|
|
|
|
|
|
SV *sep; |
48
|
|
|
|
|
|
|
SV *pair; |
49
|
|
|
|
|
|
|
SV *sortkeys; |
50
|
|
|
|
|
|
|
SV *freezer; |
51
|
|
|
|
|
|
|
SV *toaster; |
52
|
|
|
|
|
|
|
SV *bless; |
53
|
|
|
|
|
|
|
IV maxrecurse; |
54
|
|
|
|
|
|
|
bool maxrecursed; /* at some point we exceeded the maximum recursion level */ |
55
|
|
|
|
|
|
|
I32 indent; |
56
|
|
|
|
|
|
|
I32 purity; |
57
|
|
|
|
|
|
|
I32 deepcopy; |
58
|
|
|
|
|
|
|
I32 quotekeys; |
59
|
|
|
|
|
|
|
I32 maxdepth; |
60
|
|
|
|
|
|
|
I32 useqq; |
61
|
|
|
|
|
|
|
int use_sparse_seen_hash; |
62
|
|
|
|
|
|
|
int trailingcomma; |
63
|
|
|
|
|
|
|
int deparse; |
64
|
|
|
|
|
|
|
} Style; |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
static STRLEN num_q (const char *s, STRLEN slen); |
67
|
|
|
|
|
|
|
static STRLEN esc_q (char *dest, const char *src, STRLEN slen); |
68
|
|
|
|
|
|
|
static STRLEN esc_q_utf8 (pTHX_ SV *sv, const char *src, STRLEN slen, I32 do_utf8, I32 useqq); |
69
|
|
|
|
|
|
|
static bool globname_needs_quote(const char *s, STRLEN len); |
70
|
|
|
|
|
|
|
#ifndef GvNAMEUTF8 |
71
|
|
|
|
|
|
|
static bool globname_supra_ascii(const char *s, STRLEN len); |
72
|
|
|
|
|
|
|
#endif |
73
|
|
|
|
|
|
|
static bool key_needs_quote(const char *s, STRLEN len); |
74
|
|
|
|
|
|
|
static bool safe_decimal_number(const char *p, STRLEN len); |
75
|
|
|
|
|
|
|
static SV *sv_x (pTHX_ SV *sv, const char *str, STRLEN len, I32 n); |
76
|
|
|
|
|
|
|
static I32 DD_dump (pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, |
77
|
|
|
|
|
|
|
HV *seenhv, AV *postav, const I32 level, SV *apad, |
78
|
|
|
|
|
|
|
Style *style); |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
#define DD_is_integer(sv) SvIOK(sv) |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
/* does a glob name need to be protected? */ |
83
|
|
|
|
|
|
|
static bool |
84
|
75
|
|
|
|
|
|
globname_needs_quote(const char *ss, STRLEN len) |
85
|
|
|
|
|
|
|
{ |
86
|
75
|
|
|
|
|
|
const U8 *s = (const U8 *) ss; |
87
|
75
|
|
|
|
|
|
const U8 *send = s+len; |
88
|
|
|
|
|
|
|
TOP: |
89
|
97
|
100
|
|
|
|
|
if (s[0] == ':') { |
90
|
75
|
100
|
|
|
|
|
if (++s
|
91
|
74
|
50
|
|
|
|
|
if (*s++ != ':') |
92
|
0
|
|
|
|
|
|
return TRUE; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
else |
95
|
1
|
|
|
|
|
|
return TRUE; |
96
|
|
|
|
|
|
|
} |
97
|
96
|
100
|
|
|
|
|
if (isIDFIRST(*s)) { |
98
|
198
|
100
|
|
|
|
|
while (++s
|
99
|
167
|
100
|
|
|
|
|
if (!isWORDCHAR(*s)) { |
100
|
55
|
100
|
|
|
|
|
if (*s == ':') |
101
|
22
|
|
|
|
|
|
goto TOP; |
102
|
|
|
|
|
|
|
else |
103
|
33
|
|
|
|
|
|
return TRUE; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
else |
107
|
10
|
|
|
|
|
|
return TRUE; |
108
|
|
|
|
|
|
|
|
109
|
31
|
|
|
|
|
|
return FALSE; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
#ifndef GvNAMEUTF8 |
113
|
|
|
|
|
|
|
/* does a glob name contain supra-ASCII characters? */ |
114
|
|
|
|
|
|
|
static bool |
115
|
|
|
|
|
|
|
globname_supra_ascii(const char *ss, STRLEN len) |
116
|
|
|
|
|
|
|
{ |
117
|
|
|
|
|
|
|
const U8 *s = (const U8 *) ss; |
118
|
|
|
|
|
|
|
const U8 *send = s+len; |
119
|
|
|
|
|
|
|
while (s < send) { |
120
|
|
|
|
|
|
|
if (!isASCII(*s)) |
121
|
|
|
|
|
|
|
return TRUE; |
122
|
|
|
|
|
|
|
s++; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
return FALSE; |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
#endif |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
/* does a hash key need to be quoted (to the left of => ). |
129
|
|
|
|
|
|
|
Previously this used (globname_)needs_quote() which accepted strings |
130
|
|
|
|
|
|
|
like '::foo', but these aren't safe as unquoted keys under strict. |
131
|
|
|
|
|
|
|
*/ |
132
|
|
|
|
|
|
|
static bool |
133
|
206
|
|
|
|
|
|
key_needs_quote(const char *s, STRLEN len) { |
134
|
206
|
|
|
|
|
|
const char *send = s+len; |
135
|
|
|
|
|
|
|
|
136
|
206
|
100
|
|
|
|
|
if (safe_decimal_number(s, len)) { |
137
|
42
|
|
|
|
|
|
return FALSE; |
138
|
|
|
|
|
|
|
} |
139
|
164
|
100
|
|
|
|
|
else if (isIDFIRST(*s)) { |
140
|
406
|
100
|
|
|
|
|
while (++s
|
141
|
256
|
100
|
|
|
|
|
if (!isWORDCHAR(*s)) |
142
|
2
|
|
|
|
|
|
return TRUE; |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
else |
145
|
12
|
|
|
|
|
|
return TRUE; |
146
|
|
|
|
|
|
|
|
147
|
150
|
|
|
|
|
|
return FALSE; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
/* Check that the SV can be represented as a simple decimal integer. |
151
|
|
|
|
|
|
|
* |
152
|
|
|
|
|
|
|
* The perl code does this by matching against /^(?:0|-?[1-9]\d{0,8})\z/ |
153
|
|
|
|
|
|
|
*/ |
154
|
|
|
|
|
|
|
static bool |
155
|
252
|
|
|
|
|
|
safe_decimal_number(const char *p, STRLEN len) { |
156
|
252
|
100
|
|
|
|
|
if (len == 1 && *p == '0') |
|
|
100
|
|
|
|
|
|
157
|
2
|
|
|
|
|
|
return TRUE; |
158
|
|
|
|
|
|
|
|
159
|
250
|
50
|
|
|
|
|
if (len && *p == '-') { |
|
|
50
|
|
|
|
|
|
160
|
0
|
|
|
|
|
|
++p; |
161
|
0
|
|
|
|
|
|
--len; |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
|
164
|
250
|
50
|
|
|
|
|
if (len == 0 || *p < '1' || *p > '9') |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
165
|
202
|
|
|
|
|
|
return FALSE; |
166
|
|
|
|
|
|
|
|
167
|
48
|
|
|
|
|
|
++p; |
168
|
48
|
|
|
|
|
|
--len; |
169
|
|
|
|
|
|
|
|
170
|
48
|
100
|
|
|
|
|
if (len > 8) |
171
|
4
|
|
|
|
|
|
return FALSE; |
172
|
|
|
|
|
|
|
|
173
|
98
|
100
|
|
|
|
|
while (len > 0) { |
174
|
|
|
|
|
|
|
/* the perl code checks /\d/ but we don't want unicode digits here */ |
175
|
56
|
100
|
|
|
|
|
if (*p < '0' || *p > '9') |
|
|
50
|
|
|
|
|
|
176
|
2
|
|
|
|
|
|
return FALSE; |
177
|
54
|
|
|
|
|
|
++p; |
178
|
54
|
|
|
|
|
|
--len; |
179
|
|
|
|
|
|
|
} |
180
|
42
|
|
|
|
|
|
return TRUE; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
/* count the number of "'"s and "\"s in string */ |
184
|
|
|
|
|
|
|
static STRLEN |
185
|
512
|
|
|
|
|
|
num_q(const char *s, STRLEN slen) |
186
|
|
|
|
|
|
|
{ |
187
|
512
|
|
|
|
|
|
STRLEN ret = 0; |
188
|
|
|
|
|
|
|
|
189
|
2790
|
100
|
|
|
|
|
while (slen > 0) { |
190
|
2278
|
100
|
|
|
|
|
if (*s == '\'' || *s == '\\') |
|
|
100
|
|
|
|
|
|
191
|
2
|
|
|
|
|
|
++ret; |
192
|
2278
|
|
|
|
|
|
++s; |
193
|
2278
|
|
|
|
|
|
--slen; |
194
|
|
|
|
|
|
|
} |
195
|
512
|
|
|
|
|
|
return ret; |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
/* returns number of chars added to escape "'"s and "\"s in s */ |
200
|
|
|
|
|
|
|
/* slen number of characters in s will be escaped */ |
201
|
|
|
|
|
|
|
/* destination must be long enough for additional chars */ |
202
|
|
|
|
|
|
|
static STRLEN |
203
|
973
|
|
|
|
|
|
esc_q(char *d, const char *s, STRLEN slen) |
204
|
|
|
|
|
|
|
{ |
205
|
973
|
|
|
|
|
|
STRLEN ret = 0; |
206
|
|
|
|
|
|
|
|
207
|
10657
|
100
|
|
|
|
|
while (slen > 0) { |
208
|
9684
|
100
|
|
|
|
|
switch (*s) { |
209
|
|
|
|
|
|
|
case '\'': |
210
|
|
|
|
|
|
|
case '\\': |
211
|
5
|
|
|
|
|
|
*d = '\\'; |
212
|
5
|
|
|
|
|
|
++d; ++ret; |
213
|
|
|
|
|
|
|
/* FALLTHROUGH */ |
214
|
|
|
|
|
|
|
default: |
215
|
9684
|
|
|
|
|
|
*d = *s; |
216
|
9684
|
|
|
|
|
|
++d; ++s; --slen; |
217
|
9684
|
|
|
|
|
|
break; |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
} |
220
|
973
|
|
|
|
|
|
return ret; |
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
/* this function is also misused for implementing $Useqq */ |
224
|
|
|
|
|
|
|
static STRLEN |
225
|
144
|
|
|
|
|
|
esc_q_utf8(pTHX_ SV* sv, const char *src, STRLEN slen, I32 do_utf8, I32 useqq) |
226
|
|
|
|
|
|
|
{ |
227
|
|
|
|
|
|
|
char *r, *rstart; |
228
|
144
|
|
|
|
|
|
const char *s = src; |
229
|
144
|
|
|
|
|
|
const char * const send = src + slen; |
230
|
144
|
|
|
|
|
|
STRLEN j, cur = SvCUR(sv); |
231
|
|
|
|
|
|
|
/* Could count 128-255 and 256+ in two variables, if we want to |
232
|
|
|
|
|
|
|
be like &qquote and make a distinction. */ |
233
|
144
|
|
|
|
|
|
STRLEN grow = 0; /* bytes needed to represent chars 128+ */ |
234
|
|
|
|
|
|
|
/* STRLEN topbit_grow = 0; bytes needed to represent chars 128-255 */ |
235
|
144
|
|
|
|
|
|
STRLEN backslashes = 0; |
236
|
144
|
|
|
|
|
|
STRLEN single_quotes = 0; |
237
|
144
|
|
|
|
|
|
STRLEN qq_escapables = 0; /* " $ @ will need a \ in "" strings. */ |
238
|
144
|
|
|
|
|
|
STRLEN normal = 0; |
239
|
|
|
|
|
|
|
int increment; |
240
|
|
|
|
|
|
|
|
241
|
1937
|
100
|
|
|
|
|
for (s = src; s < send; s += increment) { /* Sizing pass */ |
242
|
1793
|
|
|
|
|
|
UV k = *(U8*)s; |
243
|
|
|
|
|
|
|
|
244
|
1793
|
|
|
|
|
|
increment = 1; /* Will override if necessary for utf-8 */ |
245
|
|
|
|
|
|
|
|
246
|
1793
|
50
|
|
|
|
|
if (isPRINT(k)) { |
|
|
100
|
|
|
|
|
|
247
|
2002
|
100
|
|
|
|
|
if (k == '\\') { |
248
|
6
|
|
|
|
|
|
backslashes++; |
249
|
995
|
100
|
|
|
|
|
} else if (k == '\'') { |
250
|
58
|
|
|
|
|
|
single_quotes++; |
251
|
937
|
100
|
|
|
|
|
} else if (k == '"' || k == '$' || k == '@') { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
252
|
22
|
|
|
|
|
|
qq_escapables++; |
253
|
|
|
|
|
|
|
} else { |
254
|
915
|
|
|
|
|
|
normal++; |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
} |
257
|
792
|
100
|
|
|
|
|
else if (! UTF8_IS_INVARIANT(k)) { |
258
|
|
|
|
|
|
|
/* We treat as low ordinal any code point whose representation is |
259
|
|
|
|
|
|
|
* the same under UTF-8 as not. Thus, this is a high ordinal code |
260
|
|
|
|
|
|
|
* point. |
261
|
|
|
|
|
|
|
* |
262
|
|
|
|
|
|
|
* If UTF-8, output as hex, regardless of useqq. This means there |
263
|
|
|
|
|
|
|
* is an overhead of 4 chars '\x{}'. Then count the number of hex |
264
|
|
|
|
|
|
|
* digits. */ |
265
|
636
|
100
|
|
|
|
|
if (do_utf8) { |
266
|
372
|
|
|
|
|
|
k = utf8_to_uvchr_buf((U8*)s, (U8*) send, NULL); |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
/* treat invalid utf8 byte by byte. This loop iteration gets the |
269
|
|
|
|
|
|
|
* first byte */ |
270
|
372
|
100
|
|
|
|
|
increment = (k == 0 && *s != '\0') ? 1 : UTF8SKIP(s); |
|
|
50
|
|
|
|
|
|
271
|
|
|
|
|
|
|
|
272
|
372
|
|
|
|
|
|
grow += 6; /* Smallest we do is "\x{FF}" */ |
273
|
372
|
|
|
|
|
|
k >>= 4; |
274
|
480
|
100
|
|
|
|
|
while ((k >>= 4) != 0) { /* Add space for each nibble */ |
275
|
108
|
|
|
|
|
|
grow++; |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
} |
278
|
264
|
50
|
|
|
|
|
else if (useqq) { /* Not utf8, must be <= 0xFF, hence 2 hex |
279
|
|
|
|
|
|
|
* digits. */ |
280
|
264
|
|
|
|
|
|
grow += 4 + 2; |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
else { /* Non-qq generates 3 octal digits plus backslash */ |
283
|
636
|
|
|
|
|
|
grow += 4; |
284
|
|
|
|
|
|
|
} |
285
|
|
|
|
|
|
|
} /* End of high-ordinal non-printable */ |
286
|
156
|
100
|
|
|
|
|
else if (! useqq) { /* Low ordinal, non-printable, non-qq just |
287
|
|
|
|
|
|
|
* outputs the raw char */ |
288
|
2
|
|
|
|
|
|
normal++; |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
else { /* Is qq, low ordinal, non-printable. Output escape |
291
|
|
|
|
|
|
|
* sequences */ |
292
|
154
|
100
|
|
|
|
|
if ( k == '\a' || k == '\b' || k == '\t' || k == '\n' || k == '\r' |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
293
|
132
|
100
|
|
|
|
|
|| k == '\f' || k == ESC_NATIVE) |
|
|
100
|
|
|
|
|
|
294
|
|
|
|
|
|
|
{ |
295
|
32
|
|
|
|
|
|
grow += 2; /* 1 char plus backslash */ |
296
|
|
|
|
|
|
|
} |
297
|
|
|
|
|
|
|
else /* The other low ordinals are output as an octal escape |
298
|
|
|
|
|
|
|
* sequence */ |
299
|
122
|
100
|
|
|
|
|
if (s + 1 >= send || isDIGIT(*(s+1))) { |
|
|
100
|
|
|
|
|
|
300
|
|
|
|
|
|
|
/* When the following character is a digit, use 3 octal digits |
301
|
|
|
|
|
|
|
* plus backslash, as using fewer digits would concatenate the |
302
|
|
|
|
|
|
|
* following char into this one */ |
303
|
6
|
|
|
|
|
|
grow += 4; |
304
|
|
|
|
|
|
|
} |
305
|
116
|
100
|
|
|
|
|
else if (k <= 7) { |
306
|
40
|
|
|
|
|
|
grow += 2; /* 1 octal digit, plus backslash */ |
307
|
|
|
|
|
|
|
} |
308
|
76
|
100
|
|
|
|
|
else if (k <= 077) { |
309
|
72
|
|
|
|
|
|
grow += 3; /* 2 octal digits plus backslash */ |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
else { |
312
|
4
|
|
|
|
|
|
grow += 4; /* 3 octal digits plus backslash */ |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
} /* End of size-calculating loop */ |
316
|
|
|
|
|
|
|
|
317
|
144
|
100
|
|
|
|
|
if (grow || useqq) { |
|
|
100
|
|
|
|
|
|
318
|
|
|
|
|
|
|
/* We have something needing hex. 3 is ""\0 */ |
319
|
132
|
|
|
|
|
|
sv_grow(sv, cur + 3 + grow + 2*backslashes + single_quotes |
320
|
|
|
|
|
|
|
+ 2*qq_escapables + normal); |
321
|
132
|
|
|
|
|
|
rstart = r = SvPVX(sv) + cur; |
322
|
|
|
|
|
|
|
|
323
|
132
|
|
|
|
|
|
*r++ = '"'; |
324
|
|
|
|
|
|
|
|
325
|
1860
|
100
|
|
|
|
|
for (s = src; s < send; s += increment) { |
326
|
1728
|
|
|
|
|
|
U8 c0 = *(U8 *)s; |
327
|
|
|
|
|
|
|
UV k; |
328
|
|
|
|
|
|
|
|
329
|
1728
|
100
|
|
|
|
|
if (do_utf8 && ! UTF8_IS_INVARIANT(c0)) { |
|
|
100
|
|
|
|
|
|
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
/* In UTF-8, we output as \x{} all chars that require more than |
332
|
|
|
|
|
|
|
* a single byte in UTF-8 to represent. */ |
333
|
372
|
|
|
|
|
|
k = utf8_to_uvchr_buf((U8*)s, (U8*) send, NULL); |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
/* treat invalid utf8 byte by byte. This loop iteration gets the |
336
|
|
|
|
|
|
|
* first byte */ |
337
|
372
|
100
|
|
|
|
|
increment = (k == 0 && *s != '\0') ? 1 : UTF8SKIP(s); |
|
|
50
|
|
|
|
|
|
338
|
|
|
|
|
|
|
|
339
|
372
|
|
|
|
|
|
r = r + my_sprintf(r, "\\x{%" UVxf "}", k); |
340
|
372
|
|
|
|
|
|
continue; |
341
|
|
|
|
|
|
|
} |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
/* Here 1) isn't UTF-8; or |
344
|
|
|
|
|
|
|
* 2) the current character is ASCII; or |
345
|
|
|
|
|
|
|
* 3) it is an EBCDIC platform and is a low ordinal |
346
|
|
|
|
|
|
|
* non-ASCII control. |
347
|
|
|
|
|
|
|
* In each case the character occupies just one byte */ |
348
|
1356
|
|
|
|
|
|
k = *(U8*)s; |
349
|
1356
|
|
|
|
|
|
increment = 1; |
350
|
|
|
|
|
|
|
|
351
|
1356
|
50
|
|
|
|
|
if (isPRINT(k)) { |
|
|
100
|
|
|
|
|
|
352
|
|
|
|
|
|
|
/* These need a backslash escape */ |
353
|
937
|
100
|
|
|
|
|
if (k == '"' || k == '\\' || k == '$' || k == '@') { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
354
|
24
|
|
|
|
|
|
*r++ = '\\'; |
355
|
|
|
|
|
|
|
} |
356
|
|
|
|
|
|
|
|
357
|
937
|
|
|
|
|
|
*r++ = (char)k; |
358
|
|
|
|
|
|
|
} |
359
|
419
|
100
|
|
|
|
|
else if (! useqq) { /* non-qq, non-printable, low-ordinal is |
360
|
|
|
|
|
|
|
* output raw */ |
361
|
1
|
|
|
|
|
|
*r++ = (char)k; |
362
|
|
|
|
|
|
|
} |
363
|
|
|
|
|
|
|
else { /* Is qq means use escape sequences */ |
364
|
|
|
|
|
|
|
bool next_is_digit; |
365
|
|
|
|
|
|
|
|
366
|
418
|
|
|
|
|
|
*r++ = '\\'; |
367
|
418
|
|
|
|
|
|
switch (k) { |
368
|
4
|
|
|
|
|
|
case '\a': *r++ = 'a'; break; |
369
|
4
|
|
|
|
|
|
case '\b': *r++ = 'b'; break; |
370
|
4
|
|
|
|
|
|
case '\t': *r++ = 't'; break; |
371
|
6
|
|
|
|
|
|
case '\n': *r++ = 'n'; break; |
372
|
4
|
|
|
|
|
|
case '\f': *r++ = 'f'; break; |
373
|
4
|
|
|
|
|
|
case '\r': *r++ = 'r'; break; |
374
|
6
|
|
|
|
|
|
case ESC_NATIVE: *r++ = 'e'; break; |
375
|
|
|
|
|
|
|
default: |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
/* only ASCII digits matter here, which are invariant, |
378
|
|
|
|
|
|
|
* since we only encode characters \377 and under, or |
379
|
|
|
|
|
|
|
* \x177 and under for a unicode string |
380
|
|
|
|
|
|
|
*/ |
381
|
386
|
100
|
|
|
|
|
next_is_digit = (s + 1 < send && isDIGIT(*(s+1))); |
|
|
100
|
|
|
|
|
|
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
/* faster than |
384
|
|
|
|
|
|
|
* r = r + my_sprintf(r, "%o", k); |
385
|
|
|
|
|
|
|
*/ |
386
|
386
|
100
|
|
|
|
|
if (k <= 7 && !next_is_digit) { |
|
|
100
|
|
|
|
|
|
387
|
42
|
|
|
|
|
|
*r++ = (char)k + '0'; |
388
|
344
|
100
|
|
|
|
|
} else if (k <= 63 && !next_is_digit) { |
|
|
100
|
|
|
|
|
|
389
|
72
|
|
|
|
|
|
*r++ = (char)(k>>3) + '0'; |
390
|
72
|
|
|
|
|
|
*r++ = (char)(k&7) + '0'; |
391
|
|
|
|
|
|
|
} else { |
392
|
272
|
|
|
|
|
|
*r++ = (char)(k>>6) + '0'; |
393
|
272
|
|
|
|
|
|
*r++ = (char)((k&63)>>3) + '0'; |
394
|
272
|
|
|
|
|
|
*r++ = (char)(k&7) + '0'; |
395
|
|
|
|
|
|
|
} |
396
|
|
|
|
|
|
|
} |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
} |
399
|
132
|
|
|
|
|
|
*r++ = '"'; |
400
|
|
|
|
|
|
|
} else { |
401
|
|
|
|
|
|
|
/* Single quotes. */ |
402
|
12
|
|
|
|
|
|
sv_grow(sv, cur + 3 + 2*backslashes + 2*single_quotes |
403
|
|
|
|
|
|
|
+ qq_escapables + normal); |
404
|
12
|
|
|
|
|
|
rstart = r = SvPVX(sv) + cur; |
405
|
12
|
|
|
|
|
|
*r++ = '\''; |
406
|
77
|
100
|
|
|
|
|
for (s = src; s < send; s ++) { |
407
|
65
|
|
|
|
|
|
const char k = *s; |
408
|
65
|
100
|
|
|
|
|
if (k == '\'' || k == '\\') |
|
|
50
|
|
|
|
|
|
409
|
2
|
|
|
|
|
|
*r++ = '\\'; |
410
|
65
|
|
|
|
|
|
*r++ = k; |
411
|
|
|
|
|
|
|
} |
412
|
12
|
|
|
|
|
|
*r++ = '\''; |
413
|
|
|
|
|
|
|
} |
414
|
144
|
|
|
|
|
|
*r = '\0'; |
415
|
144
|
|
|
|
|
|
j = r - rstart; |
416
|
144
|
|
|
|
|
|
SvCUR_set(sv, cur + j); |
417
|
|
|
|
|
|
|
|
418
|
144
|
|
|
|
|
|
return j; |
419
|
|
|
|
|
|
|
} |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
/* append a repeated string to an SV */ |
422
|
|
|
|
|
|
|
static SV * |
423
|
1448
|
|
|
|
|
|
sv_x(pTHX_ SV *sv, const char *str, STRLEN len, I32 n) |
424
|
|
|
|
|
|
|
{ |
425
|
1448
|
100
|
|
|
|
|
if (!sv) |
426
|
1427
|
|
|
|
|
|
sv = newSVpvs(""); |
427
|
|
|
|
|
|
|
#ifdef DEBUGGING |
428
|
|
|
|
|
|
|
else |
429
|
|
|
|
|
|
|
assert(SvTYPE(sv) >= SVt_PV); |
430
|
|
|
|
|
|
|
#endif |
431
|
|
|
|
|
|
|
|
432
|
1448
|
100
|
|
|
|
|
if (n > 0) { |
433
|
1168
|
50
|
|
|
|
|
SvGROW(sv, len*n + SvCUR(sv) + 1); |
|
|
100
|
|
|
|
|
|
434
|
1168
|
100
|
|
|
|
|
if (len == 1) { |
435
|
267
|
|
|
|
|
|
char * const start = SvPVX(sv) + SvCUR(sv); |
436
|
267
|
|
|
|
|
|
SvCUR_set(sv, SvCUR(sv) + n); |
437
|
267
|
|
|
|
|
|
start[n] = '\0'; |
438
|
2115
|
100
|
|
|
|
|
while (n > 0) |
439
|
1848
|
|
|
|
|
|
start[--n] = str[0]; |
440
|
|
|
|
|
|
|
} |
441
|
|
|
|
|
|
|
else |
442
|
2559
|
100
|
|
|
|
|
while (n > 0) { |
443
|
1658
|
|
|
|
|
|
sv_catpvn(sv, str, len); |
444
|
1658
|
|
|
|
|
|
--n; |
445
|
|
|
|
|
|
|
} |
446
|
|
|
|
|
|
|
} |
447
|
1448
|
|
|
|
|
|
return sv; |
448
|
|
|
|
|
|
|
} |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
static SV * |
451
|
5
|
|
|
|
|
|
deparsed_output(pTHX_ SV *val) |
452
|
|
|
|
|
|
|
{ |
453
|
|
|
|
|
|
|
SV *text; |
454
|
|
|
|
|
|
|
int n; |
455
|
5
|
|
|
|
|
|
dSP; |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
/* This is passed to load_module(), which decrements its ref count and |
458
|
|
|
|
|
|
|
* modifies it (so we also can't reuse it below) */ |
459
|
5
|
|
|
|
|
|
SV *pkg = newSVpvs("B::Deparse"); |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
/* Commit ebdc88085efa6fca8a1b0afaa388f0491bdccd5a (first released as part |
462
|
|
|
|
|
|
|
* of 5.19.7) changed core S_process_special_blocks() to use a new stack |
463
|
|
|
|
|
|
|
* for anything using a BEGIN block, on the grounds that doing so "avoids |
464
|
|
|
|
|
|
|
* the stack moving underneath anything that directly or indirectly calls |
465
|
|
|
|
|
|
|
* Perl_load_module()". If we're in an older Perl, we can't rely on that |
466
|
|
|
|
|
|
|
* stack, and must create a fresh sacrificial stack of our own. */ |
467
|
|
|
|
|
|
|
#if PERL_VERSION_LT(5,20,0) |
468
|
|
|
|
|
|
|
PUSHSTACKi(PERLSI_REQUIRE); |
469
|
|
|
|
|
|
|
#endif |
470
|
|
|
|
|
|
|
|
471
|
5
|
|
|
|
|
|
load_module(PERL_LOADMOD_NOIMPORT, pkg, 0); |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
#if PERL_VERSION_LT(5,20,0) |
474
|
|
|
|
|
|
|
POPSTACK; |
475
|
|
|
|
|
|
|
SPAGAIN; |
476
|
|
|
|
|
|
|
#endif |
477
|
|
|
|
|
|
|
|
478
|
5
|
|
|
|
|
|
SAVETMPS; |
479
|
|
|
|
|
|
|
|
480
|
5
|
50
|
|
|
|
|
PUSHMARK(SP); |
481
|
5
|
50
|
|
|
|
|
mXPUSHs(newSVpvs("B::Deparse")); |
482
|
5
|
|
|
|
|
|
PUTBACK; |
483
|
|
|
|
|
|
|
|
484
|
5
|
|
|
|
|
|
n = call_method("new", G_SCALAR); |
485
|
5
|
|
|
|
|
|
SPAGAIN; |
486
|
|
|
|
|
|
|
|
487
|
5
|
50
|
|
|
|
|
if (n != 1) { |
488
|
0
|
|
|
|
|
|
croak("B::Deparse->new returned %d items, but expected exactly 1", n); |
489
|
|
|
|
|
|
|
} |
490
|
|
|
|
|
|
|
|
491
|
5
|
50
|
|
|
|
|
PUSHMARK(SP - n); |
492
|
5
|
50
|
|
|
|
|
XPUSHs(val); |
493
|
5
|
|
|
|
|
|
PUTBACK; |
494
|
|
|
|
|
|
|
|
495
|
5
|
|
|
|
|
|
n = call_method("coderef2text", G_SCALAR); |
496
|
5
|
|
|
|
|
|
SPAGAIN; |
497
|
|
|
|
|
|
|
|
498
|
5
|
50
|
|
|
|
|
if (n != 1) { |
499
|
0
|
|
|
|
|
|
croak("$b_deparse->coderef2text returned %d items, but expected exactly 1", n); |
500
|
|
|
|
|
|
|
} |
501
|
|
|
|
|
|
|
|
502
|
5
|
|
|
|
|
|
text = POPs; |
503
|
5
|
|
|
|
|
|
SvREFCNT_inc(text); /* the caller will mortalise this */ |
504
|
|
|
|
|
|
|
|
505
|
5
|
50
|
|
|
|
|
FREETMPS; |
506
|
|
|
|
|
|
|
|
507
|
5
|
|
|
|
|
|
PUTBACK; |
508
|
|
|
|
|
|
|
|
509
|
5
|
|
|
|
|
|
return text; |
510
|
|
|
|
|
|
|
} |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
static void |
513
|
54
|
|
|
|
|
|
dump_regexp(pTHX_ SV *retval, SV *val) |
514
|
|
|
|
|
|
|
{ |
515
|
|
|
|
|
|
|
STRLEN rlen; |
516
|
54
|
|
|
|
|
|
SV *sv_pattern = NULL; |
517
|
54
|
|
|
|
|
|
SV *sv_flags = NULL; |
518
|
|
|
|
|
|
|
const char *rval; |
519
|
|
|
|
|
|
|
const U8 *rend; |
520
|
|
|
|
|
|
|
U8 *p; |
521
|
54
|
|
|
|
|
|
CV *re_pattern_cv = get_cv("re::regexp_pattern", 0); |
522
|
|
|
|
|
|
|
int do_utf8; |
523
|
|
|
|
|
|
|
|
524
|
54
|
50
|
|
|
|
|
if (!re_pattern_cv) { |
525
|
0
|
|
|
|
|
|
sv_pattern = val; |
526
|
|
|
|
|
|
|
} |
527
|
|
|
|
|
|
|
else { |
528
|
54
|
|
|
|
|
|
dSP; |
529
|
|
|
|
|
|
|
I32 count; |
530
|
54
|
|
|
|
|
|
ENTER; |
531
|
54
|
|
|
|
|
|
SAVETMPS; |
532
|
54
|
50
|
|
|
|
|
PUSHMARK(SP); |
533
|
54
|
50
|
|
|
|
|
XPUSHs(val); |
534
|
54
|
|
|
|
|
|
PUTBACK; |
535
|
54
|
|
|
|
|
|
count = call_sv((SV*)re_pattern_cv, G_ARRAY); |
536
|
54
|
|
|
|
|
|
SPAGAIN; |
537
|
54
|
50
|
|
|
|
|
if (count >= 2) { |
538
|
54
|
|
|
|
|
|
sv_flags = POPs; |
539
|
54
|
|
|
|
|
|
sv_pattern = POPs; |
540
|
54
|
|
|
|
|
|
SvREFCNT_inc(sv_flags); |
541
|
54
|
|
|
|
|
|
SvREFCNT_inc(sv_pattern); |
542
|
|
|
|
|
|
|
} |
543
|
54
|
|
|
|
|
|
PUTBACK; |
544
|
54
|
50
|
|
|
|
|
FREETMPS; |
545
|
54
|
|
|
|
|
|
LEAVE; |
546
|
54
|
50
|
|
|
|
|
if (sv_pattern) { |
547
|
54
|
|
|
|
|
|
sv_2mortal(sv_pattern); |
548
|
54
|
|
|
|
|
|
sv_2mortal(sv_flags); |
549
|
|
|
|
|
|
|
} |
550
|
|
|
|
|
|
|
} |
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
assert(sv_pattern); |
553
|
|
|
|
|
|
|
|
554
|
54
|
|
|
|
|
|
sv_catpvs(retval, "qr/"); |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
/* The strategy here is from commit 7894fbab1e479c2c (in June 1999) with a |
557
|
|
|
|
|
|
|
* bug fix in Feb 2012 (commit de5ef703c7d8db65). |
558
|
|
|
|
|
|
|
* We need to ensure that / is escaped as \/ |
559
|
|
|
|
|
|
|
* To be efficient, we want to avoid copying byte-for-byte, so we scan the |
560
|
|
|
|
|
|
|
* string looking for "things we need to escape", and each time we find |
561
|
|
|
|
|
|
|
* something, we copy over the verbatim section, before writing out the |
562
|
|
|
|
|
|
|
* escaped part. At the end, if there's some verbatim section left, we copy |
563
|
|
|
|
|
|
|
* that over to finish. |
564
|
|
|
|
|
|
|
* The complication (perl #58608) is that we must not convert \/ to \\/ |
565
|
|
|
|
|
|
|
* (as that would be a syntax error), so we need to walk the string looking |
566
|
|
|
|
|
|
|
* for either |
567
|
|
|
|
|
|
|
* \ and the character immediately after (together) |
568
|
|
|
|
|
|
|
* a character |
569
|
|
|
|
|
|
|
* and only for the latter, do we need to escape / |
570
|
|
|
|
|
|
|
* |
571
|
|
|
|
|
|
|
* Of course, to add to the fun, we also need to escape Unicode characters |
572
|
|
|
|
|
|
|
* to \x{...} notation (whether they are "escaped" by \ or stand alone). |
573
|
|
|
|
|
|
|
* |
574
|
|
|
|
|
|
|
* which means we need to output qr// notation |
575
|
|
|
|
|
|
|
* even if the input was expressed as q'' (eg q'$foo') |
576
|
|
|
|
|
|
|
* |
577
|
|
|
|
|
|
|
* We can do all this in one pass if we are careful... |
578
|
|
|
|
|
|
|
*/ |
579
|
|
|
|
|
|
|
|
580
|
54
|
50
|
|
|
|
|
rval = SvPV(sv_pattern, rlen); |
581
|
54
|
|
|
|
|
|
p = (U8 *)rval; |
582
|
54
|
|
|
|
|
|
rend = p + rlen; |
583
|
54
|
100
|
|
|
|
|
do_utf8 = DO_UTF8(sv_pattern); |
|
|
50
|
|
|
|
|
|
584
|
|
|
|
|
|
|
|
585
|
265
|
100
|
|
|
|
|
while (p < rend) { |
586
|
211
|
|
|
|
|
|
UV k = *p; |
587
|
211
|
|
|
|
|
|
int saw_backslash = k == '\\'; |
588
|
|
|
|
|
|
|
|
589
|
211
|
100
|
|
|
|
|
if (saw_backslash) { |
590
|
37
|
50
|
|
|
|
|
if (++p == rend) { |
591
|
|
|
|
|
|
|
/* Oh my, \ at the end. Is this possible? */ |
592
|
0
|
|
|
|
|
|
break; |
593
|
|
|
|
|
|
|
} |
594
|
|
|
|
|
|
|
/* Otherwise we look at the next octet */ |
595
|
37
|
|
|
|
|
|
k = *p; |
596
|
|
|
|
|
|
|
} |
597
|
|
|
|
|
|
|
|
598
|
211
|
100
|
|
|
|
|
if (/* / that was not backslashed */ |
599
|
23
|
100
|
|
|
|
|
(k == '/' && !saw_backslash) |
600
|
|
|
|
|
|
|
/* $ that was not backslashed, unless it is at the end of the regex |
601
|
|
|
|
|
|
|
or it is followed by | or it is followed by ) */ |
602
|
189
|
100
|
|
|
|
|
|| (k == '$' && !saw_backslash |
|
|
100
|
|
|
|
|
|
603
|
16
|
100
|
|
|
|
|
&& (p + 1 != rend && p[1] != '|' && p[1] != ')')) |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
604
|
|
|
|
|
|
|
/* or need to use \x{} notation. */ |
605
|
181
|
100
|
|
|
|
|
|| (do_utf8 && ! UTF8_IS_INVARIANT(k))) |
|
|
100
|
|
|
|
|
|
606
|
54
|
|
|
|
|
|
{ |
607
|
54
|
|
|
|
|
|
STRLEN to_copy = p - (U8 *) rval; |
608
|
54
|
100
|
|
|
|
|
if (to_copy) { |
609
|
|
|
|
|
|
|
/* If saw_backslash is true, this will copy the \ for us too. */ |
610
|
38
|
|
|
|
|
|
sv_catpvn(retval, rval, to_copy); |
611
|
|
|
|
|
|
|
} |
612
|
54
|
100
|
|
|
|
|
if (k == '/') { |
613
|
22
|
|
|
|
|
|
sv_catpvs(retval, "\\/"); |
614
|
22
|
|
|
|
|
|
++p; |
615
|
|
|
|
|
|
|
} |
616
|
32
|
100
|
|
|
|
|
else if (k == '$') { |
617
|
|
|
|
|
|
|
/* this approach suggested by Eirik Berg Hanssen: */ |
618
|
8
|
|
|
|
|
|
sv_catpvs(retval, "${\\q($)}"); |
619
|
8
|
|
|
|
|
|
++p; |
620
|
|
|
|
|
|
|
} |
621
|
|
|
|
|
|
|
else { |
622
|
|
|
|
|
|
|
/* If there was a \, we have copied it already, so all that is |
623
|
|
|
|
|
|
|
* left to do here is the \x{...} escaping. |
624
|
|
|
|
|
|
|
* |
625
|
|
|
|
|
|
|
* Since this is a pattern, presumably created by perl, we can |
626
|
|
|
|
|
|
|
* assume it is well-formed */ |
627
|
24
|
|
|
|
|
|
k = utf8_to_uvchr_buf(p, rend, NULL); |
628
|
24
|
|
|
|
|
|
sv_catpvf(retval, "\\x{%" UVxf "}", k); |
629
|
24
|
|
|
|
|
|
p += UTF8SKIP(p); |
630
|
|
|
|
|
|
|
} |
631
|
54
|
|
|
|
|
|
rval = (const char *) p; |
632
|
|
|
|
|
|
|
} |
633
|
|
|
|
|
|
|
else { |
634
|
157
|
|
|
|
|
|
++p; |
635
|
|
|
|
|
|
|
} |
636
|
|
|
|
|
|
|
} |
637
|
|
|
|
|
|
|
|
638
|
54
|
|
|
|
|
|
rlen = rend - (U8 *) rval; |
639
|
54
|
100
|
|
|
|
|
if (rlen) { |
640
|
47
|
|
|
|
|
|
sv_catpvn(retval, rval, rlen); |
641
|
|
|
|
|
|
|
} |
642
|
54
|
|
|
|
|
|
sv_catpvs(retval, "/"); |
643
|
|
|
|
|
|
|
|
644
|
54
|
50
|
|
|
|
|
if (sv_flags) |
645
|
54
|
|
|
|
|
|
sv_catsv(retval, sv_flags); |
646
|
54
|
|
|
|
|
|
} |
647
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
/* |
649
|
|
|
|
|
|
|
* This ought to be split into smaller functions. (it is one long function since |
650
|
|
|
|
|
|
|
* it exactly parallels the perl version, which was one long thing for |
651
|
|
|
|
|
|
|
* efficiency raisins.) Ugggh! |
652
|
|
|
|
|
|
|
*/ |
653
|
|
|
|
|
|
|
static I32 |
654
|
2607
|
|
|
|
|
|
DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv, |
655
|
|
|
|
|
|
|
AV *postav, const I32 level, SV *apad, Style *style) |
656
|
|
|
|
|
|
|
{ |
657
|
|
|
|
|
|
|
char tmpbuf[128]; |
658
|
|
|
|
|
|
|
Size_t i; |
659
|
|
|
|
|
|
|
char *c, *r, *realpack; |
660
|
|
|
|
|
|
|
UV id_buffer; |
661
|
2607
|
|
|
|
|
|
char *const id = (char *)&id_buffer; |
662
|
|
|
|
|
|
|
SV **svp; |
663
|
|
|
|
|
|
|
SV *sv, *ipad, *ival; |
664
|
2607
|
|
|
|
|
|
SV *blesspad = Nullsv; |
665
|
2607
|
|
|
|
|
|
AV *seenentry = NULL; |
666
|
|
|
|
|
|
|
char *iname; |
667
|
2607
|
|
|
|
|
|
STRLEN inamelen, idlen = 0; |
668
|
|
|
|
|
|
|
U32 realtype; |
669
|
2607
|
|
|
|
|
|
bool no_bless = 0; /* when a qr// is blessed into Regexp we dont want to bless it. |
670
|
|
|
|
|
|
|
in later perls we should actually check the classname of the |
671
|
|
|
|
|
|
|
engine. this gets tricky as it involves lexical issues that arent so |
672
|
|
|
|
|
|
|
easy to resolve */ |
673
|
2607
|
|
|
|
|
|
bool is_regex = 0; /* we are dumping a regex, we need to know this before we bless */ |
674
|
|
|
|
|
|
|
|
675
|
2607
|
50
|
|
|
|
|
if (!val) |
676
|
0
|
|
|
|
|
|
return 0; |
677
|
|
|
|
|
|
|
|
678
|
2607
|
100
|
|
|
|
|
if (style->maxrecursed) |
679
|
1
|
|
|
|
|
|
return 0; |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
/* If the output buffer has less than some arbitrary amount of space |
682
|
|
|
|
|
|
|
remaining, then enlarge it. For the test case (25M of output), |
683
|
|
|
|
|
|
|
*1.1 was slower, *2.0 was the same, so the first guess of 1.5 is |
684
|
|
|
|
|
|
|
deemed to be good enough. */ |
685
|
2606
|
50
|
|
|
|
|
if (SvTYPE(retval) >= SVt_PV && (SvLEN(retval) - SvCUR(retval)) < 42) { |
|
|
100
|
|
|
|
|
|
686
|
2147
|
|
|
|
|
|
sv_grow(retval, SvCUR(retval) * 3 / 2); |
687
|
|
|
|
|
|
|
} |
688
|
|
|
|
|
|
|
|
689
|
2606
|
|
|
|
|
|
realtype = SvTYPE(val); |
690
|
|
|
|
|
|
|
|
691
|
2606
|
50
|
|
|
|
|
if (SvGMAGICAL(val)) |
692
|
0
|
|
|
|
|
|
mg_get(val); |
693
|
2606
|
100
|
|
|
|
|
if (SvROK(val)) { |
694
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
/* If a freeze method is provided and the object has it, call |
696
|
|
|
|
|
|
|
it. Warn on errors. */ |
697
|
1080
|
100
|
|
|
|
|
if (SvOBJECT(SvRV(val)) && style->freezer && |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
698
|
75
|
|
|
|
|
|
SvPOK(style->freezer) && SvCUR(style->freezer) && |
699
|
7
|
|
|
|
|
|
gv_fetchmeth(SvSTASH(SvRV(val)), SvPVX_const(style->freezer), |
700
|
|
|
|
|
|
|
SvCUR(style->freezer), -1) != NULL) |
701
|
|
|
|
|
|
|
{ |
702
|
6
|
50
|
|
|
|
|
dSP; ENTER; SAVETMPS; PUSHMARK(sp); |
703
|
6
|
50
|
|
|
|
|
XPUSHs(val); PUTBACK; |
704
|
6
|
|
|
|
|
|
i = perl_call_method(SvPVX_const(style->freezer), G_EVAL|G_VOID|G_DISCARD); |
705
|
6
|
|
|
|
|
|
SPAGAIN; |
706
|
6
|
50
|
|
|
|
|
if (SvTRUE(ERRSV)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
707
|
1
|
50
|
|
|
|
|
warn("WARNING(Freezer method call failed): %" SVf, ERRSV); |
708
|
6
|
50
|
|
|
|
|
PUTBACK; FREETMPS; LEAVE; |
709
|
|
|
|
|
|
|
} |
710
|
|
|
|
|
|
|
|
711
|
1080
|
|
|
|
|
|
ival = SvRV(val); |
712
|
1080
|
|
|
|
|
|
realtype = SvTYPE(ival); |
713
|
1080
|
|
|
|
|
|
id_buffer = PTR2UV(ival); |
714
|
1080
|
|
|
|
|
|
idlen = sizeof(id_buffer); |
715
|
1080
|
100
|
|
|
|
|
if (SvOBJECT(ival)) |
716
|
70
|
50
|
|
|
|
|
realpack = HvNAME_get(SvSTASH(ival)); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
717
|
|
|
|
|
|
|
else |
718
|
1010
|
|
|
|
|
|
realpack = NULL; |
719
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
/* if it has a name, we need to either look it up, or keep a tab |
721
|
|
|
|
|
|
|
* on it so we know when we hit it later |
722
|
|
|
|
|
|
|
*/ |
723
|
1080
|
50
|
|
|
|
|
if (namelen) { |
724
|
1080
|
100
|
|
|
|
|
if ((svp = hv_fetch(seenhv, id, idlen, FALSE)) |
725
|
323
|
50
|
|
|
|
|
&& (sv = *svp) && SvROK(sv) && (seenentry = (AV*)SvRV(sv))) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
726
|
|
|
|
|
|
|
{ |
727
|
|
|
|
|
|
|
SV *othername; |
728
|
323
|
50
|
|
|
|
|
if ((svp = av_fetch(seenentry, 0, FALSE)) |
729
|
323
|
50
|
|
|
|
|
&& (othername = *svp)) |
730
|
|
|
|
|
|
|
{ |
731
|
411
|
100
|
|
|
|
|
if (style->purity && level > 0) { |
|
|
100
|
|
|
|
|
|
732
|
|
|
|
|
|
|
SV *postentry; |
733
|
|
|
|
|
|
|
|
734
|
88
|
100
|
|
|
|
|
if (realtype == SVt_PVHV) |
735
|
28
|
|
|
|
|
|
sv_catpvs(retval, "{}"); |
736
|
60
|
100
|
|
|
|
|
else if (realtype == SVt_PVAV) |
737
|
38
|
|
|
|
|
|
sv_catpvs(retval, "[]"); |
738
|
|
|
|
|
|
|
else |
739
|
22
|
|
|
|
|
|
sv_catpvs(retval, "do{my $o}"); |
740
|
88
|
|
|
|
|
|
postentry = newSVpvn(name, namelen); |
741
|
88
|
|
|
|
|
|
sv_catpvs(postentry, " = "); |
742
|
88
|
|
|
|
|
|
sv_catsv(postentry, othername); |
743
|
88
|
|
|
|
|
|
av_push(postav, postentry); |
744
|
|
|
|
|
|
|
} |
745
|
|
|
|
|
|
|
else { |
746
|
235
|
100
|
|
|
|
|
if (name[0] == '@' || name[0] == '%') { |
|
|
100
|
|
|
|
|
|
747
|
60
|
100
|
|
|
|
|
if ((SvPVX_const(othername))[0] == '\\' && |
|
|
50
|
|
|
|
|
|
748
|
10
|
|
|
|
|
|
(SvPVX_const(othername))[1] == name[0]) { |
749
|
10
|
|
|
|
|
|
sv_catpvn(retval, SvPVX_const(othername)+1, |
750
|
|
|
|
|
|
|
SvCUR(othername)-1); |
751
|
|
|
|
|
|
|
} |
752
|
|
|
|
|
|
|
else { |
753
|
20
|
|
|
|
|
|
sv_catpvn(retval, name, 1); |
754
|
20
|
|
|
|
|
|
sv_catpvs(retval, "{"); |
755
|
20
|
|
|
|
|
|
sv_catsv(retval, othername); |
756
|
20
|
|
|
|
|
|
sv_catpvs(retval, "}"); |
757
|
|
|
|
|
|
|
} |
758
|
|
|
|
|
|
|
} |
759
|
|
|
|
|
|
|
else |
760
|
205
|
|
|
|
|
|
sv_catsv(retval, othername); |
761
|
|
|
|
|
|
|
} |
762
|
323
|
|
|
|
|
|
return 1; |
763
|
|
|
|
|
|
|
} |
764
|
|
|
|
|
|
|
else { |
765
|
0
|
|
|
|
|
|
warn("ref name not found for 0x%" UVxf, PTR2UV(ival)); |
766
|
0
|
|
|
|
|
|
return 0; |
767
|
|
|
|
|
|
|
} |
768
|
|
|
|
|
|
|
} |
769
|
|
|
|
|
|
|
else { /* store our name and continue */ |
770
|
|
|
|
|
|
|
SV *namesv; |
771
|
757
|
100
|
|
|
|
|
if (name[0] == '@' || name[0] == '%') { |
|
|
100
|
|
|
|
|
|
772
|
35
|
|
|
|
|
|
namesv = newSVpvs("\\"); |
773
|
35
|
|
|
|
|
|
sv_catpvn(namesv, name, namelen); |
774
|
|
|
|
|
|
|
} |
775
|
722
|
100
|
|
|
|
|
else if (realtype == SVt_PVCV && name[0] == '*') { |
|
|
100
|
|
|
|
|
|
776
|
2
|
|
|
|
|
|
namesv = newSVpvs("\\"); |
777
|
2
|
|
|
|
|
|
sv_catpvn(namesv, name, namelen); |
778
|
2
|
|
|
|
|
|
(SvPVX(namesv))[1] = '&'; |
779
|
|
|
|
|
|
|
} |
780
|
|
|
|
|
|
|
else |
781
|
720
|
|
|
|
|
|
namesv = newSVpvn(name, namelen); |
782
|
757
|
|
|
|
|
|
seenentry = newAV(); |
783
|
757
|
|
|
|
|
|
av_push(seenentry, namesv); |
784
|
757
|
|
|
|
|
|
(void)SvREFCNT_inc(val); |
785
|
757
|
|
|
|
|
|
av_push(seenentry, val); |
786
|
757
|
|
|
|
|
|
(void)hv_store(seenhv, id, idlen, |
787
|
|
|
|
|
|
|
newRV_inc((SV*)seenentry), 0); |
788
|
757
|
|
|
|
|
|
SvREFCNT_dec(seenentry); |
789
|
|
|
|
|
|
|
} |
790
|
|
|
|
|
|
|
} |
791
|
|
|
|
|
|
|
/* regexps dont have to be blessed into package "Regexp" |
792
|
|
|
|
|
|
|
* they can be blessed into any package. |
793
|
|
|
|
|
|
|
*/ |
794
|
|
|
|
|
|
|
#if PERL_VERSION_LT(5,11,0) |
795
|
|
|
|
|
|
|
if (realpack && realtype == SVt_PVMG && mg_find(ival, PERL_MAGIC_qr)) |
796
|
|
|
|
|
|
|
#else |
797
|
757
|
100
|
|
|
|
|
if (realpack && realtype == SVt_REGEXP) |
|
|
100
|
|
|
|
|
|
798
|
|
|
|
|
|
|
#endif |
799
|
|
|
|
|
|
|
{ |
800
|
54
|
|
|
|
|
|
is_regex = 1; |
801
|
54
|
100
|
|
|
|
|
if (strEQ(realpack, "Regexp")) |
802
|
53
|
|
|
|
|
|
no_bless = 1; |
803
|
|
|
|
|
|
|
else |
804
|
1
|
|
|
|
|
|
no_bless = 0; |
805
|
|
|
|
|
|
|
} |
806
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
/* If purity is not set and maxdepth is set, then check depth: |
808
|
|
|
|
|
|
|
* if we have reached maximum depth, return the string |
809
|
|
|
|
|
|
|
* representation of the thing we are currently examining |
810
|
|
|
|
|
|
|
* at this depth (i.e., 'Foo=ARRAY(0xdeadbeef)'). |
811
|
|
|
|
|
|
|
*/ |
812
|
757
|
100
|
|
|
|
|
if (!style->purity && style->maxdepth > 0 && level >= style->maxdepth) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
813
|
|
|
|
|
|
|
STRLEN vallen; |
814
|
6
|
50
|
|
|
|
|
const char * const valstr = SvPV(val,vallen); |
815
|
6
|
|
|
|
|
|
sv_catpvs(retval, "'"); |
816
|
6
|
|
|
|
|
|
sv_catpvn(retval, valstr, vallen); |
817
|
6
|
|
|
|
|
|
sv_catpvs(retval, "'"); |
818
|
6
|
|
|
|
|
|
return 1; |
819
|
|
|
|
|
|
|
} |
820
|
|
|
|
|
|
|
|
821
|
751
|
100
|
|
|
|
|
if (style->maxrecurse > 0 && level >= style->maxrecurse) { |
|
|
100
|
|
|
|
|
|
822
|
4
|
|
|
|
|
|
style->maxrecursed = TRUE; |
823
|
|
|
|
|
|
|
} |
824
|
|
|
|
|
|
|
|
825
|
751
|
100
|
|
|
|
|
if (realpack && !no_bless) { /* we have a blessed ref */ |
|
|
100
|
|
|
|
|
|
826
|
|
|
|
|
|
|
STRLEN blesslen; |
827
|
17
|
50
|
|
|
|
|
const char * const blessstr = SvPV(style->bless, blesslen); |
828
|
17
|
|
|
|
|
|
sv_catpvn(retval, blessstr, blesslen); |
829
|
17
|
|
|
|
|
|
sv_catpvs(retval, "( "); |
830
|
17
|
100
|
|
|
|
|
if (style->indent >= 2) { |
831
|
15
|
|
|
|
|
|
blesspad = apad; |
832
|
15
|
|
|
|
|
|
apad = sv_2mortal(newSVsv(apad)); |
833
|
17
|
|
|
|
|
|
sv_x(aTHX_ apad, " ", 1, blesslen+2); |
834
|
|
|
|
|
|
|
} |
835
|
|
|
|
|
|
|
} |
836
|
|
|
|
|
|
|
|
837
|
751
|
|
|
|
|
|
ipad = sv_x(aTHX_ Nullsv, SvPVX_const(style->xpad), SvCUR(style->xpad), level+1); |
838
|
751
|
|
|
|
|
|
sv_2mortal(ipad); |
839
|
|
|
|
|
|
|
|
840
|
751
|
100
|
|
|
|
|
if (is_regex) { |
841
|
54
|
|
|
|
|
|
dump_regexp(aTHX_ retval, val); |
842
|
|
|
|
|
|
|
} |
843
|
697
|
100
|
|
|
|
|
else if ( |
844
|
|
|
|
|
|
|
#if PERL_VERSION_LT(5,9,0) |
845
|
|
|
|
|
|
|
realtype <= SVt_PVBM |
846
|
|
|
|
|
|
|
#else |
847
|
|
|
|
|
|
|
realtype <= SVt_PVMG |
848
|
|
|
|
|
|
|
#endif |
849
|
|
|
|
|
|
|
) { /* scalar ref */ |
850
|
79
|
|
|
|
|
|
SV * const namesv = sv_2mortal(newSVpvs("${")); |
851
|
79
|
|
|
|
|
|
sv_catpvn(namesv, name, namelen); |
852
|
79
|
|
|
|
|
|
sv_catpvs(namesv, "}"); |
853
|
79
|
50
|
|
|
|
|
if (realpack) { /* blessed */ |
854
|
0
|
|
|
|
|
|
sv_catpvs(retval, "do{\\(my $o = "); |
855
|
0
|
|
|
|
|
|
DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv, |
856
|
|
|
|
|
|
|
postav, level+1, apad, style); |
857
|
0
|
|
|
|
|
|
sv_catpvs(retval, ")}"); |
858
|
|
|
|
|
|
|
} /* plain */ |
859
|
|
|
|
|
|
|
else { |
860
|
79
|
|
|
|
|
|
sv_catpvs(retval, "\\"); |
861
|
79
|
|
|
|
|
|
DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv, |
862
|
|
|
|
|
|
|
postav, level+1, apad, style); |
863
|
|
|
|
|
|
|
} |
864
|
|
|
|
|
|
|
} |
865
|
618
|
100
|
|
|
|
|
else if (realtype == SVt_PVGV) { /* glob ref */ |
866
|
54
|
|
|
|
|
|
SV * const namesv = newSVpvs("*{"); |
867
|
54
|
|
|
|
|
|
sv_catpvn(namesv, name, namelen); |
868
|
54
|
|
|
|
|
|
sv_catpvs(namesv, "}"); |
869
|
54
|
|
|
|
|
|
sv_catpvs(retval, "\\"); |
870
|
54
|
|
|
|
|
|
DD_dump(aTHX_ ival, SvPVX_const(namesv), SvCUR(namesv), retval, seenhv, |
871
|
|
|
|
|
|
|
postav, level+1, apad, style); |
872
|
54
|
|
|
|
|
|
SvREFCNT_dec(namesv); |
873
|
|
|
|
|
|
|
} |
874
|
564
|
100
|
|
|
|
|
else if (realtype == SVt_PVAV) { |
875
|
|
|
|
|
|
|
SV *totpad; |
876
|
322
|
|
|
|
|
|
SSize_t ix = 0; |
877
|
322
|
|
|
|
|
|
const SSize_t ixmax = av_len((AV *)ival); |
878
|
|
|
|
|
|
|
|
879
|
322
|
|
|
|
|
|
SV * const ixsv = sv_2mortal(newSViv(0)); |
880
|
|
|
|
|
|
|
/* allowing for a 24 char wide array index */ |
881
|
322
|
|
|
|
|
|
New(0, iname, namelen+28, char); |
882
|
322
|
|
|
|
|
|
SAVEFREEPV(iname); |
883
|
322
|
|
|
|
|
|
(void) strlcpy(iname, name, namelen+28); |
884
|
322
|
|
|
|
|
|
inamelen = namelen; |
885
|
322
|
100
|
|
|
|
|
if (name[0] == '@') { |
886
|
24
|
|
|
|
|
|
sv_catpvs(retval, "("); |
887
|
24
|
|
|
|
|
|
iname[0] = '$'; |
888
|
|
|
|
|
|
|
} |
889
|
|
|
|
|
|
|
else { |
890
|
298
|
|
|
|
|
|
sv_catpvs(retval, "["); |
891
|
|
|
|
|
|
|
/* omit "->" in $foo{bar}->[0], but not in ${$foo}->[0] */ |
892
|
|
|
|
|
|
|
/*if (namelen > 0 |
893
|
|
|
|
|
|
|
&& name[namelen-1] != ']' && name[namelen-1] != '}' |
894
|
|
|
|
|
|
|
&& (namelen < 4 || (name[1] != '{' && name[2] != '{')))*/ |
895
|
298
|
50
|
|
|
|
|
if ((namelen > 0 |
896
|
298
|
100
|
|
|
|
|
&& name[namelen-1] != ']' && name[namelen-1] != '}') |
|
|
100
|
|
|
|
|
|
897
|
182
|
50
|
|
|
|
|
|| (namelen > 4 |
898
|
182
|
100
|
|
|
|
|
&& (name[1] == '{' |
899
|
178
|
50
|
|
|
|
|
|| (name[0] == '\\' && name[2] == '{')))) |
|
|
0
|
|
|
|
|
|
900
|
|
|
|
|
|
|
{ |
901
|
120
|
|
|
|
|
|
iname[inamelen++] = '-'; iname[inamelen++] = '>'; |
902
|
120
|
|
|
|
|
|
iname[inamelen] = '\0'; |
903
|
|
|
|
|
|
|
} |
904
|
|
|
|
|
|
|
} |
905
|
322
|
100
|
|
|
|
|
if (iname[0] == '*' && iname[inamelen-1] == '}' && inamelen >= 8 && |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
906
|
4
|
50
|
|
|
|
|
(instr(iname+inamelen-8, "{SCALAR}") || |
907
|
0
|
0
|
|
|
|
|
instr(iname+inamelen-7, "{ARRAY}") || |
908
|
0
|
|
|
|
|
|
instr(iname+inamelen-6, "{HASH}"))) { |
909
|
4
|
|
|
|
|
|
iname[inamelen++] = '-'; iname[inamelen++] = '>'; |
910
|
|
|
|
|
|
|
} |
911
|
322
|
|
|
|
|
|
iname[inamelen++] = '['; iname[inamelen] = '\0'; |
912
|
322
|
|
|
|
|
|
totpad = sv_2mortal(newSVsv(style->sep)); |
913
|
322
|
|
|
|
|
|
sv_catsv(totpad, style->pad); |
914
|
322
|
|
|
|
|
|
sv_catsv(totpad, apad); |
915
|
|
|
|
|
|
|
|
916
|
902
|
100
|
|
|
|
|
for (ix = 0; ix <= ixmax; ++ix) { |
917
|
|
|
|
|
|
|
STRLEN ilen; |
918
|
|
|
|
|
|
|
SV *elem; |
919
|
580
|
|
|
|
|
|
svp = av_fetch((AV*)ival, ix, FALSE); |
920
|
580
|
50
|
|
|
|
|
if (svp) |
921
|
580
|
|
|
|
|
|
elem = *svp; |
922
|
|
|
|
|
|
|
else |
923
|
0
|
|
|
|
|
|
elem = &PL_sv_undef; |
924
|
|
|
|
|
|
|
|
925
|
580
|
|
|
|
|
|
ilen = inamelen; |
926
|
580
|
|
|
|
|
|
sv_setiv(ixsv, ix); |
927
|
580
|
|
|
|
|
|
ilen = ilen + my_sprintf(iname+ilen, "%" IVdf, (IV)ix); |
928
|
580
|
|
|
|
|
|
iname[ilen++] = ']'; iname[ilen] = '\0'; |
929
|
580
|
100
|
|
|
|
|
if (style->indent >= 3) { |
930
|
16
|
|
|
|
|
|
sv_catsv(retval, totpad); |
931
|
16
|
|
|
|
|
|
sv_catsv(retval, ipad); |
932
|
16
|
|
|
|
|
|
sv_catpvs(retval, "#"); |
933
|
16
|
|
|
|
|
|
sv_catsv(retval, ixsv); |
934
|
|
|
|
|
|
|
} |
935
|
580
|
|
|
|
|
|
sv_catsv(retval, totpad); |
936
|
580
|
|
|
|
|
|
sv_catsv(retval, ipad); |
937
|
580
|
|
|
|
|
|
ENTER; |
938
|
580
|
|
|
|
|
|
SAVETMPS; |
939
|
580
|
|
|
|
|
|
DD_dump(aTHX_ elem, iname, ilen, retval, seenhv, postav, |
940
|
|
|
|
|
|
|
level+1, apad, style); |
941
|
580
|
100
|
|
|
|
|
FREETMPS; |
942
|
580
|
|
|
|
|
|
LEAVE; |
943
|
580
|
100
|
|
|
|
|
if (ix < ixmax || (style->trailingcomma && style->indent >= 1)) |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
944
|
375
|
|
|
|
|
|
sv_catpvs(retval, ","); |
945
|
|
|
|
|
|
|
} |
946
|
322
|
100
|
|
|
|
|
if (ixmax >= 0) { |
947
|
209
|
|
|
|
|
|
SV * const opad = sv_x(aTHX_ Nullsv, SvPVX_const(style->xpad), SvCUR(style->xpad), level); |
948
|
209
|
|
|
|
|
|
sv_catsv(retval, totpad); |
949
|
209
|
|
|
|
|
|
sv_catsv(retval, opad); |
950
|
209
|
|
|
|
|
|
SvREFCNT_dec(opad); |
951
|
|
|
|
|
|
|
} |
952
|
322
|
100
|
|
|
|
|
if (name[0] == '@') |
953
|
24
|
|
|
|
|
|
sv_catpvs(retval, ")"); |
954
|
|
|
|
|
|
|
else |
955
|
322
|
|
|
|
|
|
sv_catpvs(retval, "]"); |
956
|
|
|
|
|
|
|
} |
957
|
242
|
100
|
|
|
|
|
else if (realtype == SVt_PVHV) { |
958
|
|
|
|
|
|
|
SV *totpad, *newapad; |
959
|
|
|
|
|
|
|
SV *sname; |
960
|
231
|
|
|
|
|
|
HE *entry = NULL; |
961
|
|
|
|
|
|
|
char *key; |
962
|
|
|
|
|
|
|
SV *hval; |
963
|
231
|
|
|
|
|
|
AV *keys = NULL; |
964
|
|
|
|
|
|
|
|
965
|
231
|
|
|
|
|
|
SV * const iname = newSVpvn_flags(name, namelen, SVs_TEMP); |
966
|
231
|
100
|
|
|
|
|
if (name[0] == '%') { |
967
|
11
|
|
|
|
|
|
sv_catpvs(retval, "("); |
968
|
11
|
|
|
|
|
|
(SvPVX(iname))[0] = '$'; |
969
|
|
|
|
|
|
|
} |
970
|
|
|
|
|
|
|
else { |
971
|
220
|
|
|
|
|
|
sv_catpvs(retval, "{"); |
972
|
|
|
|
|
|
|
/* omit "->" in $foo[0]->{bar}, but not in ${$foo}->{bar} */ |
973
|
220
|
50
|
|
|
|
|
if ((namelen > 0 |
974
|
220
|
100
|
|
|
|
|
&& name[namelen-1] != ']' && name[namelen-1] != '}') |
|
|
100
|
|
|
|
|
|
975
|
104
|
50
|
|
|
|
|
|| (namelen > 4 |
976
|
104
|
100
|
|
|
|
|
&& (name[1] == '{' |
977
|
88
|
50
|
|
|
|
|
|| (name[0] == '\\' && name[2] == '{')))) |
|
|
0
|
|
|
|
|
|
978
|
|
|
|
|
|
|
{ |
979
|
132
|
|
|
|
|
|
sv_catpvs(iname, "->"); |
980
|
|
|
|
|
|
|
} |
981
|
|
|
|
|
|
|
} |
982
|
231
|
100
|
|
|
|
|
if (name[0] == '*' && name[namelen-1] == '}' && namelen >= 8 && |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
983
|
20
|
50
|
|
|
|
|
(instr(name+namelen-8, "{SCALAR}") || |
984
|
20
|
50
|
|
|
|
|
instr(name+namelen-7, "{ARRAY}") || |
985
|
20
|
|
|
|
|
|
instr(name+namelen-6, "{HASH}"))) { |
986
|
20
|
|
|
|
|
|
sv_catpvs(iname, "->"); |
987
|
|
|
|
|
|
|
} |
988
|
231
|
|
|
|
|
|
sv_catpvs(iname, "{"); |
989
|
231
|
|
|
|
|
|
totpad = sv_2mortal(newSVsv(style->sep)); |
990
|
231
|
|
|
|
|
|
sv_catsv(totpad, style->pad); |
991
|
231
|
|
|
|
|
|
sv_catsv(totpad, apad); |
992
|
|
|
|
|
|
|
|
993
|
|
|
|
|
|
|
/* If requested, get a sorted/filtered array of hash keys */ |
994
|
231
|
100
|
|
|
|
|
if (style->sortkeys) { |
995
|
116
|
100
|
|
|
|
|
if (style->sortkeys == &PL_sv_yes) { |
996
|
101
|
|
|
|
|
|
keys = newAV(); |
997
|
101
|
|
|
|
|
|
(void)hv_iterinit((HV*)ival); |
998
|
388
|
100
|
|
|
|
|
while ((entry = hv_iternext((HV*)ival))) { |
999
|
287
|
|
|
|
|
|
sv = hv_iterkeysv(entry); |
1000
|
287
|
|
|
|
|
|
(void)SvREFCNT_inc(sv); |
1001
|
287
|
|
|
|
|
|
av_push(keys, sv); |
1002
|
|
|
|
|
|
|
} |
1003
|
|
|
|
|
|
|
#ifdef USE_LOCALE_COLLATE |
1004
|
|
|
|
|
|
|
# ifdef IN_LC /* Use this if available */ |
1005
|
101
|
50
|
|
|
|
|
if (IN_LC(LC_COLLATE)) |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1006
|
|
|
|
|
|
|
# else |
1007
|
|
|
|
|
|
|
if (IN_LOCALE) |
1008
|
|
|
|
|
|
|
# endif |
1009
|
|
|
|
|
|
|
{ |
1010
|
0
|
|
|
|
|
|
sortsv(AvARRAY(keys), |
1011
|
|
|
|
|
|
|
av_len(keys)+1, |
1012
|
|
|
|
|
|
|
Perl_sv_cmp_locale); |
1013
|
|
|
|
|
|
|
} |
1014
|
|
|
|
|
|
|
else |
1015
|
|
|
|
|
|
|
#endif |
1016
|
|
|
|
|
|
|
{ |
1017
|
101
|
|
|
|
|
|
sortsv(AvARRAY(keys), |
1018
|
|
|
|
|
|
|
av_len(keys)+1, |
1019
|
|
|
|
|
|
|
Perl_sv_cmp); |
1020
|
|
|
|
|
|
|
} |
1021
|
|
|
|
|
|
|
} |
1022
|
|
|
|
|
|
|
else |
1023
|
|
|
|
|
|
|
{ |
1024
|
15
|
50
|
|
|
|
|
dSP; ENTER; SAVETMPS; PUSHMARK(sp); |
1025
|
15
|
50
|
|
|
|
|
XPUSHs(sv_2mortal(newRV_inc(ival))); PUTBACK; |
1026
|
15
|
|
|
|
|
|
i = perl_call_sv(style->sortkeys, G_SCALAR | G_EVAL); |
1027
|
15
|
|
|
|
|
|
SPAGAIN; |
1028
|
15
|
50
|
|
|
|
|
if (i) { |
1029
|
15
|
|
|
|
|
|
sv = POPs; |
1030
|
15
|
50
|
|
|
|
|
if (SvROK(sv) && (SvTYPE(SvRV(sv)) == SVt_PVAV)) |
|
|
100
|
|
|
|
|
|
1031
|
14
|
|
|
|
|
|
keys = (AV*)SvREFCNT_inc(SvRV(sv)); |
1032
|
|
|
|
|
|
|
} |
1033
|
15
|
100
|
|
|
|
|
if (! keys) |
1034
|
1
|
|
|
|
|
|
warn("Sortkeys subroutine did not return ARRAYREF\n"); |
1035
|
15
|
50
|
|
|
|
|
PUTBACK; FREETMPS; LEAVE; |
1036
|
|
|
|
|
|
|
} |
1037
|
116
|
100
|
|
|
|
|
if (keys) |
1038
|
116
|
|
|
|
|
|
sv_2mortal((SV*)keys); |
1039
|
|
|
|
|
|
|
} |
1040
|
|
|
|
|
|
|
else |
1041
|
115
|
|
|
|
|
|
(void)hv_iterinit((HV*)ival); |
1042
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
/* foreach (keys %hash) */ |
1044
|
231
|
|
|
|
|
|
for (i = 0; 1; i++) { |
1045
|
|
|
|
|
|
|
char *nkey; |
1046
|
953
|
|
|
|
|
|
char *nkey_buffer = NULL; |
1047
|
953
|
|
|
|
|
|
STRLEN nticks = 0; |
1048
|
|
|
|
|
|
|
SV* keysv; |
1049
|
|
|
|
|
|
|
STRLEN klen; |
1050
|
|
|
|
|
|
|
STRLEN keylen; |
1051
|
|
|
|
|
|
|
STRLEN nlen; |
1052
|
953
|
|
|
|
|
|
bool do_utf8 = FALSE; |
1053
|
|
|
|
|
|
|
|
1054
|
953
|
100
|
|
|
|
|
if (style->sortkeys) { |
1055
|
582
|
100
|
|
|
|
|
if (!(keys && (SSize_t)i <= av_len(keys))) break; |
|
|
100
|
|
|
|
|
|
1056
|
|
|
|
|
|
|
} else { |
1057
|
371
|
100
|
|
|
|
|
if (!(entry = hv_iternext((HV *)ival))) break; |
1058
|
|
|
|
|
|
|
} |
1059
|
|
|
|
|
|
|
|
1060
|
722
|
100
|
|
|
|
|
if (i) |
1061
|
501
|
|
|
|
|
|
sv_catpvs(retval, ","); |
1062
|
|
|
|
|
|
|
|
1063
|
722
|
100
|
|
|
|
|
if (style->sortkeys) { |
1064
|
|
|
|
|
|
|
char *key; |
1065
|
466
|
|
|
|
|
|
svp = av_fetch(keys, i, FALSE); |
1066
|
466
|
50
|
|
|
|
|
keysv = svp ? *svp : sv_newmortal(); |
1067
|
466
|
50
|
|
|
|
|
key = SvPV(keysv, keylen); |
1068
|
466
|
100
|
|
|
|
|
svp = hv_fetch((HV*)ival, key, |
1069
|
|
|
|
|
|
|
SvUTF8(keysv) ? -(I32)keylen : (I32)keylen, 0); |
1070
|
466
|
50
|
|
|
|
|
hval = svp ? *svp : sv_newmortal(); |
1071
|
|
|
|
|
|
|
} |
1072
|
|
|
|
|
|
|
else { |
1073
|
256
|
|
|
|
|
|
keysv = hv_iterkeysv(entry); |
1074
|
256
|
|
|
|
|
|
hval = hv_iterval((HV*)ival, entry); |
1075
|
|
|
|
|
|
|
} |
1076
|
|
|
|
|
|
|
|
1077
|
722
|
50
|
|
|
|
|
key = SvPV(keysv, keylen); |
1078
|
722
|
100
|
|
|
|
|
do_utf8 = DO_UTF8(keysv); |
|
|
50
|
|
|
|
|
|
1079
|
722
|
|
|
|
|
|
klen = keylen; |
1080
|
|
|
|
|
|
|
|
1081
|
722
|
|
|
|
|
|
sv_catsv(retval, totpad); |
1082
|
722
|
|
|
|
|
|
sv_catsv(retval, ipad); |
1083
|
|
|
|
|
|
|
|
1084
|
722
|
|
|
|
|
|
ENTER; |
1085
|
722
|
|
|
|
|
|
SAVETMPS; |
1086
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
/* The (very) |
1088
|
|
|
|
|
|
|
old logic was first to check utf8 flag, and if utf8 always |
1089
|
|
|
|
|
|
|
call esc_q_utf8. This caused test to break under -Mutf8, |
1090
|
|
|
|
|
|
|
because there even strings like 'c' have utf8 flag on. |
1091
|
|
|
|
|
|
|
Hence with quotekeys == 0 the XS code would still '' quote |
1092
|
|
|
|
|
|
|
them based on flags, whereas the perl code would not, |
1093
|
|
|
|
|
|
|
based on regexps. |
1094
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
The old logic checked that the string was a valid |
1096
|
|
|
|
|
|
|
perl glob name (foo::bar), which isn't safe under |
1097
|
|
|
|
|
|
|
strict, and differs from the perl code which only |
1098
|
|
|
|
|
|
|
accepts simple identifiers. |
1099
|
|
|
|
|
|
|
|
1100
|
|
|
|
|
|
|
With the fix for [perl #120384] I chose to make |
1101
|
|
|
|
|
|
|
their handling of key quoting compatible between XS |
1102
|
|
|
|
|
|
|
and perl. |
1103
|
|
|
|
|
|
|
*/ |
1104
|
722
|
100
|
|
|
|
|
if (style->quotekeys || key_needs_quote(key,keylen)) { |
|
|
100
|
|
|
|
|
|
1105
|
1060
|
100
|
|
|
|
|
if (do_utf8 || style->useqq) { |
|
|
100
|
|
|
|
|
|
1106
|
35
|
|
|
|
|
|
STRLEN ocur = SvCUR(retval); |
1107
|
35
|
|
|
|
|
|
klen = nlen = esc_q_utf8(aTHX_ retval, key, klen, do_utf8, style->useqq); |
1108
|
35
|
|
|
|
|
|
nkey = SvPVX(retval) + ocur; |
1109
|
|
|
|
|
|
|
} |
1110
|
|
|
|
|
|
|
else { |
1111
|
495
|
|
|
|
|
|
nticks = num_q(key, klen); |
1112
|
495
|
|
|
|
|
|
New(0, nkey_buffer, klen+nticks+3, char); |
1113
|
495
|
|
|
|
|
|
SAVEFREEPV(nkey_buffer); |
1114
|
495
|
|
|
|
|
|
nkey = nkey_buffer; |
1115
|
495
|
|
|
|
|
|
nkey[0] = '\''; |
1116
|
495
|
50
|
|
|
|
|
if (nticks) |
1117
|
0
|
|
|
|
|
|
klen += esc_q(nkey+1, key, klen); |
1118
|
|
|
|
|
|
|
else |
1119
|
495
|
|
|
|
|
|
(void)Copy(key, nkey+1, klen, char); |
1120
|
495
|
|
|
|
|
|
nkey[++klen] = '\''; |
1121
|
495
|
|
|
|
|
|
nkey[++klen] = '\0'; |
1122
|
495
|
|
|
|
|
|
nlen = klen; |
1123
|
495
|
|
|
|
|
|
sv_catpvn(retval, nkey, klen); |
1124
|
|
|
|
|
|
|
} |
1125
|
|
|
|
|
|
|
} |
1126
|
|
|
|
|
|
|
else { |
1127
|
192
|
|
|
|
|
|
nkey = key; |
1128
|
192
|
|
|
|
|
|
nlen = klen; |
1129
|
192
|
|
|
|
|
|
sv_catpvn(retval, nkey, klen); |
1130
|
|
|
|
|
|
|
} |
1131
|
|
|
|
|
|
|
|
1132
|
722
|
|
|
|
|
|
sname = sv_2mortal(newSVsv(iname)); |
1133
|
722
|
|
|
|
|
|
sv_catpvn(sname, nkey, nlen); |
1134
|
722
|
|
|
|
|
|
sv_catpvs(sname, "}"); |
1135
|
|
|
|
|
|
|
|
1136
|
722
|
|
|
|
|
|
sv_catsv(retval, style->pair); |
1137
|
722
|
100
|
|
|
|
|
if (style->indent >= 2) { |
1138
|
|
|
|
|
|
|
char *extra; |
1139
|
349
|
|
|
|
|
|
STRLEN elen = 0; |
1140
|
349
|
|
|
|
|
|
newapad = sv_2mortal(newSVsv(apad)); |
1141
|
349
|
|
|
|
|
|
New(0, extra, klen+4+1, char); |
1142
|
3824
|
100
|
|
|
|
|
while (elen < (klen+4)) |
1143
|
3475
|
|
|
|
|
|
extra[elen++] = ' '; |
1144
|
349
|
|
|
|
|
|
extra[elen] = '\0'; |
1145
|
349
|
|
|
|
|
|
sv_catpvn(newapad, extra, elen); |
1146
|
349
|
|
|
|
|
|
Safefree(extra); |
1147
|
|
|
|
|
|
|
} |
1148
|
|
|
|
|
|
|
else |
1149
|
373
|
|
|
|
|
|
newapad = apad; |
1150
|
|
|
|
|
|
|
|
1151
|
722
|
|
|
|
|
|
DD_dump(aTHX_ hval, SvPVX_const(sname), SvCUR(sname), retval, seenhv, |
1152
|
|
|
|
|
|
|
postav, level+1, newapad, style); |
1153
|
|
|
|
|
|
|
|
1154
|
722
|
50
|
|
|
|
|
FREETMPS; |
1155
|
722
|
|
|
|
|
|
LEAVE; |
1156
|
722
|
|
|
|
|
|
} |
1157
|
231
|
100
|
|
|
|
|
if (i) { |
1158
|
221
|
|
|
|
|
|
SV *opad = sv_x(aTHX_ Nullsv, SvPVX_const(style->xpad), |
1159
|
221
|
|
|
|
|
|
SvCUR(style->xpad), level); |
1160
|
221
|
100
|
|
|
|
|
if (style->trailingcomma && style->indent >= 1) |
|
|
100
|
|
|
|
|
|
1161
|
4
|
|
|
|
|
|
sv_catpvs(retval, ","); |
1162
|
221
|
|
|
|
|
|
sv_catsv(retval, totpad); |
1163
|
221
|
|
|
|
|
|
sv_catsv(retval, opad); |
1164
|
221
|
|
|
|
|
|
SvREFCNT_dec(opad); |
1165
|
|
|
|
|
|
|
} |
1166
|
231
|
100
|
|
|
|
|
if (name[0] == '%') |
1167
|
11
|
|
|
|
|
|
sv_catpvs(retval, ")"); |
1168
|
|
|
|
|
|
|
else |
1169
|
231
|
|
|
|
|
|
sv_catpvs(retval, "}"); |
1170
|
|
|
|
|
|
|
} |
1171
|
11
|
50
|
|
|
|
|
else if (realtype == SVt_PVCV) { |
1172
|
11
|
100
|
|
|
|
|
if (style->deparse) { |
1173
|
5
|
|
|
|
|
|
SV *deparsed = sv_2mortal(deparsed_output(aTHX_ val)); |
1174
|
5
|
|
|
|
|
|
SV *fullpad = sv_2mortal(newSVsv(style->sep)); |
1175
|
|
|
|
|
|
|
const char *p; |
1176
|
|
|
|
|
|
|
STRLEN plen; |
1177
|
|
|
|
|
|
|
I32 i; |
1178
|
|
|
|
|
|
|
|
1179
|
5
|
|
|
|
|
|
sv_catsv(fullpad, style->pad); |
1180
|
5
|
|
|
|
|
|
sv_catsv(fullpad, apad); |
1181
|
9
|
100
|
|
|
|
|
for (i = 0; i < level; i++) { |
1182
|
4
|
|
|
|
|
|
sv_catsv(fullpad, style->xpad); |
1183
|
|
|
|
|
|
|
} |
1184
|
|
|
|
|
|
|
|
1185
|
5
|
|
|
|
|
|
sv_catpvs(retval, "sub "); |
1186
|
5
|
50
|
|
|
|
|
p = SvPV(deparsed, plen); |
1187
|
28
|
50
|
|
|
|
|
while (plen > 0) { |
1188
|
23
|
|
|
|
|
|
const char *nl = (const char *) memchr(p, '\n', plen); |
1189
|
23
|
100
|
|
|
|
|
if (!nl) { |
1190
|
5
|
|
|
|
|
|
sv_catpvn(retval, p, plen); |
1191
|
5
|
|
|
|
|
|
break; |
1192
|
|
|
|
|
|
|
} |
1193
|
|
|
|
|
|
|
else { |
1194
|
18
|
|
|
|
|
|
size_t n = nl - p; |
1195
|
18
|
|
|
|
|
|
sv_catpvn(retval, p, n); |
1196
|
18
|
|
|
|
|
|
sv_catsv(retval, fullpad); |
1197
|
18
|
|
|
|
|
|
p += n + 1; |
1198
|
18
|
|
|
|
|
|
plen -= n + 1; |
1199
|
|
|
|
|
|
|
} |
1200
|
|
|
|
|
|
|
} |
1201
|
|
|
|
|
|
|
} |
1202
|
|
|
|
|
|
|
else { |
1203
|
6
|
|
|
|
|
|
sv_catpvs(retval, "sub { \"DUMMY\" }"); |
1204
|
6
|
50
|
|
|
|
|
if (style->purity) |
1205
|
11
|
|
|
|
|
|
warn("Encountered CODE ref, using dummy placeholder"); |
1206
|
|
|
|
|
|
|
} |
1207
|
|
|
|
|
|
|
} |
1208
|
|
|
|
|
|
|
else { |
1209
|
0
|
|
|
|
|
|
warn("cannot handle ref type %d", (int)realtype); |
1210
|
|
|
|
|
|
|
} |
1211
|
|
|
|
|
|
|
|
1212
|
751
|
100
|
|
|
|
|
if (realpack && !no_bless) { /* free blessed allocs */ |
|
|
100
|
|
|
|
|
|
1213
|
|
|
|
|
|
|
STRLEN plen, pticks; |
1214
|
|
|
|
|
|
|
|
1215
|
17
|
100
|
|
|
|
|
if (style->indent >= 2) { |
1216
|
15
|
|
|
|
|
|
apad = blesspad; |
1217
|
|
|
|
|
|
|
} |
1218
|
17
|
|
|
|
|
|
sv_catpvs(retval, ", '"); |
1219
|
|
|
|
|
|
|
|
1220
|
17
|
|
|
|
|
|
plen = strlen(realpack); |
1221
|
17
|
|
|
|
|
|
pticks = num_q(realpack, plen); |
1222
|
17
|
100
|
|
|
|
|
if (pticks) { /* needs escaping */ |
1223
|
|
|
|
|
|
|
char *npack; |
1224
|
2
|
|
|
|
|
|
char *npack_buffer = NULL; |
1225
|
|
|
|
|
|
|
|
1226
|
2
|
|
|
|
|
|
New(0, npack_buffer, plen+pticks+1, char); |
1227
|
2
|
|
|
|
|
|
npack = npack_buffer; |
1228
|
2
|
|
|
|
|
|
plen += esc_q(npack, realpack, plen); |
1229
|
2
|
|
|
|
|
|
npack[plen] = '\0'; |
1230
|
|
|
|
|
|
|
|
1231
|
2
|
|
|
|
|
|
sv_catpvn(retval, npack, plen); |
1232
|
2
|
|
|
|
|
|
Safefree(npack_buffer); |
1233
|
|
|
|
|
|
|
} |
1234
|
|
|
|
|
|
|
else { |
1235
|
15
|
|
|
|
|
|
sv_catpvn(retval, realpack, strlen(realpack)); |
1236
|
|
|
|
|
|
|
} |
1237
|
17
|
|
|
|
|
|
sv_catpvs(retval, "' )"); |
1238
|
17
|
50
|
|
|
|
|
if (style->toaster && SvPOK(style->toaster) && SvCUR(style->toaster)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1239
|
0
|
|
|
|
|
|
sv_catpvs(retval, "->"); |
1240
|
0
|
|
|
|
|
|
sv_catsv(retval, style->toaster); |
1241
|
751
|
|
|
|
|
|
sv_catpvs(retval, "()"); |
1242
|
|
|
|
|
|
|
} |
1243
|
|
|
|
|
|
|
} |
1244
|
|
|
|
|
|
|
} |
1245
|
|
|
|
|
|
|
else { |
1246
|
|
|
|
|
|
|
STRLEN i; |
1247
|
|
|
|
|
|
|
const MAGIC *mg; |
1248
|
|
|
|
|
|
|
|
1249
|
1526
|
50
|
|
|
|
|
if (namelen) { |
1250
|
1526
|
|
|
|
|
|
id_buffer = PTR2UV(val); |
1251
|
1526
|
|
|
|
|
|
idlen = sizeof(id_buffer); |
1252
|
1526
|
100
|
|
|
|
|
if ((svp = hv_fetch(seenhv, id, idlen, FALSE)) && |
|
|
50
|
|
|
|
|
|
1253
|
110
|
50
|
|
|
|
|
(sv = *svp) && SvROK(sv) && |
|
|
50
|
|
|
|
|
|
1254
|
110
|
|
|
|
|
|
(seenentry = (AV*)SvRV(sv))) |
1255
|
102
|
|
|
|
|
|
{ |
1256
|
|
|
|
|
|
|
SV *othername; |
1257
|
110
|
50
|
|
|
|
|
if ((svp = av_fetch(seenentry, 0, FALSE)) && (othername = *svp) |
|
|
50
|
|
|
|
|
|
1258
|
110
|
100
|
|
|
|
|
&& (svp = av_fetch(seenentry, 2, FALSE)) && *svp && SvIV(*svp) > 0) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1259
|
|
|
|
|
|
|
{ |
1260
|
8
|
|
|
|
|
|
sv_catpvs(retval, "${"); |
1261
|
8
|
|
|
|
|
|
sv_catsv(retval, othername); |
1262
|
8
|
|
|
|
|
|
sv_catpvs(retval, "}"); |
1263
|
8
|
|
|
|
|
|
return 1; |
1264
|
|
|
|
|
|
|
} |
1265
|
|
|
|
|
|
|
} |
1266
|
|
|
|
|
|
|
/* If we're allowed to keep only a sparse "seen" hash |
1267
|
|
|
|
|
|
|
* (IOW, the user does not expect it to contain everything |
1268
|
|
|
|
|
|
|
* after the dump, then only store in seen hash if the SV |
1269
|
|
|
|
|
|
|
* ref count is larger than 1. If it's 1, then we know that |
1270
|
|
|
|
|
|
|
* there is no other reference, duh. This is an optimization. |
1271
|
|
|
|
|
|
|
* Note that we'd have to check for weak-refs, too, but this is |
1272
|
|
|
|
|
|
|
* already the branch for non-refs only. */ |
1273
|
1416
|
50
|
|
|
|
|
else if (val != &PL_sv_undef && (!style->use_sparse_seen_hash || SvREFCNT(val) > 1)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1274
|
1400
|
|
|
|
|
|
SV * const namesv = newSVpvs("\\"); |
1275
|
1400
|
|
|
|
|
|
sv_catpvn(namesv, name, namelen); |
1276
|
1400
|
|
|
|
|
|
seenentry = newAV(); |
1277
|
1400
|
|
|
|
|
|
av_push(seenentry, namesv); |
1278
|
1400
|
|
|
|
|
|
av_push(seenentry, newRV_inc(val)); |
1279
|
1400
|
|
|
|
|
|
(void)hv_store(seenhv, id, idlen, newRV_inc((SV*)seenentry), 0); |
1280
|
1400
|
|
|
|
|
|
SvREFCNT_dec(seenentry); |
1281
|
|
|
|
|
|
|
} |
1282
|
|
|
|
|
|
|
} |
1283
|
|
|
|
|
|
|
|
1284
|
1518
|
100
|
|
|
|
|
if (DD_is_integer(val)) { |
1285
|
|
|
|
|
|
|
STRLEN len; |
1286
|
419
|
50
|
|
|
|
|
if (SvIsUV(val)) |
1287
|
0
|
0
|
|
|
|
|
len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%" UVuf, SvUV(val)); |
|
|
0
|
|
|
|
|
|
1288
|
|
|
|
|
|
|
else |
1289
|
419
|
50
|
|
|
|
|
len = my_snprintf(tmpbuf, sizeof(tmpbuf), "%" IVdf, SvIV(val)); |
|
|
50
|
|
|
|
|
|
1290
|
419
|
100
|
|
|
|
|
if (SvPOK(val)) { |
1291
|
|
|
|
|
|
|
/* Need to check to see if this is a string such as " 0". |
1292
|
|
|
|
|
|
|
I'm assuming from sprintf isn't going to clash with utf8. */ |
1293
|
|
|
|
|
|
|
STRLEN pvlen; |
1294
|
120
|
50
|
|
|
|
|
const char * const pv = SvPV(val, pvlen); |
1295
|
120
|
100
|
|
|
|
|
if (pvlen != len || memNE(pv, tmpbuf, len)) |
|
|
50
|
|
|
|
|
|
1296
|
|
|
|
|
|
|
goto integer_came_from_string; |
1297
|
|
|
|
|
|
|
} |
1298
|
387
|
100
|
|
|
|
|
if (len > 10) { |
1299
|
|
|
|
|
|
|
/* Looks like we're on a 64 bit system. Make it a string so that |
1300
|
|
|
|
|
|
|
if a 32 bit system reads the number it will cope better. */ |
1301
|
12
|
|
|
|
|
|
sv_catpvf(retval, "'%s'", tmpbuf); |
1302
|
|
|
|
|
|
|
} else |
1303
|
387
|
|
|
|
|
|
sv_catpvn(retval, tmpbuf, len); |
1304
|
|
|
|
|
|
|
} |
1305
|
1099
|
100
|
|
|
|
|
else if (realtype == SVt_PVGV) {/* GLOBs can end up with scribbly names */ |
1306
|
75
|
50
|
|
|
|
|
c = SvPV(val, i); |
1307
|
75
|
50
|
|
|
|
|
if(i) ++c, --i; /* just get the name */ |
1308
|
75
|
50
|
|
|
|
|
if (memBEGINs(c, i, "main::")) { |
|
|
100
|
|
|
|
|
|
1309
|
53
|
|
|
|
|
|
c += 4; |
1310
|
53
|
100
|
|
|
|
|
if (i == 6) |
1311
|
53
|
|
|
|
|
|
i = 0; else i -= 4; |
1312
|
|
|
|
|
|
|
} |
1313
|
75
|
100
|
|
|
|
|
if (globname_needs_quote(c,i)) { |
1314
|
44
|
|
|
|
|
|
sv_grow(retval, SvCUR(retval)+3); |
1315
|
44
|
|
|
|
|
|
r = SvPVX(retval)+SvCUR(retval); |
1316
|
44
|
|
|
|
|
|
r[0] = '*'; r[1] = '{'; r[2] = 0; |
1317
|
44
|
|
|
|
|
|
SvCUR_set(retval, SvCUR(retval)+2); |
1318
|
44
|
|
|
|
|
|
i = 3 + esc_q_utf8(aTHX_ retval, c, i, |
1319
|
|
|
|
|
|
|
#ifdef GvNAMEUTF8 |
1320
|
44
|
|
|
|
|
|
!!GvNAMEUTF8(val), style->useqq |
1321
|
|
|
|
|
|
|
#else |
1322
|
|
|
|
|
|
|
0, style->useqq || globname_supra_ascii(c, i) |
1323
|
|
|
|
|
|
|
#endif |
1324
|
|
|
|
|
|
|
); |
1325
|
44
|
|
|
|
|
|
sv_grow(retval, SvCUR(retval)+2); |
1326
|
44
|
|
|
|
|
|
r = SvPVX(retval)+SvCUR(retval); |
1327
|
44
|
|
|
|
|
|
r[0] = '}'; r[1] = '\0'; |
1328
|
44
|
|
|
|
|
|
SvCUR_set(retval, SvCUR(retval)+1); |
1329
|
44
|
|
|
|
|
|
r = r+1 - i; |
1330
|
|
|
|
|
|
|
} |
1331
|
|
|
|
|
|
|
else { |
1332
|
31
|
|
|
|
|
|
sv_grow(retval, SvCUR(retval)+i+2); |
1333
|
31
|
|
|
|
|
|
r = SvPVX(retval)+SvCUR(retval); |
1334
|
31
|
|
|
|
|
|
r[0] = '*'; strlcpy(r+1, c, SvLEN(retval)); |
1335
|
31
|
|
|
|
|
|
i++; |
1336
|
31
|
|
|
|
|
|
SvCUR_set(retval, SvCUR(retval)+i); |
1337
|
|
|
|
|
|
|
} |
1338
|
|
|
|
|
|
|
|
1339
|
75
|
100
|
|
|
|
|
if (style->purity) { |
1340
|
|
|
|
|
|
|
static const char* const entries[] = { "{SCALAR}", "{ARRAY}", "{HASH}" }; |
1341
|
|
|
|
|
|
|
static const STRLEN sizes[] = { 8, 7, 6 }; |
1342
|
|
|
|
|
|
|
SV *e; |
1343
|
24
|
|
|
|
|
|
SV * const nname = newSVpvs(""); |
1344
|
24
|
|
|
|
|
|
SV * const newapad = newSVpvs(""); |
1345
|
24
|
|
|
|
|
|
GV * const gv = (GV*)val; |
1346
|
|
|
|
|
|
|
I32 j; |
1347
|
|
|
|
|
|
|
|
1348
|
96
|
100
|
|
|
|
|
for (j=0; j<3; j++) { |
1349
|
72
|
100
|
|
|
|
|
e = ((j == 0) ? GvSV(gv) : (j == 1) ? (SV*)GvAV(gv) : (SV*)GvHV(gv)); |
|
|
100
|
|
|
|
|
|
1350
|
72
|
100
|
|
|
|
|
if (!e) |
1351
|
16
|
|
|
|
|
|
continue; |
1352
|
56
|
100
|
|
|
|
|
if (j == 0 && !SvOK(e)) |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1353
|
12
|
|
|
|
|
|
continue; |
1354
|
|
|
|
|
|
|
|
1355
|
|
|
|
|
|
|
{ |
1356
|
44
|
|
|
|
|
|
SV *postentry = newSVpvn(r,i); |
1357
|
|
|
|
|
|
|
|
1358
|
44
|
|
|
|
|
|
sv_setsv(nname, postentry); |
1359
|
44
|
|
|
|
|
|
sv_catpvn(nname, entries[j], sizes[j]); |
1360
|
44
|
|
|
|
|
|
sv_catpvs(postentry, " = "); |
1361
|
44
|
|
|
|
|
|
av_push(postav, postentry); |
1362
|
44
|
|
|
|
|
|
e = newRV_inc(e); |
1363
|
|
|
|
|
|
|
|
1364
|
44
|
|
|
|
|
|
SvCUR_set(newapad, 0); |
1365
|
44
|
100
|
|
|
|
|
if (style->indent >= 2) |
1366
|
6
|
|
|
|
|
|
(void)sv_x(aTHX_ newapad, " ", 1, SvCUR(postentry)); |
1367
|
|
|
|
|
|
|
|
1368
|
44
|
|
|
|
|
|
DD_dump(aTHX_ e, SvPVX_const(nname), SvCUR(nname), postentry, |
1369
|
|
|
|
|
|
|
seenhv, postav, 0, newapad, style); |
1370
|
44
|
|
|
|
|
|
SvREFCNT_dec(e); |
1371
|
|
|
|
|
|
|
} |
1372
|
|
|
|
|
|
|
} |
1373
|
|
|
|
|
|
|
|
1374
|
24
|
|
|
|
|
|
SvREFCNT_dec(newapad); |
1375
|
75
|
|
|
|
|
|
SvREFCNT_dec(nname); |
1376
|
|
|
|
|
|
|
} |
1377
|
|
|
|
|
|
|
} |
1378
|
1024
|
50
|
|
|
|
|
else if (val == &PL_sv_undef || !SvOK(val)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1379
|
12
|
|
|
|
|
|
sv_catpvs(retval, "undef"); |
1380
|
|
|
|
|
|
|
} |
1381
|
|
|
|
|
|
|
#ifdef SvVOK |
1382
|
1012
|
100
|
|
|
|
|
else if (SvMAGICAL(val) && (mg = mg_find(val, 'V'))) { |
|
|
100
|
|
|
|
|
|
1383
|
|
|
|
|
|
|
# if !defined(PL_vtbl_vstring) && PERL_VERSION_LT(5,17,0) |
1384
|
|
|
|
|
|
|
SV * const vecsv = sv_newmortal(); |
1385
|
|
|
|
|
|
|
# if PERL_VERSION_LT(5,10,0) |
1386
|
|
|
|
|
|
|
scan_vstring(mg->mg_ptr, vecsv); |
1387
|
|
|
|
|
|
|
# else |
1388
|
|
|
|
|
|
|
scan_vstring(mg->mg_ptr, mg->mg_ptr + mg->mg_len, vecsv); |
1389
|
|
|
|
|
|
|
# endif |
1390
|
|
|
|
|
|
|
if (!sv_eq(vecsv, val)) goto integer_came_from_string; |
1391
|
|
|
|
|
|
|
# endif |
1392
|
6
|
|
|
|
|
|
sv_catpvn(retval, (const char *)mg->mg_ptr, mg->mg_len); |
1393
|
|
|
|
|
|
|
} |
1394
|
|
|
|
|
|
|
#endif |
1395
|
|
|
|
|
|
|
|
1396
|
|
|
|
|
|
|
else { |
1397
|
|
|
|
|
|
|
integer_came_from_string: |
1398
|
1038
|
100
|
|
|
|
|
c = SvPV(val, i); |
1399
|
|
|
|
|
|
|
/* the pure perl and XS non-qq outputs have historically been |
1400
|
|
|
|
|
|
|
* different in this case, but for useqq, let's try to match |
1401
|
|
|
|
|
|
|
* the pure perl code. |
1402
|
|
|
|
|
|
|
* see [perl #74798] |
1403
|
|
|
|
|
|
|
*/ |
1404
|
1038
|
100
|
|
|
|
|
if (style->useqq && safe_decimal_number(c, i)) { |
|
|
100
|
|
|
|
|
|
1405
|
2
|
|
|
|
|
|
sv_catsv(retval, val); |
1406
|
|
|
|
|
|
|
} |
1407
|
1036
|
100
|
|
|
|
|
else if (DO_UTF8(val) || style->useqq) |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1408
|
65
|
100
|
|
|
|
|
i += esc_q_utf8(aTHX_ retval, c, i, DO_UTF8(val), style->useqq); |
|
|
50
|
|
|
|
|
|
1409
|
|
|
|
|
|
|
else { |
1410
|
971
|
|
|
|
|
|
sv_grow(retval, SvCUR(retval)+3+2*i); /* 3: ""\0 */ |
1411
|
971
|
|
|
|
|
|
r = SvPVX(retval) + SvCUR(retval); |
1412
|
971
|
|
|
|
|
|
r[0] = '\''; |
1413
|
971
|
|
|
|
|
|
i += esc_q(r+1, c, i); |
1414
|
971
|
|
|
|
|
|
++i; |
1415
|
971
|
|
|
|
|
|
r[i++] = '\''; |
1416
|
971
|
|
|
|
|
|
r[i] = '\0'; |
1417
|
1518
|
|
|
|
|
|
SvCUR_set(retval, SvCUR(retval)+i); |
1418
|
|
|
|
|
|
|
} |
1419
|
|
|
|
|
|
|
} |
1420
|
|
|
|
|
|
|
} |
1421
|
|
|
|
|
|
|
|
1422
|
2269
|
50
|
|
|
|
|
if (idlen) { |
1423
|
2269
|
100
|
|
|
|
|
if (style->deepcopy) |
1424
|
90
|
|
|
|
|
|
(void)hv_delete(seenhv, id, idlen, G_DISCARD); |
1425
|
2179
|
50
|
|
|
|
|
else if (namelen && seenentry) { |
|
|
100
|
|
|
|
|
|
1426
|
2163
|
|
|
|
|
|
SV *mark = *av_fetch(seenentry, 2, TRUE); |
1427
|
2163
|
|
|
|
|
|
sv_setiv(mark,1); |
1428
|
|
|
|
|
|
|
} |
1429
|
|
|
|
|
|
|
} |
1430
|
2607
|
|
|
|
|
|
return 1; |
1431
|
|
|
|
|
|
|
} |
1432
|
|
|
|
|
|
|
|
1433
|
|
|
|
|
|
|
|
1434
|
|
|
|
|
|
|
MODULE = Data::Dumper PACKAGE = Data::Dumper PREFIX = Data_Dumper_ |
1435
|
|
|
|
|
|
|
|
1436
|
|
|
|
|
|
|
# |
1437
|
|
|
|
|
|
|
# This is the exact equivalent of Dump. Well, almost. The things that are |
1438
|
|
|
|
|
|
|
# different as of now (due to Laziness): |
1439
|
|
|
|
|
|
|
# * doesn't do deparse yet.' |
1440
|
|
|
|
|
|
|
# |
1441
|
|
|
|
|
|
|
|
1442
|
|
|
|
|
|
|
void |
1443
|
|
|
|
|
|
|
Data_Dumper_Dumpxs(href, ...) |
1444
|
|
|
|
|
|
|
SV *href; |
1445
|
|
|
|
|
|
|
PROTOTYPE: $;$$ |
1446
|
|
|
|
|
|
|
PPCODE: |
1447
|
|
|
|
|
|
|
{ |
1448
|
|
|
|
|
|
|
HV *hv; |
1449
|
|
|
|
|
|
|
SV *retval, *valstr; |
1450
|
371
|
|
|
|
|
|
HV *seenhv = NULL; |
1451
|
|
|
|
|
|
|
AV *postav, *todumpav, *namesav; |
1452
|
371
|
|
|
|
|
|
I32 terse = 0; |
1453
|
|
|
|
|
|
|
SSize_t i, imax, postlen; |
1454
|
|
|
|
|
|
|
SV **svp; |
1455
|
371
|
|
|
|
|
|
SV *apad = &PL_sv_undef; |
1456
|
|
|
|
|
|
|
Style style; |
1457
|
|
|
|
|
|
|
|
1458
|
371
|
|
|
|
|
|
SV *name, *val = &PL_sv_undef, *varname = &PL_sv_undef; |
1459
|
|
|
|
|
|
|
char tmpbuf[1024]; |
1460
|
371
|
100
|
|
|
|
|
I32 gimme = GIMME_V; |
1461
|
|
|
|
|
|
|
|
1462
|
371
|
100
|
|
|
|
|
if (!SvROK(href)) { /* call new to get an object first */ |
1463
|
151
|
50
|
|
|
|
|
if (items < 2) |
1464
|
0
|
|
|
|
|
|
croak("Usage: Data::Dumper::Dumpxs(PACKAGE, VAL_ARY_REF, [NAME_ARY_REF])"); |
1465
|
|
|
|
|
|
|
|
1466
|
151
|
|
|
|
|
|
ENTER; |
1467
|
151
|
|
|
|
|
|
SAVETMPS; |
1468
|
|
|
|
|
|
|
|
1469
|
151
|
50
|
|
|
|
|
PUSHMARK(sp); |
1470
|
151
|
50
|
|
|
|
|
EXTEND(SP, 3); /* 3 == max of all branches below */ |
1471
|
151
|
|
|
|
|
|
PUSHs(href); |
1472
|
151
|
|
|
|
|
|
PUSHs(sv_2mortal(newSVsv(ST(1)))); |
1473
|
151
|
100
|
|
|
|
|
if (items >= 3) |
1474
|
54
|
|
|
|
|
|
PUSHs(sv_2mortal(newSVsv(ST(2)))); |
1475
|
151
|
|
|
|
|
|
PUTBACK; |
1476
|
151
|
|
|
|
|
|
i = perl_call_method("new", G_SCALAR); |
1477
|
151
|
|
|
|
|
|
SPAGAIN; |
1478
|
151
|
50
|
|
|
|
|
if (i) |
1479
|
151
|
|
|
|
|
|
href = newSVsv(POPs); |
1480
|
|
|
|
|
|
|
|
1481
|
151
|
|
|
|
|
|
PUTBACK; |
1482
|
151
|
50
|
|
|
|
|
FREETMPS; |
1483
|
151
|
|
|
|
|
|
LEAVE; |
1484
|
151
|
50
|
|
|
|
|
if (i) |
1485
|
151
|
|
|
|
|
|
(void)sv_2mortal(href); |
1486
|
|
|
|
|
|
|
} |
1487
|
|
|
|
|
|
|
|
1488
|
371
|
|
|
|
|
|
todumpav = namesav = NULL; |
1489
|
371
|
|
|
|
|
|
style.indent = 2; |
1490
|
371
|
|
|
|
|
|
style.quotekeys = 1; |
1491
|
371
|
|
|
|
|
|
style.maxrecurse = 1000; |
1492
|
371
|
|
|
|
|
|
style.maxrecursed = FALSE; |
1493
|
371
|
|
|
|
|
|
style.purity = style.deepcopy = style.useqq = style.maxdepth |
1494
|
371
|
|
|
|
|
|
= style.use_sparse_seen_hash = style.trailingcomma = 0; |
1495
|
371
|
|
|
|
|
|
style.pad = style.xpad = style.sep = style.pair = style.sortkeys |
1496
|
371
|
|
|
|
|
|
= style.freezer = style.toaster = style.bless = &PL_sv_undef; |
1497
|
371
|
|
|
|
|
|
seenhv = NULL; |
1498
|
371
|
|
|
|
|
|
name = sv_newmortal(); |
1499
|
|
|
|
|
|
|
|
1500
|
371
|
|
|
|
|
|
retval = newSVpvs_flags("", SVs_TEMP); |
1501
|
371
|
50
|
|
|
|
|
if (SvROK(href) |
1502
|
371
|
50
|
|
|
|
|
&& (hv = (HV*)SvRV((SV*)href)) |
1503
|
371
|
50
|
|
|
|
|
&& SvTYPE(hv) == SVt_PVHV) { |
1504
|
|
|
|
|
|
|
|
1505
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "seen", FALSE)) && SvROK(*svp)) |
|
|
50
|
|
|
|
|
|
1506
|
371
|
|
|
|
|
|
seenhv = (HV*)SvRV(*svp); |
1507
|
|
|
|
|
|
|
else |
1508
|
0
|
|
|
|
|
|
style.use_sparse_seen_hash = 1; |
1509
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "noseen", FALSE))) |
1510
|
371
|
100
|
|
|
|
|
style.use_sparse_seen_hash = (SvOK(*svp) && SvIV(*svp) != 0); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1511
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "todump", FALSE)) && SvROK(*svp)) |
|
|
50
|
|
|
|
|
|
1512
|
371
|
|
|
|
|
|
todumpav = (AV*)SvRV(*svp); |
1513
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "names", FALSE)) && SvROK(*svp)) |
|
|
50
|
|
|
|
|
|
1514
|
371
|
|
|
|
|
|
namesav = (AV*)SvRV(*svp); |
1515
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "indent", FALSE))) |
1516
|
371
|
50
|
|
|
|
|
style.indent = SvIV(*svp); |
1517
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "purity", FALSE))) |
1518
|
371
|
50
|
|
|
|
|
style.purity = SvIV(*svp); |
1519
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "terse", FALSE))) |
1520
|
371
|
50
|
|
|
|
|
terse = SvTRUE(*svp); |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1521
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "useqq", FALSE))) |
1522
|
371
|
50
|
|
|
|
|
style.useqq = SvTRUE(*svp); |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1523
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "pad", FALSE))) |
1524
|
371
|
|
|
|
|
|
style.pad = *svp; |
1525
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "xpad", FALSE))) |
1526
|
371
|
|
|
|
|
|
style.xpad = *svp; |
1527
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "apad", FALSE))) |
1528
|
371
|
|
|
|
|
|
apad = *svp; |
1529
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "sep", FALSE))) |
1530
|
371
|
|
|
|
|
|
style.sep = *svp; |
1531
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "pair", FALSE))) |
1532
|
371
|
|
|
|
|
|
style.pair = *svp; |
1533
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "varname", FALSE))) |
1534
|
371
|
|
|
|
|
|
varname = *svp; |
1535
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "freezer", FALSE))) |
1536
|
371
|
|
|
|
|
|
style.freezer = *svp; |
1537
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "toaster", FALSE))) |
1538
|
371
|
|
|
|
|
|
style.toaster = *svp; |
1539
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "deepcopy", FALSE))) |
1540
|
371
|
50
|
|
|
|
|
style.deepcopy = SvTRUE(*svp); |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1541
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "quotekeys", FALSE))) |
1542
|
371
|
50
|
|
|
|
|
style.quotekeys = SvTRUE(*svp); |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1543
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "trailingcomma", FALSE))) |
1544
|
371
|
50
|
|
|
|
|
style.trailingcomma = SvTRUE(*svp); |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1545
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "deparse", FALSE))) |
1546
|
371
|
50
|
|
|
|
|
style.deparse = SvTRUE(*svp); |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1547
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "bless", FALSE))) |
1548
|
371
|
|
|
|
|
|
style.bless = *svp; |
1549
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "maxdepth", FALSE))) |
1550
|
371
|
50
|
|
|
|
|
style.maxdepth = SvIV(*svp); |
1551
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "maxrecurse", FALSE))) |
1552
|
371
|
50
|
|
|
|
|
style.maxrecurse = SvIV(*svp); |
1553
|
371
|
50
|
|
|
|
|
if ((svp = hv_fetchs(hv, "sortkeys", FALSE))) { |
1554
|
371
|
|
|
|
|
|
SV *sv = *svp; |
1555
|
371
|
50
|
|
|
|
|
if (! SvTRUE(sv)) |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1556
|
177
|
|
|
|
|
|
style.sortkeys = NULL; |
1557
|
194
|
100
|
|
|
|
|
else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVCV) |
|
|
50
|
|
|
|
|
|
1558
|
10
|
|
|
|
|
|
style.sortkeys = sv; |
1559
|
|
|
|
|
|
|
else |
1560
|
|
|
|
|
|
|
/* flag to use sortsv() for sorting hash keys */ |
1561
|
184
|
|
|
|
|
|
style.sortkeys = &PL_sv_yes; |
1562
|
|
|
|
|
|
|
} |
1563
|
371
|
|
|
|
|
|
postav = newAV(); |
1564
|
371
|
|
|
|
|
|
sv_2mortal((SV*)postav); |
1565
|
|
|
|
|
|
|
|
1566
|
371
|
50
|
|
|
|
|
if (todumpav) |
1567
|
371
|
|
|
|
|
|
imax = av_len(todumpav); |
1568
|
|
|
|
|
|
|
else |
1569
|
0
|
|
|
|
|
|
imax = -1; |
1570
|
371
|
|
|
|
|
|
valstr = newSVpvs_flags("", SVs_TEMP); |
1571
|
1499
|
100
|
|
|
|
|
for (i = 0; i <= imax; ++i) { |
1572
|
|
|
|
|
|
|
SV *newapad; |
1573
|
|
|
|
|
|
|
|
1574
|
1128
|
|
|
|
|
|
av_clear(postav); |
1575
|
1128
|
50
|
|
|
|
|
if ((svp = av_fetch(todumpav, i, FALSE))) |
1576
|
1128
|
|
|
|
|
|
val = *svp; |
1577
|
|
|
|
|
|
|
else |
1578
|
0
|
|
|
|
|
|
val = &PL_sv_undef; |
1579
|
1128
|
50
|
|
|
|
|
if ((svp = av_fetch(namesav, i, TRUE))) { |
1580
|
1128
|
|
|
|
|
|
sv_setsv(name, *svp); |
1581
|
1128
|
100
|
|
|
|
|
if (SvOK(*svp) && !SvPOK(*svp)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1582
|
1128
|
50
|
|
|
|
|
(void)SvPV_nolen_const(name); |
1583
|
|
|
|
|
|
|
} |
1584
|
|
|
|
|
|
|
else |
1585
|
0
|
0
|
|
|
|
|
(void)SvOK_off(name); |
1586
|
|
|
|
|
|
|
|
1587
|
1128
|
100
|
|
|
|
|
if (SvPOK(name)) { |
1588
|
266
|
100
|
|
|
|
|
if ((SvPVX_const(name))[0] == '*') { |
1589
|
81
|
100
|
|
|
|
|
if (SvROK(val)) { |
1590
|
79
|
|
|
|
|
|
switch (SvTYPE(SvRV(val))) { |
1591
|
|
|
|
|
|
|
case SVt_PVAV: |
1592
|
28
|
|
|
|
|
|
(SvPVX(name))[0] = '@'; |
1593
|
28
|
|
|
|
|
|
break; |
1594
|
|
|
|
|
|
|
case SVt_PVHV: |
1595
|
37
|
|
|
|
|
|
(SvPVX(name))[0] = '%'; |
1596
|
37
|
|
|
|
|
|
break; |
1597
|
|
|
|
|
|
|
case SVt_PVCV: |
1598
|
4
|
|
|
|
|
|
(SvPVX(name))[0] = '*'; |
1599
|
4
|
|
|
|
|
|
break; |
1600
|
|
|
|
|
|
|
default: |
1601
|
10
|
|
|
|
|
|
(SvPVX(name))[0] = '$'; |
1602
|
79
|
|
|
|
|
|
break; |
1603
|
|
|
|
|
|
|
} |
1604
|
|
|
|
|
|
|
} |
1605
|
|
|
|
|
|
|
else |
1606
|
81
|
|
|
|
|
|
(SvPVX(name))[0] = '$'; |
1607
|
|
|
|
|
|
|
} |
1608
|
185
|
100
|
|
|
|
|
else if ((SvPVX_const(name))[0] != '$') |
1609
|
266
|
|
|
|
|
|
sv_insert(name, 0, 0, "$", 1); |
1610
|
|
|
|
|
|
|
} |
1611
|
|
|
|
|
|
|
else { |
1612
|
|
|
|
|
|
|
STRLEN nchars; |
1613
|
862
|
|
|
|
|
|
sv_setpvs(name, "$"); |
1614
|
862
|
|
|
|
|
|
sv_catsv(name, varname); |
1615
|
862
|
50
|
|
|
|
|
nchars = my_snprintf(tmpbuf, sizeof(tmpbuf), "%" IVdf, |
1616
|
|
|
|
|
|
|
(IV)(i+1)); |
1617
|
862
|
|
|
|
|
|
sv_catpvn(name, tmpbuf, nchars); |
1618
|
|
|
|
|
|
|
} |
1619
|
|
|
|
|
|
|
|
1620
|
1374
|
100
|
|
|
|
|
if (style.indent >= 2 && !terse) { |
|
|
100
|
|
|
|
|
|
1621
|
246
|
|
|
|
|
|
SV * const tmpsv = sv_x(aTHX_ NULL, " ", 1, SvCUR(name)+3); |
1622
|
246
|
|
|
|
|
|
newapad = sv_2mortal(newSVsv(apad)); |
1623
|
246
|
|
|
|
|
|
sv_catsv(newapad, tmpsv); |
1624
|
246
|
|
|
|
|
|
SvREFCNT_dec(tmpsv); |
1625
|
|
|
|
|
|
|
} |
1626
|
|
|
|
|
|
|
else |
1627
|
882
|
|
|
|
|
|
newapad = apad; |
1628
|
|
|
|
|
|
|
|
1629
|
1128
|
|
|
|
|
|
ENTER; |
1630
|
1128
|
|
|
|
|
|
SAVETMPS; |
1631
|
1128
|
|
|
|
|
|
PUTBACK; |
1632
|
1128
|
|
|
|
|
|
DD_dump(aTHX_ val, SvPVX_const(name), SvCUR(name), valstr, seenhv, |
1633
|
|
|
|
|
|
|
postav, 0, newapad, &style); |
1634
|
1128
|
|
|
|
|
|
SPAGAIN; |
1635
|
1128
|
100
|
|
|
|
|
FREETMPS; |
1636
|
1128
|
|
|
|
|
|
LEAVE; |
1637
|
|
|
|
|
|
|
|
1638
|
1128
|
|
|
|
|
|
postlen = av_len(postav); |
1639
|
1128
|
100
|
|
|
|
|
if (postlen >= 0 || !terse) { |
|
|
100
|
|
|
|
|
|
1640
|
1119
|
|
|
|
|
|
sv_insert(valstr, 0, 0, " = ", 3); |
1641
|
1119
|
|
|
|
|
|
sv_insert(valstr, 0, 0, SvPVX_const(name), SvCUR(name)); |
1642
|
1119
|
|
|
|
|
|
sv_catpvs(valstr, ";"); |
1643
|
|
|
|
|
|
|
} |
1644
|
1128
|
|
|
|
|
|
sv_catsv(retval, style.pad); |
1645
|
1128
|
|
|
|
|
|
sv_catsv(retval, valstr); |
1646
|
1128
|
|
|
|
|
|
sv_catsv(retval, style.sep); |
1647
|
1128
|
100
|
|
|
|
|
if (postlen >= 0) { |
1648
|
|
|
|
|
|
|
SSize_t i; |
1649
|
36
|
|
|
|
|
|
sv_catsv(retval, style.pad); |
1650
|
168
|
100
|
|
|
|
|
for (i = 0; i <= postlen; ++i) { |
1651
|
|
|
|
|
|
|
SV *elem; |
1652
|
132
|
|
|
|
|
|
svp = av_fetch(postav, i, FALSE); |
1653
|
132
|
50
|
|
|
|
|
if (svp && (elem = *svp)) { |
|
|
50
|
|
|
|
|
|
1654
|
132
|
|
|
|
|
|
sv_catsv(retval, elem); |
1655
|
132
|
100
|
|
|
|
|
if (i < postlen) { |
1656
|
96
|
|
|
|
|
|
sv_catpvs(retval, ";"); |
1657
|
96
|
|
|
|
|
|
sv_catsv(retval, style.sep); |
1658
|
96
|
|
|
|
|
|
sv_catsv(retval, style.pad); |
1659
|
|
|
|
|
|
|
} |
1660
|
|
|
|
|
|
|
} |
1661
|
|
|
|
|
|
|
} |
1662
|
36
|
|
|
|
|
|
sv_catpvs(retval, ";"); |
1663
|
36
|
|
|
|
|
|
sv_catsv(retval, style.sep); |
1664
|
|
|
|
|
|
|
} |
1665
|
1128
|
|
|
|
|
|
SvPVCLEAR(valstr); |
1666
|
1128
|
100
|
|
|
|
|
if (gimme == G_ARRAY) { |
1667
|
241
|
50
|
|
|
|
|
XPUSHs(retval); |
1668
|
241
|
100
|
|
|
|
|
if (i < imax) /* not the last time thro ? */ |
1669
|
79
|
|
|
|
|
|
retval = newSVpvs_flags("", SVs_TEMP); |
1670
|
|
|
|
|
|
|
} |
1671
|
|
|
|
|
|
|
} |
1672
|
|
|
|
|
|
|
|
1673
|
|
|
|
|
|
|
/* we defer croaking until here so that temporary SVs and |
1674
|
|
|
|
|
|
|
* buffers won't be leaked */ |
1675
|
371
|
100
|
|
|
|
|
if (style.maxrecursed) |
1676
|
4
|
|
|
|
|
|
croak("Recursion limit of %" IVdf " exceeded", |
1677
|
|
|
|
|
|
|
style.maxrecurse); |
1678
|
|
|
|
|
|
|
|
1679
|
|
|
|
|
|
|
} |
1680
|
|
|
|
|
|
|
else |
1681
|
0
|
|
|
|
|
|
croak("Call to new() method failed to return HASH ref"); |
1682
|
367
|
100
|
|
|
|
|
if (gimme != G_ARRAY) |
1683
|
205
|
50
|
|
|
|
|
XPUSHs(retval); |
1684
|
|
|
|
|
|
|
} |
1685
|
|
|
|
|
|
|
|
1686
|
|
|
|
|
|
|
SV * |
1687
|
|
|
|
|
|
|
Data_Dumper__vstring(sv) |
1688
|
|
|
|
|
|
|
SV *sv; |
1689
|
|
|
|
|
|
|
PROTOTYPE: $ |
1690
|
|
|
|
|
|
|
CODE: |
1691
|
|
|
|
|
|
|
{ |
1692
|
|
|
|
|
|
|
#ifdef SvVOK |
1693
|
|
|
|
|
|
|
const MAGIC *mg; |
1694
|
1711
|
|
|
|
|
|
RETVAL = |
1695
|
6
|
50
|
|
|
|
|
SvMAGICAL(sv) && (mg = mg_find(sv, 'V')) |
1696
|
6
|
|
|
|
|
|
? newSVpvn((const char *)mg->mg_ptr, mg->mg_len) |
1697
|
1717
|
100
|
|
|
|
|
: &PL_sv_undef; |
1698
|
|
|
|
|
|
|
#else |
1699
|
|
|
|
|
|
|
RETVAL = &PL_sv_undef; |
1700
|
|
|
|
|
|
|
#endif |
1701
|
|
|
|
|
|
|
} |
1702
|
|
|
|
|
|
|
OUTPUT: RETVAL |