| 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 |