| 262 | Store into *PLEN the length in bytes of FIELD. */ |
| 263 | |
| 264 | static char * |
| 265 | find_field (struct linebuffer const *line, idx_t *plen) |
| 266 | { |
| 267 | char *lp = line->buffer; |
| 268 | char const *lim = lp + line->length - 1; |
| 269 | |
| 270 | for (idx_t i = skip_fields; 0 < i && lp < lim; i--) |
| 271 | { |
| 272 | lp = skip_buf_matching (lp, lim, newline_or_blank, true); |
| 273 | lp = skip_buf_matching (lp, lim, newline_or_blank, false); |
| 274 | } |
| 275 | |
| 276 | for (idx_t i = skip_chars; 0 < i && lp < lim; i--) |
| 277 | lp += mcel_scan (lp, lim).len; |
| 278 | |
| 279 | /* Compute the length in bytes cheaply if possible; otherwise, scan. */ |
| 280 | idx_t len; |
| 281 | if (lim - lp <= check_chars) |
| 282 | len = lim - lp; |
| 283 | else if (MB_CUR_MAX <= 1) |
| 284 | len = check_chars; |
| 285 | else |
| 286 | { |
| 287 | char *ep = lp; |
| 288 | for (idx_t i = check_chars; 0 < i && lp < lim; i--) |
| 289 | ep += mcel_scan (lp, lim).len; |
| 290 | len = ep - lp; |
| 291 | } |
| 292 | |
| 293 | *plen = len; |
| 294 | return lp; |
| 295 | } |
| 296 | |
| 297 | /* Return false if two strings OLD and NEW match, true if not. |
| 298 | OLD and NEW point not to the beginnings of the lines |
no test coverage detected