diff --git a/common/string-table.c b/common/string-table.c index dc9a5f74..298066ce 100644 --- a/common/string-table.c +++ b/common/string-table.c @@ -20,6 +20,7 @@ #include #include "common/messages.h" #include "common/string-table.h" +#include "common/internal.h" /* * Create an array of char* which will point to table cell strings @@ -88,6 +89,8 @@ char *table_printf(struct string_table *tab, unsigned int column, unsigned int r /* * Print the table to stdout, interpret the alignment and expand specifiers. + * @from: row from which to start + * @to: upper row limit (not inclusive), 0 for the whole table * * Formatting: * ncols]; - int i, j; + unsigned int sizes[tab->ncols]; + unsigned int i, j; + unsigned int prescan; + + if (to == 0) + to = tab->nrows; + + if (from > to) { + error("invalid range for table dump %u > %u", from, to); + return; + } + + prescan = max_t(unsigned int, 100, to); + prescan = min_t(unsigned int, tab->nrows, prescan); for (i = 0; i < tab->ncols; i++) { sizes[i] = 0; - for (j = 0; j < tab->nrows; j++) { + for (j = 0; j < prescan; j++) { int idx = i + j * tab->ncols; int len; @@ -118,7 +133,7 @@ void table_dump(struct string_table *tab) } } - for (j = 0; j < tab->nrows; j++) { + for (j = from; j < to; j++) { for (i = 0; i < tab->ncols; i++) { int idx = i + j * tab->ncols; char *cell = tab->cells[idx]; @@ -160,3 +175,20 @@ void table_free(struct string_table *tab) free(tab); } + +void table_clear_range(struct string_table *tab, unsigned int from, unsigned int to) +{ + unsigned int row, col; + + if (to == 0) + to = tab->nrows; + + for (row = from; row < to; row++) { + char **rowstart = &tab->cells[row * tab->ncols]; + + for (col = 0; col < tab->ncols; col++) { + free(rowstart[col]); + rowstart[col] = NULL; + } + } +} diff --git a/common/string-table.h b/common/string-table.h index ab5f7d66..cdc066fa 100644 --- a/common/string-table.h +++ b/common/string-table.h @@ -27,6 +27,8 @@ enum string_table_spacing { struct string_table { unsigned int ncols; unsigned int nrows; + /* How many rows are header (names and separators). */ + unsigned int hrows; enum string_table_spacing spacing; char *cells[]; }; @@ -37,7 +39,35 @@ char *table_printf(struct string_table *tab, unsigned int column, unsigned int r const char *fmt, ...); char *table_vprintf(struct string_table *tab, unsigned int column, unsigned int row, const char *fmt, va_list ap); -void table_dump(struct string_table *tab); void table_free(struct string_table *tab); +void table_dump_range(struct string_table *tab, unsigned int from, unsigned int to); + +static inline void table_dump(struct string_table *tab) +{ + table_dump_range(tab, 0, 0); +} + +static inline void table_dump_header(struct string_table *tab) +{ + table_dump_range(tab, 0, tab->hrows); +} + +static inline void table_dump_body(struct string_table *tab) +{ + table_dump_range(tab, tab->hrows, 0); +} + +void table_clear_range(struct string_table *tab, unsigned int from, unsigned int to); + +static inline void table_clear_header(struct string_table *tab) +{ + table_clear_range(tab, 0, tab->hrows); +} + +static inline void table_clear_body(struct string_table *tab) +{ + table_clear_range(tab, tab->hrows, 0); +} + #endif