table_display takes a list of lists of strings (representing the table cells) and displays them formatted as a table. The exact format depends on the longest string in each column. Signed-off-by: Jakob Gruber <jakob.gruber@gmail.com> --- src/pacman/util.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pacman/util.h | 1 + 2 files changed, 109 insertions(+), 0 deletions(-) diff --git a/src/pacman/util.c b/src/pacman/util.c index 85d2d8c..8f7b5e5 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -435,6 +435,114 @@ void string_display(const char *title, const char *string) printf("\n"); } +static void table_print_line(const alpm_list_t *line, + const alpm_list_t *formats) +{ + const alpm_list_t *curformat = formats; + const alpm_list_t *curcell = line; + + while (curcell && curformat) { + printf(alpm_list_getdata(curformat), alpm_list_getdata(curcell)); + curcell = alpm_list_next(curcell); + curformat = alpm_list_next(curformat); + } + + printf("\n"); +} + +/* creates a format string by checking max cell lengths in rows */ +static alpm_list_t *table_create_format(const alpm_list_t *rows) +{ + alpm_list_t *format, *curformat; + const alpm_list_t *currow, *curcell; + char *str, *formatstr; + const int padding = 2; + int cols, neededcols = 0; + + /* initial format list element */ + format = alpm_list_add(NULL, NULL); + + /* go through each cell and store the longest string for each + * column in the format list */ + currow = rows; + while(currow != NULL) { + + /* starting on new row, reset format pointer to first column */ + curformat = format; + + /* loop through all row cells and update format pointer if necessary */ + curcell = alpm_list_getdata(currow); + while(curcell != NULL) { + if(curformat == NULL) { + curformat = alpm_list_last(alpm_list_add(format, NULL)); + } + + str = alpm_list_getdata(curcell); + if(curformat->data == NULL || + strlen(str) > strlen(alpm_list_getdata(curformat))) + curformat->data = str; + + curformat = alpm_list_next(curformat); + curcell = alpm_list_next(curcell); + } + + currow = alpm_list_next(currow); + } + + /* now use the column width info to generate format strings */ + curformat = format; + while(curformat != NULL) { + cols = strlen(curformat->data) + padding; + neededcols += cols; + + str = (alpm_list_next(curformat) != NULL) ? "%%-%ds" : "%%%ds"; + pm_asprintf(&formatstr, str, cols); + + curformat->data = formatstr; + curformat = alpm_list_next(curformat); + } + + /* return NULL if terminal is not wide enough */ + if(neededcols > getcols()) { + FREELIST(format); + return NULL; + } + + return format; +} + +/** Displays the list in table format + * + * @param title the tables title + * @param rows the rows to display as a list of lists of strings. the outer + * list represents the rows, the inner list the cells (= columns) + * + * @return -1 if not enough terminal cols available, else 0 + */ +int table_display(const char *title, const alpm_list_t *rows) +{ + alpm_list_t *i, *formats; + + if(rows == NULL) + return 0; + + formats = table_create_format(rows); + if(formats == NULL) { + return -1; + } + + if(title != NULL) { + printf("%s\n\n", title); + } + + for(i = alpm_list_first(rows); i; i = alpm_list_next(i)) { + table_print_line(alpm_list_getdata(i), formats); + } + + FREELIST(formats); + return 0; +} + void list_display(const char *title, const alpm_list_t *list) { const alpm_list_t *i; diff --git a/src/pacman/util.h b/src/pacman/util.h index ed03c13..494becf 100644 --- a/src/pacman/util.h +++ b/src/pacman/util.h @@ -56,6 +56,7 @@ char *size_to_human_string_mb(off_t bytes); char *size_to_human_string_kb(off_t bytes); char *size_to_human_string_short(off_t bytes); void string_display(const char *title, const char *string); +int table_display(const char *title, const alpm_list_t *rows); void list_display(const char *title, const alpm_list_t *list); void list_display_linebreak(const char *title, const alpm_list_t *list); void display_targets(const alpm_list_t *pkgs, int install); -- 1.7.4.1