]> mj.ucw.cz Git - xsv.git/commitdiff
Each read/write hook gets a pointer to its format
authorMartin Mares <mj@ucw.cz>
Tue, 24 Jul 2012 12:15:19 +0000 (14:15 +0200)
committerMartin Mares <mj@ucw.cz>
Tue, 24 Jul 2012 12:15:19 +0000 (14:15 +0200)
xsv.c

diff --git a/xsv.c b/xsv.c
index 3de4d7c0ccef5d01f08bbfe5ce2fb303a686f016..bd1f389d5caa22abde331c7c0f3d54488afe679d 100644 (file)
--- a/xsv.c
+++ b/xsv.c
@@ -96,8 +96,8 @@ struct format {
        int fs;
        int quote;
        int quiet;
-       int (*read_line)(void);
-       void (*write_line)(void);
+       int (*read_line)(struct format *fmt);
+       void (*write_line)(struct format *fmt);
        int needs_two_passes;
 
        // CSV backend:
@@ -194,7 +194,7 @@ static int field_chars(struct field *f)
 
 /*** CSV/TSV back-end */
 
-static int csv_read(void)
+static int csv_read(struct format *fmt)
 {
        int quoted = 0;
        for (;;) {
@@ -205,26 +205,26 @@ restart:
                        continue;
                if (c < 0 || c == '\n') {
                        if (quoted)
-                               warn(in_format, "Missing closing quote.");
+                               warn(fmt, "Missing closing quote.");
                        if (c < 0)
                                return !!fields_count(&in_fields);
                        else
                                return 1;
                }
                if (quoted) {
-                       if (c == in_format->quote) {
+                       if (c == fmt->quote) {
                                c = getchar_unlocked();
-                               if (c != in_format->quote) {
+                               if (c != fmt->quote) {
                                        quoted = 0;
                                        goto restart;
                                }
                                // Two quotes assimilate to one
                        }
                        // Fall through to pushing the character
-               } else if (c == in_format->quote) {
+               } else if (c == fmt->quote) {
                        quoted = 1;
                        continue;
-               } else if (c == in_format->fs && !quoted) {
+               } else if (c == fmt->fs && !quoted) {
                        ensure_field(i);
                        new_field(i);
                        continue;
@@ -240,42 +240,42 @@ static int is_ws(int c)
        return (c == ' ' || c == '\t' || c == '\f');
 }
 
-static void csv_write(void)
+static void csv_write(struct format *fmt)
 {
        unsigned char *line = line_first(&in_line);
        int n = fields_count(&out_fields);
        for (int i=0; i<n; i++) {
                struct field *f = fields_nth(&out_fields, i);
                int need_quotes = 0;
-               if (out_format->quote >= 0) {
-                       need_quotes = out_format->always_quote;
+               if (fmt->quote >= 0) {
+                       need_quotes = fmt->always_quote;
                        for (int j=0; !need_quotes && j < f->len; j++) {
                                int c = line[f->start_pos + j];
-                               if (c == out_format->fs || c == out_format->quote)
+                               if (c == fmt->fs || c == fmt->quote)
                                        need_quotes = 1;
                        }
                }
                if (i)
-                       putchar_unlocked(out_format->fs);
+                       putchar_unlocked(fmt->fs);
                if (need_quotes)
-                       putchar_unlocked(out_format->quote);
+                       putchar_unlocked(fmt->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)
+                       if (c == fmt->fs && !need_quotes)
+                               warn(fmt, "Field separator found inside field and quoting is turned off.");
+                       if (c == fmt->quote)
                                putchar_unlocked(c);
                        putchar_unlocked(c);
                }
                if (need_quotes)
-                       putchar_unlocked(out_format->quote);
+                       putchar_unlocked(fmt->quote);
        }
        putchar_unlocked('\n');
 }
 
 /*** White-space back-end ***/
 
-static int ws_read(void)
+static int ws_read(struct format *fmt)
 {
        if (!next_line())
                return 0;
@@ -295,7 +295,7 @@ static int ws_read(void)
                        if (ws) {
                                if (!in_field->start_pos &&
                                    !in_field->len &&
-                                   !in_format->strict_ws)
+                                   !fmt->strict_ws)
                                        in_field->start_pos = i;
                                else
                                        new_field(i);
@@ -305,7 +305,7 @@ static int ws_read(void)
                }
        }
 
-       if (ws && in_format->strict_ws)
+       if (ws && fmt->strict_ws)
                new_field(n);
        return 1;
 }
@@ -327,7 +327,7 @@ static const char *regex_set(struct format *f, char *rx)
        return NULL;
 }
 
-static int regex_read(void)
+static int regex_read(struct format *fmt)
 {
        if (!next_line())
                return 0;
@@ -340,10 +340,10 @@ static int regex_read(void)
        int i = 0;
        for (;;) {
                int ovec[3];
-               int sep = pcre_exec(in_format->pcre, in_format->pcre_extra, (char *) c, n, i, 0, ovec, 3);
+               int sep = pcre_exec(fmt->pcre, fmt->pcre_extra, (char *) c, n, i, 0, ovec, 3);
                if (sep < 0) {
                        if (sep != PCRE_ERROR_NOMATCH)
-                               warn(in_format, "PCRE matching error %d", sep);
+                               warn(fmt, "PCRE matching error %d", sep);
                        // No further occurrence of the separator: the rest is a single field
                        new_field(i);
                        in_field->len = n - i;
@@ -357,16 +357,16 @@ static int regex_read(void)
 
 /*** Table back-end ***/
 
-static void table_write(void)
+static void table_write(struct format *fmt)
 {
        for (int i = 0; i < fields_count(&in_fields); i++) {
                if (i)
-                       printf("%*s", out_format->table_sep, "");
+                       printf("%*s", fmt->table_sep, "");
                struct field *f = fields_nth(&in_fields, i);
                int fw = field_chars(f);
                int cw = *intarray_nth(&in_format->column_widths, i);
                if (fw > cw) {
-                       warn(out_format, "Internal error: Wrongly calculated column width (%d > %d)", fw, cw);
+                       warn(fmt, "Internal error: Wrongly calculated column width (%d > %d)", fw, cw);
                        cw = fw;
                }
                unsigned char *p = line_nth(&in_line, f->start_pos);
@@ -382,9 +382,9 @@ static void table_write(void)
 
 /*** Temporary file back-end ***/
 
-static int tmp_read(void)
+static int tmp_read(struct format *fmt)
 {
-       FILE *tf = in_format->tmp_file;
+       FILE *tf = fmt->tmp_file;
 
        for (;;) {
                int c = getc_unlocked(tf);
@@ -403,7 +403,7 @@ static int tmp_read(void)
                while (c--) {
                        int x = getc_unlocked(tf);
                        if (x < 0) {
-                               warn(in_format, "Truncated temporary file");
+                               warn(fmt, "Truncated temporary file");
                                return 0;
                        }
                        *line_push(&in_line) = x;
@@ -414,9 +414,9 @@ static int tmp_read(void)
                die("I/O error when reading temporary file");
 }
 
-static void tmp_write(void)
+static void tmp_write(struct format *fmt)
 {
-       FILE *tf = out_format->tmp_file;
+       FILE *tf = fmt->tmp_file;
 
        for (int i = 0; i < fields_count(&in_fields); i++) {
                struct field *f = fields_nth(&in_fields, i);
@@ -434,7 +434,7 @@ static void tmp_write(void)
                for (int j = 0; j < f->len; j++)
                        putc_unlocked(*p++, tf);
 
-               intarray_t *w = &out_format->column_widths;
+               intarray_t *w = &fmt->column_widths;
                while (i >= intarray_count(w))
                        *intarray_push(w) = 0;
                int fw = field_chars(f);
@@ -523,7 +523,7 @@ static void one_pass(void)
                fields_reset(&in_fields);
                line_reset(&in_line);
                in_field = NULL;
-               if (!in_format->read_line())
+               if (!in_format->read_line(in_format))
                        break;
                if (ferror_unlocked(stdin))
                        die("I/O error when reading standard input");
@@ -534,7 +534,7 @@ static void one_pass(void)
                fields_reset(&out_fields);
                select_fields();
 
-               out_format->write_line();
+               out_format->write_line(out_format);
                if (ferror_unlocked(stdout))
                        die("I/O error when writing standard input");
        }