[pacman-dev] [PATCH 5/6] Table formatted output functions

Dan McGee dpmcgee at gmail.com
Fri Feb 25 10:21:24 EST 2011


On Mon, Feb 21, 2011 at 1:02 PM, Jakob Gruber <jakob.gruber at gmail.com> wrote:
> 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 at gmail.com>
> ---
>  src/pacman/util.c |  108 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/pacman/util.h |    1 +
>  2 files changed, 109 insertions(+), 0 deletions(-)

Noticing it now, but please read the coding style document. We always
use {}, even on one line conditionals. We also format all return
statements as return(value). Yes, this one is suspect, but consistency
is more important than anything.

>
> 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);
What's going on here? We always have a NULL first item?

> +
> +       /* go through each cell and store the longest string for each
> +        * column in the format list */
> +       currow = rows;
> +       while(currow != NULL) {
You've wrote a for() loop without the for here and the last line of the block.
> +
> +               /* starting on new row, reset format pointer to first column */
> +               curformat = format;
> +
> +               /* loop through all row cells and update format pointer if necessary */
Which isn't really a format pointer at all, but a pointer to actual data?

> +               curcell = alpm_list_getdata(currow);
> +               while(curcell != NULL) {
> +                       if(curformat == NULL) {
> +                               curformat = alpm_list_last(alpm_list_add(format, NULL));
This makes assumptions. I doubt we'll ever break it, but alpm_list_add
always needs to be reassigned back to format, in this case, before
doing anything else on it.

> +                       }
> +
> +                       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";
Magic here- everything else seems generic, but why is this last column special?

> +               pm_asprintf(&formatstr, str, cols);
> +
> +               curformat->data = formatstr;
> +               curformat = alpm_list_next(curformat);
> +       }
I had a real hard time following all this, but that might just be the
morning brain not working well. Your reuse of curformat->data as first
a immutable string holder and later a alloced format string holder is
particularly hard to wrap the brain around until you see it. I'd
highly recommend not mixing the two for clarity.

input: a list of rows, each with a list of cols (cells)?
output: a list of formats for each col?

> +
> +       /* return NULL if terminal is not wide enough */
> +       if(neededcols > getcols()) {
> +               FREELIST(format);
> +               return NULL;
> +       }
Hmm. Is this likely to happen? Seems odd to then not have anything
printed at all. I think we should truncate strings as necessary, just
like we do in the callback functions.

> +
> +       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
>
>
>


More information about the pacman-dev mailing list