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