From: Karel Zak Date: Wed, 27 Apr 2011 15:15:36 +0000 (+0200) Subject: lib: [tt.c] support fixed width and multiple tt_print_table() calls X-Git-Tag: v2.20-rc1~318 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ce56db846681ee5035411c63d3223424f224c7c8;p=thirdparty%2Futil-linux.git lib: [tt.c] support fixed width and multiple tt_print_table() calls Signed-off-by: Karel Zak --- diff --git a/include/tt.h b/include/tt.h index 400d6ba5e6..569e81b3a4 100644 --- a/include/tt.h +++ b/include/tt.h @@ -18,12 +18,14 @@ enum { TT_FL_ASCII = (1 << 4), TT_FL_NOHEADINGS = (1 << 5), TT_FL_RIGHT = (1 << 6), + TT_FL_STRICTWIDTH = (1 << 7) }; struct tt { int ncols; /* number of columns */ int termwidth; /* terminal width */ int flags; + int first_run; struct list_head tb_columns; struct list_head tb_lines; @@ -60,6 +62,7 @@ struct tt_line { extern struct tt *tt_new_table(int flags); extern void tt_free_table(struct tt *tb); +extern void tt_remove_lines(struct tt *tb); extern int tt_print_table(struct tt *tb); extern struct tt_column *tt_define_column(struct tt *tb, const char *name, diff --git a/lib/tt.c b/lib/tt.c index b149d0099f..3e78ad0ced 100644 --- a/lib/tt.c +++ b/lib/tt.c @@ -81,13 +81,16 @@ struct tt *tt_new_table(int flags) else #endif tb->symbols = &ascii_tt_symbols; + + tb->first_run = TRUE; return tb; } -void tt_free_table(struct tt *tb) +void tt_remove_lines(struct tt *tb) { if (!tb) return; + while (!list_empty(&tb->tb_lines)) { struct tt_line *ln = list_entry(tb->tb_lines.next, struct tt_line, ln_lines); @@ -95,6 +98,15 @@ void tt_free_table(struct tt *tb) free(ln->data); free(ln); } +} + +void tt_free_table(struct tt *tb) +{ + if (!tb) + return; + + tt_remove_lines(tb); + while (!list_empty(&tb->tb_columns)) { struct tt_column *cl = list_entry(tb->tb_columns.next, struct tt_column, cl_columns); @@ -104,12 +116,24 @@ void tt_free_table(struct tt *tb) free(tb); } + /* * @tb: table * @name: column header * @whint: column width hint (absolute width: N > 1; relative width: N < 1) * @flags: usually TT_FL_{TREE,TRUNCATE} * + * The column width is possible to define by three ways: + * + * @whint = 0..1 : relative width, percent of terminal width + * + * @whint = 1..N : absolute width, empty colum will be truncated to + * the column header width + * + * @whint = 1..N + * @flags = TT_FL_STRICTWIDTH + * : absolute width, empty colum won't be truncated + * * The column is necessary to address (for example for tt_line_set_data()) by * sequential number. The first defined column has the colnum = 0. For example: * @@ -351,7 +375,8 @@ static void recount_widths(struct tt *tb, char *buf, size_t bufsz) if (cl->name) cl->width_min = mbs_width(cl->name); - if (cl->width < cl->width_min) + if (cl->width < cl->width_min && + !(cl->flags & TT_FL_STRICTWIDTH)) cl->width = cl->width_min; else if (cl->width_hint >= 1 && @@ -508,7 +533,9 @@ static void print_header(struct tt *tb, char *buf, size_t bufsz) { struct list_head *p; - if ((tb->flags & TT_FL_NOHEADINGS) || list_empty(&tb->tb_lines)) + if (!tb->first_run || + (tb->flags & TT_FL_NOHEADINGS) || + list_empty(&tb->tb_lines)) return; /* set width according to the size of data @@ -583,7 +610,8 @@ int tt_print_table(struct tt *tb) if (!tb) return -1; - if (!tb->termwidth) { + + if (tb->first_run && !tb->termwidth) { tb->termwidth = get_terminal_width(); if (tb->termwidth <= 0) tb->termwidth = 80; @@ -600,14 +628,18 @@ int tt_print_table(struct tt *tb) line = malloc(line_sz); if (!line) return -1; - if (!(tb->flags & TT_FL_RAW)) + + if (tb->first_run && !(tb->flags & TT_FL_RAW)) recount_widths(tb, line, line_sz); + if (tb->flags & TT_FL_TREE) print_tree(tb, line, line_sz); else print_table(tb, line, line_sz); free(line); + + tb->first_run = FALSE; return 0; }