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).
* All rights reserved.
*
@@ -49,12 +49,16 @@ struct column_data {
unsigned flags;
size_t num_rows;
struct column_entry *rows;
unsigned int column_id;
char *suffix;
};
struct rtbl_data {
char *column_prefix;
size_t num_columns;
struct column_data **columns;
unsigned int flags;
char *column_separator;
};
rtbl_t
@@ -63,6 +67,28 @@ rtbl_create (void)
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 *
rtbl_get_column (rtbl_t table, const char *column)
{
@@ -86,15 +112,18 @@ rtbl_destroy (rtbl_t table)
free (c->rows);
free (c->header);
free (c->prefix);
free (c->suffix);
free (c);
}
free (table->column_prefix);
free (table->column_separator);
free (table->columns);
free (table);
}
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;
@@ -110,25 +139,64 @@ rtbl_add_column (rtbl_t table, const char *header, unsigned int flags)
free (col);
return ENOMEM;
}
col->prefix = NULL;
col->width = 0;
col->flags = flags;
col->prefix = NULL;
col->width = 0;
col->flags = flags;
col->num_rows = 0;
col->rows = NULL;
col->rows = NULL;
col->column_id = id;
col->suffix = NULL;
table->columns[table->num_columns++] = col;
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
column_compute_width (struct column_data *column)
column_compute_width (rtbl_t table, struct column_data *column)
{
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++)
column->width = max (column->width, strlen (column->rows[i].data));
}
/* DEPRECATED */
int
rtbl_set_prefix (rtbl_t table, const char *prefix)
{
@@ -140,6 +208,17 @@ rtbl_set_prefix (rtbl_t table, const char *prefix)
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
rtbl_set_column_prefix (rtbl_t table, const char *column,
const char *prefix)
@@ -156,6 +235,36 @@ rtbl_set_column_prefix (rtbl_t table, const char *column,
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 *
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 "";
}
int
rtbl_add_column_entry (rtbl_t table, const char *column, const char *data)
static const char *
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_data *c = rtbl_get_column (table, column);
if (c == NULL)
return -1;
row.data = strdup (data);
if (row.data == NULL)
return ENOMEM;
@@ -192,24 +304,56 @@ rtbl_add_column_entry (rtbl_t table, const char *column, const char *data)
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
rtbl_format (rtbl_t table, FILE * f)
{
int i, j;
for (i = 0; i < table->num_columns; i++)
column_compute_width (table->columns[i]);
for (i = 0; i < table->num_columns; i++) {
struct column_data *c = table->columns[i];
column_compute_width (table, table->columns[i]);
if((table->flags & RTBL_HEADER_STYLE_NONE) == 0) {
for (i = 0; i < table->num_columns; i++) {
struct column_data *c = table->columns[i];
fprintf (f, "%s", get_column_prefix (table, c));
fprintf (f, "%-*s", (int)c->width, c->header);
if(table->column_separator != NULL && i > 0)
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++) {
int flag = 0;
/* are there any more rows left? */
for (i = 0; flag == 0 && i < table->num_columns; ++i) {
struct column_data *c = table->columns[i];
@@ -225,15 +369,24 @@ rtbl_format (rtbl_t table, FILE * f)
int w;
struct column_data *c = table->columns[i];
if(table->column_separator != NULL && i > 0)
fprintf (f, "%s", table->column_separator);
w = c->width;
if ((c->flags & RTBL_ALIGN_RIGHT) == 0)
w = -w;
if ((c->flags & RTBL_ALIGN_RIGHT) == 0) {
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));
if (c->num_rows <= j)
fprintf (f, "%*s", w, "");
else
fprintf (f, "%*s", w, c->rows[j].data);
fprintf (f, "%s", get_column_suffix (table, c));
}
fprintf (f, "\n");
}
@@ -245,36 +398,57 @@ int
main (int argc, char **argv)
{
rtbl_t table;
unsigned int a, b, c, d;
table = rtbl_create ();
rtbl_add_column (table, "Issued", 0, &a);
rtbl_add_column (table, "Expires", 0, &b);
rtbl_add_column (table, "Foo", RTBL_ALIGN_RIGHT, &d);
rtbl_add_column (table, "Principal", 0, &c);
rtbl_add_column_by_id (table, 0, "Issued", 0);
rtbl_add_column_by_id (table, 1, "Expires", 0);
rtbl_add_column_by_id (table, 2, "Foo", RTBL_ALIGN_RIGHT);
rtbl_add_column_by_id (table, 3, "Principal", 0);
rtbl_add_column_entry (table, a, "Jul 7 21:19:29");
rtbl_add_column_entry (table, b, "Jul 8 07:19:29");
rtbl_add_column_entry (table, d, "73");
rtbl_add_column_entry (table, d, "0");
rtbl_add_column_entry (table, d, "-2000");
rtbl_add_column_entry (table, c, "krbtgt/NADA.KTH.SE@NADA.KTH.SE");
rtbl_add_column_entry_by_id (table, 0, "Jul 7 21:19:29");
rtbl_add_column_entry_by_id (table, 1, "Jul 8 07:19:29");
rtbl_add_column_entry_by_id (table, 2, "73");
rtbl_add_column_entry_by_id (table, 2, "0");
rtbl_add_column_entry_by_id (table, 2, "-2000");
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 (table, b, "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, 0, "Jul 7 21:19:29");
rtbl_add_column_entry_by_id (table, 1, "Jul 8 07:19:29");
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 (table, b, "Jul 8 07:19:29");
rtbl_add_column_entry (table, c, "afs@NADA.KTH.SE");
rtbl_add_column_entry_by_id (table, 0, "Jul 7 21:19:29");
rtbl_add_column_entry_by_id (table, 1, "Jul 8 07:19:29");
rtbl_add_column_entry_by_id (table, 3, "afs@NADA.KTH.SE");
rtbl_set_prefix (table, " ");
rtbl_set_column_prefix (table, a, "");
rtbl_set_separator (table, " ");
rtbl_format (table, stdout);
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