| 11459 | |
| 11460 | |
| 11461 | ResultType Line::PerformLoopParseCSV(ResultToken *aResultToken, Line *&aJumpToLine, Line *aUntil) |
| 11462 | // This function is similar to PerformLoopParse() so the two should be maintained together. |
| 11463 | // See PerformLoopParse() for comments about the below (comments have been mostly stripped |
| 11464 | // from this function). |
| 11465 | { |
| 11466 | if (!*ARG1) // Since the input variable's contents are blank, the loop will execute zero times. |
| 11467 | return CONDITION_FALSE; |
| 11468 | |
| 11469 | // See comments in PerformLoopParse() for details. |
| 11470 | size_t space_needed = ArgLength(1) + 1; // +1 for the zero terminator. |
| 11471 | LPTSTR stack_buf, buf; |
| 11472 | if (space_needed <= LOOP_PARSE_BUF_SIZE) |
| 11473 | { |
| 11474 | stack_buf = (LPTSTR)talloca(space_needed); // Helps performance. See comments above. |
| 11475 | buf = stack_buf; |
| 11476 | } |
| 11477 | else |
| 11478 | { |
| 11479 | if ( !(buf = tmalloc(space_needed)) ) |
| 11480 | return MemoryError(); |
| 11481 | stack_buf = NULL; // For comparison purposes later below. |
| 11482 | } |
| 11483 | _tcscpy(buf, ARG1); // Make the copy. |
| 11484 | |
| 11485 | TCHAR omit_list[512]; |
| 11486 | tcslcpy(omit_list, ARG3, _countof(omit_list)); |
| 11487 | |
| 11488 | ResultType result = CONDITION_FALSE; |
| 11489 | Line *jump_to_line = nullptr; |
| 11490 | TCHAR *field, *field_end, saved_char; |
| 11491 | size_t field_length; |
| 11492 | bool field_is_enclosed_in_quotes; |
| 11493 | global_struct &g = *::g; // Primarily for performance in this case. |
| 11494 | |
| 11495 | for (field = buf;;) |
| 11496 | { |
| 11497 | if (*field == '"') |
| 11498 | { |
| 11499 | // For each field, check if the optional leading double-quote is present. If it is, |
| 11500 | // skip over it since we always know it's the one that marks the beginning of |
| 11501 | // the that field. This assumes that a field containing escaped double-quote is |
| 11502 | // always contained in double quotes, which is how Excel does it. For example: |
| 11503 | // """string with escaped quotes""" resolves to a literal quoted string: |
| 11504 | field_is_enclosed_in_quotes = true; |
| 11505 | ++field; |
| 11506 | } |
| 11507 | else |
| 11508 | field_is_enclosed_in_quotes = false; |
| 11509 | |
| 11510 | for (field_end = field;;) |
| 11511 | { |
| 11512 | if ( !(field_end = _tcschr(field_end, field_is_enclosed_in_quotes ? '"' : ',')) ) |
| 11513 | { |
| 11514 | // This is the last field in the string, so set field_end to the position of |
| 11515 | // the zero terminator instead: |
| 11516 | field_end = field + _tcslen(field); |
| 11517 | break; |
| 11518 | } |
no test coverage detected