]> mj.ucw.cz Git - xsv.git/commitdiff
Cleaned up statistics
authorMartin Mares <mj@ucw.cz>
Tue, 24 Jul 2012 12:23:38 +0000 (14:23 +0200)
committerMartin Mares <mj@ucw.cz>
Tue, 24 Jul 2012 12:23:38 +0000 (14:23 +0200)
TODO
xsv.c

diff --git a/TODO b/TODO
index 93a27da1a7c6b4553c32979682f62ace84fabfc9..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1 +0,0 @@
-- call ferror()
diff --git a/xsv.c b/xsv.c
index bd1f389d5caa22abde331c7c0f3d54488afe679d..4ebe79844cf98cd2820dece4f54007b859fcda9e 100644 (file)
--- a/xsv.c
+++ b/xsv.c
@@ -98,7 +98,7 @@ struct format {
        int quiet;
        int (*read_line)(struct format *fmt);
        void (*write_line)(struct format *fmt);
-       int needs_two_passes;
+       int needs_stats;
 
        // CSV backend:
        int always_quote;
@@ -112,7 +112,6 @@ struct format {
 
        // Temporary file backend:
        FILE *tmp_file;
-       intarray_t column_widths;
 
        // Table backend:
        int table_sep;
@@ -192,6 +191,24 @@ static int field_chars(struct field *f)
        return chars;
 }
 
+/*** Field statistics ***/
+
+static intarray_t column_widths;
+
+static void update_stats(void)
+{
+       for (int i = 0; i < fields_count(&in_fields); i++) {
+               struct field *f = fields_nth(&in_fields, i);
+               intarray_t *w = &column_widths;
+
+               while (i >= intarray_count(w))
+                       *intarray_push(w) = 0;
+               int fw = field_chars(f);
+               if (*intarray_nth(w, i) < fw)
+                       *intarray_nth(w, i) = fw;
+       }
+}
+
 /*** CSV/TSV back-end */
 
 static int csv_read(struct format *fmt)
@@ -364,7 +381,7 @@ static void table_write(struct format *fmt)
                        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);
+               int cw = *intarray_nth(&column_widths, i);
                if (fw > cw) {
                        warn(fmt, "Internal error: Wrongly calculated column width (%d > %d)", fw, cw);
                        cw = fw;
@@ -433,13 +450,6 @@ static void tmp_write(struct format *fmt)
                unsigned char *p = line_nth(&in_line, f->start_pos);
                for (int j = 0; j < f->len; j++)
                        putc_unlocked(*p++, tf);
-
-               intarray_t *w = &fmt->column_widths;
-               while (i >= intarray_count(w))
-                       *intarray_push(w) = 0;
-               int fw = field_chars(f);
-               if (*intarray_nth(w, i) < fw)
-                       *intarray_nth(w, i) = fw;
        }
        putc_unlocked(0xff, tf);
 
@@ -534,6 +544,8 @@ static void one_pass(void)
                fields_reset(&out_fields);
                select_fields();
 
+               if (out_format->needs_stats)
+                       update_stats();
                out_format->write_line(out_format);
                if (ferror_unlocked(stdout))
                        die("I/O error when writing standard input");
@@ -553,12 +565,14 @@ static void two_pass(void)
        out_format->read_line = tmp_read;
        out_format->write_line = tmp_write;
        out_format->tmp_file = tmpfile();
+       out_format->needs_stats = final_format->needs_stats;
        one_pass();
 
        // Pass 2: Set up reader of intermediate format
        in_format = out_format;
        rewind(in_format->tmp_file);
        out_format = final_format;
+       out_format->needs_stats = 0;
        one_pass();
        fclose(in_format->tmp_file);
 }
@@ -659,7 +673,7 @@ static void set_format(int format_id)
                        break;
                case FORM_TABLE:
                        f->write_line = table_write;
-                       f->needs_two_passes = 1;
+                       f->needs_stats = 1;
                        f->table_sep = 2;
                        break;
        }
@@ -752,7 +766,7 @@ int main(int argc, char **argv)
        }
        finish_parse_selectors();
 
-       if (out_format->needs_two_passes)
+       if (out_format->needs_stats)
                two_pass();
        else
                one_pass();