line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
/* Copyright (c) 2007-2023 H.Merijn Brand. All rights reserved. |
2
|
|
|
|
|
|
|
* Copyright (c) 1998-2001 Jochen Wiedmann. All rights reserved. |
3
|
|
|
|
|
|
|
* This program is free software; you can redistribute it and/or |
4
|
|
|
|
|
|
|
* modify it under the same terms as Perl itself. |
5
|
|
|
|
|
|
|
*/ |
6
|
|
|
|
|
|
|
#define PERL_NO_GET_CONTEXT |
7
|
|
|
|
|
|
|
#include |
8
|
|
|
|
|
|
|
#include |
9
|
|
|
|
|
|
|
#include |
10
|
|
|
|
|
|
|
#define DPPP_PL_parser_NO_DUMMY |
11
|
|
|
|
|
|
|
#define NEED_utf8_to_uvchr_buf |
12
|
|
|
|
|
|
|
#define NEED_my_snprintf |
13
|
|
|
|
|
|
|
#define NEED_pv_escape |
14
|
|
|
|
|
|
|
#define NEED_pv_pretty |
15
|
|
|
|
|
|
|
#ifndef PERLIO_F_UTF8 |
16
|
|
|
|
|
|
|
# define PERLIO_F_UTF8 0x00008000 |
17
|
|
|
|
|
|
|
# endif |
18
|
|
|
|
|
|
|
#ifndef MAXINT |
19
|
|
|
|
|
|
|
# define MAXINT ((int)(~(unsigned)0 >> 1)) |
20
|
|
|
|
|
|
|
# endif |
21
|
|
|
|
|
|
|
#include "ppport.h" |
22
|
|
|
|
|
|
|
#define is_utf8_sv(s) is_utf8_string ((U8 *)SvPV_nolen (s), SvCUR (s)) |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
#define MAINT_DEBUG 0 |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
#define BUFFER_SIZE 1024 |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
#define CSV_XS_TYPE_WARN 1 |
29
|
|
|
|
|
|
|
#define CSV_XS_TYPE_PV 0 |
30
|
|
|
|
|
|
|
#define CSV_XS_TYPE_IV 1 |
31
|
|
|
|
|
|
|
#define CSV_XS_TYPE_NV 2 |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
/* maximum length for EOL, SEP, and QUOTE - keep in sync with .pm */ |
34
|
|
|
|
|
|
|
#define MAX_ATTR_LEN 16 |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
#define CSV_FLAGS_QUO 0x0001 |
37
|
|
|
|
|
|
|
#define CSV_FLAGS_BIN 0x0002 |
38
|
|
|
|
|
|
|
#define CSV_FLAGS_EIF 0x0004 |
39
|
|
|
|
|
|
|
#define CSV_FLAGS_MIS 0x0010 |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
#define HOOK_ERROR 0x0001 |
42
|
|
|
|
|
|
|
#define HOOK_AFTER_PARSE 0x0002 |
43
|
|
|
|
|
|
|
#define HOOK_BEFORE_PRINT 0x0004 |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
#ifdef __THW_370__ |
46
|
|
|
|
|
|
|
/* EBCDIC on os390 z/OS: IS_EBCDIC reads better than __THW_370__ */ |
47
|
|
|
|
|
|
|
#define IS_EBCDIC |
48
|
|
|
|
|
|
|
#endif |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
#define CH_TAB '\t' |
51
|
|
|
|
|
|
|
#define CH_NL '\n' |
52
|
|
|
|
|
|
|
#define CH_CR '\r' |
53
|
|
|
|
|
|
|
#define CH_SPACE ' ' |
54
|
|
|
|
|
|
|
#define CH_QUO '"' |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
#ifdef IS_EBCDIC |
57
|
|
|
|
|
|
|
#define CH_DEL '\007' |
58
|
|
|
|
|
|
|
static unsigned char ec, ebcdic2ascii[256] = { |
59
|
|
|
|
|
|
|
0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f, |
60
|
|
|
|
|
|
|
0x97, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
61
|
|
|
|
|
|
|
0x10, 0x11, 0x12, 0x13, 0x9d, 0x0a, 0x08, 0x87, |
62
|
|
|
|
|
|
|
0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d, 0x1e, 0x1f, |
63
|
|
|
|
|
|
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1b, |
64
|
|
|
|
|
|
|
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, |
65
|
|
|
|
|
|
|
0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, |
66
|
|
|
|
|
|
|
0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, |
67
|
|
|
|
|
|
|
0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, |
68
|
|
|
|
|
|
|
0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, |
69
|
|
|
|
|
|
|
0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, |
70
|
|
|
|
|
|
|
0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, |
71
|
|
|
|
|
|
|
0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, |
72
|
|
|
|
|
|
|
0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, |
73
|
|
|
|
|
|
|
0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, |
74
|
|
|
|
|
|
|
0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, |
75
|
|
|
|
|
|
|
0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, |
76
|
|
|
|
|
|
|
0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, |
77
|
|
|
|
|
|
|
0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, |
78
|
|
|
|
|
|
|
0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, |
79
|
|
|
|
|
|
|
0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, |
80
|
|
|
|
|
|
|
0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, |
81
|
|
|
|
|
|
|
0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, |
82
|
|
|
|
|
|
|
0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7, |
83
|
|
|
|
|
|
|
0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, |
84
|
|
|
|
|
|
|
/* v this 0xa0 really should be 0xad. Needed for UTF = binary */ |
85
|
|
|
|
|
|
|
0x48, 0x49, 0xa0, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, |
86
|
|
|
|
|
|
|
0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, |
87
|
|
|
|
|
|
|
0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, |
88
|
|
|
|
|
|
|
0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, |
89
|
|
|
|
|
|
|
0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, |
90
|
|
|
|
|
|
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, |
91
|
|
|
|
|
|
|
0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f |
92
|
|
|
|
|
|
|
}; |
93
|
|
|
|
|
|
|
#define is_csv_binary(ch) ((((ec = ebcdic2ascii[ch]) < 0x20 || ec >= 0x7f) && ch != CH_TAB) || ch == EOF) |
94
|
|
|
|
|
|
|
#else |
95
|
|
|
|
|
|
|
#define CH_DEL '\177' |
96
|
|
|
|
|
|
|
#define is_csv_binary(ch) ((ch < CH_SPACE || ch >= CH_DEL) && ch != CH_TAB) |
97
|
|
|
|
|
|
|
#endif |
98
|
|
|
|
|
|
|
#define CH_EOLX 1215 |
99
|
|
|
|
|
|
|
#define CH_EOL *csv->eol |
100
|
|
|
|
|
|
|
#define CH_SEPX 8888 |
101
|
|
|
|
|
|
|
#define CH_SEP *csv->sep |
102
|
|
|
|
|
|
|
#define CH_QUOTEX 8889 |
103
|
|
|
|
|
|
|
#define CH_QUOTE *csv->quo |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
#define useIO_EOF 0x10 |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
#define unless(expr) if (!(expr)) |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
#define _is_reftype(f,x) \ |
110
|
|
|
|
|
|
|
(f && ((SvGMAGICAL (f) && mg_get (f)) || 1) && SvROK (f) && SvTYPE (SvRV (f)) == x) |
111
|
|
|
|
|
|
|
#define _is_arrayref(f) _is_reftype (f, SVt_PVAV) |
112
|
|
|
|
|
|
|
#define _is_hashref(f) _is_reftype (f, SVt_PVHV) |
113
|
|
|
|
|
|
|
#define _is_coderef(f) _is_reftype (f, SVt_PVCV) |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
#define SvSetUndef(sv) sv_setpvn (sv, NULL, 0) |
116
|
|
|
|
|
|
|
#define SvSetEmpty(sv) sv_setpvn_mg (sv, "", 0) |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
#define CSV_XS_SELF \ |
119
|
|
|
|
|
|
|
if (!self || !SvOK (self) || !SvROK (self) || \ |
120
|
|
|
|
|
|
|
SvTYPE (SvRV (self)) != SVt_PVHV) \ |
121
|
|
|
|
|
|
|
croak ("self is not a hash ref"); \ |
122
|
|
|
|
|
|
|
hv = (HV *)SvRV (self) |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
/* Keep in sync with .pm! */ |
125
|
|
|
|
|
|
|
#define CACHE_ID_quote_char 0 |
126
|
|
|
|
|
|
|
#define CACHE_ID_escape_char 1 |
127
|
|
|
|
|
|
|
#define CACHE_ID_sep_char 2 |
128
|
|
|
|
|
|
|
#define CACHE_ID_binary 3 |
129
|
|
|
|
|
|
|
#define CACHE_ID_keep_meta_info 4 |
130
|
|
|
|
|
|
|
#define CACHE_ID_always_quote 5 |
131
|
|
|
|
|
|
|
#define CACHE_ID_allow_loose_quotes 6 |
132
|
|
|
|
|
|
|
#define CACHE_ID_allow_loose_escapes 7 |
133
|
|
|
|
|
|
|
#define CACHE_ID_allow_unquoted_escape 8 |
134
|
|
|
|
|
|
|
#define CACHE_ID_allow_whitespace 9 |
135
|
|
|
|
|
|
|
#define CACHE_ID_blank_is_undef 10 |
136
|
|
|
|
|
|
|
#define CACHE_ID_sep 39 |
137
|
|
|
|
|
|
|
#define CACHE_ID_sep_len 38 |
138
|
|
|
|
|
|
|
#define CACHE_ID_eol 11 |
139
|
|
|
|
|
|
|
#define CACHE_ID_eol_len 12 |
140
|
|
|
|
|
|
|
#define CACHE_ID_eol_is_cr 13 |
141
|
|
|
|
|
|
|
#define CACHE_ID_quo 15 |
142
|
|
|
|
|
|
|
#define CACHE_ID_quo_len 16 |
143
|
|
|
|
|
|
|
#define CACHE_ID_verbatim 22 |
144
|
|
|
|
|
|
|
#define CACHE_ID_empty_is_undef 23 |
145
|
|
|
|
|
|
|
#define CACHE_ID_auto_diag 24 |
146
|
|
|
|
|
|
|
#define CACHE_ID_quote_space 25 |
147
|
|
|
|
|
|
|
#define CACHE_ID_quote_empty 37 |
148
|
|
|
|
|
|
|
#define CACHE_ID__is_bound 26 |
149
|
|
|
|
|
|
|
#define CACHE_ID__has_ahead 30 |
150
|
|
|
|
|
|
|
#define CACHE_ID_escape_null 31 |
151
|
|
|
|
|
|
|
#define CACHE_ID_quote_binary 32 |
152
|
|
|
|
|
|
|
#define CACHE_ID_diag_verbose 33 |
153
|
|
|
|
|
|
|
#define CACHE_ID_has_error_input 34 |
154
|
|
|
|
|
|
|
#define CACHE_ID_decode_utf8 35 |
155
|
|
|
|
|
|
|
#define CACHE_ID__has_hooks 36 |
156
|
|
|
|
|
|
|
#define CACHE_ID_formula 38 |
157
|
|
|
|
|
|
|
#define CACHE_ID_strict 42 |
158
|
|
|
|
|
|
|
#define CACHE_ID_skip_empty_rows 43 |
159
|
|
|
|
|
|
|
#define CACHE_ID_undef_str 46 |
160
|
|
|
|
|
|
|
#define CACHE_ID_comment_str 54 |
161
|
|
|
|
|
|
|
#define CACHE_ID_types 62 |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
#define byte unsigned char |
164
|
|
|
|
|
|
|
#define ulng unsigned long |
165
|
|
|
|
|
|
|
typedef struct { |
166
|
|
|
|
|
|
|
byte quote_char; |
167
|
|
|
|
|
|
|
byte escape_char; |
168
|
|
|
|
|
|
|
byte fld_idx; |
169
|
|
|
|
|
|
|
byte binary; |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
byte keep_meta_info; |
172
|
|
|
|
|
|
|
byte always_quote; |
173
|
|
|
|
|
|
|
byte useIO; /* Also used to indicate EOF */ |
174
|
|
|
|
|
|
|
byte eol_is_cr; |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
byte allow_loose_quotes; |
177
|
|
|
|
|
|
|
byte allow_loose_escapes; |
178
|
|
|
|
|
|
|
byte allow_unquoted_escape; |
179
|
|
|
|
|
|
|
byte allow_whitespace; |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
byte blank_is_undef; |
182
|
|
|
|
|
|
|
byte empty_is_undef; |
183
|
|
|
|
|
|
|
byte verbatim; |
184
|
|
|
|
|
|
|
byte auto_diag; |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
byte quote_space; |
187
|
|
|
|
|
|
|
byte escape_null; |
188
|
|
|
|
|
|
|
byte quote_binary; |
189
|
|
|
|
|
|
|
byte first_safe_char; |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
byte diag_verbose; |
192
|
|
|
|
|
|
|
byte has_error_input; |
193
|
|
|
|
|
|
|
byte decode_utf8; |
194
|
|
|
|
|
|
|
byte has_hooks; |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
byte quote_empty; |
197
|
|
|
|
|
|
|
byte formula; |
198
|
|
|
|
|
|
|
byte utf8; |
199
|
|
|
|
|
|
|
byte has_ahead; |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
byte eolx; |
202
|
|
|
|
|
|
|
byte strict; |
203
|
|
|
|
|
|
|
short strict_n; |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
byte skip_empty_rows; |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
long is_bound; |
208
|
|
|
|
|
|
|
ulng recno; |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
byte * cache; |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
SV * pself; /* PL_self, for error_diag */ |
213
|
|
|
|
|
|
|
HV * self; |
214
|
|
|
|
|
|
|
SV * bound; |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
char * types; |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
byte eol_len; |
219
|
|
|
|
|
|
|
byte sep_len; |
220
|
|
|
|
|
|
|
byte quo_len; |
221
|
|
|
|
|
|
|
byte types_len; |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
char * bptr; |
224
|
|
|
|
|
|
|
SV * tmp; |
225
|
|
|
|
|
|
|
byte undef_flg; |
226
|
|
|
|
|
|
|
byte * undef_str; |
227
|
|
|
|
|
|
|
byte * comment_str; |
228
|
|
|
|
|
|
|
int eol_pos; |
229
|
|
|
|
|
|
|
STRLEN size; |
230
|
|
|
|
|
|
|
STRLEN used; |
231
|
|
|
|
|
|
|
byte eol[MAX_ATTR_LEN]; |
232
|
|
|
|
|
|
|
byte sep[MAX_ATTR_LEN]; |
233
|
|
|
|
|
|
|
byte quo[MAX_ATTR_LEN]; |
234
|
|
|
|
|
|
|
char buffer[BUFFER_SIZE]; |
235
|
|
|
|
|
|
|
} csv_t; |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
#define bool_opt_def(o,d) \ |
238
|
|
|
|
|
|
|
(((svp = hv_fetchs (self, o, FALSE)) && *svp) ? SvTRUE (*svp) : d) |
239
|
|
|
|
|
|
|
#define bool_opt(o) bool_opt_def (o, 0) |
240
|
|
|
|
|
|
|
#define num_opt_def(o,d) \ |
241
|
|
|
|
|
|
|
(((svp = hv_fetchs (self, o, FALSE)) && *svp) ? SvIV (*svp) : d) |
242
|
|
|
|
|
|
|
#define num_opt(o) num_opt_def (o, 0) |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
typedef struct { |
245
|
|
|
|
|
|
|
int xs_errno; |
246
|
|
|
|
|
|
|
char *xs_errstr; |
247
|
|
|
|
|
|
|
} xs_error_t; |
248
|
|
|
|
|
|
|
static const xs_error_t xs_errors[] = { |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
/* Generic errors */ |
251
|
|
|
|
|
|
|
{ 1000, "INI - constructor failed" }, |
252
|
|
|
|
|
|
|
{ 1001, "INI - sep_char is equal to quote_char or escape_char" }, |
253
|
|
|
|
|
|
|
{ 1002, "INI - allow_whitespace with escape_char or quote_char SP or TAB" }, |
254
|
|
|
|
|
|
|
{ 1003, "INI - \\r or \\n in main attr not allowed" }, |
255
|
|
|
|
|
|
|
{ 1004, "INI - callbacks should be undef or a hashref" }, |
256
|
|
|
|
|
|
|
{ 1005, "INI - EOL too long" }, |
257
|
|
|
|
|
|
|
{ 1006, "INI - SEP too long" }, |
258
|
|
|
|
|
|
|
{ 1007, "INI - QUOTE too long" }, |
259
|
|
|
|
|
|
|
{ 1008, "INI - SEP undefined" }, |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
{ 1010, "INI - the header is empty" }, |
262
|
|
|
|
|
|
|
{ 1011, "INI - the header contains more than one valid separator" }, |
263
|
|
|
|
|
|
|
{ 1012, "INI - the header contains an empty field" }, |
264
|
|
|
|
|
|
|
{ 1013, "INI - the header contains nun-unique fields" }, |
265
|
|
|
|
|
|
|
{ 1014, "INI - header called on undefined stream" }, |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
/* Syntax errors */ |
268
|
|
|
|
|
|
|
{ 1500, "PRM - Invalid/unsupported argument(s)" }, |
269
|
|
|
|
|
|
|
{ 1501, "PRM - The key attribute is passed as an unsupported type" }, |
270
|
|
|
|
|
|
|
{ 1502, "PRM - The value attribute is passed without the key attribute" }, |
271
|
|
|
|
|
|
|
{ 1503, "PRM - The value attribute is passed as an unsupported type" }, |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
/* Parse errors */ |
274
|
|
|
|
|
|
|
{ 2010, "ECR - QUO char inside quotes followed by CR not part of EOL" }, |
275
|
|
|
|
|
|
|
{ 2011, "ECR - Characters after end of quoted field" }, |
276
|
|
|
|
|
|
|
{ 2012, "EOF - End of data in parsing input stream" }, |
277
|
|
|
|
|
|
|
{ 2013, "ESP - Specification error for fragments RFC7111" }, |
278
|
|
|
|
|
|
|
{ 2014, "ENF - Inconsistent number of fields" }, |
279
|
|
|
|
|
|
|
{ 2015, "ERW - Empty row" }, |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
/* EIQ - Error Inside Quotes */ |
282
|
|
|
|
|
|
|
{ 2021, "EIQ - NL char inside quotes, binary off" }, |
283
|
|
|
|
|
|
|
{ 2022, "EIQ - CR char inside quotes, binary off" }, |
284
|
|
|
|
|
|
|
{ 2023, "EIQ - QUO character not allowed" }, |
285
|
|
|
|
|
|
|
{ 2024, "EIQ - EOF cannot be escaped, not even inside quotes" }, |
286
|
|
|
|
|
|
|
{ 2025, "EIQ - Loose unescaped escape" }, |
287
|
|
|
|
|
|
|
{ 2026, "EIQ - Binary character inside quoted field, binary off" }, |
288
|
|
|
|
|
|
|
{ 2027, "EIQ - Quoted field not terminated" }, |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
/* EIF - Error Inside Field */ |
291
|
|
|
|
|
|
|
{ 2030, "EIF - NL char inside unquoted verbatim, binary off" }, |
292
|
|
|
|
|
|
|
{ 2031, "EIF - CR char is first char of field, not part of EOL" }, |
293
|
|
|
|
|
|
|
{ 2032, "EIF - CR char inside unquoted, not part of EOL" }, |
294
|
|
|
|
|
|
|
{ 2034, "EIF - Loose unescaped quote" }, |
295
|
|
|
|
|
|
|
{ 2035, "EIF - Escaped EOF in unquoted field" }, |
296
|
|
|
|
|
|
|
{ 2036, "EIF - ESC error" }, |
297
|
|
|
|
|
|
|
{ 2037, "EIF - Binary character in unquoted field, binary off" }, |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
/* Combine errors */ |
300
|
|
|
|
|
|
|
{ 2110, "ECB - Binary character in Combine, binary off" }, |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
/* IO errors */ |
303
|
|
|
|
|
|
|
{ 2200, "EIO - print to IO failed. See errno" }, |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
/* Hash-Ref errors */ |
306
|
|
|
|
|
|
|
{ 3001, "EHR - Unsupported syntax for column_names ()" }, |
307
|
|
|
|
|
|
|
{ 3002, "EHR - getline_hr () called before column_names ()" }, |
308
|
|
|
|
|
|
|
{ 3003, "EHR - bind_columns () and column_names () fields count mismatch" }, |
309
|
|
|
|
|
|
|
{ 3004, "EHR - bind_columns () only accepts refs to scalars" }, |
310
|
|
|
|
|
|
|
{ 3006, "EHR - bind_columns () did not pass enough refs for parsed fields" }, |
311
|
|
|
|
|
|
|
{ 3007, "EHR - bind_columns needs refs to writable scalars" }, |
312
|
|
|
|
|
|
|
{ 3008, "EHR - unexpected error in bound fields" }, |
313
|
|
|
|
|
|
|
{ 3009, "EHR - print_hr () called before column_names ()" }, |
314
|
|
|
|
|
|
|
{ 3010, "EHR - print_hr () called with invalid arguments" }, |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
{ 4001, "PRM - The key does not exist as field in the data" }, |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
{ 5001, "PRM - The result does not match the output to append to" }, |
319
|
|
|
|
|
|
|
{ 5002, "PRM - Unsupported output" }, |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
{ 0, "" }, |
322
|
|
|
|
|
|
|
}; |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
static int last_error = 0; |
325
|
|
|
|
|
|
|
static SV *m_getline, *m_print; |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
#define is_EOL(c) (c == CH_EOLX) |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
#define __is_SEPX(c) (c == CH_SEP && (csv->sep_len == 0 || (\ |
330
|
|
|
|
|
|
|
csv->size - csv->used >= (STRLEN)csv->sep_len - 1 &&\ |
331
|
|
|
|
|
|
|
!memcmp (csv->bptr + csv->used, csv->sep + 1, csv->sep_len - 1) &&\ |
332
|
|
|
|
|
|
|
(csv->used += csv->sep_len - 1) &&\ |
333
|
|
|
|
|
|
|
(c = CH_SEPX)))) |
334
|
|
|
|
|
|
|
#if MAINT_DEBUG > 1 |
335
|
|
|
|
|
|
|
static byte _is_SEPX (unsigned int c, csv_t *csv, int line) { |
336
|
|
|
|
|
|
|
unsigned int b = __is_SEPX (c); |
337
|
|
|
|
|
|
|
(void)fprintf (stderr, "# %4d - is_SEPX:\t%d (%d)\n", line, b, csv->sep_len); |
338
|
|
|
|
|
|
|
if (csv->sep_len) |
339
|
|
|
|
|
|
|
(void)fprintf (stderr, |
340
|
|
|
|
|
|
|
"# len: %d, siz: %d, usd: %d, c: %03x, *sep: %03x\n", |
341
|
|
|
|
|
|
|
csv->sep_len, csv->size, csv->used, c, CH_SEP); |
342
|
|
|
|
|
|
|
return b; |
343
|
|
|
|
|
|
|
} /* _is_SEPX */ |
344
|
|
|
|
|
|
|
#define is_SEP(c) _is_SEPX (c, csv, __LINE__) |
345
|
|
|
|
|
|
|
#else |
346
|
|
|
|
|
|
|
#define is_SEP(c) __is_SEPX (c) |
347
|
|
|
|
|
|
|
#endif |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
#define __is_QUOTEX(c) (CH_QUOTE && c == CH_QUOTE && (csv->quo_len == 0 || (\ |
350
|
|
|
|
|
|
|
csv->size - csv->used >= (STRLEN)csv->quo_len - 1 &&\ |
351
|
|
|
|
|
|
|
!memcmp (csv->bptr + csv->used, csv->quo + 1, csv->quo_len - 1) &&\ |
352
|
|
|
|
|
|
|
(csv->used += csv->quo_len - 1) &&\ |
353
|
|
|
|
|
|
|
(c = CH_QUOTEX)))) |
354
|
|
|
|
|
|
|
#if MAINT_DEBUG > 1 |
355
|
|
|
|
|
|
|
static byte _is_QUOTEX (unsigned int c, csv_t *csv, int line) { |
356
|
|
|
|
|
|
|
unsigned int b = __is_QUOTEX (c); |
357
|
|
|
|
|
|
|
(void)fprintf (stderr, "# %4d - is_QUOTEX:\t%d (%d)\n", line, b, csv->quo_len); |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
if (csv->quo_len) |
360
|
|
|
|
|
|
|
(void)fprintf (stderr, |
361
|
|
|
|
|
|
|
"# len: %d, siz: %d, usd: %d, c: %03x, *quo: %03x\n", |
362
|
|
|
|
|
|
|
csv->quo_len, csv->size, csv->used, c, CH_QUOTE); |
363
|
|
|
|
|
|
|
return b; |
364
|
|
|
|
|
|
|
} /* _is_QUOTEX */ |
365
|
|
|
|
|
|
|
#define is_QUOTE(c) _is_QUOTEX (c, csv, __LINE__) |
366
|
|
|
|
|
|
|
#else |
367
|
|
|
|
|
|
|
#define is_QUOTE(c) __is_QUOTEX (c) |
368
|
|
|
|
|
|
|
#endif |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
#define is_whitespace(ch) \ |
371
|
|
|
|
|
|
|
( (ch) != CH_SEP && \ |
372
|
|
|
|
|
|
|
(ch) != CH_QUOTE && \ |
373
|
|
|
|
|
|
|
(ch) != csv->escape_char && \ |
374
|
|
|
|
|
|
|
( (ch) == CH_SPACE || \ |
375
|
|
|
|
|
|
|
(ch) == CH_TAB \ |
376
|
|
|
|
|
|
|
) \ |
377
|
|
|
|
|
|
|
) |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
#define SvDiag(xse) cx_SvDiag (aTHX_ xse) |
380
|
3591
|
|
|
|
|
|
static SV *cx_SvDiag (pTHX_ int xse) { |
381
|
3591
|
|
|
|
|
|
int i = 0; |
382
|
|
|
|
|
|
|
SV *err; |
383
|
|
|
|
|
|
|
|
384
|
71066
|
100
|
|
|
|
|
while (xs_errors[i].xs_errno && xs_errors[i].xs_errno != xse) i++; |
|
|
100
|
|
|
|
|
|
385
|
3591
|
50
|
|
|
|
|
if ((err = newSVpv (xs_errors[i].xs_errstr, 0))) { |
386
|
3591
|
50
|
|
|
|
|
(void)SvUPGRADE (err, SVt_PVIV); |
387
|
3591
|
|
|
|
|
|
SvIV_set (err, xse); |
388
|
3591
|
|
|
|
|
|
SvIOK_on (err); |
389
|
|
|
|
|
|
|
} |
390
|
3591
|
|
|
|
|
|
return (err); |
391
|
|
|
|
|
|
|
} /* SvDiag */ |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
/* This function should be altered to deal with the optional extra argument |
394
|
|
|
|
|
|
|
* that holds the replacement message */ |
395
|
|
|
|
|
|
|
#define SetDiag(csv,xse) cx_SetDiag (aTHX_ csv, xse) |
396
|
1698
|
|
|
|
|
|
static SV *cx_SetDiag (pTHX_ csv_t *csv, int xse) { |
397
|
1698
|
|
|
|
|
|
dSP; |
398
|
1698
|
|
|
|
|
|
SV *err = SvDiag (xse); |
399
|
1698
|
|
|
|
|
|
SV *pself = csv->pself; |
400
|
|
|
|
|
|
|
|
401
|
1698
|
|
|
|
|
|
last_error = xse; |
402
|
1698
|
|
|
|
|
|
(void)hv_store (csv->self, "_ERROR_DIAG", 11, err, 0); |
403
|
1698
|
100
|
|
|
|
|
if (xse == 0) { |
404
|
6
|
|
|
|
|
|
(void)hv_store (csv->self, "_ERROR_POS", 10, newSViv (0), 0); |
405
|
6
|
|
|
|
|
|
(void)hv_store (csv->self, "_ERROR_FLD", 10, newSViv (0), 0); |
406
|
6
|
|
|
|
|
|
(void)hv_store (csv->self, "_ERROR_INPUT", 12, &PL_sv_undef, 0); |
407
|
6
|
|
|
|
|
|
csv->has_error_input = 0; |
408
|
|
|
|
|
|
|
} |
409
|
1698
|
100
|
|
|
|
|
if (xse == 2012) /* EOF */ |
410
|
333
|
|
|
|
|
|
(void)hv_store (csv->self, "_EOF", 4, &PL_sv_yes, 0); |
411
|
1698
|
100
|
|
|
|
|
if (csv->auto_diag) { |
412
|
284
|
50
|
|
|
|
|
unless (_is_hashref (pself)) |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
413
|
162
|
|
|
|
|
|
pself = newRV_inc ((SV *)csv->self); |
414
|
284
|
|
|
|
|
|
ENTER; |
415
|
284
|
50
|
|
|
|
|
PUSHMARK (SP); |
416
|
284
|
50
|
|
|
|
|
XPUSHs (pself); |
417
|
284
|
|
|
|
|
|
PUTBACK; |
418
|
284
|
|
|
|
|
|
call_pv ("Text::CSV_XS::error_diag", G_VOID | G_DISCARD); |
419
|
281
|
|
|
|
|
|
LEAVE; |
420
|
281
|
100
|
|
|
|
|
unless (pself == csv->pself) |
421
|
161
|
|
|
|
|
|
sv_free (pself); |
422
|
|
|
|
|
|
|
} |
423
|
1695
|
|
|
|
|
|
return (err); |
424
|
|
|
|
|
|
|
} /* SetDiag */ |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
#define xs_cache_set(hv,idx,val) cx_xs_cache_set (aTHX_ hv, idx, val) |
427
|
23241
|
|
|
|
|
|
static void cx_xs_cache_set (pTHX_ HV *hv, int idx, SV *val) { |
428
|
|
|
|
|
|
|
SV **svp; |
429
|
|
|
|
|
|
|
byte *cache; |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
csv_t csvs; |
432
|
23241
|
|
|
|
|
|
csv_t *csv = &csvs; |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
IV iv; |
435
|
|
|
|
|
|
|
byte bv; |
436
|
23241
|
|
|
|
|
|
char *cp = "\0"; |
437
|
23241
|
|
|
|
|
|
STRLEN len = 0; |
438
|
|
|
|
|
|
|
|
439
|
23241
|
100
|
|
|
|
|
unless ((svp = hv_fetchs (hv, "_CACHE", FALSE)) && *svp) |
|
|
50
|
|
|
|
|
|
440
|
764
|
|
|
|
|
|
return; |
441
|
|
|
|
|
|
|
|
442
|
22477
|
50
|
|
|
|
|
cache = (byte *)SvPV_nolen (*svp); |
443
|
22477
|
|
|
|
|
|
(void)memcpy (csv, cache, sizeof (csv_t)); |
444
|
|
|
|
|
|
|
|
445
|
22477
|
100
|
|
|
|
|
if (SvPOK (val)) |
446
|
16683
|
50
|
|
|
|
|
cp = SvPV (val, len); |
447
|
22477
|
100
|
|
|
|
|
if (SvIOK (val)) |
448
|
5782
|
50
|
|
|
|
|
iv = SvIV (val); |
449
|
16695
|
50
|
|
|
|
|
else if (SvNOK (val)) /* Needed for 5.6.x but safe for 5.8.x+ */ |
450
|
0
|
0
|
|
|
|
|
iv = (IV)SvNV (val); /* uncoverable statement ancient perl required */ |
451
|
|
|
|
|
|
|
else |
452
|
16695
|
|
|
|
|
|
iv = *cp; |
453
|
22477
|
|
|
|
|
|
bv = (unsigned)iv & 0xff; |
454
|
|
|
|
|
|
|
|
455
|
22477
|
|
|
|
|
|
switch (idx) { |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
/* single char/byte */ |
458
|
|
|
|
|
|
|
case CACHE_ID_sep_char: |
459
|
3122
|
|
|
|
|
|
CH_SEP = *cp; |
460
|
3122
|
|
|
|
|
|
csv->sep_len = 0; |
461
|
3122
|
|
|
|
|
|
break; |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
case CACHE_ID_quote_char: |
464
|
3369
|
|
|
|
|
|
CH_QUOTE = *cp; |
465
|
3369
|
|
|
|
|
|
csv->quo_len = 0; |
466
|
3369
|
|
|
|
|
|
break; |
467
|
|
|
|
|
|
|
|
468
|
3478
|
|
|
|
|
|
case CACHE_ID_escape_char: csv->escape_char = *cp; break; |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
/* boolean/numeric */ |
471
|
11
|
|
|
|
|
|
case CACHE_ID_binary: csv->binary = bv; break; |
472
|
10
|
|
|
|
|
|
case CACHE_ID_keep_meta_info: csv->keep_meta_info = bv; break; |
473
|
1798
|
|
|
|
|
|
case CACHE_ID_always_quote: csv->always_quote = bv; break; |
474
|
3
|
|
|
|
|
|
case CACHE_ID_quote_empty: csv->quote_empty = bv; break; |
475
|
6
|
|
|
|
|
|
case CACHE_ID_quote_space: csv->quote_space = bv; break; |
476
|
10
|
|
|
|
|
|
case CACHE_ID_escape_null: csv->escape_null = bv; break; |
477
|
6
|
|
|
|
|
|
case CACHE_ID_quote_binary: csv->quote_binary = bv; break; |
478
|
1
|
|
|
|
|
|
case CACHE_ID_decode_utf8: csv->decode_utf8 = bv; break; |
479
|
11
|
|
|
|
|
|
case CACHE_ID_allow_loose_escapes: csv->allow_loose_escapes = bv; break; |
480
|
11
|
|
|
|
|
|
case CACHE_ID_allow_loose_quotes: csv->allow_loose_quotes = bv; break; |
481
|
2
|
|
|
|
|
|
case CACHE_ID_allow_unquoted_escape: csv->allow_unquoted_escape = bv; break; |
482
|
3719
|
|
|
|
|
|
case CACHE_ID_allow_whitespace: csv->allow_whitespace = bv; break; |
483
|
1
|
|
|
|
|
|
case CACHE_ID_blank_is_undef: csv->blank_is_undef = bv; break; |
484
|
1
|
|
|
|
|
|
case CACHE_ID_empty_is_undef: csv->empty_is_undef = bv; break; |
485
|
1
|
|
|
|
|
|
case CACHE_ID_formula: csv->formula = bv; break; |
486
|
1
|
|
|
|
|
|
case CACHE_ID_strict: csv->strict = bv; break; |
487
|
6
|
|
|
|
|
|
case CACHE_ID_verbatim: csv->verbatim = bv; break; |
488
|
1
|
|
|
|
|
|
case CACHE_ID_skip_empty_rows: csv->skip_empty_rows = bv; break; |
489
|
9
|
|
|
|
|
|
case CACHE_ID_auto_diag: csv->auto_diag = bv; break; |
490
|
8
|
|
|
|
|
|
case CACHE_ID_diag_verbose: csv->diag_verbose = bv; break; |
491
|
142
|
|
|
|
|
|
case CACHE_ID__has_ahead: csv->has_ahead = bv; break; |
492
|
11
|
|
|
|
|
|
case CACHE_ID__has_hooks: csv->has_hooks = bv; break; |
493
|
1
|
|
|
|
|
|
case CACHE_ID_has_error_input: csv->has_error_input = bv; break; |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
/* a 4-byte IV */ |
496
|
11
|
|
|
|
|
|
case CACHE_ID__is_bound: csv->is_bound = iv; break; |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
/* string */ |
499
|
|
|
|
|
|
|
case CACHE_ID_sep: |
500
|
3223
|
|
|
|
|
|
(void)memcpy (csv->sep, cp, len); |
501
|
3223
|
50
|
|
|
|
|
csv->sep_len = len == 1 ? 0 : len; |
502
|
3223
|
|
|
|
|
|
break; |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
case CACHE_ID_quo: |
505
|
3377
|
|
|
|
|
|
(void)memcpy (csv->quo, cp, len); |
506
|
3377
|
50
|
|
|
|
|
csv->quo_len = len == 1 ? 0 : len; |
507
|
3377
|
|
|
|
|
|
break; |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
case CACHE_ID_eol: |
510
|
112
|
|
|
|
|
|
(void)memcpy (csv->eol, cp, len); |
511
|
112
|
|
|
|
|
|
csv->eol_len = len; |
512
|
112
|
100
|
|
|
|
|
csv->eol_is_cr = len == 1 && *cp == CH_CR ? 1 : 0; |
|
|
100
|
|
|
|
|
|
513
|
112
|
|
|
|
|
|
break; |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
case CACHE_ID_undef_str: |
516
|
11
|
100
|
|
|
|
|
if (*cp) { |
517
|
8
|
|
|
|
|
|
csv->undef_str = (byte *)cp; |
518
|
8
|
100
|
|
|
|
|
if (SvUTF8 (val)) |
519
|
8
|
|
|
|
|
|
csv->undef_flg = 3; |
520
|
|
|
|
|
|
|
} |
521
|
|
|
|
|
|
|
else { |
522
|
3
|
|
|
|
|
|
csv->undef_str = NULL; |
523
|
3
|
|
|
|
|
|
csv->undef_flg = 0; |
524
|
|
|
|
|
|
|
} |
525
|
11
|
|
|
|
|
|
break; |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
case CACHE_ID_comment_str: |
528
|
2
|
100
|
|
|
|
|
csv->comment_str = *cp ? (byte *)cp : NULL; |
529
|
2
|
|
|
|
|
|
break; |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
case CACHE_ID_types: |
532
|
1
|
50
|
|
|
|
|
if (cp && len) { |
|
|
50
|
|
|
|
|
|
533
|
0
|
|
|
|
|
|
csv->types = cp; |
534
|
0
|
|
|
|
|
|
csv->types_len = len; |
535
|
|
|
|
|
|
|
} |
536
|
|
|
|
|
|
|
else { |
537
|
1
|
|
|
|
|
|
csv->types = NULL; |
538
|
1
|
|
|
|
|
|
csv->types_len = 0; |
539
|
|
|
|
|
|
|
} |
540
|
1
|
|
|
|
|
|
break; |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
default: |
543
|
1
|
|
|
|
|
|
warn ("Unknown cache index %d ignored\n", idx); |
544
|
|
|
|
|
|
|
} |
545
|
|
|
|
|
|
|
|
546
|
22477
|
|
|
|
|
|
csv->cache = cache; |
547
|
22477
|
|
|
|
|
|
(void)memcpy (cache, csv, sizeof (csv_t)); |
548
|
|
|
|
|
|
|
} /* cache_set */ |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
#define _pretty_strl(csv) cx_pretty_str (aTHX_ csv, strlen (csv)) |
551
|
|
|
|
|
|
|
#define _pretty_str(csv,xse) cx_pretty_str (aTHX_ csv, xse) |
552
|
8
|
|
|
|
|
|
static char *cx_pretty_str (pTHX_ byte *s, STRLEN l) { |
553
|
8
|
|
|
|
|
|
SV *dsv = newSVpvs_flags ("", SVs_TEMP); |
554
|
8
|
|
|
|
|
|
return (pv_pretty (dsv, (char *)s, l, 0, NULL, NULL, |
555
|
|
|
|
|
|
|
(PERL_PV_PRETTY_DUMP | PERL_PV_ESCAPE_UNI_DETECT))); |
556
|
|
|
|
|
|
|
} /* _pretty_str */ |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
#define _cache_show_byte(trim,c) \ |
559
|
|
|
|
|
|
|
warn (" %-21s %02x:%3d\n", trim, c, c) |
560
|
|
|
|
|
|
|
#define _cache_show_char(trim,c) \ |
561
|
|
|
|
|
|
|
warn (" %-21s %02x:%s\n", trim, c, _pretty_str (&c, 1)) |
562
|
|
|
|
|
|
|
#define _cache_show_str(trim,l,str) \ |
563
|
|
|
|
|
|
|
warn (" %-21s %3d:%s\n", trim, l, _pretty_str (str, l)) |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
#define _csv_diag(csv) _xs_csv_diag (aTHX_ csv) |
566
|
1
|
|
|
|
|
|
static void _xs_csv_diag (pTHX_ csv_t *csv) { |
567
|
1
|
|
|
|
|
|
warn ("CACHE:\n"); |
568
|
1
|
|
|
|
|
|
_cache_show_char ("quote_char", CH_QUOTE); |
569
|
1
|
|
|
|
|
|
_cache_show_char ("escape_char", csv->escape_char); |
570
|
1
|
|
|
|
|
|
_cache_show_char ("sep_char", CH_SEP); |
571
|
1
|
|
|
|
|
|
_cache_show_byte ("binary", csv->binary); |
572
|
1
|
|
|
|
|
|
_cache_show_byte ("decode_utf8", csv->decode_utf8); |
573
|
|
|
|
|
|
|
|
574
|
1
|
|
|
|
|
|
_cache_show_byte ("allow_loose_escapes", csv->allow_loose_escapes); |
575
|
1
|
|
|
|
|
|
_cache_show_byte ("allow_loose_quotes", csv->allow_loose_quotes); |
576
|
1
|
|
|
|
|
|
_cache_show_byte ("allow_unquoted_escape", csv->allow_unquoted_escape); |
577
|
1
|
|
|
|
|
|
_cache_show_byte ("allow_whitespace", csv->allow_whitespace); |
578
|
1
|
|
|
|
|
|
_cache_show_byte ("always_quote", csv->always_quote); |
579
|
1
|
|
|
|
|
|
_cache_show_byte ("quote_empty", csv->quote_empty); |
580
|
1
|
|
|
|
|
|
_cache_show_byte ("quote_space", csv->quote_space); |
581
|
1
|
|
|
|
|
|
_cache_show_byte ("escape_null", csv->escape_null); |
582
|
1
|
|
|
|
|
|
_cache_show_byte ("quote_binary", csv->quote_binary); |
583
|
1
|
|
|
|
|
|
_cache_show_byte ("auto_diag", csv->auto_diag); |
584
|
1
|
|
|
|
|
|
_cache_show_byte ("diag_verbose", csv->diag_verbose); |
585
|
1
|
|
|
|
|
|
_cache_show_byte ("formula", csv->formula); |
586
|
1
|
|
|
|
|
|
_cache_show_byte ("strict", csv->strict); |
587
|
1
|
|
|
|
|
|
_cache_show_byte ("skip_empty_rows", csv->skip_empty_rows); |
588
|
1
|
|
|
|
|
|
_cache_show_byte ("has_error_input", csv->has_error_input); |
589
|
1
|
|
|
|
|
|
_cache_show_byte ("blank_is_undef", csv->blank_is_undef); |
590
|
1
|
|
|
|
|
|
_cache_show_byte ("empty_is_undef", csv->empty_is_undef); |
591
|
1
|
|
|
|
|
|
_cache_show_byte ("has_ahead", csv->has_ahead); |
592
|
1
|
|
|
|
|
|
_cache_show_byte ("keep_meta_info", csv->keep_meta_info); |
593
|
1
|
|
|
|
|
|
_cache_show_byte ("verbatim", csv->verbatim); |
594
|
|
|
|
|
|
|
|
595
|
1
|
|
|
|
|
|
_cache_show_byte ("has_hooks", csv->has_hooks); |
596
|
1
|
|
|
|
|
|
_cache_show_byte ("eol_is_cr", csv->eol_is_cr); |
597
|
1
|
|
|
|
|
|
_cache_show_byte ("eol_len", csv->eol_len); |
598
|
1
|
|
|
|
|
|
_cache_show_str ("eol", csv->eol_len, csv->eol); |
599
|
1
|
|
|
|
|
|
_cache_show_byte ("sep_len", csv->sep_len); |
600
|
1
|
50
|
|
|
|
|
if (csv->sep_len > 1) |
601
|
1
|
|
|
|
|
|
_cache_show_str ("sep", csv->sep_len, csv->sep); |
602
|
1
|
|
|
|
|
|
_cache_show_byte ("quo_len", csv->quo_len); |
603
|
1
|
50
|
|
|
|
|
if (csv->quo_len > 1) |
604
|
1
|
|
|
|
|
|
_cache_show_str ("quote", csv->quo_len, csv->quo); |
605
|
1
|
50
|
|
|
|
|
if (csv->types_len) |
606
|
0
|
|
|
|
|
|
_cache_show_str ("types", csv->types_len, (byte *)csv->types); |
607
|
|
|
|
|
|
|
else |
608
|
1
|
|
|
|
|
|
_cache_show_str ("types", 0, (byte *)""); |
609
|
|
|
|
|
|
|
|
610
|
1
|
50
|
|
|
|
|
if (csv->bptr) |
611
|
1
|
|
|
|
|
|
_cache_show_str ("bptr", (int)strlen (csv->bptr), (byte *)csv->bptr); |
612
|
1
|
50
|
|
|
|
|
if (csv->tmp && SvPOK (csv->tmp)) { |
|
|
50
|
|
|
|
|
|
613
|
0
|
0
|
|
|
|
|
char *s = SvPV_nolen (csv->tmp); |
614
|
0
|
|
|
|
|
|
_cache_show_str ("tmp", (int)strlen (s), (byte *)s); |
615
|
|
|
|
|
|
|
} |
616
|
1
|
50
|
|
|
|
|
if (csv->cache) |
617
|
1
|
|
|
|
|
|
warn (" %-20s %4d:0x%08x\n", "cache", sizeof (csv_t), csv->cache); |
618
|
|
|
|
|
|
|
else |
619
|
0
|
|
|
|
|
|
warn (" %-22s --:no cache yet\n", "cache"); |
620
|
1
|
|
|
|
|
|
} /* _csv_diag */ |
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
#define xs_cache_diag(hv) cx_xs_cache_diag (aTHX_ hv) |
623
|
2
|
|
|
|
|
|
static void cx_xs_cache_diag (pTHX_ HV *hv) { |
624
|
|
|
|
|
|
|
SV **svp; |
625
|
|
|
|
|
|
|
byte *cache; |
626
|
|
|
|
|
|
|
csv_t csvs; |
627
|
2
|
|
|
|
|
|
csv_t *csv = &csvs; |
628
|
|
|
|
|
|
|
|
629
|
2
|
100
|
|
|
|
|
unless ((svp = hv_fetchs (hv, "_CACHE", FALSE)) && *svp) { |
|
|
50
|
|
|
|
|
|
630
|
1
|
|
|
|
|
|
warn ("CACHE: invalid\n"); |
631
|
1
|
|
|
|
|
|
return; |
632
|
|
|
|
|
|
|
} |
633
|
|
|
|
|
|
|
|
634
|
1
|
50
|
|
|
|
|
cache = (byte *)SvPV_nolen (*svp); |
635
|
1
|
|
|
|
|
|
(void)memcpy (csv, cache, sizeof (csv_t)); |
636
|
1
|
|
|
|
|
|
_csv_diag (csv); |
637
|
|
|
|
|
|
|
} /* xs_cache_diag */ |
638
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
#define set_eol_is_cr(csv) cx_set_eol_is_cr (aTHX_ csv) |
640
|
8
|
|
|
|
|
|
static void cx_set_eol_is_cr (pTHX_ csv_t *csv) { |
641
|
8
|
|
|
|
|
|
csv->eol[0] = CH_CR; |
642
|
8
|
|
|
|
|
|
csv->eol_is_cr = 1; |
643
|
8
|
|
|
|
|
|
csv->eol_len = 1; |
644
|
8
|
|
|
|
|
|
(void)memcpy (csv->cache, csv, sizeof (csv_t)); |
645
|
|
|
|
|
|
|
|
646
|
8
|
|
|
|
|
|
(void)hv_store (csv->self, "eol", 3, newSVpvn ((char *)csv->eol, 1), 0); |
647
|
8
|
|
|
|
|
|
} /* set_eol_is_cr */ |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
#define SetupCsv(csv,self,pself) cx_SetupCsv (aTHX_ csv, self, pself) |
650
|
27276
|
|
|
|
|
|
static void cx_SetupCsv (pTHX_ csv_t *csv, HV *self, SV *pself) { |
651
|
|
|
|
|
|
|
SV **svp; |
652
|
|
|
|
|
|
|
STRLEN len; |
653
|
|
|
|
|
|
|
char *ptr; |
654
|
|
|
|
|
|
|
|
655
|
27276
|
|
|
|
|
|
last_error = 0; |
656
|
|
|
|
|
|
|
|
657
|
27276
|
100
|
|
|
|
|
if ((svp = hv_fetchs (self, "_CACHE", FALSE)) && *svp) { |
|
|
50
|
|
|
|
|
|
658
|
26453
|
|
|
|
|
|
byte *cache = (byte *)SvPVX (*svp); |
659
|
26453
|
|
|
|
|
|
(void)memcpy (csv, cache, sizeof (csv_t)); |
660
|
|
|
|
|
|
|
} |
661
|
|
|
|
|
|
|
else { |
662
|
|
|
|
|
|
|
SV *sv_cache; |
663
|
|
|
|
|
|
|
|
664
|
823
|
|
|
|
|
|
(void)memset (csv, 0, sizeof (csv_t)); /* Reset everything */ |
665
|
|
|
|
|
|
|
|
666
|
823
|
|
|
|
|
|
csv->self = self; |
667
|
823
|
|
|
|
|
|
csv->pself = pself; |
668
|
|
|
|
|
|
|
|
669
|
823
|
|
|
|
|
|
CH_SEP = ','; |
670
|
823
|
50
|
|
|
|
|
if ((svp = hv_fetchs (self, "sep_char", FALSE)) && *svp && SvOK (*svp)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
671
|
823
|
50
|
|
|
|
|
CH_SEP = *SvPV (*svp, len); |
672
|
823
|
100
|
|
|
|
|
if ((svp = hv_fetchs (self, "sep", FALSE)) && *svp && SvOK (*svp)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
673
|
224
|
50
|
|
|
|
|
ptr = SvPV (*svp, len); |
674
|
224
|
|
|
|
|
|
(void)memcpy (csv->sep, ptr, len); |
675
|
224
|
100
|
|
|
|
|
if (len > 1) |
676
|
5
|
|
|
|
|
|
csv->sep_len = len; |
677
|
|
|
|
|
|
|
} |
678
|
|
|
|
|
|
|
|
679
|
823
|
|
|
|
|
|
CH_QUOTE = '"'; |
680
|
823
|
50
|
|
|
|
|
if ((svp = hv_fetchs (self, "quote_char", FALSE)) && *svp) { |
|
|
50
|
|
|
|
|
|
681
|
823
|
100
|
|
|
|
|
if (SvOK (*svp)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
682
|
820
|
50
|
|
|
|
|
ptr = SvPV (*svp, len); |
683
|
820
|
50
|
|
|
|
|
CH_QUOTE = len ? *ptr : (char)0; |
684
|
|
|
|
|
|
|
} |
685
|
|
|
|
|
|
|
else |
686
|
3
|
|
|
|
|
|
CH_QUOTE = (char)0; |
687
|
|
|
|
|
|
|
} |
688
|
823
|
100
|
|
|
|
|
if ((svp = hv_fetchs (self, "quote", FALSE)) && *svp && SvOK (*svp)) { |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
689
|
5
|
50
|
|
|
|
|
ptr = SvPV (*svp, len); |
690
|
5
|
|
|
|
|
|
(void)memcpy (csv->quo, ptr, len); |
691
|
5
|
100
|
|
|
|
|
if (len > 1) |
692
|
4
|
|
|
|
|
|
csv->quo_len = len; |
693
|
|
|
|
|
|
|
} |
694
|
|
|
|
|
|
|
|
695
|
823
|
|
|
|
|
|
csv->escape_char = '"'; |
696
|
823
|
50
|
|
|
|
|
if ((svp = hv_fetchs (self, "escape_char", FALSE)) && *svp) { |
|
|
50
|
|
|
|
|
|
697
|
823
|
100
|
|
|
|
|
if (SvOK (*svp)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
698
|
817
|
50
|
|
|
|
|
ptr = SvPV (*svp, len); |
699
|
817
|
100
|
|
|
|
|
csv->escape_char = len ? *ptr : (char)0; |
700
|
|
|
|
|
|
|
} |
701
|
|
|
|
|
|
|
else |
702
|
6
|
|
|
|
|
|
csv->escape_char = (char)0; |
703
|
|
|
|
|
|
|
} |
704
|
|
|
|
|
|
|
|
705
|
823
|
50
|
|
|
|
|
if ((svp = hv_fetchs (self, "eol", FALSE)) && *svp && SvOK (*svp)) { |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
706
|
819
|
50
|
|
|
|
|
char *eol = SvPV (*svp, len); |
707
|
819
|
|
|
|
|
|
(void)memcpy (csv->eol, eol, len); |
708
|
819
|
|
|
|
|
|
csv->eol_len = len; |
709
|
819
|
100
|
|
|
|
|
if (len == 1 && *csv->eol == CH_CR) |
|
|
100
|
|
|
|
|
|
710
|
42
|
|
|
|
|
|
csv->eol_is_cr = 1; |
711
|
|
|
|
|
|
|
} |
712
|
|
|
|
|
|
|
|
713
|
823
|
|
|
|
|
|
csv->undef_flg = 0; |
714
|
823
|
50
|
|
|
|
|
if ((svp = hv_fetchs (self, "undef_str", FALSE)) && *svp && SvOK (*svp)) { |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
715
|
|
|
|
|
|
|
/*if (sv && (SvOK (sv) || ( |
716
|
|
|
|
|
|
|
(SvGMAGICAL (sv) && (mg_get (sv), 1) && SvOK (sv))))) {*/ |
717
|
1
|
50
|
|
|
|
|
csv->undef_str = (byte *)SvPV_nolen (*svp); |
718
|
1
|
50
|
|
|
|
|
if (SvUTF8 (*svp)) |
719
|
0
|
|
|
|
|
|
csv->undef_flg = 3; |
720
|
|
|
|
|
|
|
} |
721
|
|
|
|
|
|
|
else |
722
|
822
|
|
|
|
|
|
csv->undef_str = NULL; |
723
|
|
|
|
|
|
|
|
724
|
823
|
50
|
|
|
|
|
if ((svp = hv_fetchs (self, "comment_str", FALSE)) && *svp && SvOK (*svp)) |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
725
|
12
|
50
|
|
|
|
|
csv->comment_str = (byte *)SvPV_nolen (*svp); |
726
|
|
|
|
|
|
|
else |
727
|
811
|
|
|
|
|
|
csv->comment_str = NULL; |
728
|
|
|
|
|
|
|
|
729
|
823
|
100
|
|
|
|
|
if ((svp = hv_fetchs (self, "_types", FALSE)) && *svp && SvOK (*svp)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
730
|
1
|
50
|
|
|
|
|
csv->types = SvPV (*svp, len); |
731
|
1
|
|
|
|
|
|
csv->types_len = len; |
732
|
|
|
|
|
|
|
} |
733
|
|
|
|
|
|
|
|
734
|
823
|
100
|
|
|
|
|
if ((svp = hv_fetchs (self, "_is_bound", FALSE)) && *svp && SvOK (*svp)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
735
|
4
|
50
|
|
|
|
|
csv->is_bound = SvIV (*svp); |
736
|
823
|
50
|
|
|
|
|
if ((svp = hv_fetchs (self, "callbacks", FALSE)) && _is_hashref (*svp)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
737
|
301
|
|
|
|
|
|
HV *cb = (HV *)SvRV (*svp); |
738
|
301
|
100
|
|
|
|
|
if ((svp = hv_fetchs (cb, "after_parse", FALSE)) && _is_coderef (*svp)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
739
|
9
|
|
|
|
|
|
csv->has_hooks |= HOOK_AFTER_PARSE; |
740
|
301
|
100
|
|
|
|
|
if ((svp = hv_fetchs (cb, "before_print", FALSE)) && _is_coderef (*svp)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
741
|
1
|
|
|
|
|
|
csv->has_hooks |= HOOK_BEFORE_PRINT; |
742
|
|
|
|
|
|
|
} |
743
|
|
|
|
|
|
|
|
744
|
823
|
50
|
|
|
|
|
csv->binary = bool_opt ("binary"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
745
|
823
|
50
|
|
|
|
|
csv->decode_utf8 = bool_opt ("decode_utf8"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
746
|
823
|
50
|
|
|
|
|
csv->always_quote = bool_opt ("always_quote"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
747
|
823
|
50
|
|
|
|
|
csv->strict = bool_opt ("strict"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
748
|
823
|
50
|
|
|
|
|
csv->quote_empty = bool_opt ("quote_empty"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
749
|
823
|
50
|
|
|
|
|
csv->quote_space = bool_opt_def ("quote_space", 1); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
750
|
823
|
50
|
|
|
|
|
csv->escape_null = bool_opt_def ("escape_null", 1); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
751
|
823
|
50
|
|
|
|
|
csv->quote_binary = bool_opt_def ("quote_binary", 1); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
752
|
823
|
50
|
|
|
|
|
csv->allow_loose_quotes = bool_opt ("allow_loose_quotes"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
753
|
823
|
50
|
|
|
|
|
csv->allow_loose_escapes = bool_opt ("allow_loose_escapes"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
754
|
823
|
50
|
|
|
|
|
csv->allow_unquoted_escape = bool_opt ("allow_unquoted_escape"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
755
|
823
|
50
|
|
|
|
|
csv->allow_whitespace = bool_opt ("allow_whitespace"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
756
|
823
|
50
|
|
|
|
|
csv->blank_is_undef = bool_opt ("blank_is_undef"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
757
|
823
|
50
|
|
|
|
|
csv->empty_is_undef = bool_opt ("empty_is_undef"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
758
|
823
|
50
|
|
|
|
|
csv->verbatim = bool_opt ("verbatim"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
759
|
|
|
|
|
|
|
|
760
|
823
|
50
|
|
|
|
|
csv->auto_diag = num_opt ("auto_diag"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
761
|
823
|
50
|
|
|
|
|
csv->diag_verbose = num_opt ("diag_verbose"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
762
|
823
|
50
|
|
|
|
|
csv->keep_meta_info = num_opt ("keep_meta_info"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
763
|
823
|
50
|
|
|
|
|
csv->skip_empty_rows = num_opt ("skip_empty_rows"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
764
|
823
|
50
|
|
|
|
|
csv->formula = num_opt ("formula"); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
765
|
|
|
|
|
|
|
|
766
|
823
|
100
|
|
|
|
|
unless (csv->escape_char) csv->escape_null = 0; |
767
|
|
|
|
|
|
|
|
768
|
823
|
|
|
|
|
|
sv_cache = newSVpvn ((char *)csv, sizeof (csv_t)); |
769
|
823
|
|
|
|
|
|
csv->cache = (byte *)SvPVX (sv_cache); |
770
|
823
|
|
|
|
|
|
SvREADONLY_on (sv_cache); |
771
|
|
|
|
|
|
|
|
772
|
823
|
|
|
|
|
|
(void)memcpy (csv->cache, csv, sizeof (csv_t)); |
773
|
|
|
|
|
|
|
|
774
|
823
|
|
|
|
|
|
(void)hv_store (self, "_CACHE", 6, sv_cache, 0); |
775
|
|
|
|
|
|
|
} |
776
|
|
|
|
|
|
|
|
777
|
27276
|
|
|
|
|
|
csv->utf8 = 0; |
778
|
27276
|
|
|
|
|
|
csv->size = 0; |
779
|
27276
|
|
|
|
|
|
csv->used = 0; |
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
/* This is EBCDIC-safe, as it is used after translation */ |
782
|
27276
|
100
|
|
|
|
|
csv->first_safe_char = csv->quote_space ? 0x21 : 0x20; |
783
|
|
|
|
|
|
|
|
784
|
27276
|
100
|
|
|
|
|
if (csv->is_bound) { |
785
|
83
|
50
|
|
|
|
|
if ((svp = hv_fetchs (self, "_BOUND_COLUMNS", FALSE)) && _is_arrayref (*svp)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
786
|
69
|
|
|
|
|
|
csv->bound = *svp; |
787
|
|
|
|
|
|
|
else |
788
|
14
|
|
|
|
|
|
csv->is_bound = 0; |
789
|
|
|
|
|
|
|
} |
790
|
|
|
|
|
|
|
|
791
|
27276
|
|
|
|
|
|
csv->eol_pos = -1; |
792
|
54552
|
|
|
|
|
|
csv->eolx = csv->eol_len |
793
|
1305
|
100
|
|
|
|
|
? csv->verbatim || csv->eol_len >= 2 |
794
|
|
|
|
|
|
|
? 1 |
795
|
853
|
100
|
|
|
|
|
: csv->eol[0] == CH_CR || csv->eol[0] == CH_NL |
796
|
|
|
|
|
|
|
? 0 |
797
|
366
|
100
|
|
|
|
|
: 1 |
798
|
28581
|
100
|
|
|
|
|
: 0; |
|
|
100
|
|
|
|
|
|
799
|
27276
|
100
|
|
|
|
|
if (csv->sep_len > 1 && is_utf8_string ((U8 *)(csv->sep), csv->sep_len)) |
|
|
50
|
|
|
|
|
|
800
|
51
|
|
|
|
|
|
csv->utf8 = 1; |
801
|
27276
|
100
|
|
|
|
|
if (csv->quo_len > 1 && is_utf8_string ((U8 *)(csv->quo), csv->quo_len)) |
|
|
50
|
|
|
|
|
|
802
|
27
|
|
|
|
|
|
csv->utf8 = 1; |
803
|
27276
|
|
|
|
|
|
} /* SetupCsv */ |
804
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
#define Print(csv,dst) cx_Print (aTHX_ csv, dst) |
806
|
941266
|
|
|
|
|
|
static int cx_Print (pTHX_ csv_t *csv, SV *dst) { |
807
|
|
|
|
|
|
|
int result; |
808
|
941266
|
|
|
|
|
|
int keep = 0; |
809
|
|
|
|
|
|
|
|
810
|
941266
|
100
|
|
|
|
|
if (csv->useIO) { |
811
|
939877
|
|
|
|
|
|
SV *tmp = newSVpvn_flags (csv->buffer, csv->used, SVs_TEMP); |
812
|
939877
|
|
|
|
|
|
dSP; |
813
|
939877
|
50
|
|
|
|
|
PUSHMARK (sp); |
814
|
939877
|
50
|
|
|
|
|
EXTEND (sp, 2); |
815
|
939877
|
|
|
|
|
|
PUSHs ((dst)); |
816
|
939877
|
100
|
|
|
|
|
if (csv->utf8) { |
817
|
|
|
|
|
|
|
STRLEN len; |
818
|
|
|
|
|
|
|
char *ptr; |
819
|
|
|
|
|
|
|
int j; |
820
|
|
|
|
|
|
|
|
821
|
939649
|
50
|
|
|
|
|
ptr = SvPV (tmp, len); |
822
|
1690511
|
50
|
|
|
|
|
while (len > 0 && !is_utf8_sv (tmp) && keep < 16) { |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
823
|
750862
|
|
|
|
|
|
ptr[--len] = (char)0; |
824
|
750862
|
|
|
|
|
|
SvCUR_set (tmp, len); |
825
|
750862
|
|
|
|
|
|
keep++; |
826
|
|
|
|
|
|
|
} |
827
|
1690511
|
100
|
|
|
|
|
for (j = 0; j < keep; j++) |
828
|
750862
|
|
|
|
|
|
csv->buffer[j] = csv->buffer[csv->used - keep + j]; |
829
|
939649
|
|
|
|
|
|
SvUTF8_on (tmp); |
830
|
|
|
|
|
|
|
} |
831
|
939877
|
|
|
|
|
|
PUSHs (tmp); |
832
|
939877
|
|
|
|
|
|
PUTBACK; |
833
|
939877
|
|
|
|
|
|
result = call_sv (m_print, G_METHOD); |
834
|
939877
|
|
|
|
|
|
SPAGAIN; |
835
|
939877
|
50
|
|
|
|
|
if (result) { |
836
|
939877
|
100
|
|
|
|
|
result = POPi; |
837
|
939877
|
100
|
|
|
|
|
unless (result) |
838
|
1
|
|
|
|
|
|
(void)SetDiag (csv, 2200); |
839
|
|
|
|
|
|
|
} |
840
|
939877
|
|
|
|
|
|
PUTBACK; |
841
|
|
|
|
|
|
|
} |
842
|
|
|
|
|
|
|
else { |
843
|
1389
|
|
|
|
|
|
sv_catpvn (SvRV (dst), csv->buffer, csv->used); |
844
|
1389
|
|
|
|
|
|
result = TRUE; |
845
|
|
|
|
|
|
|
} |
846
|
941266
|
100
|
|
|
|
|
if (csv->utf8 && !csv->useIO && csv->decode_utf8 |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
847
|
25
|
50
|
|
|
|
|
&& SvROK (dst) && is_utf8_sv (SvRV (dst))) |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
848
|
24
|
|
|
|
|
|
SvUTF8_on (SvRV (dst)); |
849
|
941266
|
|
|
|
|
|
csv->used = keep; |
850
|
941266
|
|
|
|
|
|
return result; |
851
|
|
|
|
|
|
|
} /* Print */ |
852
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
#define CSV_PUT(csv,dst,c) { \ |
854
|
|
|
|
|
|
|
if ((csv)->used == sizeof ((csv)->buffer) - 1) { \ |
855
|
|
|
|
|
|
|
unless (Print ((csv), (dst))) \ |
856
|
|
|
|
|
|
|
return FALSE; \ |
857
|
|
|
|
|
|
|
} \ |
858
|
|
|
|
|
|
|
(csv)->buffer[(csv)->used++] = (c); \ |
859
|
|
|
|
|
|
|
} |
860
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
#define bound_field(csv,i,keep) cx_bound_field (aTHX_ csv, i, keep) |
862
|
101
|
|
|
|
|
|
static SV *cx_bound_field (pTHX_ csv_t *csv, SSize_t i, int keep) { |
863
|
101
|
|
|
|
|
|
SV *sv = csv->bound; |
864
|
|
|
|
|
|
|
AV *av; |
865
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
/* fprintf (stderr, "# New bind %d/%d\n", i, csv->is_bound);\ */ |
867
|
101
|
100
|
|
|
|
|
if (i >= csv->is_bound) { |
868
|
3
|
|
|
|
|
|
(void)SetDiag (csv, 3006); |
869
|
3
|
|
|
|
|
|
return (NULL); |
870
|
|
|
|
|
|
|
} |
871
|
|
|
|
|
|
|
|
872
|
98
|
50
|
|
|
|
|
if (sv && SvROK (sv)) { |
|
|
50
|
|
|
|
|
|
873
|
98
|
|
|
|
|
|
av = (AV *)(SvRV (sv)); |
874
|
|
|
|
|
|
|
/* fprintf (stderr, "# Bind %d/%d/%d\n", i, csv->is_bound, av_len (av)); */ |
875
|
98
|
|
|
|
|
|
sv = *av_fetch (av, i, FALSE); |
876
|
98
|
50
|
|
|
|
|
if (sv && SvROK (sv)) { |
|
|
50
|
|
|
|
|
|
877
|
98
|
|
|
|
|
|
sv = SvRV (sv); |
878
|
98
|
100
|
|
|
|
|
if (keep) |
879
|
14
|
|
|
|
|
|
return (sv); |
880
|
|
|
|
|
|
|
|
881
|
84
|
100
|
|
|
|
|
unless (SvREADONLY (sv)) { |
882
|
83
|
|
|
|
|
|
SvSetEmpty (sv); |
883
|
83
|
|
|
|
|
|
return (sv); |
884
|
|
|
|
|
|
|
} |
885
|
|
|
|
|
|
|
} |
886
|
|
|
|
|
|
|
} |
887
|
1
|
|
|
|
|
|
(void)SetDiag (csv, 3008); |
888
|
1
|
|
|
|
|
|
return (NULL); |
889
|
|
|
|
|
|
|
} /* bound_field */ |
890
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
#define was_quoted(mf,idx) cx_was_quoted (aTHX_ mf, idx) |
892
|
17
|
|
|
|
|
|
static int cx_was_quoted (pTHX_ AV *mf, int idx) { |
893
|
17
|
|
|
|
|
|
SV **x = av_fetch (mf, idx, FALSE); |
894
|
17
|
50
|
|
|
|
|
return (x && SvIOK (*x) && SvIV (*x) & CSV_FLAGS_QUO ? 1 : 0); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
895
|
|
|
|
|
|
|
} /* was_quoted */ |
896
|
|
|
|
|
|
|
|
897
|
|
|
|
|
|
|
#define _formula(csv,sv,len,f) cx_formula (aTHX_ csv, sv, len, f) |
898
|
37
|
|
|
|
|
|
static char *cx_formula (pTHX_ csv_t *csv, SV *sv, STRLEN *len, int f) { |
899
|
|
|
|
|
|
|
|
900
|
37
|
|
|
|
|
|
int fa = csv->formula; |
901
|
|
|
|
|
|
|
|
902
|
37
|
100
|
|
|
|
|
if (fa == 1) die ("Formulas are forbidden\n"); |
903
|
34
|
100
|
|
|
|
|
if (fa == 2) croak ("Formulas are forbidden\n"); |
904
|
|
|
|
|
|
|
|
905
|
31
|
100
|
|
|
|
|
if (fa == 3) { |
906
|
6
|
50
|
|
|
|
|
char *ptr = SvPV_nolen (sv); |
907
|
|
|
|
|
|
|
char rec[40]; |
908
|
|
|
|
|
|
|
char field[128]; |
909
|
|
|
|
|
|
|
SV **svp; |
910
|
|
|
|
|
|
|
|
911
|
6
|
100
|
|
|
|
|
if (csv->recno) (void)sprintf (rec, " in record %lu", csv->recno + 1); |
912
|
3
|
|
|
|
|
|
else *rec = (char)0; |
913
|
|
|
|
|
|
|
|
914
|
6
|
|
|
|
|
|
*field = (char)0; |
915
|
6
|
50
|
|
|
|
|
if ((svp = hv_fetchs (csv->self, "_COLUMN_NAMES", FALSE)) && _is_arrayref (*svp)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
916
|
1
|
|
|
|
|
|
AV *avp = (AV *)SvRV (*svp); |
917
|
1
|
50
|
|
|
|
|
if (avp && av_len (avp) >= (f - 1)) { |
|
|
50
|
|
|
|
|
|
918
|
1
|
|
|
|
|
|
SV **fnm = av_fetch (avp, f - 1, FALSE); |
919
|
1
|
50
|
|
|
|
|
if (fnm && *fnm && SvOK (*fnm)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
920
|
1
|
50
|
|
|
|
|
(void)sprintf (field, " (column: '%.100s')", SvPV_nolen (*fnm)); |
921
|
|
|
|
|
|
|
} |
922
|
|
|
|
|
|
|
} |
923
|
|
|
|
|
|
|
|
924
|
6
|
|
|
|
|
|
warn ("Field %d%s%s contains formula '%s'\n", f, field, rec, ptr); |
925
|
6
|
|
|
|
|
|
return ptr; |
926
|
|
|
|
|
|
|
} |
927
|
|
|
|
|
|
|
|
928
|
25
|
100
|
|
|
|
|
if (len) *len = 0; |
929
|
|
|
|
|
|
|
|
930
|
25
|
100
|
|
|
|
|
if (fa == 4) { |
931
|
5
|
100
|
|
|
|
|
unless (SvREADONLY (sv)) SvSetEmpty (sv); |
932
|
5
|
|
|
|
|
|
return ""; |
933
|
|
|
|
|
|
|
} |
934
|
|
|
|
|
|
|
|
935
|
20
|
100
|
|
|
|
|
if (fa == 5) { |
936
|
5
|
100
|
|
|
|
|
unless (SvREADONLY (sv)) SvSetUndef (sv); |
937
|
5
|
|
|
|
|
|
return NULL; |
938
|
|
|
|
|
|
|
} |
939
|
|
|
|
|
|
|
|
940
|
15
|
50
|
|
|
|
|
if (fa == 6) { |
941
|
|
|
|
|
|
|
int result; |
942
|
15
|
|
|
|
|
|
SV **svp = hv_fetchs (csv->self, "_FORMULA_CB", FALSE); |
943
|
15
|
50
|
|
|
|
|
if (svp && _is_coderef (*svp)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
944
|
15
|
|
|
|
|
|
dSP; |
945
|
15
|
|
|
|
|
|
ENTER; |
946
|
15
|
|
|
|
|
|
SAVE_DEFSV; /* local $_ */ |
947
|
15
|
50
|
|
|
|
|
DEFSV = sv; |
948
|
15
|
50
|
|
|
|
|
PUSHMARK (SP); |
949
|
15
|
|
|
|
|
|
PUTBACK; |
950
|
15
|
|
|
|
|
|
result = call_sv (*svp, G_SCALAR); |
951
|
15
|
|
|
|
|
|
SPAGAIN; |
952
|
15
|
50
|
|
|
|
|
if (result) |
953
|
15
|
|
|
|
|
|
sv_setsv (sv, POPs); |
954
|
15
|
|
|
|
|
|
PUTBACK; |
955
|
15
|
|
|
|
|
|
LEAVE; |
956
|
|
|
|
|
|
|
} |
957
|
15
|
50
|
|
|
|
|
return len ? SvPV (sv, *len) : SvPV_nolen (sv); |
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
958
|
|
|
|
|
|
|
} |
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
/* So far undefined behavior */ |
961
|
0
|
|
|
|
|
|
return NULL; |
962
|
|
|
|
|
|
|
} /* _formula */ |
963
|
|
|
|
|
|
|
|
964
|
|
|
|
|
|
|
#define SkipEmptyRow {\ |
965
|
|
|
|
|
|
|
int ser = csv->skip_empty_rows; \ |
966
|
|
|
|
|
|
|
\ |
967
|
|
|
|
|
|
|
if (ser == 3) { (void)SetDiag (csv, 2015); die ("Empty row"); } \ |
968
|
|
|
|
|
|
|
if (ser == 4) { (void)SetDiag (csv, 2015); croak ("Empty row"); } \ |
969
|
|
|
|
|
|
|
if (ser == 5) { (void)SetDiag (csv, 2015); return FALSE; } \ |
970
|
|
|
|
|
|
|
\ |
971
|
|
|
|
|
|
|
if (ser <= 2) { /* skip & eof */ \ |
972
|
|
|
|
|
|
|
csv->fld_idx = 0; \ |
973
|
|
|
|
|
|
|
c = CSV_GET; \ |
974
|
|
|
|
|
|
|
if (c == EOF || ser == 2) { \ |
975
|
|
|
|
|
|
|
sv_free (sv); \ |
976
|
|
|
|
|
|
|
sv = NULL; \ |
977
|
|
|
|
|
|
|
waitingForField = 0; \ |
978
|
|
|
|
|
|
|
if (ser == 2) return FALSE; \ |
979
|
|
|
|
|
|
|
break; \ |
980
|
|
|
|
|
|
|
} \ |
981
|
|
|
|
|
|
|
} \ |
982
|
|
|
|
|
|
|
\ |
983
|
|
|
|
|
|
|
if (ser == 6) { \ |
984
|
|
|
|
|
|
|
int result, n, i; \ |
985
|
|
|
|
|
|
|
SV *rv, **svp = hv_fetchs (csv->self, "_EMPTROW_CB", FALSE); \ |
986
|
|
|
|
|
|
|
AV *avp; \ |
987
|
|
|
|
|
|
|
unless (svp && _is_coderef (*svp)) \ |
988
|
|
|
|
|
|
|
return FALSE; /* A callback is wanted, but none found */ \ |
989
|
|
|
|
|
|
|
\ |
990
|
|
|
|
|
|
|
dSP; \ |
991
|
|
|
|
|
|
|
ENTER; \ |
992
|
|
|
|
|
|
|
SAVE_DEFSV; /* local $_ */ \ |
993
|
|
|
|
|
|
|
DEFSV = sv; \ |
994
|
|
|
|
|
|
|
PUSHMARK (SP); \ |
995
|
|
|
|
|
|
|
PUTBACK; \ |
996
|
|
|
|
|
|
|
result = call_sv (*svp, G_SCALAR); \ |
997
|
|
|
|
|
|
|
SPAGAIN; \ |
998
|
|
|
|
|
|
|
unless (result) { \ |
999
|
|
|
|
|
|
|
/* A false return will stop the parsing */ \ |
1000
|
|
|
|
|
|
|
sv_free (sv); \ |
1001
|
|
|
|
|
|
|
sv = NULL; \ |
1002
|
|
|
|
|
|
|
waitingForField = 0; \ |
1003
|
|
|
|
|
|
|
return FALSE; \ |
1004
|
|
|
|
|
|
|
} \ |
1005
|
|
|
|
|
|
|
\ |
1006
|
|
|
|
|
|
|
PUTBACK; \ |
1007
|
|
|
|
|
|
|
LEAVE; \ |
1008
|
|
|
|
|
|
|
\ |
1009
|
|
|
|
|
|
|
rv = POPs; \ |
1010
|
|
|
|
|
|
|
/* Result should be a ref to a list. */ \ |
1011
|
|
|
|
|
|
|
unless (_is_arrayref (rv)) \ |
1012
|
|
|
|
|
|
|
return FALSE; \ |
1013
|
|
|
|
|
|
|
\ |
1014
|
|
|
|
|
|
|
avp = (AV *)SvRV (rv); \ |
1015
|
|
|
|
|
|
|
\ |
1016
|
|
|
|
|
|
|
unless (avp) return FALSE; \ |
1017
|
|
|
|
|
|
|
n = av_len (avp); \ |
1018
|
|
|
|
|
|
|
if (n <= 0) return TRUE; \ |
1019
|
|
|
|
|
|
|
\ |
1020
|
|
|
|
|
|
|
if (csv->is_bound && csv->is_bound < n) \ |
1021
|
|
|
|
|
|
|
n = csv->is_bound - 1; \ |
1022
|
|
|
|
|
|
|
\ |
1023
|
|
|
|
|
|
|
for (i = 0; i <= n; i++) { \ |
1024
|
|
|
|
|
|
|
SV **svp = av_fetch (avp, i, FALSE); \ |
1025
|
|
|
|
|
|
|
sv = svp && *svp ? *svp : NULL; \ |
1026
|
|
|
|
|
|
|
if (sv) { \ |
1027
|
|
|
|
|
|
|
SvREFCNT_inc (sv); \ |
1028
|
|
|
|
|
|
|
/* upgrade IV to IVPV if needed */ \ |
1029
|
|
|
|
|
|
|
(void)SvPV_nolen (sv); \ |
1030
|
|
|
|
|
|
|
} \ |
1031
|
|
|
|
|
|
|
AV_PUSH; \ |
1032
|
|
|
|
|
|
|
} \ |
1033
|
|
|
|
|
|
|
return TRUE; \ |
1034
|
|
|
|
|
|
|
} \ |
1035
|
|
|
|
|
|
|
} |
1036
|
|
|
|
|
|
|
|
1037
|
|
|
|
|
|
|
#define Combine(csv,dst,fields) cx_Combine (aTHX_ csv, dst, fields) |
1038
|
21647
|
|
|
|
|
|
static int cx_Combine (pTHX_ csv_t *csv, SV *dst, AV *fields) { |
1039
|
|
|
|
|
|
|
SSize_t i, n; |
1040
|
21647
|
|
|
|
|
|
int bound = 0; |
1041
|
21647
|
|
|
|
|
|
int aq = (int)csv->always_quote; |
1042
|
21647
|
|
|
|
|
|
int qe = (int)csv->quote_empty; |
1043
|
21647
|
|
|
|
|
|
int kmi = (int)csv->keep_meta_info; |
1044
|
21647
|
|
|
|
|
|
AV *qm = NULL; |
1045
|
|
|
|
|
|
|
|
1046
|
21647
|
|
|
|
|
|
n = (IV)av_len (fields); |
1047
|
21647
|
100
|
|
|
|
|
if (n < 0 && csv->is_bound) { |
|
|
100
|
|
|
|
|
|
1048
|
5
|
|
|
|
|
|
n = csv->is_bound - 1; |
1049
|
5
|
|
|
|
|
|
bound = 1; |
1050
|
|
|
|
|
|
|
} |
1051
|
|
|
|
|
|
|
|
1052
|
21647
|
100
|
|
|
|
|
if (kmi >= 10) { |
1053
|
|
|
|
|
|
|
SV **svp; |
1054
|
2
|
50
|
|
|
|
|
if ((svp = hv_fetchs (csv->self, "_FFLAGS", FALSE)) && _is_arrayref (*svp)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1055
|
2
|
|
|
|
|
|
AV *avp = (AV *)SvRV (*svp); |
1056
|
2
|
50
|
|
|
|
|
if (avp && av_len (avp) >= n) |
|
|
50
|
|
|
|
|
|
1057
|
2
|
|
|
|
|
|
qm = avp; |
1058
|
|
|
|
|
|
|
} |
1059
|
|
|
|
|
|
|
} |
1060
|
|
|
|
|
|
|
|
1061
|
75481
|
100
|
|
|
|
|
for (i = 0; i <= n; i++) { |
1062
|
|
|
|
|
|
|
SV *sv; |
1063
|
53845
|
|
|
|
|
|
STRLEN len = 0; |
1064
|
53845
|
|
|
|
|
|
char *ptr = NULL; |
1065
|
|
|
|
|
|
|
|
1066
|
53845
|
100
|
|
|
|
|
if (i > 0) { |
1067
|
32206
|
50
|
|
|
|
|
CSV_PUT (csv, dst, CH_SEP); |
|
|
0
|
|
|
|
|
|
1068
|
32199
|
100
|
|
|
|
|
if (csv->sep_len) { |
1069
|
|
|
|
|
|
|
int x; |
1070
|
30
|
100
|
|
|
|
|
for (x = 1; x < (int)csv->sep_len; x++) |
1071
|
20
|
50
|
|
|
|
|
CSV_PUT (csv, dst, csv->sep[x]); |
|
|
0
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
} |
1073
|
|
|
|
|
|
|
} |
1074
|
|
|
|
|
|
|
|
1075
|
53845
|
100
|
|
|
|
|
if (bound) |
1076
|
14
|
|
|
|
|
|
sv = bound_field (csv, i, 1); |
1077
|
|
|
|
|
|
|
else { |
1078
|
53831
|
|
|
|
|
|
SV **svp = av_fetch (fields, i, FALSE); |
1079
|
53831
|
50
|
|
|
|
|
sv = svp && *svp ? *svp : NULL; |
|
|
50
|
|
|
|
|
|
1080
|
|
|
|
|
|
|
} |
1081
|
|
|
|
|
|
|
|
1082
|
53845
|
50
|
|
|
|
|
if (sv && (SvOK (sv) || ( |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1083
|
53779
|
0
|
|
|
|
|
(SvGMAGICAL (sv) && (mg_get (sv), 1) && SvOK (sv))))) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
|
1085
|
|
|
|
|
|
|
int quoteMe; |
1086
|
|
|
|
|
|
|
|
1087
|
53792
|
100
|
|
|
|
|
ptr = SvPV (sv, len); |
1088
|
|
|
|
|
|
|
|
1089
|
53792
|
100
|
|
|
|
|
if (*ptr == '=' && csv->formula) { |
|
|
100
|
|
|
|
|
|
1090
|
10
|
100
|
|
|
|
|
unless (ptr = _formula (csv, sv, &len, i)) |
1091
|
2
|
|
|
|
|
|
continue; |
1092
|
|
|
|
|
|
|
} |
1093
|
53786
|
100
|
|
|
|
|
if (len == 0) |
1094
|
1404
|
100
|
|
|
|
|
quoteMe = aq ? 1 : qe ? 1 : qm ? was_quoted (qm, i) : 0; |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
else { |
1096
|
|
|
|
|
|
|
|
1097
|
52382
|
100
|
|
|
|
|
if (SvUTF8 (sv)) { |
1098
|
20041
|
|
|
|
|
|
csv->utf8 = 1; |
1099
|
20041
|
|
|
|
|
|
csv->binary = 1; |
1100
|
|
|
|
|
|
|
} |
1101
|
|
|
|
|
|
|
|
1102
|
52382
|
100
|
|
|
|
|
quoteMe = aq ? 1 : qm ? was_quoted (qm, i) : 0; |
|
|
100
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
|
1104
|
|
|
|
|
|
|
/* Do we need quoting? We do quote, if the user requested |
1105
|
|
|
|
|
|
|
* (always_quote), if binary or blank characters are found |
1106
|
|
|
|
|
|
|
* and if the string contains quote or escape characters. |
1107
|
|
|
|
|
|
|
*/ |
1108
|
99136
|
100
|
|
|
|
|
if (!quoteMe && |
|
|
100
|
|
|
|
|
|
1109
|
46754
|
100
|
|
|
|
|
( quoteMe = (!SvIOK (sv) && !SvNOK (sv) && CH_QUOTE))) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
char *ptr2; |
1111
|
|
|
|
|
|
|
STRLEN l; |
1112
|
|
|
|
|
|
|
|
1113
|
|
|
|
|
|
|
#if MAINT_DEBUG > 4 |
1114
|
|
|
|
|
|
|
(void)fprintf (stderr, "# Combine:\n"); |
1115
|
|
|
|
|
|
|
sv_dump (sv); |
1116
|
|
|
|
|
|
|
#endif |
1117
|
85816
|
100
|
|
|
|
|
for (ptr2 = ptr, l = len; l; ++ptr2, --l) { |
1118
|
83767
|
|
|
|
|
|
byte c = *ptr2; |
1119
|
|
|
|
|
|
|
#ifdef IS_EBCDIC |
1120
|
|
|
|
|
|
|
byte x = ebcdic2ascii[c]; |
1121
|
|
|
|
|
|
|
#if MAINT_DEBUG > 4 |
1122
|
|
|
|
|
|
|
(void)fprintf (stderr, " %02x", x); |
1123
|
|
|
|
|
|
|
#endif |
1124
|
|
|
|
|
|
|
#else |
1125
|
83767
|
|
|
|
|
|
byte x = c; |
1126
|
|
|
|
|
|
|
#endif |
1127
|
|
|
|
|
|
|
|
1128
|
166851
|
50
|
|
|
|
|
if ((CH_QUOTE && c == CH_QUOTE) || |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1129
|
83459
|
100
|
|
|
|
|
(CH_SEP && c == CH_SEP) || |
|
|
100
|
|
|
|
|
|
1130
|
166388
|
100
|
|
|
|
|
(csv->escape_char && c == csv->escape_char) || |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1131
|
83074
|
100
|
|
|
|
|
(csv->quote_binary ? (x >= 0x7f && x <= 0xa0) || |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1132
|
63053
|
|
|
|
|
|
x < csv->first_safe_char |
1133
|
15
|
50
|
|
|
|
|
: c == CH_NL || c == CH_CR || |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1134
|
5
|
100
|
|
|
|
|
(csv->quote_space && ( |
1135
|
3
|
50
|
|
|
|
|
c == CH_SPACE || c == CH_TAB)))) { |
1136
|
|
|
|
|
|
|
/* Binary character */ |
1137
|
|
|
|
|
|
|
break; |
1138
|
|
|
|
|
|
|
} |
1139
|
|
|
|
|
|
|
} |
1140
|
|
|
|
|
|
|
#if defined(IS_EBCDIC) && MAINT_DEBUG > 4 |
1141
|
|
|
|
|
|
|
(void)fprintf (stderr, "\n"); |
1142
|
|
|
|
|
|
|
#endif |
1143
|
25179
|
|
|
|
|
|
quoteMe = (l > 0); |
1144
|
|
|
|
|
|
|
} |
1145
|
|
|
|
|
|
|
} |
1146
|
53786
|
100
|
|
|
|
|
if (quoteMe) { |
1147
|
29412
|
50
|
|
|
|
|
CSV_PUT (csv, dst, CH_QUOTE); |
|
|
0
|
|
|
|
|
|
1148
|
29412
|
100
|
|
|
|
|
if (csv->quo_len) { |
1149
|
|
|
|
|
|
|
int x; |
1150
|
51
|
100
|
|
|
|
|
for (x = 1; x < (int)csv->quo_len; x++) |
1151
|
34
|
50
|
|
|
|
|
CSV_PUT (csv, dst, csv->quo[x]); |
|
|
0
|
|
|
|
|
|
1152
|
|
|
|
|
|
|
} |
1153
|
|
|
|
|
|
|
} |
1154
|
950415231
|
100
|
|
|
|
|
while (len-- > 0) { |
1155
|
950361452
|
|
|
|
|
|
char c = *ptr++; |
1156
|
950361452
|
|
|
|
|
|
int e = 0; |
1157
|
|
|
|
|
|
|
|
1158
|
950361452
|
100
|
|
|
|
|
if (!csv->binary && is_csv_binary (c)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1159
|
7
|
|
|
|
|
|
SvREFCNT_inc (sv); |
1160
|
7
|
|
|
|
|
|
csv->has_error_input = 1; |
1161
|
7
|
50
|
|
|
|
|
unless (hv_store (csv->self, "_ERROR_INPUT", 12, sv, 0)) |
1162
|
0
|
|
|
|
|
|
SvREFCNT_dec (sv); /* uncoverable statement memory fail */ |
1163
|
7
|
|
|
|
|
|
(void)SetDiag (csv, 2110); |
1164
|
7
|
|
|
|
|
|
return FALSE; |
1165
|
|
|
|
|
|
|
} |
1166
|
950361445
|
100
|
|
|
|
|
if (CH_QUOTE && (byte)c == CH_QUOTE && (csv->quo_len == 0 || |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1167
|
9
|
|
|
|
|
|
memcmp (ptr, csv->quo +1, csv->quo_len - 1) == 0)) |
1168
|
3217
|
|
|
|
|
|
e = 1; |
1169
|
|
|
|
|
|
|
else |
1170
|
950358228
|
100
|
|
|
|
|
if (c == csv->escape_char && csv->escape_char) |
|
|
100
|
|
|
|
|
|
1171
|
2163
|
|
|
|
|
|
e = 1; |
1172
|
|
|
|
|
|
|
else |
1173
|
950356065
|
100
|
|
|
|
|
if (c == (char)0 && csv->escape_null) { |
|
|
100
|
|
|
|
|
|
1174
|
29
|
|
|
|
|
|
e = 1; |
1175
|
29
|
|
|
|
|
|
c = '0'; |
1176
|
|
|
|
|
|
|
} |
1177
|
950361445
|
100
|
|
|
|
|
if (e && csv->escape_char) |
|
|
50
|
|
|
|
|
|
1178
|
5409
|
50
|
|
|
|
|
CSV_PUT (csv, dst, csv->escape_char); |
|
|
0
|
|
|
|
|
|
1179
|
950361445
|
100
|
|
|
|
|
CSV_PUT (csv, dst, c); |
|
|
50
|
|
|
|
|
|
1180
|
|
|
|
|
|
|
} |
1181
|
53779
|
100
|
|
|
|
|
if (quoteMe) { |
1182
|
29405
|
50
|
|
|
|
|
CSV_PUT (csv, dst, CH_QUOTE); |
|
|
0
|
|
|
|
|
|
1183
|
29405
|
100
|
|
|
|
|
if (csv->quo_len) { |
1184
|
|
|
|
|
|
|
int x; |
1185
|
51
|
100
|
|
|
|
|
for (x = 1; x < (int)csv->quo_len; x++) |
1186
|
34
|
50
|
|
|
|
|
CSV_PUT (csv, dst, csv->quo[x]); |
|
|
0
|
|
|
|
|
|
1187
|
|
|
|
|
|
|
} |
1188
|
|
|
|
|
|
|
} |
1189
|
|
|
|
|
|
|
} |
1190
|
|
|
|
|
|
|
else { |
1191
|
53
|
100
|
|
|
|
|
if (csv->undef_str) { |
1192
|
8
|
|
|
|
|
|
byte *ptr = csv->undef_str; |
1193
|
8
|
|
|
|
|
|
STRLEN len = strlen ((char *)ptr); |
1194
|
|
|
|
|
|
|
|
1195
|
8
|
100
|
|
|
|
|
if (csv->undef_flg) { |
1196
|
3
|
|
|
|
|
|
csv->utf8 = 1; |
1197
|
3
|
|
|
|
|
|
csv->binary = 1; |
1198
|
|
|
|
|
|
|
} |
1199
|
|
|
|
|
|
|
|
1200
|
53852
|
100
|
|
|
|
|
while (len--) |
1201
|
20
|
50
|
|
|
|
|
CSV_PUT (csv, dst, *ptr++); |
|
|
0
|
|
|
|
|
|
1202
|
|
|
|
|
|
|
} |
1203
|
|
|
|
|
|
|
} |
1204
|
|
|
|
|
|
|
} |
1205
|
21636
|
100
|
|
|
|
|
if (csv->eol_len) { |
1206
|
249
|
|
|
|
|
|
STRLEN len = csv->eol_len; |
1207
|
249
|
|
|
|
|
|
byte *ptr = csv->eol; |
1208
|
|
|
|
|
|
|
|
1209
|
696
|
100
|
|
|
|
|
while (len--) |
1210
|
447
|
50
|
|
|
|
|
CSV_PUT (csv, dst, *ptr++); |
|
|
0
|
|
|
|
|
|
1211
|
|
|
|
|
|
|
} |
1212
|
21636
|
100
|
|
|
|
|
if (csv->used) |
1213
|
21634
|
|
|
|
|
|
return Print (csv, dst); |
1214
|
2
|
|
|
|
|
|
return TRUE; |
1215
|
|
|
|
|
|
|
} /* Combine */ |
1216
|
|
|
|
|
|
|
|
1217
|
|
|
|
|
|
|
#define ParseError(csv,xse,pos) cx_ParseError (aTHX_ csv, xse, pos) |
1218
|
299
|
|
|
|
|
|
static void cx_ParseError (pTHX_ csv_t *csv, int xse, STRLEN pos) { |
1219
|
299
|
|
|
|
|
|
(void)hv_store (csv->self, "_ERROR_POS", 10, newSViv (pos), 0); |
1220
|
299
|
|
|
|
|
|
(void)hv_store (csv->self, "_ERROR_FLD", 10, newSViv (csv->fld_idx), 0); |
1221
|
299
|
50
|
|
|
|
|
if (csv->tmp) { |
1222
|
299
|
|
|
|
|
|
csv->has_error_input = 1; |
1223
|
299
|
50
|
|
|
|
|
if (hv_store (csv->self, "_ERROR_INPUT", 12, csv->tmp, 0)) |
1224
|
299
|
|
|
|
|
|
SvREFCNT_inc (csv->tmp); |
1225
|
|
|
|
|
|
|
} |
1226
|
299
|
|
|
|
|
|
(void)SetDiag (csv, xse); |
1227
|
296
|
|
|
|
|
|
} /* ParseError */ |
1228
|
|
|
|
|
|
|
|
1229
|
|
|
|
|
|
|
#define CsvGet(csv,src) cx_CsvGet (aTHX_ csv, src) |
1230
|
4868
|
|
|
|
|
|
static int cx_CsvGet (pTHX_ csv_t *csv, SV *src) { |
1231
|
4868
|
100
|
|
|
|
|
unless (csv->useIO) |
1232
|
1518
|
|
|
|
|
|
return EOF; |
1233
|
|
|
|
|
|
|
|
1234
|
3350
|
100
|
|
|
|
|
if (csv->tmp && csv->eol_pos >= 0) { |
|
|
100
|
|
|
|
|
|
1235
|
348
|
|
|
|
|
|
csv->eol_pos = -2; |
1236
|
348
|
|
|
|
|
|
sv_setpvn (csv->tmp, (char *)csv->eol, csv->eol_len); |
1237
|
348
|
50
|
|
|
|
|
csv->bptr = SvPV (csv->tmp, csv->size); |
1238
|
348
|
|
|
|
|
|
csv->used = 0; |
1239
|
348
|
|
|
|
|
|
return CH_EOLX; |
1240
|
|
|
|
|
|
|
} |
1241
|
|
|
|
|
|
|
|
1242
|
|
|
|
|
|
|
{ STRLEN result; |
1243
|
3002
|
|
|
|
|
|
dSP; |
1244
|
|
|
|
|
|
|
|
1245
|
3002
|
50
|
|
|
|
|
PUSHMARK (sp); |
1246
|
3002
|
50
|
|
|
|
|
EXTEND (sp, 1); |
1247
|
3002
|
|
|
|
|
|
PUSHs (src); |
1248
|
3002
|
|
|
|
|
|
PUTBACK; |
1249
|
3002
|
|
|
|
|
|
result = call_sv (m_getline, G_METHOD); |
1250
|
3002
|
|
|
|
|
|
SPAGAIN; |
1251
|
3002
|
|
|
|
|
|
csv->eol_pos = -1; |
1252
|
3002
|
50
|
|
|
|
|
csv->tmp = result ? POPs : NULL; |
1253
|
3002
|
|
|
|
|
|
PUTBACK; |
1254
|
|
|
|
|
|
|
|
1255
|
|
|
|
|
|
|
#if MAINT_DEBUG > 4 |
1256
|
|
|
|
|
|
|
(void)fprintf (stderr, "getline () returned:\n"); |
1257
|
|
|
|
|
|
|
sv_dump (csv->tmp); |
1258
|
|
|
|
|
|
|
#endif |
1259
|
|
|
|
|
|
|
} |
1260
|
3002
|
50
|
|
|
|
|
if (csv->tmp && SvOK (csv->tmp)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1261
|
|
|
|
|
|
|
STRLEN tmp_len; |
1262
|
2453
|
50
|
|
|
|
|
csv->bptr = SvPV (csv->tmp, tmp_len); |
1263
|
2453
|
|
|
|
|
|
csv->used = 0; |
1264
|
2453
|
|
|
|
|
|
csv->size = tmp_len; |
1265
|
2453
|
100
|
|
|
|
|
if (csv->eolx && csv->size >= csv->eol_len) { |
|
|
50
|
|
|
|
|
|
1266
|
358
|
|
|
|
|
|
int i, match = 1; |
1267
|
1817
|
100
|
|
|
|
|
for (i = 1; i <= (int)csv->eol_len; i++) { |
1268
|
1463
|
100
|
|
|
|
|
unless (csv->bptr[csv->size - i] == csv->eol[csv->eol_len - i]) { |
1269
|
4
|
|
|
|
|
|
match = 0; |
1270
|
4
|
|
|
|
|
|
break; |
1271
|
|
|
|
|
|
|
} |
1272
|
|
|
|
|
|
|
} |
1273
|
358
|
100
|
|
|
|
|
if (match) { |
1274
|
|
|
|
|
|
|
#if MAINT_DEBUG > 4 |
1275
|
|
|
|
|
|
|
(void)fprintf (stderr, "# EOLX match, size: %d\n", csv->size); |
1276
|
|
|
|
|
|
|
#endif |
1277
|
354
|
|
|
|
|
|
csv->size -= csv->eol_len; |
1278
|
354
|
100
|
|
|
|
|
unless (csv->verbatim) |
1279
|
351
|
|
|
|
|
|
csv->eol_pos = csv->size; |
1280
|
354
|
|
|
|
|
|
csv->bptr[csv->size] = (char)0; |
1281
|
354
|
|
|
|
|
|
SvCUR_set (csv->tmp, csv->size); |
1282
|
354
|
100
|
|
|
|
|
unless (csv->verbatim || csv->size) |
|
|
100
|
|
|
|
|
|
1283
|
2453
|
|
|
|
|
|
return CH_EOLX; |
1284
|
|
|
|
|
|
|
} |
1285
|
|
|
|
|
|
|
} |
1286
|
2447
|
100
|
|
|
|
|
if (SvUTF8 (csv->tmp)) csv->utf8 = 1; |
1287
|
2447
|
50
|
|
|
|
|
if (tmp_len) |
1288
|
2447
|
|
|
|
|
|
return ((byte)csv->bptr[csv->used++]); |
1289
|
|
|
|
|
|
|
} |
1290
|
549
|
|
|
|
|
|
csv->useIO |= useIO_EOF; |
1291
|
549
|
|
|
|
|
|
return EOF; |
1292
|
|
|
|
|
|
|
} /* CsvGet */ |
1293
|
|
|
|
|
|
|
|
1294
|
|
|
|
|
|
|
#define ERROR_INSIDE_QUOTES(diag_code) { \ |
1295
|
|
|
|
|
|
|
unless (csv->is_bound) SvREFCNT_dec (sv); \ |
1296
|
|
|
|
|
|
|
ParseError (csv, diag_code, csv->used - 1); \ |
1297
|
|
|
|
|
|
|
return FALSE; \ |
1298
|
|
|
|
|
|
|
} |
1299
|
|
|
|
|
|
|
#define ERROR_INSIDE_FIELD(diag_code) { \ |
1300
|
|
|
|
|
|
|
unless (csv->is_bound) SvREFCNT_dec (sv); \ |
1301
|
|
|
|
|
|
|
ParseError (csv, diag_code, csv->used - 1); \ |
1302
|
|
|
|
|
|
|
return FALSE; \ |
1303
|
|
|
|
|
|
|
} |
1304
|
|
|
|
|
|
|
|
1305
|
|
|
|
|
|
|
#if MAINT_DEBUG > 4 |
1306
|
|
|
|
|
|
|
#define PUT_RPT (void)fprintf (stderr, "# CSV_PUT @ %4d: 0x%02x '%c'\n", __LINE__, c, isprint (c) ? c : '?') |
1307
|
|
|
|
|
|
|
#define PUT_SEPX_RPT1 (void)fprintf (stderr, "# PUT SEPX @ %4d\n", __LINE__) |
1308
|
|
|
|
|
|
|
#define PUT_SEPX_RPT2 (void)fprintf (stderr, "# Done putting SEPX\n") |
1309
|
|
|
|
|
|
|
#define PUT_QUOX_RPT1 (void)fprintf (stderr, "# PUT QUOX @ %4d\n", __LINE__) |
1310
|
|
|
|
|
|
|
#define PUT_QUOX_RPT2 (void)fprintf (stderr, "# Done putting QUOX\n") |
1311
|
|
|
|
|
|
|
#define PUT_EOLX_RPT1 (void)fprintf (stderr, "# PUT EOLX @ %4d\n", __LINE__) |
1312
|
|
|
|
|
|
|
#define PUT_EOLX_RPT2 (void)fprintf (stderr, "# Done putting EOLX\n") |
1313
|
|
|
|
|
|
|
#define PUSH_RPT (void)fprintf (stderr, "# AV_PUSHd @ %4d\n", __LINE__); sv_dump (sv) |
1314
|
|
|
|
|
|
|
#else |
1315
|
|
|
|
|
|
|
#define PUT_RPT |
1316
|
|
|
|
|
|
|
#define PUT_SEPX_RPT1 |
1317
|
|
|
|
|
|
|
#define PUT_SEPX_RPT2 |
1318
|
|
|
|
|
|
|
#define PUT_QUOX_RPT1 |
1319
|
|
|
|
|
|
|
#define PUT_QUOX_RPT2 |
1320
|
|
|
|
|
|
|
#define PUT_EOLX_RPT1 |
1321
|
|
|
|
|
|
|
#define PUT_EOLX_RPT2 |
1322
|
|
|
|
|
|
|
#define PUSH_RPT |
1323
|
|
|
|
|
|
|
#endif |
1324
|
|
|
|
|
|
|
#define CSV_PUT_SV1(c) { \ |
1325
|
|
|
|
|
|
|
len = SvCUR ((sv)); \ |
1326
|
|
|
|
|
|
|
SvGROW ((sv), len + 2); \ |
1327
|
|
|
|
|
|
|
*SvEND ((sv)) = c; \ |
1328
|
|
|
|
|
|
|
PUT_RPT; \ |
1329
|
|
|
|
|
|
|
SvCUR_set ((sv), len + 1); \ |
1330
|
|
|
|
|
|
|
} |
1331
|
|
|
|
|
|
|
#define CSV_PUT_SV(c) { \ |
1332
|
|
|
|
|
|
|
if (c == CH_EOLX) { \ |
1333
|
|
|
|
|
|
|
int x; PUT_EOLX_RPT1; \ |
1334
|
|
|
|
|
|
|
if (csv->eol_pos == -2) \ |
1335
|
|
|
|
|
|
|
csv->size = 0; \ |
1336
|
|
|
|
|
|
|
for (x = 0; x < (int)csv->eol_len; x++) \ |
1337
|
|
|
|
|
|
|
CSV_PUT_SV1 (csv->eol[x]); \ |
1338
|
|
|
|
|
|
|
csv->eol_pos = -1; \ |
1339
|
|
|
|
|
|
|
PUT_EOLX_RPT2; \ |
1340
|
|
|
|
|
|
|
} \ |
1341
|
|
|
|
|
|
|
else if (c == CH_SEPX) { \ |
1342
|
|
|
|
|
|
|
int x; PUT_SEPX_RPT1; \ |
1343
|
|
|
|
|
|
|
for (x = 0; x < (int)csv->sep_len; x++) \ |
1344
|
|
|
|
|
|
|
CSV_PUT_SV1 (csv->sep[x]); \ |
1345
|
|
|
|
|
|
|
PUT_SEPX_RPT2; \ |
1346
|
|
|
|
|
|
|
} \ |
1347
|
|
|
|
|
|
|
else if (c == CH_QUOTEX) { \ |
1348
|
|
|
|
|
|
|
int x; PUT_QUOX_RPT1; \ |
1349
|
|
|
|
|
|
|
for (x = 0; x < (int)csv->quo_len; x++) \ |
1350
|
|
|
|
|
|
|
CSV_PUT_SV1 (csv->quo[x]); \ |
1351
|
|
|
|
|
|
|
PUT_QUOX_RPT2; \ |
1352
|
|
|
|
|
|
|
} \ |
1353
|
|
|
|
|
|
|
else \ |
1354
|
|
|
|
|
|
|
CSV_PUT_SV1 (c); \ |
1355
|
|
|
|
|
|
|
} |
1356
|
|
|
|
|
|
|
|
1357
|
|
|
|
|
|
|
#define CSV_GET1 \ |
1358
|
|
|
|
|
|
|
(csv->used < csv->size ? (byte)csv->bptr[csv->used++] : CsvGet (csv, src)) |
1359
|
|
|
|
|
|
|
|
1360
|
|
|
|
|
|
|
#if MAINT_DEBUG > 3 |
1361
|
|
|
|
|
|
|
int CSV_GET_ (pTHX_ csv_t *csv, SV *src, int l) { |
1362
|
|
|
|
|
|
|
int c; |
1363
|
|
|
|
|
|
|
(void)fprintf (stderr, "# 1-CSV_GET @ %4d: (used: %d, size: %d, eol_pos: %d, eolx = %d)\n", l, csv->used, csv->size, csv->eol_pos, csv->eolx); |
1364
|
|
|
|
|
|
|
c = CSV_GET1; |
1365
|
|
|
|
|
|
|
(void)fprintf (stderr, "# 2-CSV_GET @ %4d: 0x%02x '%c'\n", l, c, isprint (c) ? c : '?'); |
1366
|
|
|
|
|
|
|
return (c); |
1367
|
|
|
|
|
|
|
} /* CSV_GET_ */ |
1368
|
|
|
|
|
|
|
#define CSV_GET CSV_GET_ (aTHX_ csv, src, __LINE__) |
1369
|
|
|
|
|
|
|
#else |
1370
|
|
|
|
|
|
|
#define CSV_GET CSV_GET1 |
1371
|
|
|
|
|
|
|
#endif |
1372
|
|
|
|
|
|
|
|
1373
|
|
|
|
|
|
|
#define AV_PUSH { \ |
1374
|
|
|
|
|
|
|
int svc; \ |
1375
|
|
|
|
|
|
|
*SvEND (sv) = (char)0; \ |
1376
|
|
|
|
|
|
|
svc = SvCUR (sv); \ |
1377
|
|
|
|
|
|
|
SvUTF8_off (sv); \ |
1378
|
|
|
|
|
|
|
if (svc && csv->formula && *(SvPV_nolen (sv)) == '=') \ |
1379
|
|
|
|
|
|
|
(void)_formula (csv, sv, NULL, fnum); \ |
1380
|
|
|
|
|
|
|
if (svc == 0 && ( \ |
1381
|
|
|
|
|
|
|
csv->empty_is_undef || \ |
1382
|
|
|
|
|
|
|
(!(f & CSV_FLAGS_QUO) && csv->blank_is_undef))) \ |
1383
|
|
|
|
|
|
|
SvSetUndef (sv); \ |
1384
|
|
|
|
|
|
|
else { \ |
1385
|
|
|
|
|
|
|
if (csv->allow_whitespace && ! (f & CSV_FLAGS_QUO)) \ |
1386
|
|
|
|
|
|
|
strip_trail_whitespace (sv); \ |
1387
|
|
|
|
|
|
|
if (f & CSV_FLAGS_BIN && csv->decode_utf8 \ |
1388
|
|
|
|
|
|
|
&& (csv->utf8 || is_utf8_sv (sv))) \ |
1389
|
|
|
|
|
|
|
SvUTF8_on (sv); \ |
1390
|
|
|
|
|
|
|
} \ |
1391
|
|
|
|
|
|
|
SvSETMAGIC (sv); \ |
1392
|
|
|
|
|
|
|
unless (csv->is_bound) av_push (fields, sv); \ |
1393
|
|
|
|
|
|
|
PUSH_RPT; \ |
1394
|
|
|
|
|
|
|
sv = NULL; \ |
1395
|
|
|
|
|
|
|
if (csv->keep_meta_info && fflags) \ |
1396
|
|
|
|
|
|
|
av_push (fflags, newSViv (f)); \ |
1397
|
|
|
|
|
|
|
waitingForField = 1; \ |
1398
|
|
|
|
|
|
|
} |
1399
|
|
|
|
|
|
|
|
1400
|
|
|
|
|
|
|
#define strip_trail_whitespace(sv) cx_strip_trail_whitespace (aTHX_ sv) |
1401
|
1723
|
|
|
|
|
|
static void cx_strip_trail_whitespace (pTHX_ SV *sv) { |
1402
|
|
|
|
|
|
|
STRLEN len; |
1403
|
1723
|
50
|
|
|
|
|
char *s = SvPV (sv, len); |
1404
|
1723
|
50
|
|
|
|
|
unless (s && len) return; |
|
|
50
|
|
|
|
|
|
1405
|
1899
|
100
|
|
|
|
|
while (s[len - 1] == CH_SPACE || s[len - 1] == CH_TAB) |
|
|
50
|
|
|
|
|
|
1406
|
176
|
|
|
|
|
|
s[--len] = (char)0; |
1407
|
1723
|
|
|
|
|
|
SvCUR_set (sv, len); |
1408
|
|
|
|
|
|
|
} /* strip_trail_whitespace */ |
1409
|
|
|
|
|
|
|
|
1410
|
|
|
|
|
|
|
#define NewField \ |
1411
|
|
|
|
|
|
|
unless (sv) { \ |
1412
|
|
|
|
|
|
|
if (csv->is_bound) \ |
1413
|
|
|
|
|
|
|
sv = bound_field (csv, fnum, 0); \ |
1414
|
|
|
|
|
|
|
else \ |
1415
|
|
|
|
|
|
|
sv = newSVpvs (""); \ |
1416
|
|
|
|
|
|
|
fnum++; \ |
1417
|
|
|
|
|
|
|
unless (sv) return FALSE; \ |
1418
|
|
|
|
|
|
|
f = 0; csv->fld_idx++; \ |
1419
|
|
|
|
|
|
|
} |
1420
|
|
|
|
|
|
|
|
1421
|
|
|
|
|
|
|
#if MAINT_DEBUG |
1422
|
|
|
|
|
|
|
static char str_parsed[40]; |
1423
|
|
|
|
|
|
|
#endif |
1424
|
|
|
|
|
|
|
|
1425
|
|
|
|
|
|
|
#if MAINT_DEBUG > 1 |
1426
|
|
|
|
|
|
|
static char *_sep_string (csv_t *csv) { |
1427
|
|
|
|
|
|
|
char sep[64]; |
1428
|
|
|
|
|
|
|
if (csv->sep_len) { |
1429
|
|
|
|
|
|
|
int x; |
1430
|
|
|
|
|
|
|
for (x = 0; x < csv->sep_len; x++) |
1431
|
|
|
|
|
|
|
(void)sprintf (sep + x * x, "%02x ", csv->sep[x]); |
1432
|
|
|
|
|
|
|
} |
1433
|
|
|
|
|
|
|
else |
1434
|
|
|
|
|
|
|
(void)sprintf (sep, "'%c' (0x%02x)", CH_SEP, CH_SEP); |
1435
|
|
|
|
|
|
|
return sep; |
1436
|
|
|
|
|
|
|
} /* _sep_string */ |
1437
|
|
|
|
|
|
|
#endif |
1438
|
|
|
|
|
|
|
|
1439
|
|
|
|
|
|
|
#define Parse(csv,src,fields,fflags) cx_Parse (aTHX_ csv, src, fields, fflags) |
1440
|
4554
|
|
|
|
|
|
static int cx_Parse (pTHX_ csv_t *csv, SV *src, AV *fields, AV *fflags) { |
1441
|
4554
|
|
|
|
|
|
int c, f = 0; |
1442
|
4554
|
|
|
|
|
|
int waitingForField = 1; |
1443
|
4554
|
|
|
|
|
|
SV *sv = NULL; |
1444
|
|
|
|
|
|
|
STRLEN len; |
1445
|
4554
|
|
|
|
|
|
int seenSomething = FALSE; |
1446
|
4554
|
|
|
|
|
|
int fnum = 0; |
1447
|
4554
|
|
|
|
|
|
int spl = -1; |
1448
|
|
|
|
|
|
|
#if MAINT_DEBUG |
1449
|
|
|
|
|
|
|
(void)memset (str_parsed, 0, 40); |
1450
|
|
|
|
|
|
|
#endif |
1451
|
|
|
|
|
|
|
|
1452
|
4554
|
|
|
|
|
|
csv->fld_idx = 0; |
1453
|
|
|
|
|
|
|
|
1454
|
186728
|
100
|
|
|
|
|
while ((c = CSV_GET) != EOF) { |
|
|
100
|
|
|
|
|
|
1455
|
|
|
|
|
|
|
|
1456
|
185991
|
100
|
|
|
|
|
NewField; |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1457
|
|
|
|
|
|
|
|
1458
|
185987
|
|
|
|
|
|
seenSomething = TRUE; |
1459
|
185987
|
|
|
|
|
|
spl++; |
1460
|
|
|
|
|
|
|
#if MAINT_DEBUG |
1461
|
|
|
|
|
|
|
if (spl < 39) str_parsed[spl] = c; |
1462
|
|
|
|
|
|
|
#endif |
1463
|
|
|
|
|
|
|
restart: |
1464
|
|
|
|
|
|
|
#if MAINT_DEBUG > 9 |
1465
|
|
|
|
|
|
|
(void)fprintf (stderr, "# at restart: %d/%d/%03x pos %d = 0x%02x\n", |
1466
|
|
|
|
|
|
|
waitingForField ? 1 : 0, sv ? 1 : 0, f, spl, c); |
1467
|
|
|
|
|
|
|
#endif |
1468
|
196721
|
100
|
|
|
|
|
if (is_SEP (c)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1469
|
|
|
|
|
|
|
#if MAINT_DEBUG > 1 |
1470
|
|
|
|
|
|
|
(void)fprintf (stderr, "# %d/%d/%03x pos %d = SEP %s\t%s\n", |
1471
|
|
|
|
|
|
|
waitingForField ? 1 : 0, sv ? 1 : 0, f, spl, |
1472
|
|
|
|
|
|
|
_sep_string (csv), _pretty_strl (csv->bptr + csv->used)); |
1473
|
|
|
|
|
|
|
#endif |
1474
|
23634
|
100
|
|
|
|
|
if (waitingForField) { |
1475
|
|
|
|
|
|
|
/* ,1,"foo, 3",,bar, |
1476
|
|
|
|
|
|
|
* ^ ^ |
1477
|
|
|
|
|
|
|
*/ |
1478
|
1170
|
100
|
|
|
|
|
if (csv->blank_is_undef || csv->empty_is_undef) |
|
|
100
|
|
|
|
|
|
1479
|
50
|
|
|
|
|
|
SvSetUndef (sv); |
1480
|
|
|
|
|
|
|
else |
1481
|
1120
|
|
|
|
|
|
SvSetEmpty (sv); |
1482
|
1170
|
50
|
|
|
|
|
unless (csv->is_bound) |
1483
|
1170
|
|
|
|
|
|
av_push (fields, sv); |
1484
|
1170
|
|
|
|
|
|
sv = NULL; |
1485
|
1170
|
100
|
|
|
|
|
if (csv->keep_meta_info && fflags) |
|
|
50
|
|
|
|
|
|
1486
|
1170
|
|
|
|
|
|
av_push (fflags, newSViv (f)); |
1487
|
|
|
|
|
|
|
} |
1488
|
|
|
|
|
|
|
else |
1489
|
10648
|
100
|
|
|
|
|
if (f & CSV_FLAGS_QUO) { |
1490
|
|
|
|
|
|
|
/* ,1,"foo, 3",,bar, |
1491
|
|
|
|
|
|
|
* ^ |
1492
|
|
|
|
|
|
|
*/ |
1493
|
2194
|
50
|
|
|
|
|
CSV_PUT_SV (c) |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1494
|
|
|
|
|
|
|
} |
1495
|
|
|
|
|
|
|
else { |
1496
|
|
|
|
|
|
|
/* ,1,"foo, 3",,bar, |
1497
|
|
|
|
|
|
|
* ^ ^ ^ |
1498
|
|
|
|
|
|
|
*/ |
1499
|
8454
|
100
|
|
|
|
|
AV_PUSH; |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1500
|
|
|
|
|
|
|
} |
1501
|
|
|
|
|
|
|
} /* SEP char */ |
1502
|
|
|
|
|
|
|
else |
1503
|
184903
|
100
|
|
|
|
|
if (is_QUOTE (c)) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1504
|
|
|
|
|
|
|
#if MAINT_DEBUG > 1 |
1505
|
|
|
|
|
|
|
(void)fprintf (stderr, "# %d/%d/%03x pos %d = QUO '%c'\t\t%s\n", |
1506
|
|
|
|
|
|
|
waitingForField ? 1 : 0, sv ? 1 : 0, f, spl, c, |
1507
|
|
|
|
|
|
|
_pretty_strl (csv->bptr + csv->used)); |
1508
|
|
|
|
|
|
|
#endif |
1509
|
22820
|
100
|
|
|
|
|
if (waitingForField) { |
1510
|
|
|
|
|
|
|
/* ,1,"foo, 3",,bar,\r\n |
1511
|
|
|
|
|
|
|
* ^ |
1512
|
|
|
|
|
|
|
*/ |
1513
|
10904
|
|
|
|
|
|
f |= CSV_FLAGS_QUO; |
1514
|
10904
|
|
|
|
|
|
waitingForField = 0; |
1515
|
10904
|
|
|
|
|
|
continue; |
1516
|
|
|
|
|
|
|
} |
1517
|
|
|
|
|
|
|
|
1518
|
11916
|
100
|
|
|
|
|
if (f & CSV_FLAGS_QUO) { |
1519
|
|
|
|
|
|
|
|
1520
|
|
|
|
|
|
|
/* ,1,"foo, 3",,bar,\r\n |
1521
|
|
|
|
|
|
|
* ^ |
1522
|
|
|
|
|
|
|
*/ |
1523
|
|
|
|
|
|
|
|
1524
|
11850
|
|
|
|
|
|
int quoesc = 0; |
1525
|
11850
|
100
|
|
|
|
|
int c2 = CSV_GET; |
1526
|
|
|
|
|
|
|
|
1527
|
11850
|
100
|
|
|
|
|
if (csv->allow_whitespace) { |
1528
|
|
|
|
|
|
|
/* , 1 , "foo, 3" , , bar , \r\n |
1529
|
|
|
|
|
|
|
* ^ |
1530
|
|
|
|
|
|
|
*/ |
1531
|
4330
|
100
|
|
|
|
|
while (is_whitespace (c2)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1532
|
90
|
100
|
|
|
|
|
if (csv->allow_loose_quotes && |
|
|
50
|
|
|
|
|
|
1533
|
0
|
0
|
|
|
|
|
!(csv->escape_char && c2 == csv->escape_char)) { |
1534
|
|
|
|
|
|
|
/* This feels like a brittle fix for RT115953, where |
1535
|
|
|
|
|
|
|
* ["foo "bar" baz"] got parsed as [foo "bar"baz] |
1536
|
|
|
|
|
|
|
* when both allow_whitespace and allow_loose_quotes |
1537
|
|
|
|
|
|
|
* are true and escape does not equal quote |
1538
|
|
|
|
|
|
|
*/ |
1539
|
1
|
50
|
|
|
|
|
CSV_PUT_SV (c); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1540
|
1
|
|
|
|
|
|
c = c2; |
1541
|
|
|
|
|
|
|
} |
1542
|
90
|
100
|
|
|
|
|
c2 = CSV_GET; |
1543
|
|
|
|
|
|
|
} |
1544
|
|
|
|
|
|
|
} |
1545
|
|
|
|
|
|
|
|
1546
|
11850
|
100
|
|
|
|
|
if (is_SEP (c2)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1547
|
|
|
|
|
|
|
/* ,1,"foo, 3",,bar,\r\n |
1548
|
|
|
|
|
|
|
* ^ |
1549
|
|
|
|
|
|
|
*/ |
1550
|
9014
|
100
|
|
|
|
|
AV_PUSH; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1551
|
9014
|
|
|
|
|
|
continue; |
1552
|
|
|
|
|
|
|
} |
1553
|
|
|
|
|
|
|
|
1554
|
2836
|
100
|
|
|
|
|
if (c2 == CH_NL || c2 == CH_EOLX) { |
|
|
100
|
|
|
|
|
|
1555
|
|
|
|
|
|
|
/* ,1,"foo, 3",,"bar"\n |
1556
|
|
|
|
|
|
|
* ^ |
1557
|
|
|
|
|
|
|
*/ |
1558
|
195
|
100
|
|
|
|
|
AV_PUSH; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1559
|
195
|
|
|
|
|
|
return TRUE; |
1560
|
|
|
|
|
|
|
} |
1561
|
|
|
|
|
|
|
|
1562
|
|
|
|
|
|
|
/* --- |
1563
|
|
|
|
|
|
|
* if QUOTE eq ESCAPE |
1564
|
|
|
|
|
|
|
* AND ( c2 eq QUOTE 1,"abc""def",2 |
1565
|
|
|
|
|
|
|
* OR c2 eq ESCAPE 1,"abc""def",2 (QUO eq ESC) |
1566
|
|
|
|
|
|
|
* OR c2 eq NULL ) 1,"abc"0def",2 |
1567
|
|
|
|
|
|
|
* --- |
1568
|
|
|
|
|
|
|
*/ |
1569
|
2641
|
100
|
|
|
|
|
if (csv->escape_char && c == csv->escape_char) { |
|
|
100
|
|
|
|
|
|
1570
|
|
|
|
|
|
|
|
1571
|
1544
|
|
|
|
|
|
quoesc = 1; |
1572
|
1544
|
100
|
|
|
|
|
if (c2 == '0') { |
1573
|
|
|
|
|
|
|
/* ,1,"foo, 3"056",,bar,\r\n |
1574
|
|
|
|
|
|
|
* ^ |
1575
|
|
|
|
|
|
|
*/ |
1576
|
25
|
50
|
|
|
|
|
CSV_PUT_SV (0) |
|
|
50
|
|
|
|
|
|
1577
|
25
|
|
|
|
|
|
continue; |
1578
|
|
|
|
|
|
|
} |
1579
|
|
|
|
|
|
|
|
1580
|
1519
|
50
|
|
|
|
|
if (is_QUOTE (c2)) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1581
|
|
|
|
|
|
|
/* ,1,"foo, 3""56",,bar,\r\n |
1582
|
|
|
|
|
|
|
* ^ |
1583
|
|
|
|
|
|
|
*/ |
1584
|
1056
|
100
|
|
|
|
|
if (csv->utf8) |
1585
|
1
|
|
|
|
|
|
f |= CSV_FLAGS_BIN; |
1586
|
1056
|
50
|
|
|
|
|
CSV_PUT_SV (c2) |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1587
|
1056
|
|
|
|
|
|
continue; |
1588
|
|
|
|
|
|
|
} |
1589
|
|
|
|
|
|
|
|
1590
|
463
|
100
|
|
|
|
|
if (csv->allow_loose_escapes && c2 != CH_CR) { |
|
|
100
|
|
|
|
|
|
1591
|
|
|
|
|
|
|
/* ,1,"foo, 3"56",,bar,\r\n |
1592
|
|
|
|
|
|
|
* ^ |
1593
|
|
|
|
|
|
|
*/ |
1594
|
2
|
50
|
|
|
|
|
CSV_PUT_SV (c); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1595
|
2
|
|
|
|
|
|
c = c2; |
1596
|
2
|
|
|
|
|
|
goto restart; |
1597
|
|
|
|
|
|
|
} |
1598
|
|
|
|
|
|
|
} |
1599
|
|
|
|
|
|
|
|
1600
|
1558
|
100
|
|
|
|
|
if (c2 == CH_CR) { |
1601
|
|
|
|
|
|
|
int c3; |
1602
|
|
|
|
|
|
|
|
1603
|
197
|
100
|
|
|
|
|
if (csv->eol_is_cr) { |
1604
|
|
|
|
|
|
|
/* ,1,"foo, 3"\r |
1605
|
|
|
|
|
|
|
* ^ |
1606
|
|
|
|
|
|
|
*/ |
1607
|
102
|
100
|
|
|
|
|
AV_PUSH; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1608
|
102
|
|
|
|
|
|
return TRUE; |
1609
|
|
|
|
|
|
|
} |
1610
|
|
|
|
|
|
|
|
1611
|
95
|
100
|
|
|
|
|
c3 = CSV_GET; |
1612
|
|
|
|
|
|
|
|
1613
|
95
|
100
|
|
|
|
|
if (c3 == CH_NL) { /* \r is not optional before EOLX! */ |
1614
|
|
|
|
|
|
|
/* ,1,"foo, 3"\r\n |
1615
|
|
|
|
|
|
|
* ^ |
1616
|
|
|
|
|
|
|
*/ |
1617
|
81
|
100
|
|
|
|
|
AV_PUSH; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1618
|
81
|
|
|
|
|
|
return TRUE; |
1619
|
|
|
|
|
|
|
} |
1620
|
|
|
|
|
|
|
|
1621
|
14
|
100
|
|
|
|
|
if (csv->useIO && csv->eol_len == 0) { |
|
|
50
|
|
|
|
|
|
1622
|
1
|
50
|
|
|
|
|
if (c3 == CH_CR) { /* \r followed by an empty line */ |
1623
|
|
|
|
|
|
|
/* ,1,"foo, 3"\r\r |
1624
|
|
|
|
|
|
|
* ^ |
1625
|
|
|
|
|
|
|
*/ |
1626
|
0
|
|
|
|
|
|
set_eol_is_cr (csv); |
1627
|
0
|
|
|
|
|
|
goto EOLX; |
1628
|
|
|
|
|
|
|
} |
1629
|
|
|
|
|
|
|
|
1630
|
1
|
50
|
|
|
|
|
if (!is_csv_binary (c3)) { |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1631
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,"bar"\r |
1632
|
|
|
|
|
|
|
* baz,4 |
1633
|
|
|
|
|
|
|
* ^ |
1634
|
|
|
|
|
|
|
*/ |
1635
|
1
|
|
|
|
|
|
set_eol_is_cr (csv); |
1636
|
1
|
|
|
|
|
|
csv->used--; |
1637
|
1
|
|
|
|
|
|
csv->has_ahead++; |
1638
|
1
|
50
|
|
|
|
|
AV_PUSH; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1639
|
1
|
|
|
|
|
|
return TRUE; |
1640
|
|
|
|
|
|
|
} |
1641
|
|
|
|
|
|
|
} |
1642
|
|
|
|
|
|
|
|
1643
|
13
|
100
|
|
|
|
|
ParseError (csv, quoesc ? 2023 : 2010, csv->used - 2); |
1644
|
13
|
|
|
|
|
|
return FALSE; |
1645
|
|
|
|
|
|
|
} |
1646
|
|
|
|
|
|
|
|
1647
|
1361
|
100
|
|
|
|
|
if (c2 == EOF) { |
1648
|
|
|
|
|
|
|
/* ,1,"foo, 3" |
1649
|
|
|
|
|
|
|
* ^ |
1650
|
|
|
|
|
|
|
*/ |
1651
|
1304
|
100
|
|
|
|
|
AV_PUSH; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1652
|
1304
|
|
|
|
|
|
return TRUE; |
1653
|
|
|
|
|
|
|
} |
1654
|
|
|
|
|
|
|
|
1655
|
57
|
100
|
|
|
|
|
if (csv->allow_loose_quotes && !quoesc) { |
|
|
100
|
|
|
|
|
|
1656
|
|
|
|
|
|
|
/* ,1,"foo, 3"456",,bar,\r\n |
1657
|
|
|
|
|
|
|
* ^ |
1658
|
|
|
|
|
|
|
*/ |
1659
|
10
|
50
|
|
|
|
|
CSV_PUT_SV (c); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1660
|
10
|
|
|
|
|
|
c = c2; |
1661
|
10
|
|
|
|
|
|
goto restart; |
1662
|
|
|
|
|
|
|
} |
1663
|
|
|
|
|
|
|
|
1664
|
|
|
|
|
|
|
/* 1,"foo" ",3 |
1665
|
|
|
|
|
|
|
* ^ |
1666
|
|
|
|
|
|
|
*/ |
1667
|
47
|
100
|
|
|
|
|
if (quoesc) { |
1668
|
39
|
|
|
|
|
|
csv->used--; |
1669
|
39
|
50
|
|
|
|
|
ERROR_INSIDE_QUOTES (2023); |
1670
|
|
|
|
|
|
|
} |
1671
|
|
|
|
|
|
|
|
1672
|
8
|
50
|
|
|
|
|
ERROR_INSIDE_QUOTES (2011); |
1673
|
|
|
|
|
|
|
} |
1674
|
|
|
|
|
|
|
|
1675
|
|
|
|
|
|
|
/* !waitingForField, !InsideQuotes */ |
1676
|
82
|
100
|
|
|
|
|
if (csv->allow_loose_quotes) { /* 1,foo "boo" d'uh,1 */ |
1677
|
16
|
|
|
|
|
|
f |= CSV_FLAGS_EIF; /* Mark as error-in-field */ |
1678
|
16
|
50
|
|
|
|
|
CSV_PUT_SV (c); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1679
|
|
|
|
|
|
|
} |
1680
|
|
|
|
|
|
|
else |
1681
|
50
|
100
|
|
|
|
|
ERROR_INSIDE_FIELD (2034); |
1682
|
|
|
|
|
|
|
} /* QUO char */ |
1683
|
|
|
|
|
|
|
else |
1684
|
162083
|
100
|
|
|
|
|
if (c == csv->escape_char && csv->escape_char) { |
|
|
100
|
|
|
|
|
|
1685
|
|
|
|
|
|
|
#if MAINT_DEBUG > 1 |
1686
|
|
|
|
|
|
|
(void)fprintf (stderr, "# %d/%d/%03x pos %d = ESC '%c'\t%s\n", |
1687
|
|
|
|
|
|
|
waitingForField ? 1 : 0, sv ? 1 : 0, f, spl, c, |
1688
|
|
|
|
|
|
|
_pretty_strl (csv->bptr + csv->used)); |
1689
|
|
|
|
|
|
|
#endif |
1690
|
|
|
|
|
|
|
/* This means quote_char != escape_char */ |
1691
|
9268
|
100
|
|
|
|
|
if (waitingForField) { |
1692
|
33
|
|
|
|
|
|
waitingForField = 0; |
1693
|
33
|
100
|
|
|
|
|
if (csv->allow_unquoted_escape) { |
1694
|
|
|
|
|
|
|
/* The escape character is the first character of an |
1695
|
|
|
|
|
|
|
* unquoted field */ |
1696
|
|
|
|
|
|
|
/* ... get and store next character */ |
1697
|
3
|
100
|
|
|
|
|
int c2 = CSV_GET; |
1698
|
|
|
|
|
|
|
|
1699
|
3
|
|
|
|
|
|
SvSetEmpty (sv); |
1700
|
|
|
|
|
|
|
|
1701
|
3
|
100
|
|
|
|
|
if (c2 == EOF) { |
1702
|
1
|
|
|
|
|
|
csv->used--; |
1703
|
1
|
50
|
|
|
|
|
ERROR_INSIDE_FIELD (2035); |
1704
|
|
|
|
|
|
|
} |
1705
|
|
|
|
|
|
|
|
1706
|
2
|
100
|
|
|
|
|
if (c2 == '0') |
1707
|
1
|
50
|
|
|
|
|
CSV_PUT_SV (0) |
|
|
50
|
|
|
|
|
|
1708
|
|
|
|
|
|
|
else |
1709
|
1
|
50
|
|
|
|
|
if ( is_QUOTE (c2) || is_SEP (c2) || |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1710
|
0
|
0
|
|
|
|
|
c2 == csv->escape_char || csv->allow_loose_escapes) { |
1711
|
1
|
50
|
|
|
|
|
if (csv->utf8) |
1712
|
0
|
|
|
|
|
|
f |= CSV_FLAGS_BIN; |
1713
|
1
|
50
|
|
|
|
|
CSV_PUT_SV (c2) |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1714
|
|
|
|
|
|
|
} |
1715
|
|
|
|
|
|
|
else { |
1716
|
0
|
|
|
|
|
|
csv->used--; |
1717
|
32
|
0
|
|
|
|
|
ERROR_INSIDE_QUOTES (2025); |
1718
|
|
|
|
|
|
|
} |
1719
|
|
|
|
|
|
|
} |
1720
|
|
|
|
|
|
|
} |
1721
|
|
|
|
|
|
|
else |
1722
|
4618
|
100
|
|
|
|
|
if (f & CSV_FLAGS_QUO) { |
1723
|
4610
|
100
|
|
|
|
|
int c2 = CSV_GET; |
1724
|
|
|
|
|
|
|
|
1725
|
4610
|
100
|
|
|
|
|
if (c2 == EOF) { |
1726
|
3
|
|
|
|
|
|
csv->used--; |
1727
|
3
|
50
|
|
|
|
|
ERROR_INSIDE_QUOTES (2024); |
1728
|
|
|
|
|
|
|
} |
1729
|
|
|
|
|
|
|
|
1730
|
4607
|
100
|
|
|
|
|
if (c2 == '0') |
1731
|
2
|
50
|
|
|
|
|
CSV_PUT_SV (0) |
|
|
50
|
|
|
|
|
|
1732
|
|
|
|
|
|
|
else |
1733
|
4605
|
50
|
|
|
|
|
if ( is_QUOTE (c2) || is_SEP (c2) || |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1734
|
28
|
100
|
|
|
|
|
c2 == csv->escape_char || csv->allow_loose_escapes) { |
1735
|
4579
|
100
|
|
|
|
|
if (csv->utf8) |
1736
|
1
|
|
|
|
|
|
f |= CSV_FLAGS_BIN; |
1737
|
4582
|
50
|
|
|
|
|
CSV_PUT_SV (c2) |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1738
|
|
|
|
|
|
|
} |
1739
|
|
|
|
|
|
|
else { |
1740
|
26
|
|
|
|
|
|
csv->used--; |
1741
|
4607
|
50
|
|
|
|
|
ERROR_INSIDE_QUOTES (2025); |
1742
|
|
|
|
|
|
|
} |
1743
|
|
|
|
|
|
|
} |
1744
|
|
|
|
|
|
|
else |
1745
|
8
|
50
|
|
|
|
|
if (sv) { |
1746
|
8
|
100
|
|
|
|
|
int c2 = CSV_GET; |
1747
|
|
|
|
|
|
|
|
1748
|
8
|
100
|
|
|
|
|
if (c2 == EOF) { |
1749
|
4
|
|
|
|
|
|
csv->used--; |
1750
|
4
|
50
|
|
|
|
|
ERROR_INSIDE_FIELD (2035); |
1751
|
|
|
|
|
|
|
} |
1752
|
|
|
|
|
|
|
|
1753
|
4
|
50
|
|
|
|
|
CSV_PUT_SV (c2); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1754
|
|
|
|
|
|
|
} |
1755
|
|
|
|
|
|
|
else |
1756
|
0
|
0
|
|
|
|
|
ERROR_INSIDE_FIELD (2036); /* uncoverable statement I think there's no way to get here */ |
1757
|
|
|
|
|
|
|
} /* ESC char */ |
1758
|
|
|
|
|
|
|
else |
1759
|
157432
|
100
|
|
|
|
|
if (c == CH_NL || is_EOL (c)) { |
|
|
100
|
|
|
|
|
|
1760
|
|
|
|
|
|
|
EOLX: |
1761
|
|
|
|
|
|
|
#if MAINT_DEBUG > 1 |
1762
|
|
|
|
|
|
|
(void)fprintf (stderr, "# %d/%d/%03x pos %d = NL\t%s\n", |
1763
|
|
|
|
|
|
|
waitingForField ? 1 : 0, sv ? 1 : 0, f, spl, |
1764
|
|
|
|
|
|
|
_pretty_strl (csv->bptr + csv->used)); |
1765
|
|
|
|
|
|
|
#endif |
1766
|
2638
|
100
|
|
|
|
|
if (fnum == 1 && f == 0 && SvCUR (sv) == 0 && csv->skip_empty_rows) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1767
|
91
|
100
|
|
|
|
|
SkipEmptyRow; |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1768
|
37
|
|
|
|
|
|
goto restart; |
1769
|
|
|
|
|
|
|
} |
1770
|
|
|
|
|
|
|
|
1771
|
2579
|
100
|
|
|
|
|
if (waitingForField) { |
1772
|
|
|
|
|
|
|
/* ,1,"foo, 3",,bar, |
1773
|
|
|
|
|
|
|
* ^ |
1774
|
|
|
|
|
|
|
*/ |
1775
|
226
|
100
|
|
|
|
|
if (csv->blank_is_undef || csv->empty_is_undef) |
|
|
100
|
|
|
|
|
|
1776
|
16
|
|
|
|
|
|
SvSetUndef (sv); |
1777
|
|
|
|
|
|
|
else |
1778
|
210
|
|
|
|
|
|
SvSetEmpty (sv); |
1779
|
226
|
50
|
|
|
|
|
unless (csv->is_bound) |
1780
|
226
|
|
|
|
|
|
av_push (fields, sv); |
1781
|
226
|
100
|
|
|
|
|
if (csv->keep_meta_info && fflags) |
|
|
50
|
|
|
|
|
|
1782
|
14
|
|
|
|
|
|
av_push (fflags, newSViv (f)); |
1783
|
226
|
|
|
|
|
|
return TRUE; |
1784
|
|
|
|
|
|
|
} |
1785
|
|
|
|
|
|
|
|
1786
|
3086
|
100
|
|
|
|
|
if (f & CSV_FLAGS_QUO) { |
1787
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,bar, |
1788
|
|
|
|
|
|
|
* ^ |
1789
|
|
|
|
|
|
|
*/ |
1790
|
744
|
|
|
|
|
|
f |= CSV_FLAGS_BIN; |
1791
|
744
|
100
|
|
|
|
|
unless (csv->binary) |
1792
|
19
|
50
|
|
|
|
|
ERROR_INSIDE_QUOTES (2021); |
1793
|
|
|
|
|
|
|
|
1794
|
799
|
100
|
|
|
|
|
CSV_PUT_SV (c); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1795
|
|
|
|
|
|
|
} |
1796
|
|
|
|
|
|
|
else |
1797
|
1609
|
100
|
|
|
|
|
if (csv->verbatim) { |
1798
|
|
|
|
|
|
|
/* ,1,foo\n 3,,bar, |
1799
|
|
|
|
|
|
|
* This feature should be deprecated |
1800
|
|
|
|
|
|
|
*/ |
1801
|
9
|
|
|
|
|
|
f |= CSV_FLAGS_BIN; |
1802
|
9
|
100
|
|
|
|
|
unless (csv->binary) |
1803
|
1
|
50
|
|
|
|
|
ERROR_INSIDE_FIELD (2030); |
1804
|
|
|
|
|
|
|
|
1805
|
14
|
100
|
|
|
|
|
CSV_PUT_SV (c); |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1806
|
|
|
|
|
|
|
} |
1807
|
|
|
|
|
|
|
else { |
1808
|
|
|
|
|
|
|
/* sep=, |
1809
|
|
|
|
|
|
|
* ^ |
1810
|
|
|
|
|
|
|
*/ |
1811
|
1600
|
100
|
|
|
|
|
if (csv->recno == 0 && csv->fld_idx == 1 && csv->useIO && |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1812
|
28
|
50
|
|
|
|
|
(csv->bptr[0] == 's' || csv->bptr[0] == 'S') && |
|
|
50
|
|
|
|
|
|
1813
|
5
|
0
|
|
|
|
|
(csv->bptr[1] == 'e' || csv->bptr[1] == 'E') && |
|
|
50
|
|
|
|
|
|
1814
|
5
|
0
|
|
|
|
|
(csv->bptr[2] == 'p' || csv->bptr[2] == 'P') && |
|
|
50
|
|
|
|
|
|
1815
|
5
|
|
|
|
|
|
csv->bptr[3] == '=') { |
1816
|
5
|
|
|
|
|
|
char *sep = csv->bptr + 4; |
1817
|
5
|
|
|
|
|
|
int lnu = csv->used - 5; |
1818
|
5
|
100
|
|
|
|
|
if (lnu <= MAX_ATTR_LEN) { |
1819
|
4
|
|
|
|
|
|
sep[lnu] = (char)0; |
1820
|
4
|
|
|
|
|
|
(void)memcpy (csv->sep, sep, lnu); |
1821
|
4
|
100
|
|
|
|
|
csv->sep_len = lnu == 1 ? 0 : lnu; |
1822
|
4
|
|
|
|
|
|
return Parse (csv, src, fields, fflags); |
1823
|
|
|
|
|
|
|
} |
1824
|
|
|
|
|
|
|
} |
1825
|
|
|
|
|
|
|
|
1826
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,bar |
1827
|
|
|
|
|
|
|
* ^ |
1828
|
|
|
|
|
|
|
*/ |
1829
|
1596
|
100
|
|
|
|
|
AV_PUSH; |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1830
|
1596
|
|
|
|
|
|
return TRUE; |
1831
|
|
|
|
|
|
|
} |
1832
|
|
|
|
|
|
|
} /* CH_NL */ |
1833
|
|
|
|
|
|
|
else |
1834
|
155257
|
100
|
|
|
|
|
if (c == CH_CR && !(csv->verbatim)) { |
|
|
100
|
|
|
|
|
|
1835
|
|
|
|
|
|
|
#if MAINT_DEBUG > 1 |
1836
|
|
|
|
|
|
|
(void)fprintf (stderr, "# %d/%d/%03x pos %d = CR\n", |
1837
|
|
|
|
|
|
|
waitingForField ? 1 : 0, sv ? 1 : 0, f, spl); |
1838
|
|
|
|
|
|
|
#endif |
1839
|
1106
|
100
|
|
|
|
|
if (waitingForField) { |
1840
|
|
|
|
|
|
|
int c2; |
1841
|
|
|
|
|
|
|
|
1842
|
117
|
100
|
|
|
|
|
if (csv->eol_is_cr) { |
1843
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,bar,\r |
1844
|
|
|
|
|
|
|
* ^ |
1845
|
|
|
|
|
|
|
*/ |
1846
|
29
|
|
|
|
|
|
c = CH_NL; |
1847
|
29
|
|
|
|
|
|
goto EOLX; |
1848
|
|
|
|
|
|
|
} |
1849
|
|
|
|
|
|
|
|
1850
|
88
|
100
|
|
|
|
|
c2 = CSV_GET; |
1851
|
|
|
|
|
|
|
|
1852
|
88
|
100
|
|
|
|
|
if (c2 == EOF) { |
1853
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,bar,\r |
1854
|
|
|
|
|
|
|
* ^ |
1855
|
|
|
|
|
|
|
*/ |
1856
|
5
|
|
|
|
|
|
c = EOF; |
1857
|
|
|
|
|
|
|
|
1858
|
|
|
|
|
|
|
#if MAINT_DEBUG > 9 |
1859
|
|
|
|
|
|
|
(void)fprintf (stderr, "# (%d) ... CR EOF 0x%x\n", |
1860
|
|
|
|
|
|
|
seenSomething, c); |
1861
|
|
|
|
|
|
|
#endif |
1862
|
5
|
50
|
|
|
|
|
unless (seenSomething) |
1863
|
0
|
|
|
|
|
|
break; |
1864
|
5
|
|
|
|
|
|
goto restart; |
1865
|
|
|
|
|
|
|
} |
1866
|
|
|
|
|
|
|
|
1867
|
83
|
100
|
|
|
|
|
if (c2 == CH_NL) { /* \r is not optional before EOLX! */ |
1868
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,bar,\r\n |
1869
|
|
|
|
|
|
|
* ^ |
1870
|
|
|
|
|
|
|
*/ |
1871
|
73
|
|
|
|
|
|
c = c2; |
1872
|
73
|
|
|
|
|
|
goto EOLX; |
1873
|
|
|
|
|
|
|
} |
1874
|
|
|
|
|
|
|
|
1875
|
10
|
100
|
|
|
|
|
if (csv->useIO && csv->eol_len == 0) { |
|
|
50
|
|
|
|
|
|
1876
|
5
|
50
|
|
|
|
|
if (c2 == CH_CR) { /* \r followed by an empty line */ |
1877
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,bar,\r\r |
1878
|
|
|
|
|
|
|
* ^ |
1879
|
|
|
|
|
|
|
*/ |
1880
|
0
|
|
|
|
|
|
set_eol_is_cr (csv); |
1881
|
0
|
|
|
|
|
|
goto EOLX; |
1882
|
|
|
|
|
|
|
} |
1883
|
|
|
|
|
|
|
|
1884
|
5
|
|
|
|
|
|
waitingForField = 0; |
1885
|
|
|
|
|
|
|
|
1886
|
5
|
100
|
|
|
|
|
if (!is_csv_binary (c2)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1887
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,bar,\r |
1888
|
|
|
|
|
|
|
* baz,4 |
1889
|
|
|
|
|
|
|
* ^ |
1890
|
|
|
|
|
|
|
*/ |
1891
|
2
|
|
|
|
|
|
set_eol_is_cr (csv); |
1892
|
2
|
|
|
|
|
|
csv->used--; |
1893
|
2
|
|
|
|
|
|
csv->has_ahead++; |
1894
|
2
|
100
|
|
|
|
|
if (fnum == 1 && f == 0 && SvCUR (sv) == 0 && csv->skip_empty_rows) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1895
|
1
|
50
|
|
|
|
|
SkipEmptyRow; |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1896
|
1
|
|
|
|
|
|
goto restart; |
1897
|
|
|
|
|
|
|
} |
1898
|
1
|
50
|
|
|
|
|
AV_PUSH; |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1899
|
1
|
|
|
|
|
|
return TRUE; |
1900
|
|
|
|
|
|
|
} |
1901
|
|
|
|
|
|
|
} |
1902
|
|
|
|
|
|
|
|
1903
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,bar,\r\t |
1904
|
|
|
|
|
|
|
* ^ |
1905
|
|
|
|
|
|
|
*/ |
1906
|
8
|
|
|
|
|
|
csv->used--; |
1907
|
8
|
50
|
|
|
|
|
ERROR_INSIDE_FIELD (2031); |
1908
|
|
|
|
|
|
|
} |
1909
|
|
|
|
|
|
|
|
1910
|
1539
|
100
|
|
|
|
|
if (f & CSV_FLAGS_QUO) { |
1911
|
|
|
|
|
|
|
/* ,1,"foo\r 3",,bar,\r\t |
1912
|
|
|
|
|
|
|
* ^ |
1913
|
|
|
|
|
|
|
*/ |
1914
|
620
|
|
|
|
|
|
f |= CSV_FLAGS_BIN; |
1915
|
620
|
100
|
|
|
|
|
unless (csv->binary) |
1916
|
70
|
50
|
|
|
|
|
ERROR_INSIDE_QUOTES (2022); |
1917
|
|
|
|
|
|
|
|
1918
|
550
|
50
|
|
|
|
|
CSV_PUT_SV (c); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1919
|
|
|
|
|
|
|
} |
1920
|
|
|
|
|
|
|
else { |
1921
|
|
|
|
|
|
|
int c2; |
1922
|
|
|
|
|
|
|
|
1923
|
369
|
100
|
|
|
|
|
if (csv->eol_is_cr) { |
1924
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,bar\r |
1925
|
|
|
|
|
|
|
* ^ |
1926
|
|
|
|
|
|
|
*/ |
1927
|
181
|
|
|
|
|
|
goto EOLX; |
1928
|
|
|
|
|
|
|
} |
1929
|
|
|
|
|
|
|
|
1930
|
188
|
100
|
|
|
|
|
c2 = CSV_GET; |
1931
|
|
|
|
|
|
|
|
1932
|
188
|
100
|
|
|
|
|
if (c2 == CH_NL) { /* \r is not optional before EOLX! */ |
1933
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,bar\r\n |
1934
|
|
|
|
|
|
|
* ^ |
1935
|
|
|
|
|
|
|
*/ |
1936
|
172
|
|
|
|
|
|
goto EOLX; |
1937
|
|
|
|
|
|
|
} |
1938
|
|
|
|
|
|
|
|
1939
|
16
|
100
|
|
|
|
|
if (csv->useIO && csv->eol_len == 0) { |
|
|
50
|
|
|
|
|
|
1940
|
11
|
100
|
|
|
|
|
if (!is_csv_binary (c2) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1941
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,bar\r |
1942
|
|
|
|
|
|
|
* baz,4 |
1943
|
|
|
|
|
|
|
* ^ |
1944
|
|
|
|
|
|
|
*/ |
1945
|
7
|
100
|
|
|
|
|
|| c2 == CH_CR) { |
1946
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,bar,\r\r |
1947
|
|
|
|
|
|
|
* ^ |
1948
|
|
|
|
|
|
|
*/ |
1949
|
5
|
|
|
|
|
|
set_eol_is_cr (csv); |
1950
|
5
|
|
|
|
|
|
csv->used--; |
1951
|
5
|
|
|
|
|
|
csv->has_ahead++; |
1952
|
5
|
50
|
|
|
|
|
if (fnum == 1 && f == 0 && SvCUR (sv) == 0 && csv->skip_empty_rows) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1953
|
0
|
0
|
|
|
|
|
SkipEmptyRow; |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1954
|
0
|
|
|
|
|
|
goto restart; |
1955
|
|
|
|
|
|
|
} |
1956
|
5
|
50
|
|
|
|
|
AV_PUSH; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1957
|
5
|
|
|
|
|
|
return TRUE; |
1958
|
|
|
|
|
|
|
} |
1959
|
|
|
|
|
|
|
} |
1960
|
|
|
|
|
|
|
|
1961
|
|
|
|
|
|
|
/* ,1,"foo\n 3",,bar\r\t |
1962
|
|
|
|
|
|
|
* ^ |
1963
|
|
|
|
|
|
|
*/ |
1964
|
11
|
50
|
|
|
|
|
ERROR_INSIDE_FIELD (2032); |
1965
|
|
|
|
|
|
|
} |
1966
|
|
|
|
|
|
|
} /* CH_CR */ |
1967
|
|
|
|
|
|
|
else { |
1968
|
|
|
|
|
|
|
#if MAINT_DEBUG > 1 |
1969
|
|
|
|
|
|
|
(void)fprintf (stderr, "# %d/%d/%03x pos %d = CCC '%c'\t\t%s\n", |
1970
|
|
|
|
|
|
|
waitingForField ? 1 : 0, sv ? 1 : 0, f, spl, c, |
1971
|
|
|
|
|
|
|
_pretty_strl (csv->bptr + csv->used)); |
1972
|
|
|
|
|
|
|
#endif |
1973
|
|
|
|
|
|
|
/* Needed for non-IO parse, where EOL is not set during read */ |
1974
|
154151
|
100
|
|
|
|
|
if (csv->eolx && c == CH_EOL && |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1975
|
8
|
50
|
|
|
|
|
csv->size - csv->used >= (STRLEN)csv->eol_len - 1 && |
1976
|
8
|
50
|
|
|
|
|
!memcmp (csv->bptr + csv->used, csv->eol + 1, csv->eol_len - 1) && |
1977
|
8
|
|
|
|
|
|
(csv->used += csv->eol_len - 1)) { |
1978
|
8
|
|
|
|
|
|
c = CH_EOLX; |
1979
|
|
|
|
|
|
|
#if MAINT_DEBUG > 5 |
1980
|
|
|
|
|
|
|
(void)fprintf (stderr, "# -> EOLX (0x%x)\n", c); |
1981
|
|
|
|
|
|
|
#endif |
1982
|
8
|
|
|
|
|
|
goto EOLX; |
1983
|
|
|
|
|
|
|
} |
1984
|
|
|
|
|
|
|
|
1985
|
154143
|
100
|
|
|
|
|
if (waitingForField) { |
1986
|
10680
|
100
|
|
|
|
|
if (csv->comment_str && !f && !spl && c == *csv->comment_str) { |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
1987
|
24
|
|
|
|
|
|
STRLEN cl = strlen ((char *)csv->comment_str); |
1988
|
|
|
|
|
|
|
|
1989
|
|
|
|
|
|
|
#if MAINT_DEBUG > 5 |
1990
|
|
|
|
|
|
|
(void)fprintf (stderr, |
1991
|
|
|
|
|
|
|
"COMMENT? cl = %d, size = %d, used = %d\n", |
1992
|
|
|
|
|
|
|
cl, csv->size, csv->used); |
1993
|
|
|
|
|
|
|
#endif |
1994
|
24
|
100
|
|
|
|
|
if (cl == 1 || ( |
|
|
50
|
|
|
|
|
|
1995
|
18
|
50
|
|
|
|
|
(csv->size - csv->used >= cl - 1 && |
1996
|
18
|
50
|
|
|
|
|
!memcmp (csv->bptr + csv->used, csv->comment_str + 1, cl - 1) && |
1997
|
18
|
|
|
|
|
|
(csv->used += cl - 1)))) { |
1998
|
24
|
|
|
|
|
|
csv->used = csv->size; |
1999
|
24
|
|
|
|
|
|
csv->fld_idx = 0; |
2000
|
24
|
50
|
|
|
|
|
c = CSV_GET; |
2001
|
|
|
|
|
|
|
#if MAINT_DEBUG > 5 |
2002
|
|
|
|
|
|
|
(void)fprintf (stderr, "# COMMENT, SKIPPED\n"); |
2003
|
|
|
|
|
|
|
#endif |
2004
|
24
|
|
|
|
|
|
goto restart; |
2005
|
|
|
|
|
|
|
} |
2006
|
|
|
|
|
|
|
} |
2007
|
|
|
|
|
|
|
|
2008
|
10656
|
100
|
|
|
|
|
if (csv->allow_whitespace && is_whitespace (c)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2009
|
|
|
|
|
|
|
do { |
2010
|
311
|
100
|
|
|
|
|
c = CSV_GET; |
2011
|
|
|
|
|
|
|
#if MAINT_DEBUG > 5 |
2012
|
|
|
|
|
|
|
(void)fprintf (stderr, "# WS next got (0x%x)\n", c); |
2013
|
|
|
|
|
|
|
#endif |
2014
|
311
|
100
|
|
|
|
|
} while (is_whitespace (c)); |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2015
|
201
|
100
|
|
|
|
|
if (c == EOF) |
2016
|
1
|
|
|
|
|
|
break; |
2017
|
200
|
|
|
|
|
|
goto restart; |
2018
|
|
|
|
|
|
|
} |
2019
|
10455
|
|
|
|
|
|
waitingForField = 0; |
2020
|
10455
|
|
|
|
|
|
goto restart; |
2021
|
|
|
|
|
|
|
} |
2022
|
|
|
|
|
|
|
|
2023
|
|
|
|
|
|
|
#if MAINT_DEBUG > 5 |
2024
|
|
|
|
|
|
|
(void)fprintf (stderr, "# %sc 0x%x is%s binary %s utf8\n", |
2025
|
|
|
|
|
|
|
f & CSV_FLAGS_QUO ? "quoted " : "", c, |
2026
|
|
|
|
|
|
|
is_csv_binary (c) ? "" : " not", |
2027
|
|
|
|
|
|
|
csv->utf8 ? "is" : "not"); |
2028
|
|
|
|
|
|
|
#endif |
2029
|
143463
|
100
|
|
|
|
|
if (f & CSV_FLAGS_QUO) { |
2030
|
111032
|
100
|
|
|
|
|
if (is_csv_binary (c)) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
2031
|
3454
|
|
|
|
|
|
f |= CSV_FLAGS_BIN; |
2032
|
3454
|
100
|
|
|
|
|
unless (csv->binary || csv->utf8) |
|
|
100
|
|
|
|
|
|
2033
|
5
|
50
|
|
|
|
|
ERROR_INSIDE_QUOTES (2026); |
2034
|
|
|
|
|
|
|
} |
2035
|
111027
|
50
|
|
|
|
|
CSV_PUT_SV (c); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
2036
|
|
|
|
|
|
|
} |
2037
|
|
|
|
|
|
|
else { |
2038
|
32431
|
100
|
|
|
|
|
if (is_csv_binary (c)) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
2039
|
453
|
100
|
|
|
|
|
if (csv->useIO && c == EOF) |
|
|
100
|
|
|
|
|
|
2040
|
3
|
|
|
|
|
|
break; |
2041
|
450
|
|
|
|
|
|
f |= CSV_FLAGS_BIN; |
2042
|
450
|
100
|
|
|
|
|
unless (csv->binary || csv->utf8) |
|
|
50
|
|
|
|
|
|
2043
|
9
|
50
|
|
|
|
|
ERROR_INSIDE_FIELD (2037); |
2044
|
|
|
|
|
|
|
} |
2045
|
32419
|
50
|
|
|
|
|
CSV_PUT_SV (c); |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
2046
|
|
|
|
|
|
|
} |
2047
|
|
|
|
|
|
|
} |
2048
|
|
|
|
|
|
|
|
2049
|
|
|
|
|
|
|
/* continue */ |
2050
|
161178
|
100
|
|
|
|
|
if (csv->verbatim && csv->useIO && csv->used == csv->size) |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
2051
|
3
|
|
|
|
|
|
break; |
2052
|
|
|
|
|
|
|
} |
2053
|
|
|
|
|
|
|
|
2054
|
746
|
100
|
|
|
|
|
if (waitingForField) { |
2055
|
366
|
100
|
|
|
|
|
if (seenSomething || !csv->useIO) { |
|
|
100
|
|
|
|
|
|
2056
|
34
|
100
|
|
|
|
|
NewField; |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2057
|
34
|
100
|
|
|
|
|
if (csv->blank_is_undef || csv->empty_is_undef) |
|
|
100
|
|
|
|
|
|
2058
|
8
|
|
|
|
|
|
SvSetUndef (sv); |
2059
|
|
|
|
|
|
|
else |
2060
|
26
|
|
|
|
|
|
SvSetEmpty (sv); |
2061
|
34
|
100
|
|
|
|
|
unless (csv->is_bound) |
2062
|
33
|
|
|
|
|
|
av_push (fields, sv); |
2063
|
34
|
100
|
|
|
|
|
if (csv->keep_meta_info && fflags) |
|
|
50
|
|
|
|
|
|
2064
|
3
|
|
|
|
|
|
av_push (fflags, newSViv (f)); |
2065
|
34
|
|
|
|
|
|
return TRUE; |
2066
|
|
|
|
|
|
|
} |
2067
|
|
|
|
|
|
|
|
2068
|
332
|
|
|
|
|
|
(void)SetDiag (csv, 2012); |
2069
|
332
|
|
|
|
|
|
return FALSE; |
2070
|
|
|
|
|
|
|
} |
2071
|
|
|
|
|
|
|
|
2072
|
380
|
100
|
|
|
|
|
if (f & CSV_FLAGS_QUO) |
2073
|
24
|
50
|
|
|
|
|
ERROR_INSIDE_QUOTES (2027); |
2074
|
|
|
|
|
|
|
|
2075
|
356
|
100
|
|
|
|
|
if (sv) { |
2076
|
354
|
100
|
|
|
|
|
AV_PUSH; |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2077
|
|
|
|
|
|
|
} |
2078
|
2
|
50
|
|
|
|
|
else if (f == 0 && fnum == 1 && csv->skip_empty_rows == 1) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2079
|
2
|
|
|
|
|
|
return FALSE; |
2080
|
354
|
|
|
|
|
|
return TRUE; |
2081
|
|
|
|
|
|
|
} /* Parse */ |
2082
|
|
|
|
|
|
|
|
2083
|
125
|
|
|
|
|
|
static int hook (pTHX_ HV *hv, char *cb_name, AV *av) { |
2084
|
|
|
|
|
|
|
SV **svp; |
2085
|
|
|
|
|
|
|
HV *cb; |
2086
|
|
|
|
|
|
|
int res; |
2087
|
|
|
|
|
|
|
|
2088
|
|
|
|
|
|
|
#if MAINT_DEBUG > 1 |
2089
|
|
|
|
|
|
|
(void)fprintf (stderr, "# HOOK %s %x\n", cb_name, av); |
2090
|
|
|
|
|
|
|
#endif |
2091
|
125
|
50
|
|
|
|
|
unless ((svp = hv_fetchs (hv, "callbacks", FALSE)) && _is_hashref (*svp)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2092
|
0
|
|
|
|
|
|
return 0; /* uncoverable statement defensive programming */ |
2093
|
|
|
|
|
|
|
|
2094
|
125
|
|
|
|
|
|
cb = (HV *)SvRV (*svp); |
2095
|
125
|
|
|
|
|
|
svp = hv_fetch (cb, cb_name, strlen (cb_name), FALSE); |
2096
|
125
|
50
|
|
|
|
|
unless (svp && _is_coderef (*svp)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2097
|
0
|
|
|
|
|
|
return 0; |
2098
|
|
|
|
|
|
|
|
2099
|
125
|
|
|
|
|
|
{ dSP; |
2100
|
125
|
|
|
|
|
|
ENTER; |
2101
|
125
|
|
|
|
|
|
SAVETMPS; |
2102
|
125
|
50
|
|
|
|
|
PUSHMARK (SP); |
2103
|
125
|
50
|
|
|
|
|
mXPUSHs (newRV_inc ((SV *)hv)); |
2104
|
125
|
50
|
|
|
|
|
mXPUSHs (newRV_inc ((SV *)av)); |
2105
|
125
|
|
|
|
|
|
PUTBACK; |
2106
|
125
|
|
|
|
|
|
res = call_sv (*svp, G_SCALAR); |
2107
|
125
|
|
|
|
|
|
SPAGAIN; |
2108
|
125
|
50
|
|
|
|
|
if (res) { |
2109
|
125
|
|
|
|
|
|
SV *rv = POPs; |
2110
|
125
|
100
|
|
|
|
|
if (SvROK (rv) && (rv = SvRV (rv)) && SvPOK (rv)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2111
|
64
|
50
|
|
|
|
|
if (strcmp (SvPV_nolen (rv), "skip") == 0) |
|
|
50
|
|
|
|
|
|
2112
|
64
|
|
|
|
|
|
res = 0; |
2113
|
|
|
|
|
|
|
} |
2114
|
|
|
|
|
|
|
} |
2115
|
125
|
|
|
|
|
|
PUTBACK; |
2116
|
125
|
50
|
|
|
|
|
FREETMPS; |
2117
|
125
|
|
|
|
|
|
LEAVE; |
2118
|
|
|
|
|
|
|
} |
2119
|
125
|
|
|
|
|
|
return res; |
2120
|
|
|
|
|
|
|
} /* hook */ |
2121
|
|
|
|
|
|
|
|
2122
|
|
|
|
|
|
|
#define c_xsParse(csv,hv,av,avf,src,useIO) cx_c_xsParse (aTHX_ csv, hv, av, avf, src, useIO) |
2123
|
4550
|
|
|
|
|
|
static int cx_c_xsParse (pTHX_ csv_t csv, HV *hv, AV *av, AV *avf, SV *src, bool useIO) { |
2124
|
4550
|
|
|
|
|
|
int result, ahead = 0; |
2125
|
4550
|
|
|
|
|
|
SV *pos = NULL; |
2126
|
|
|
|
|
|
|
|
2127
|
4550
|
|
|
|
|
|
ENTER; |
2128
|
4550
|
100
|
|
|
|
|
if (csv.eolx || csv.eol_is_cr) { |
|
|
100
|
|
|
|
|
|
2129
|
|
|
|
|
|
|
/* local $/ = $eol */ |
2130
|
849
|
|
|
|
|
|
SAVEGENERICSV (PL_rs); |
2131
|
849
|
|
|
|
|
|
PL_rs = newSVpvn ((char *)csv.eol, csv.eol_len); |
2132
|
|
|
|
|
|
|
} |
2133
|
|
|
|
|
|
|
|
2134
|
4550
|
100
|
|
|
|
|
if ((csv.useIO = useIO)) { |
2135
|
2622
|
|
|
|
|
|
csv.tmp = NULL; |
2136
|
|
|
|
|
|
|
|
2137
|
2622
|
100
|
|
|
|
|
if ((ahead = csv.has_ahead)) { |
2138
|
|
|
|
|
|
|
SV **svp; |
2139
|
176
|
50
|
|
|
|
|
if ((svp = hv_fetchs (hv, "_AHEAD", FALSE)) && *svp) { |
|
|
50
|
|
|
|
|
|
2140
|
176
|
100
|
|
|
|
|
csv.bptr = SvPV (csv.tmp = *svp, csv.size); |
2141
|
176
|
|
|
|
|
|
csv.used = 0; |
2142
|
176
|
50
|
|
|
|
|
if (pos && SvIV (pos) > (IV)csv.size) |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2143
|
2622
|
0
|
|
|
|
|
sv_setiv (pos, SvIV (pos) - csv.size); |
2144
|
|
|
|
|
|
|
} |
2145
|
|
|
|
|
|
|
} |
2146
|
|
|
|
|
|
|
} |
2147
|
|
|
|
|
|
|
else { |
2148
|
1928
|
|
|
|
|
|
csv.tmp = src; |
2149
|
1928
|
|
|
|
|
|
csv.utf8 = SvUTF8 (src) ? 1 : 0; |
2150
|
1928
|
50
|
|
|
|
|
csv.bptr = SvPV (src, csv.size); |
2151
|
|
|
|
|
|
|
} |
2152
|
4550
|
100
|
|
|
|
|
if (csv.has_error_input) { |
2153
|
217
|
|
|
|
|
|
(void)hv_store (hv, "_ERROR_INPUT", 12, &PL_sv_undef, 0); |
2154
|
217
|
|
|
|
|
|
csv.has_error_input = 0; |
2155
|
|
|
|
|
|
|
} |
2156
|
|
|
|
|
|
|
|
2157
|
4550
|
|
|
|
|
|
result = Parse (&csv, src, av, avf); |
2158
|
4539
|
|
|
|
|
|
(void)hv_store (hv, "_RECNO", 6, newSViv (++csv.recno), 0); |
2159
|
4539
|
|
|
|
|
|
(void)hv_store (hv, "_EOF", 4, &PL_sv_no, 0); |
2160
|
|
|
|
|
|
|
|
2161
|
4539
|
100
|
|
|
|
|
if (csv.strict) { |
2162
|
27
|
100
|
|
|
|
|
unless (csv.strict_n) csv.strict_n = (short)csv.fld_idx; |
2163
|
27
|
100
|
|
|
|
|
if (csv.fld_idx != csv.strict_n) { |
2164
|
12
|
100
|
|
|
|
|
unless (csv.useIO & useIO_EOF) |
2165
|
8
|
|
|
|
|
|
ParseError (&csv, 2014, csv.used); |
2166
|
12
|
100
|
|
|
|
|
if (last_error) /* an error callback can reset and accept */ |
2167
|
8
|
|
|
|
|
|
result = FALSE; |
2168
|
|
|
|
|
|
|
} |
2169
|
|
|
|
|
|
|
} |
2170
|
|
|
|
|
|
|
|
2171
|
4539
|
100
|
|
|
|
|
if (csv.useIO) { |
2172
|
2651
|
50
|
|
|
|
|
if (csv.tmp && csv.used < csv.size && csv.has_ahead) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
2173
|
37
|
|
|
|
|
|
SV *sv = newSVpvn (csv.bptr + csv.used, csv.size - csv.used); |
2174
|
37
|
|
|
|
|
|
(void)hv_store (hv, "_AHEAD", 6, sv, 0); |
2175
|
|
|
|
|
|
|
} |
2176
|
|
|
|
|
|
|
else { |
2177
|
2577
|
|
|
|
|
|
csv.has_ahead = 0; |
2178
|
2577
|
100
|
|
|
|
|
if (csv.useIO & useIO_EOF) |
2179
|
549
|
|
|
|
|
|
(void)hv_store (hv, "_EOF", 4, &PL_sv_yes, 0); |
2180
|
|
|
|
|
|
|
} |
2181
|
|
|
|
|
|
|
/* csv.cache[CACHE_ID__has_ahead] = csv.has_ahead; */ |
2182
|
2614
|
|
|
|
|
|
(void)memcpy (csv.cache, &csv, sizeof (csv_t)); |
2183
|
|
|
|
|
|
|
|
2184
|
2614
|
100
|
|
|
|
|
if (avf) { |
2185
|
1580
|
100
|
|
|
|
|
if (csv.keep_meta_info) |
2186
|
11
|
|
|
|
|
|
(void)hv_store (hv, "_FFLAGS", 7, newRV_noinc ((SV *)avf), 0); |
2187
|
|
|
|
|
|
|
else { |
2188
|
1569
|
|
|
|
|
|
av_undef (avf); |
2189
|
2614
|
|
|
|
|
|
sv_free ((SV *)avf); |
2190
|
|
|
|
|
|
|
} |
2191
|
|
|
|
|
|
|
} |
2192
|
|
|
|
|
|
|
} |
2193
|
|
|
|
|
|
|
else { /* just copy to the cache */ |
2194
|
1925
|
|
|
|
|
|
SV **svp = hv_fetchs (hv, "_CACHE", FALSE); |
2195
|
|
|
|
|
|
|
|
2196
|
1925
|
50
|
|
|
|
|
if (svp && *svp) |
|
|
50
|
|
|
|
|
|
2197
|
1925
|
50
|
|
|
|
|
csv.cache = (byte *)SvPV_nolen (*svp); |
2198
|
1925
|
|
|
|
|
|
(void)memcpy (csv.cache, &csv, sizeof (csv_t)); |
2199
|
|
|
|
|
|
|
} |
2200
|
|
|
|
|
|
|
|
2201
|
4539
|
100
|
|
|
|
|
if (result && csv.types) { |
|
|
100
|
|
|
|
|
|
2202
|
|
|
|
|
|
|
STRLEN i; |
2203
|
2
|
|
|
|
|
|
STRLEN len = av_len (av); |
2204
|
|
|
|
|
|
|
SV **svp; |
2205
|
|
|
|
|
|
|
|
2206
|
8
|
100
|
|
|
|
|
for (i = 0; i <= len && i <= csv.types_len; i++) { |
|
|
50
|
|
|
|
|
|
2207
|
6
|
50
|
|
|
|
|
if ((svp = av_fetch (av, i, FALSE)) && *svp && SvOK (*svp)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
2208
|
6
|
|
|
|
|
|
switch (csv.types[i]) { |
2209
|
|
|
|
|
|
|
case CSV_XS_TYPE_IV: |
2210
|
|
|
|
|
|
|
#ifdef CSV_XS_TYPE_WARN |
2211
|
2
|
50
|
|
|
|
|
sv_setiv (*svp, SvIV (*svp)); |
2212
|
|
|
|
|
|
|
#else |
2213
|
|
|
|
|
|
|
if (SvTRUE (*svp)) |
2214
|
|
|
|
|
|
|
sv_setiv (*svp, SvIV (*svp)); |
2215
|
|
|
|
|
|
|
else |
2216
|
|
|
|
|
|
|
sv_setiv (*svp, 0); |
2217
|
|
|
|
|
|
|
#endif |
2218
|
2
|
|
|
|
|
|
break; |
2219
|
|
|
|
|
|
|
|
2220
|
|
|
|
|
|
|
case CSV_XS_TYPE_NV: |
2221
|
|
|
|
|
|
|
#ifdef CSV_XS_TYPE_WARN |
2222
|
2
|
50
|
|
|
|
|
sv_setnv (*svp, SvNV (*svp)); |
2223
|
|
|
|
|
|
|
#else |
2224
|
|
|
|
|
|
|
if (SvTRUE (*svp)) |
2225
|
|
|
|
|
|
|
sv_setnv (*svp, SvNV (*svp)); |
2226
|
|
|
|
|
|
|
else |
2227
|
|
|
|
|
|
|
sv_setnv (*svp, 0.0); |
2228
|
|
|
|
|
|
|
#endif |
2229
|
2
|
|
|
|
|
|
break; |
2230
|
|
|
|
|
|
|
|
2231
|
|
|
|
|
|
|
default: |
2232
|
2
|
|
|
|
|
|
break; |
2233
|
|
|
|
|
|
|
} |
2234
|
|
|
|
|
|
|
} |
2235
|
|
|
|
|
|
|
} |
2236
|
|
|
|
|
|
|
} |
2237
|
|
|
|
|
|
|
|
2238
|
4539
|
|
|
|
|
|
LEAVE; |
2239
|
|
|
|
|
|
|
|
2240
|
4539
|
|
|
|
|
|
return result; |
2241
|
|
|
|
|
|
|
} /* c_xsParse */ |
2242
|
|
|
|
|
|
|
|
2243
|
|
|
|
|
|
|
#define xsParse(self,hv,av,avf,src,useIO) cx_xsParse (aTHX_ self, hv, av, avf, src, useIO) |
2244
|
3510
|
|
|
|
|
|
static int cx_xsParse (pTHX_ SV *self, HV *hv, AV *av, AV *avf, SV *src, bool useIO) { |
2245
|
|
|
|
|
|
|
csv_t csv; |
2246
|
|
|
|
|
|
|
int state; |
2247
|
3510
|
|
|
|
|
|
SetupCsv (&csv, hv, self); |
2248
|
3510
|
|
|
|
|
|
state = c_xsParse (csv, hv, av, avf, src, useIO); |
2249
|
3505
|
100
|
|
|
|
|
if (state && csv.has_hooks & HOOK_AFTER_PARSE) |
|
|
100
|
|
|
|
|
|
2250
|
5
|
|
|
|
|
|
(void)hook (aTHX_ hv, "after_parse", av); |
2251
|
3505
|
100
|
|
|
|
|
return (state || !last_error); |
|
|
100
|
|
|
|
|
|
2252
|
|
|
|
|
|
|
} /* xsParse */ |
2253
|
|
|
|
|
|
|
|
2254
|
|
|
|
|
|
|
/* API also offers av_clear and av_undef, but they have more overhead */ |
2255
|
|
|
|
|
|
|
#define av_empty(av) cx_av_empty (aTHX_ av) |
2256
|
83
|
|
|
|
|
|
static void cx_av_empty (pTHX_ AV *av) { |
2257
|
333
|
100
|
|
|
|
|
while (av_len (av) >= 0) |
2258
|
250
|
|
|
|
|
|
sv_free (av_pop (av)); |
2259
|
83
|
|
|
|
|
|
} /* av_empty */ |
2260
|
|
|
|
|
|
|
|
2261
|
|
|
|
|
|
|
#define xsParse_all(self,hv,io,off,len) cx_xsParse_all (aTHX_ self, hv, io, off, len) |
2262
|
334
|
|
|
|
|
|
static SV *cx_xsParse_all (pTHX_ SV *self, HV *hv, SV *io, SV *off, SV *len) { |
2263
|
|
|
|
|
|
|
csv_t csv; |
2264
|
334
|
|
|
|
|
|
int n = 0, skip = 0, length = MAXINT, tail = MAXINT; |
2265
|
334
|
|
|
|
|
|
AV *avr = newAV (); |
2266
|
334
|
|
|
|
|
|
AV *row = newAV (); |
2267
|
|
|
|
|
|
|
|
2268
|
334
|
|
|
|
|
|
SetupCsv (&csv, hv, self); |
2269
|
|
|
|
|
|
|
|
2270
|
334
|
100
|
|
|
|
|
if (SvOK (off)) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2271
|
56
|
100
|
|
|
|
|
skip = SvIV (off); |
2272
|
56
|
100
|
|
|
|
|
if (skip < 0) { |
2273
|
12
|
|
|
|
|
|
tail = -skip; |
2274
|
12
|
|
|
|
|
|
skip = -1; |
2275
|
|
|
|
|
|
|
} |
2276
|
|
|
|
|
|
|
} |
2277
|
334
|
100
|
|
|
|
|
if (SvOK (len)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2278
|
44
|
100
|
|
|
|
|
length = SvIV (len); |
2279
|
|
|
|
|
|
|
|
2280
|
1040
|
100
|
|
|
|
|
while (c_xsParse (csv, hv, row, NULL, io, 1)) { |
2281
|
|
|
|
|
|
|
|
2282
|
738
|
|
|
|
|
|
SetupCsv (&csv, hv, self); |
2283
|
|
|
|
|
|
|
|
2284
|
738
|
100
|
|
|
|
|
if (skip > 0) { |
2285
|
20
|
|
|
|
|
|
skip--; |
2286
|
20
|
|
|
|
|
|
av_empty (row); /* re-use */ |
2287
|
20
|
|
|
|
|
|
continue; |
2288
|
|
|
|
|
|
|
} |
2289
|
|
|
|
|
|
|
|
2290
|
718
|
100
|
|
|
|
|
if (n++ >= tail) { |
2291
|
12
|
|
|
|
|
|
SvREFCNT_dec (av_shift (avr)); |
2292
|
12
|
|
|
|
|
|
n--; |
2293
|
|
|
|
|
|
|
} |
2294
|
|
|
|
|
|
|
|
2295
|
718
|
100
|
|
|
|
|
if (csv.has_hooks & HOOK_AFTER_PARSE) { |
2296
|
117
|
100
|
|
|
|
|
unless (hook (aTHX_ hv, "after_parse", row)) { |
2297
|
63
|
|
|
|
|
|
av_empty (row); /* re-use */ |
2298
|
63
|
|
|
|
|
|
continue; |
2299
|
|
|
|
|
|
|
} |
2300
|
|
|
|
|
|
|
} |
2301
|
655
|
|
|
|
|
|
av_push (avr, newRV_noinc ((SV *)row)); |
2302
|
|
|
|
|
|
|
|
2303
|
655
|
100
|
|
|
|
|
if (n >= length && skip >= 0) |
|
|
100
|
|
|
|
|
|
2304
|
32
|
|
|
|
|
|
break; /* We have enough */ |
2305
|
|
|
|
|
|
|
|
2306
|
623
|
|
|
|
|
|
row = newAV (); |
2307
|
|
|
|
|
|
|
} |
2308
|
336
|
100
|
|
|
|
|
while (n > length) { |
2309
|
8
|
|
|
|
|
|
SvREFCNT_dec (av_pop (avr)); |
2310
|
8
|
|
|
|
|
|
n--; |
2311
|
|
|
|
|
|
|
} |
2312
|
|
|
|
|
|
|
|
2313
|
328
|
|
|
|
|
|
return (SV *)sv_2mortal (newRV_noinc ((SV *)avr)); |
2314
|
|
|
|
|
|
|
} /* xsParse_all */ |
2315
|
|
|
|
|
|
|
|
2316
|
|
|
|
|
|
|
#define xsCombine(self,hv,av,io,useIO) cx_xsCombine (aTHX_ self, hv, av, io, useIO) |
2317
|
21647
|
|
|
|
|
|
static int cx_xsCombine (pTHX_ SV *self, HV *hv, AV *av, SV *io, bool useIO) { |
2318
|
|
|
|
|
|
|
csv_t csv; |
2319
|
|
|
|
|
|
|
int result; |
2320
|
|
|
|
|
|
|
#if (PERL_BCDVERSION >= 0x5008000) |
2321
|
21647
|
|
|
|
|
|
SV *ors = PL_ors_sv; |
2322
|
|
|
|
|
|
|
#endif |
2323
|
|
|
|
|
|
|
|
2324
|
21647
|
|
|
|
|
|
SetupCsv (&csv, hv, self); |
2325
|
21647
|
|
|
|
|
|
csv.useIO = useIO; |
2326
|
|
|
|
|
|
|
#if (PERL_BCDVERSION >= 0x5008000) |
2327
|
21647
|
100
|
|
|
|
|
if (*csv.eol) |
2328
|
260
|
|
|
|
|
|
PL_ors_sv = NULL; |
2329
|
|
|
|
|
|
|
#endif |
2330
|
21647
|
100
|
|
|
|
|
if (useIO && csv.has_hooks & HOOK_BEFORE_PRINT) |
|
|
100
|
|
|
|
|
|
2331
|
3
|
|
|
|
|
|
(void)hook (aTHX_ hv, "before_print", av); |
2332
|
21647
|
|
|
|
|
|
result = Combine (&csv, io, av); |
2333
|
|
|
|
|
|
|
#if (PERL_BCDVERSION >= 0x5008000) |
2334
|
21643
|
|
|
|
|
|
PL_ors_sv = ors; |
2335
|
|
|
|
|
|
|
#endif |
2336
|
21643
|
100
|
|
|
|
|
if (result && !useIO && csv.utf8) |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
2337
|
25
|
|
|
|
|
|
sv_utf8_upgrade (io); |
2338
|
21643
|
|
|
|
|
|
return result; |
2339
|
|
|
|
|
|
|
} /* xsCombine */ |
2340
|
|
|
|
|
|
|
|
2341
|
|
|
|
|
|
|
MODULE = Text::CSV_XS PACKAGE = Text::CSV_XS |
2342
|
|
|
|
|
|
|
|
2343
|
|
|
|
|
|
|
PROTOTYPES: DISABLE |
2344
|
|
|
|
|
|
|
|
2345
|
|
|
|
|
|
|
BOOT: |
2346
|
32
|
|
|
|
|
|
m_getline = newSVpvs ("getline"); |
2347
|
32
|
|
|
|
|
|
m_print = newSVpvs ("print"); |
2348
|
32
|
|
|
|
|
|
Perl_load_module (aTHX_ PERL_LOADMOD_NOIMPORT, newSVpvs ("IO::Handle"), NULL, NULL, NULL); |
2349
|
|
|
|
|
|
|
|
2350
|
|
|
|
|
|
|
void |
2351
|
|
|
|
|
|
|
SetDiag (SV *self, int xse, ...) |
2352
|
|
|
|
|
|
|
|
2353
|
|
|
|
|
|
|
PPCODE: |
2354
|
|
|
|
|
|
|
HV *hv; |
2355
|
|
|
|
|
|
|
csv_t csv; |
2356
|
|
|
|
|
|
|
|
2357
|
2940
|
50
|
|
|
|
|
if (SvOK (self) && SvROK (self)) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
2358
|
1047
|
50
|
|
|
|
|
CSV_XS_SELF; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2359
|
1047
|
|
|
|
|
|
SetupCsv (&csv, hv, self); |
2360
|
1047
|
|
|
|
|
|
ST (0) = SetDiag (&csv, xse); |
2361
|
|
|
|
|
|
|
} |
2362
|
|
|
|
|
|
|
else { |
2363
|
1893
|
|
|
|
|
|
last_error = xse; |
2364
|
1893
|
|
|
|
|
|
ST (0) = sv_2mortal (SvDiag (xse)); |
2365
|
|
|
|
|
|
|
} |
2366
|
|
|
|
|
|
|
|
2367
|
2940
|
100
|
|
|
|
|
if (xse && items > 2 && SvPOK (ST (2))) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2368
|
941
|
|
|
|
|
|
sv_setpvn (ST (0), SvPVX (ST (2)), SvCUR (ST (2))); |
2369
|
941
|
|
|
|
|
|
SvIOK_on (ST (0)); |
2370
|
|
|
|
|
|
|
} |
2371
|
|
|
|
|
|
|
|
2372
|
2940
|
|
|
|
|
|
XSRETURN (1); |
2373
|
|
|
|
|
|
|
/* XS SetDiag */ |
2374
|
|
|
|
|
|
|
|
2375
|
|
|
|
|
|
|
void |
2376
|
|
|
|
|
|
|
error_input (SV *self) |
2377
|
|
|
|
|
|
|
|
2378
|
|
|
|
|
|
|
PPCODE: |
2379
|
12
|
50
|
|
|
|
|
if (self && SvOK (self) && SvROK (self) && SvTYPE (SvRV (self)) == SVt_PVHV) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
2380
|
4
|
|
|
|
|
|
HV *hv = (HV *)SvRV (self); |
2381
|
4
|
|
|
|
|
|
SV **sv = hv_fetchs (hv, "_ERROR_INPUT", FALSE); |
2382
|
4
|
100
|
|
|
|
|
if (SvOK (*sv)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2383
|
3
|
|
|
|
|
|
ST (0) = *sv; |
2384
|
|
|
|
|
|
|
else |
2385
|
1
|
|
|
|
|
|
ST (0) = newSV (0); |
2386
|
|
|
|
|
|
|
} |
2387
|
|
|
|
|
|
|
else |
2388
|
4
|
|
|
|
|
|
ST (0) = newSV (0); |
2389
|
|
|
|
|
|
|
|
2390
|
8
|
|
|
|
|
|
XSRETURN (1); |
2391
|
|
|
|
|
|
|
/* XS error_input */ |
2392
|
|
|
|
|
|
|
|
2393
|
|
|
|
|
|
|
void |
2394
|
|
|
|
|
|
|
Combine (SV *self, SV *dst, SV *fields, bool useIO) |
2395
|
|
|
|
|
|
|
|
2396
|
|
|
|
|
|
|
PPCODE: |
2397
|
|
|
|
|
|
|
HV *hv; |
2398
|
|
|
|
|
|
|
AV *av; |
2399
|
|
|
|
|
|
|
|
2400
|
1396
|
50
|
|
|
|
|
CSV_XS_SELF; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2401
|
1396
|
|
|
|
|
|
av = (AV *)SvRV (fields); |
2402
|
1396
|
100
|
|
|
|
|
ST (0) = xsCombine (self, hv, av, dst, useIO) ? &PL_sv_yes : &PL_sv_undef; |
2403
|
1392
|
|
|
|
|
|
XSRETURN (1); |
2404
|
|
|
|
|
|
|
/* XS Combine */ |
2405
|
|
|
|
|
|
|
|
2406
|
|
|
|
|
|
|
void |
2407
|
|
|
|
|
|
|
Parse (SV *self, SV *src, SV *fields, SV *fflags) |
2408
|
|
|
|
|
|
|
|
2409
|
|
|
|
|
|
|
PPCODE: |
2410
|
|
|
|
|
|
|
HV *hv; |
2411
|
|
|
|
|
|
|
AV *av; |
2412
|
|
|
|
|
|
|
AV *avf; |
2413
|
|
|
|
|
|
|
|
2414
|
1928
|
50
|
|
|
|
|
CSV_XS_SELF; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2415
|
1928
|
|
|
|
|
|
av = (AV *)SvRV (fields); |
2416
|
1928
|
|
|
|
|
|
avf = (AV *)SvRV (fflags); |
2417
|
|
|
|
|
|
|
|
2418
|
1928
|
100
|
|
|
|
|
ST (0) = xsParse (self, hv, av, avf, src, 0) ? &PL_sv_yes : &PL_sv_no; |
2419
|
1925
|
|
|
|
|
|
XSRETURN (1); |
2420
|
|
|
|
|
|
|
/* XS Parse */ |
2421
|
|
|
|
|
|
|
|
2422
|
|
|
|
|
|
|
void |
2423
|
|
|
|
|
|
|
print (SV *self, SV *io, SV *fields) |
2424
|
|
|
|
|
|
|
|
2425
|
|
|
|
|
|
|
PPCODE: |
2426
|
|
|
|
|
|
|
HV *hv; |
2427
|
|
|
|
|
|
|
AV *av; |
2428
|
|
|
|
|
|
|
|
2429
|
20256
|
50
|
|
|
|
|
CSV_XS_SELF; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2430
|
20256
|
100
|
|
|
|
|
if (fields == &PL_sv_undef) |
2431
|
5
|
|
|
|
|
|
av = newAV (); |
2432
|
|
|
|
|
|
|
else { |
2433
|
20251
|
50
|
|
|
|
|
unless (_is_arrayref (fields)) |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
2434
|
5
|
|
|
|
|
|
croak ("Expected fields to be an array ref"); |
2435
|
|
|
|
|
|
|
|
2436
|
20246
|
|
|
|
|
|
av = (AV *)SvRV (fields); |
2437
|
|
|
|
|
|
|
} |
2438
|
|
|
|
|
|
|
|
2439
|
20251
|
100
|
|
|
|
|
ST (0) = xsCombine (self, hv, av, io, 1) ? &PL_sv_yes : &PL_sv_no; |
2440
|
20251
|
|
|
|
|
|
XSRETURN (1); |
2441
|
|
|
|
|
|
|
/* XS print */ |
2442
|
|
|
|
|
|
|
|
2443
|
|
|
|
|
|
|
void |
2444
|
|
|
|
|
|
|
getline (SV *self, SV *io) |
2445
|
|
|
|
|
|
|
|
2446
|
|
|
|
|
|
|
PPCODE: |
2447
|
|
|
|
|
|
|
HV *hv; |
2448
|
|
|
|
|
|
|
AV *av; |
2449
|
|
|
|
|
|
|
AV *avf; |
2450
|
|
|
|
|
|
|
|
2451
|
1582
|
50
|
|
|
|
|
CSV_XS_SELF; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2452
|
1582
|
|
|
|
|
|
av = newAV (); |
2453
|
1582
|
|
|
|
|
|
avf = newAV (); |
2454
|
1582
|
|
|
|
|
|
ST (0) = xsParse (self, hv, av, avf, io, 1) |
2455
|
1443
|
|
|
|
|
|
? sv_2mortal (newRV_noinc ((SV *)av)) |
2456
|
3023
|
100
|
|
|
|
|
: &PL_sv_undef; |
2457
|
1580
|
|
|
|
|
|
XSRETURN (1); |
2458
|
|
|
|
|
|
|
/* XS getline */ |
2459
|
|
|
|
|
|
|
|
2460
|
|
|
|
|
|
|
void |
2461
|
|
|
|
|
|
|
getline_all (SV *self, SV *io, ...) |
2462
|
|
|
|
|
|
|
|
2463
|
|
|
|
|
|
|
PPCODE: |
2464
|
|
|
|
|
|
|
HV *hv; |
2465
|
|
|
|
|
|
|
SV *offset, *length; |
2466
|
|
|
|
|
|
|
|
2467
|
334
|
50
|
|
|
|
|
CSV_XS_SELF; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2468
|
|
|
|
|
|
|
|
2469
|
334
|
100
|
|
|
|
|
offset = items > 2 ? ST (2) : &PL_sv_undef; |
2470
|
334
|
100
|
|
|
|
|
length = items > 3 ? ST (3) : &PL_sv_undef; |
2471
|
|
|
|
|
|
|
|
2472
|
334
|
|
|
|
|
|
ST (0) = xsParse_all (self, hv, io, offset, length); |
2473
|
328
|
|
|
|
|
|
XSRETURN (1); |
2474
|
|
|
|
|
|
|
/* XS getline_all */ |
2475
|
|
|
|
|
|
|
|
2476
|
|
|
|
|
|
|
void |
2477
|
|
|
|
|
|
|
_cache_set (SV *self, int idx, SV *val) |
2478
|
|
|
|
|
|
|
|
2479
|
|
|
|
|
|
|
PPCODE: |
2480
|
|
|
|
|
|
|
HV *hv; |
2481
|
|
|
|
|
|
|
|
2482
|
23241
|
50
|
|
|
|
|
CSV_XS_SELF; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2483
|
23241
|
|
|
|
|
|
xs_cache_set (hv, idx, val); |
2484
|
23241
|
|
|
|
|
|
XSRETURN (1); |
2485
|
|
|
|
|
|
|
/* XS _cache_set */ |
2486
|
|
|
|
|
|
|
|
2487
|
|
|
|
|
|
|
void |
2488
|
|
|
|
|
|
|
_cache_diag (SV *self) |
2489
|
|
|
|
|
|
|
|
2490
|
|
|
|
|
|
|
PPCODE: |
2491
|
|
|
|
|
|
|
HV *hv; |
2492
|
|
|
|
|
|
|
|
2493
|
2
|
50
|
|
|
|
|
CSV_XS_SELF; |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
2494
|
2
|
|
|
|
|
|
xs_cache_diag (hv); |
2495
|
2
|
|
|
|
|
|
XSRETURN (1); |
2496
|
|
|
|
|
|
|
/* XS _cache_diag */ |