implement a bunch of stuff:

* column separator (instead of global column prefix)
* per column suffix
* indexing columns by id-number instead of column header
* optional header supression (via settable flags)
* ability to end a row
* don't extend last column to full width


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@13982 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
2004-06-23 15:24:22 +00:00
parent d3453f7087
commit b13da28587

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2002 Kungliga Tekniska H<>gskolan * Copyright (c) 2000, 2002, 2004 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -49,12 +49,16 @@ struct column_data {
unsigned flags; unsigned flags;
size_t num_rows; size_t num_rows;
struct column_entry *rows; struct column_entry *rows;
unsigned int column_id;
char *suffix;
}; };
struct rtbl_data { struct rtbl_data {
char *column_prefix; char *column_prefix;
size_t num_columns; size_t num_columns;
struct column_data **columns; struct column_data **columns;
unsigned int flags;
char *column_separator;
}; };
rtbl_t rtbl_t
@@ -63,6 +67,28 @@ rtbl_create (void)
return calloc (1, sizeof (struct rtbl_data)); return calloc (1, sizeof (struct rtbl_data));
} }
void
rtbl_set_flags (rtbl_t table, unsigned int flags)
{
table->flags = flags;
}
unsigned int
rtbl_get_flags (rtbl_t table)
{
return table->flags;
}
static struct column_data *
rtbl_get_column_by_id (rtbl_t table, unsigned int id)
{
int i;
for(i = 0; i < table->num_columns; i++)
if(table->columns[i]->column_id == id)
return table->columns[i];
return NULL;
}
static struct column_data * static struct column_data *
rtbl_get_column (rtbl_t table, const char *column) rtbl_get_column (rtbl_t table, const char *column)
{ {
@@ -86,15 +112,18 @@ rtbl_destroy (rtbl_t table)
free (c->rows); free (c->rows);
free (c->header); free (c->header);
free (c->prefix); free (c->prefix);
free (c->suffix);
free (c); free (c);
} }
free (table->column_prefix); free (table->column_prefix);
free (table->column_separator);
free (table->columns); free (table->columns);
free (table); free (table);
} }
int int
rtbl_add_column (rtbl_t table, const char *header, unsigned int flags) rtbl_add_column_by_id (rtbl_t table, unsigned int id,
const char *header, unsigned int flags)
{ {
struct column_data *col, **tmp; struct column_data *col, **tmp;
@@ -110,25 +139,64 @@ rtbl_add_column (rtbl_t table, const char *header, unsigned int flags)
free (col); free (col);
return ENOMEM; return ENOMEM;
} }
col->prefix = NULL; col->prefix = NULL;
col->width = 0; col->width = 0;
col->flags = flags; col->flags = flags;
col->num_rows = 0; col->num_rows = 0;
col->rows = NULL; col->rows = NULL;
col->column_id = id;
col->suffix = NULL;
table->columns[table->num_columns++] = col; table->columns[table->num_columns++] = col;
return 0; return 0;
} }
int
rtbl_add_column (rtbl_t table, const char *header, unsigned int flags)
{
return rtbl_add_column_by_id(table, 0, header, flags);
}
int rtbl_new_row(rtbl_t);
int
rtbl_new_row(rtbl_t table)
{
size_t max_rows = 0;
size_t c;
for (c = 0; c < table->num_columns; c++)
if(table->columns[c]->num_rows > max_rows)
max_rows = table->columns[c]->num_rows;
for (c = 0; c < table->num_columns; c++) {
struct column_entry *tmp;
if(table->columns[c]->num_rows == max_rows)
continue;
tmp = realloc(table->columns[c]->rows,
max_rows * sizeof(table->columns[c]->rows));
if(tmp == NULL)
return ENOMEM;
table->columns[c]->rows = tmp;
while(table->columns[c]->num_rows < max_rows) {
if((tmp[table->columns[c]->num_rows++].data = strdup("")) == NULL)
return ENOMEM;
}
}
return 0;
}
static void static void
column_compute_width (struct column_data *column) column_compute_width (rtbl_t table, struct column_data *column)
{ {
int i; int i;
column->width = strlen (column->header); if(table->flags & RTBL_HEADER_STYLE_NONE)
column->width = 0;
else
column->width = strlen (column->header);
for (i = 0; i < column->num_rows; i++) for (i = 0; i < column->num_rows; i++)
column->width = max (column->width, strlen (column->rows[i].data)); column->width = max (column->width, strlen (column->rows[i].data));
} }
/* DEPRECATED */
int int
rtbl_set_prefix (rtbl_t table, const char *prefix) rtbl_set_prefix (rtbl_t table, const char *prefix)
{ {
@@ -140,6 +208,17 @@ rtbl_set_prefix (rtbl_t table, const char *prefix)
return 0; return 0;
} }
int
rtbl_set_separator (rtbl_t table, const char *separator)
{
if (table->column_separator)
free (table->column_separator);
table->column_separator = strdup (separator);
if (table->column_separator == NULL)
return ENOMEM;
return 0;
}
int int
rtbl_set_column_prefix (rtbl_t table, const char *column, rtbl_set_column_prefix (rtbl_t table, const char *column,
const char *prefix) const char *prefix)
@@ -156,6 +235,36 @@ rtbl_set_column_prefix (rtbl_t table, const char *column,
return 0; return 0;
} }
int
rtbl_set_column_affix_by_id(rtbl_t table, unsigned int id,
const char *prefix, const char *suffix)
{
struct column_data *c = rtbl_get_column_by_id (table, id);
if (c == NULL)
return -1;
if (c->prefix)
free (c->prefix);
if(prefix == NULL)
c->prefix = NULL;
else {
c->prefix = strdup (prefix);
if (c->prefix == NULL)
return ENOMEM;
}
if (c->suffix)
free (c->suffix);
if(suffix == NULL)
c->suffix = NULL;
else {
c->suffix = strdup (suffix);
if (c->suffix == NULL)
return ENOMEM;
}
return 0;
}
static const char * static const char *
get_column_prefix (rtbl_t table, struct column_data *c) get_column_prefix (rtbl_t table, struct column_data *c)
@@ -169,16 +278,19 @@ get_column_prefix (rtbl_t table, struct column_data *c)
return ""; return "";
} }
int static const char *
rtbl_add_column_entry (rtbl_t table, const char *column, const char *data) get_column_suffix (rtbl_t table, struct column_data *c)
{
if (c && c->suffix)
return c->suffix;
return "";
}
static int
add_column_entry (struct column_data *c, const char *data)
{ {
struct column_entry row, *tmp; struct column_entry row, *tmp;
struct column_data *c = rtbl_get_column (table, column);
if (c == NULL)
return -1;
row.data = strdup (data); row.data = strdup (data);
if (row.data == NULL) if (row.data == NULL)
return ENOMEM; return ENOMEM;
@@ -192,24 +304,56 @@ rtbl_add_column_entry (rtbl_t table, const char *column, const char *data)
return 0; return 0;
} }
int
rtbl_add_column_entry_by_id (rtbl_t table, unsigned int id, const char *data)
{
struct column_data *c = rtbl_get_column_by_id (table, id);
if (c == NULL)
return -1;
return add_column_entry(c, data);
}
int
rtbl_add_column_entry (rtbl_t table, const char *column, const char *data)
{
struct column_data *c = rtbl_get_column (table, column);
if (c == NULL)
return -1;
return add_column_entry(c, data);
}
int int
rtbl_format (rtbl_t table, FILE * f) rtbl_format (rtbl_t table, FILE * f)
{ {
int i, j; int i, j;
for (i = 0; i < table->num_columns; i++) for (i = 0; i < table->num_columns; i++)
column_compute_width (table->columns[i]); column_compute_width (table, table->columns[i]);
for (i = 0; i < table->num_columns; i++) { if((table->flags & RTBL_HEADER_STYLE_NONE) == 0) {
struct column_data *c = table->columns[i]; for (i = 0; i < table->num_columns; i++) {
struct column_data *c = table->columns[i];
fprintf (f, "%s", get_column_prefix (table, c)); if(table->column_separator != NULL && i > 0)
fprintf (f, "%-*s", (int)c->width, c->header); fprintf (f, "%s", table->column_separator);
fprintf (f, "%s", get_column_prefix (table, c));
if(i == table->num_columns - 1 && c->suffix == NULL)
/* last column, so no need to pad with spaces */
fprintf (f, "%-*s", 0, c->header);
else
fprintf (f, "%-*s", (int)c->width, c->header);
fprintf (f, "%s", get_column_suffix (table, c));
}
fprintf (f, "\n");
} }
fprintf (f, "\n");
for (j = 0;; j++) { for (j = 0;; j++) {
int flag = 0; int flag = 0;
/* are there any more rows left? */
for (i = 0; flag == 0 && i < table->num_columns; ++i) { for (i = 0; flag == 0 && i < table->num_columns; ++i) {
struct column_data *c = table->columns[i]; struct column_data *c = table->columns[i];
@@ -225,15 +369,24 @@ rtbl_format (rtbl_t table, FILE * f)
int w; int w;
struct column_data *c = table->columns[i]; struct column_data *c = table->columns[i];
if(table->column_separator != NULL && i > 0)
fprintf (f, "%s", table->column_separator);
w = c->width; w = c->width;
if ((c->flags & RTBL_ALIGN_RIGHT) == 0) if ((c->flags & RTBL_ALIGN_RIGHT) == 0) {
w = -w; if(i == table->num_columns - 1 && c->suffix == NULL)
/* last column, so no need to pad with spaces */
w = 0;
else
w = -w;
}
fprintf (f, "%s", get_column_prefix (table, c)); fprintf (f, "%s", get_column_prefix (table, c));
if (c->num_rows <= j) if (c->num_rows <= j)
fprintf (f, "%*s", w, ""); fprintf (f, "%*s", w, "");
else else
fprintf (f, "%*s", w, c->rows[j].data); fprintf (f, "%*s", w, c->rows[j].data);
fprintf (f, "%s", get_column_suffix (table, c));
} }
fprintf (f, "\n"); fprintf (f, "\n");
} }
@@ -245,36 +398,57 @@ int
main (int argc, char **argv) main (int argc, char **argv)
{ {
rtbl_t table; rtbl_t table;
unsigned int a, b, c, d;
table = rtbl_create (); table = rtbl_create ();
rtbl_add_column (table, "Issued", 0, &a); rtbl_add_column_by_id (table, 0, "Issued", 0);
rtbl_add_column (table, "Expires", 0, &b); rtbl_add_column_by_id (table, 1, "Expires", 0);
rtbl_add_column (table, "Foo", RTBL_ALIGN_RIGHT, &d); rtbl_add_column_by_id (table, 2, "Foo", RTBL_ALIGN_RIGHT);
rtbl_add_column (table, "Principal", 0, &c); rtbl_add_column_by_id (table, 3, "Principal", 0);
rtbl_add_column_entry (table, a, "Jul 7 21:19:29"); rtbl_add_column_entry_by_id (table, 0, "Jul 7 21:19:29");
rtbl_add_column_entry (table, b, "Jul 8 07:19:29"); rtbl_add_column_entry_by_id (table, 1, "Jul 8 07:19:29");
rtbl_add_column_entry (table, d, "73"); rtbl_add_column_entry_by_id (table, 2, "73");
rtbl_add_column_entry (table, d, "0"); rtbl_add_column_entry_by_id (table, 2, "0");
rtbl_add_column_entry (table, d, "-2000"); rtbl_add_column_entry_by_id (table, 2, "-2000");
rtbl_add_column_entry (table, c, "krbtgt/NADA.KTH.SE@NADA.KTH.SE"); rtbl_add_column_entry_by_id (table, 3, "krbtgt/NADA.KTH.SE@NADA.KTH.SE");
rtbl_add_column_entry (table, a, "Jul 7 21:19:29"); rtbl_add_column_entry_by_id (table, 0, "Jul 7 21:19:29");
rtbl_add_column_entry (table, b, "Jul 8 07:19:29"); rtbl_add_column_entry_by_id (table, 1, "Jul 8 07:19:29");
rtbl_add_column_entry (table, c, "afs/pdc.kth.se@NADA.KTH.SE"); rtbl_add_column_entry_by_id (table, 3, "afs/pdc.kth.se@NADA.KTH.SE");
rtbl_add_column_entry (table, a, "Jul 7 21:19:29"); rtbl_add_column_entry_by_id (table, 0, "Jul 7 21:19:29");
rtbl_add_column_entry (table, b, "Jul 8 07:19:29"); rtbl_add_column_entry_by_id (table, 1, "Jul 8 07:19:29");
rtbl_add_column_entry (table, c, "afs@NADA.KTH.SE"); rtbl_add_column_entry_by_id (table, 3, "afs@NADA.KTH.SE");
rtbl_set_prefix (table, " "); rtbl_set_separator (table, " ");
rtbl_set_column_prefix (table, a, "");
rtbl_format (table, stdout); rtbl_format (table, stdout);
rtbl_destroy (table); rtbl_destroy (table);
printf("\n");
table = rtbl_create ();
rtbl_add_column_by_id (table, 0, "Column A", 0);
rtbl_set_column_affix_by_id (table, 0, "<", ">");
rtbl_add_column_by_id (table, 1, "Column B", 0);
rtbl_set_column_affix_by_id (table, 1, "[", "]");
rtbl_add_column_by_id (table, 2, "Column C", 0);
rtbl_set_column_affix_by_id (table, 2, "(", ")");
rtbl_add_column_entry_by_id (table, 0, "1");
rtbl_new_row(table);
rtbl_add_column_entry_by_id (table, 1, "2");
rtbl_new_row(table);
rtbl_add_column_entry_by_id (table, 2, "3");
rtbl_new_row(table);
rtbl_set_separator (table, " ");
rtbl_format (table, stdout);
rtbl_destroy (table);
return 0;
} }
#endif #endif