- " text field delimiter.
- , field separator.
Code: Select all
ResultType Line::PerformLoopParseCSV(ExprTokenType *aResultToken, bool &aContinueMainLoop, Line *&aJumpToLine, Line *aUntil)
// This function is similar to PerformLoopParse() so the two should be maintained together.
// See PerformLoopParse() for comments about the below (comments have been mostly stripped
// from this function).
{
if (!*ARG2) // Since the input variable's contents are blank, the loop will execute zero times.
return OK;
// See comments in PerformLoopParse() for details.
size_t space_needed = ArgLength(2) + 1; // +1 for the zero terminator.
LPTSTR stack_buf, buf;
if (space_needed <= LOOP_PARSE_BUF_SIZE)
{
stack_buf = (LPTSTR)talloca(space_needed); // Helps performance. See comments above.
buf = stack_buf;
}
else
{
if ( !(buf = tmalloc(space_needed)) )
return LineError(ERR_OUTOFMEM, FAIL, ARG2);
stack_buf = NULL; // For comparison purposes later below.
}
_tcscpy(buf, ARG2); // Make the copy.
TCHAR omit_list[512];
tcslcpy(omit_list, ARG4, _countof(omit_list));
ResultType result;
Line *jump_to_line;
TCHAR *field, *field_end, saved_char;
size_t field_length;
bool field_is_enclosed_in_quotes;
global_struct &g = *::g; // Primarily for performance in this case.
for (field = buf;;)
{
if (*field == '"')
{
// For each field, check if the optional leading double-quote is present. If it is,
// skip over it since we always know it's the one that marks the beginning of
// the that field. This assumes that a field containing escaped double-quote is
// always contained in double quotes, which is how Excel does it. For example:
// """string with escaped quotes""" resolves to a literal quoted string:
field_is_enclosed_in_quotes = true;
++field;
}
else
field_is_enclosed_in_quotes = false;
for (field_end = field;;)
{
if ( !(field_end = _tcschr(field_end, field_is_enclosed_in_quotes ? '"' : ',')) )
{
// This is the last field in the string, so set field_end to the position of
// the zero terminator instead:
field_end = field + _tcslen(field);
break;
}
if (field_is_enclosed_in_quotes)
{
// The quote discovered above marks the end of the string if it isn't followed
// by another quote. But if it is a pair of quotes, replace it with a single
// literal double-quote and then keep searching for the real ending quote:
if (field_end[1] == '"') // A pair of quotes was encountered.
{
tmemmove(field_end, field_end + 1, _tcslen(field_end + 1) + 1); // +1 to include terminator.
++field_end; // Skip over the literal double quote that we just produced.
continue; // Keep looking for the "real" ending quote.
}
// Otherwise, this quote marks the end of the field, so just fall through and break.
}
// else field is not enclosed in quotes, so the comma discovered above must be a delimiter.
break;
}