enum format_id id;
int fs;
int quote;
+ int quiet;
int (*read_line)(void);
void (*write_line)(void);
};
static fields_t in_fields, out_fields;
static struct field *in_field;
static line_t in_line;
+static int line_number;
static void new_field(void)
{
new_field();
}
+static void warn(struct format *fmt, char *msg)
+{
+ if (!fmt->quiet)
+ fprintf(stderr, "Warning at line %d: %s\n", line_number, msg);
+}
+
static int csv_read(void)
{
int quoted = 0;
- // FIXME: Complain if closing quote is missing?
for (;;) {
int c = getchar();
restart:
- if (c < 0)
- return !!fields_count(&in_fields);
if (c == '\r')
continue;
- if (c == '\n')
- return 1;
+ if (c < 0 || c == '\n') {
+ if (quoted)
+ warn(in_format, "Missing closing quote.");
+ if (c < 0)
+ return !!fields_count(&in_fields);
+ else
+ return 1;
+ }
if (quoted) {
if (c == in_format->quote) {
c = getchar();
putchar(out_format->quote);
for (int j=0; j < f->len; j++) {
int c = line[f->start_pos + j];
+ if (c == out_format->fs && !need_quotes)
+ warn(out_format, "Field separator found inside field and quoting is turned off.");
if (c == out_format->quote)
putchar(c);
putchar(c);
\n\
Format parameters:\n\
-d, --fs=<char> Delimiter of fields\n\
+-q, --quiet Do not show warnings\n\
\n\
Other options:\n\
--trim Trim leading and trailing whitespaces in fields\n\
exit(1);
}
-static const char short_options[] = "cd:tw";
+static const char short_options[] = "cd:qtw";
enum long_options {
OPT_HELP = 256,
static const struct option long_options[] = {
{ "csv", 0, NULL, 'c' },
{ "fs", 1, NULL, 'd' },
+ { "quiet", 0, NULL, 'q' },
{ "trim", 0, NULL, OPT_TRIM },
{ "tsv", 0, NULL, 't' },
{ "ws", 0, NULL, 'w' },
else
bad_args("No field delimiter given.");
break;
+ case 'q':
+ current_format()->quiet = 1;
+ break;
case 't':
set_format(FORM_TSV);
break;
line_init(&in_line);
for (;;) {
+ line_number++;
fields_reset(&in_fields);
line_reset(&in_line);
in_field = NULL;