* Parse a CSV record. */
| 188 | * Parse a CSV record. |
| 189 | */ |
| 190 | static bool parseRecord(CSV &csv, Record &record) |
| 191 | { |
| 192 | MatchVal val; |
| 193 | if (!parseEntry(csv, val)) |
| 194 | return false; |
| 195 | record.push_back(val); |
| 196 | |
| 197 | while (true) |
| 198 | { |
| 199 | char c = getChar(csv); |
| 200 | switch (c) |
| 201 | { |
| 202 | case '\r': |
| 203 | c = getChar(csv); |
| 204 | if (c != '\n') |
| 205 | error("failed to parse CSV file \"%s\" at line %u; " |
| 206 | "expected newline after carriage return", csv.filename, |
| 207 | csv.lineno); |
| 208 | return true; |
| 209 | case '\n': case EOF: |
| 210 | return true; |
| 211 | case ',': |
| 212 | break; |
| 213 | default: |
| 214 | error("failed to parse CSV file \"%s\" at line %u; unexpected " |
| 215 | "character `%c'", csv.filename, csv.lineno); |
| 216 | } |
| 217 | if (!parseEntry(csv, val)) |
| 218 | return false; |
| 219 | record.push_back(val); |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | /* |
| 224 | * Parse a CSV file. |
no test coverage detected