From: Martin Mares Date: Tue, 24 Jul 2012 14:13:20 +0000 (+0200) Subject: Added --equalize X-Git-Tag: v1.0~25 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=e0be90cb432c569d2aac3bba0b9e9de460e39bf7;p=xsv.git Added --equalize --- diff --git a/xsv.c b/xsv.c index 352771a..b0e9124 100644 --- a/xsv.c +++ b/xsv.c @@ -128,7 +128,7 @@ struct format { }; static struct format *in_format, *out_format; -static int want_trim; +static int want_trim, want_equalize, want_stats; struct field { int start_pos; @@ -242,6 +242,9 @@ static intarray_t column_widths; static void update_stats(void) { + if (!want_stats) + return; + for (int i = 0; i < fields_count(&out_fields); i++) { struct field *f = fields_nth(&out_fields, i); intarray_t *w = &column_widths; @@ -434,7 +437,7 @@ static void table_write(struct format *fmt) unsigned char *p = get_field(&out_fields, i, &len); fw = field_chars(fields_nth(&out_fields, i)); if (fw > cw) { - warn(fmt, "Internal error: Wrongly calculated column width (%d > %d)", fw, cw); + warn(fmt, "Internal error: Wrongly calculated width of column %d (%d > %d)", i, fw, cw); cw = fw; } while (len--) @@ -544,6 +547,14 @@ static void trim_fields(void) } } +static void equalize_fields(void) +{ + while (fields_count(&out_fields) < intarray_count(&column_widths)) { + struct field *f = fields_push(&out_fields); + f->start_pos = f->len = 0; + } +} + /*** Field names and headers ***/ struct field_names { @@ -626,7 +637,11 @@ static void write_header(void) // This is tricky: when we are formatting a table, field names are normally // calculated in pass 1, but the header is written in pass 2, so we have to // update column statistics, because field name can be too wide to fit. + want_stats++; update_stats(); + want_stats--; + if (want_equalize) + equalize_fields(); write_grid(-1); write_line(); write_grid(0); @@ -754,9 +769,9 @@ static void one_pass(int pass) else select_all_fields(); - if (out_format->needs_stats) - update_stats(); - + if (want_equalize && (pass & 2)) + equalize_fields(); + update_stats(); write_line(); } @@ -777,7 +792,6 @@ 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; out_format->field_names = in_format->field_names; one_pass(1); @@ -786,7 +800,7 @@ static void two_pass(void) rewind(in_format->tmp_file); line_number = 0; out_format = final_format; - out_format->needs_stats = 0; + want_stats = 0; one_pass(2); fclose(in_format->tmp_file); } @@ -817,6 +831,7 @@ Format parameters:\n\ \n\ Other options:\n\ --trim Trim leading and trailing whitespaces in fields\n\ + --equalize Pad all lines to the maximum number of fields\n\ "); exit(0); } @@ -844,11 +859,13 @@ enum long_options { OPT_TABLE, OPT_TABLE_SEP, OPT_GRID, + OPT_EQUALIZE, }; static const struct option long_options[] = { { "always-quote", 0, NULL, OPT_ALWAYS_QUOTE }, { "csv", 0, NULL, 'c' }, + { "equalize", 0, NULL, OPT_EQUALIZE }, { "fields", 1, NULL, 'f' }, { "fs", 1, NULL, 'd' }, { "grid", 0, NULL, OPT_GRID }, @@ -978,6 +995,9 @@ int main(int argc, char **argv) case OPT_GRID: current_format()->table_grid = 1; break; + case OPT_EQUALIZE: + want_equalize = 1; + break; default: bad_args(NULL); } @@ -998,7 +1018,8 @@ int main(int argc, char **argv) } finish_parse_selectors(); - if (out_format->needs_stats) + want_stats = out_format->needs_stats | want_equalize; + if (want_stats) two_pass(); else one_pass(3);