rtbl.c revision 103423
1310419Sdelphij/* 2285612Sdelphij * Copyright (c) 2000, 2002 Kungliga Tekniska H�gskolan 3285612Sdelphij * (Royal Institute of Technology, Stockholm, Sweden). 4285612Sdelphij * All rights reserved. 555857Ssheldonh * 655857Ssheldonh * Redistribution and use in source and binary forms, with or without 755857Ssheldonh * modification, are permitted provided that the following conditions 8310419Sdelphij * are met: 9285612Sdelphij * 10285612Sdelphij * 1. Redistributions of source code must retain the above copyright 1155857Ssheldonh * notice, this list of conditions and the following disclaimer. 1255857Ssheldonh * 1355857Ssheldonh * 2. Redistributions in binary form must reproduce the above copyright 1455857Ssheldonh * notice, this list of conditions and the following disclaimer in the 1555857Ssheldonh * documentation and/or other materials provided with the distribution. 16285612Sdelphij * 17285612Sdelphij * 3. Neither the name of the Institute nor the names of its contributors 18285612Sdelphij * may be used to endorse or promote products derived from this software 19285612Sdelphij * without specific prior written permission. 20285612Sdelphij * 21285612Sdelphij * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2255857Ssheldonh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2382501Ssheldonh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2455857Ssheldonh * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25285612Sdelphij * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26285612Sdelphij * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27285612Sdelphij * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28285612Sdelphij * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29285612Sdelphij * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30285612Sdelphij * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31285612Sdelphij * SUCH DAMAGE. 32285612Sdelphij */ 33285612Sdelphij 34285612Sdelphij#ifdef HAVE_CONFIG_H 35285612Sdelphij#include <config.h> 36285612SdelphijRCSID ("$Id: rtbl.c,v 1.4 2002/09/04 21:25:09 joda Exp $"); 3782501Ssheldonh#endif 3855857Ssheldonh#include "roken.h" 39285612Sdelphij#include "rtbl.h" 40285612Sdelphij 41285612Sdelphijstruct column_entry { 4282501Ssheldonh char *data; 4382501Ssheldonh}; 4455857Ssheldonh 4582501Ssheldonhstruct column_data { 4682501Ssheldonh char *header; 4782501Ssheldonh char *prefix; 4882501Ssheldonh int width; 4982501Ssheldonh unsigned flags; 5055857Ssheldonh size_t num_rows; 5182501Ssheldonh struct column_entry *rows; 5282501Ssheldonh}; 5382501Ssheldonh 5455857Ssheldonhstruct rtbl_data { 5599968Scharnier char *column_prefix; 5655857Ssheldonh size_t num_columns; 5799968Scharnier struct column_data **columns; 5882501Ssheldonh}; 5955857Ssheldonh 60285612Sdelphijrtbl_t 6182501Ssheldonhrtbl_create (void) 6282501Ssheldonh{ 6382501Ssheldonh return calloc (1, sizeof (struct rtbl_data)); 6482501Ssheldonh} 6582501Ssheldonh 6699968Scharnierstatic struct column_data * 6755857Ssheldonhrtbl_get_column (rtbl_t table, const char *column) 6899968Scharnier{ 6982501Ssheldonh int i; 7082501Ssheldonh for(i = 0; i < table->num_columns; i++) 7182501Ssheldonh if(strcmp(table->columns[i]->header, column) == 0) 7282501Ssheldonh return table->columns[i]; 7382501Ssheldonh return NULL; 7482501Ssheldonh} 7582501Ssheldonh 7682501Ssheldonhvoid 7782501Ssheldonhrtbl_destroy (rtbl_t table) 7882501Ssheldonh{ 7982501Ssheldonh int i, j; 8082501Ssheldonh 8182501Ssheldonh for (i = 0; i < table->num_columns; i++) { 8282501Ssheldonh struct column_data *c = table->columns[i]; 8382501Ssheldonh 8482501Ssheldonh for (j = 0; j < c->num_rows; j++) 8582501Ssheldonh free (c->rows[j].data); 8682501Ssheldonh free (c->rows); 8782501Ssheldonh free (c->header); 8882501Ssheldonh free (c->prefix); 8982501Ssheldonh free (c); 9082501Ssheldonh } 9182501Ssheldonh free (table->column_prefix); 9255857Ssheldonh free (table->columns); 9399968Scharnier free (table); 9482501Ssheldonh} 9555857Ssheldonh 96285612Sdelphijint 97285612Sdelphijrtbl_add_column (rtbl_t table, const char *header, unsigned int flags) 9855857Ssheldonh{ 9955857Ssheldonh struct column_data *col, **tmp; 100285612Sdelphij 10182501Ssheldonh tmp = realloc (table->columns, (table->num_columns + 1) * sizeof (*tmp)); 10282501Ssheldonh if (tmp == NULL) 10368965Sru return ENOMEM; 10455857Ssheldonh table->columns = tmp; 105285612Sdelphij col = malloc (sizeof (*col)); 10682501Ssheldonh if (col == NULL) 10782501Ssheldonh return ENOMEM; 10855857Ssheldonh col->header = strdup (header); 10955857Ssheldonh if (col->header == NULL) { 11055857Ssheldonh free (col); 11182501Ssheldonh return ENOMEM; 11282501Ssheldonh } 113285612Sdelphij col->prefix = NULL; 114285612Sdelphij col->width = 0; 11555857Ssheldonh col->flags = flags; 116285612Sdelphij col->num_rows = 0; 11755857Ssheldonh col->rows = NULL; 118285612Sdelphij table->columns[table->num_columns++] = col; 11982501Ssheldonh return 0; 12082501Ssheldonh} 12182501Ssheldonh 12255857Ssheldonhstatic void 12382501Ssheldonhcolumn_compute_width (struct column_data *column) 12482501Ssheldonh{ 12582501Ssheldonh int i; 12699968Scharnier 12755857Ssheldonh column->width = strlen (column->header); 12899968Scharnier for (i = 0; i < column->num_rows; i++) 12955857Ssheldonh column->width = max (column->width, strlen (column->rows[i].data)); 13055857Ssheldonh} 13155857Ssheldonh 13255857Ssheldonhint 13357673Ssheldonhrtbl_set_prefix (rtbl_t table, const char *prefix) 13457673Ssheldonh{ 13555857Ssheldonh if (table->column_prefix) 13682501Ssheldonh free (table->column_prefix); 13782501Ssheldonh table->column_prefix = strdup (prefix); 13882501Ssheldonh if (table->column_prefix == NULL) 139285612Sdelphij return ENOMEM; 14055857Ssheldonh return 0; 14155857Ssheldonh} 14282501Ssheldonh 14382501Ssheldonhint 144107311Srurtbl_set_column_prefix (rtbl_t table, const char *column, 14582501Ssheldonh const char *prefix) 14682501Ssheldonh{ 147285612Sdelphij struct column_data *c = rtbl_get_column (table, column); 148285612Sdelphij 149285612Sdelphij if (c == NULL) 150285612Sdelphij return -1; 151285612Sdelphij if (c->prefix) 152285612Sdelphij free (c->prefix); 153285612Sdelphij c->prefix = strdup (prefix); 154285612Sdelphij if (c->prefix == NULL) 155285612Sdelphij return ENOMEM; 156285612Sdelphij return 0; 157285612Sdelphij} 158285612Sdelphij 159285612Sdelphij 160285612Sdelphijstatic const char * 161285612Sdelphijget_column_prefix (rtbl_t table, struct column_data *c) 162285612Sdelphij{ 163285612Sdelphij if (c == NULL) 164285612Sdelphij return ""; 165285612Sdelphij if (c->prefix) 166285612Sdelphij return c->prefix; 167285612Sdelphij if (table->column_prefix) 168285612Sdelphij return table->column_prefix; 169285612Sdelphij return ""; 170285612Sdelphij} 171285612Sdelphij 172285612Sdelphijint 17355857Ssheldonhrtbl_add_column_entry (rtbl_t table, const char *column, const char *data) 17482501Ssheldonh{ 17582501Ssheldonh struct column_entry row, *tmp; 17682501Ssheldonh 17782501Ssheldonh struct column_data *c = rtbl_get_column (table, column); 17882501Ssheldonh 17955857Ssheldonh if (c == NULL) 18055857Ssheldonh return -1; 181285612Sdelphij 18282501Ssheldonh row.data = strdup (data); 183131531Sru if (row.data == NULL) 184285612Sdelphij return ENOMEM; 185285612Sdelphij tmp = realloc (c->rows, (c->num_rows + 1) * sizeof (*tmp)); 186285612Sdelphij if (tmp == NULL) { 18782501Ssheldonh free (row.data); 18882501Ssheldonh return ENOMEM; 18982501Ssheldonh } 190285612Sdelphij c->rows = tmp; 19160588Ssheldonh c->rows[c->num_rows++] = row; 192285612Sdelphij return 0; 193285612Sdelphij} 19455857Ssheldonh 19582501Ssheldonhint 19682501Ssheldonhrtbl_format (rtbl_t table, FILE * f) 19782501Ssheldonh{ 19882501Ssheldonh int i, j; 19982501Ssheldonh 20082501Ssheldonh for (i = 0; i < table->num_columns; i++) 20182501Ssheldonh column_compute_width (table->columns[i]); 20255857Ssheldonh for (i = 0; i < table->num_columns; i++) { 203285612Sdelphij struct column_data *c = table->columns[i]; 204285612Sdelphij 205285612Sdelphij fprintf (f, "%s", get_column_prefix (table, c)); 20655857Ssheldonh fprintf (f, "%-*s", (int)c->width, c->header); 20755857Ssheldonh } 208285612Sdelphij fprintf (f, "\n"); 209285612Sdelphij 210285612Sdelphij for (j = 0;; j++) { 21155857Ssheldonh int flag = 0; 21282501Ssheldonh 21382501Ssheldonh for (i = 0; flag == 0 && i < table->num_columns; ++i) { 21482501Ssheldonh struct column_data *c = table->columns[i]; 21555857Ssheldonh 21682501Ssheldonh if (c->num_rows > j) { 21782501Ssheldonh ++flag; 21882501Ssheldonh break; 21955857Ssheldonh } 22082501Ssheldonh } 22182501Ssheldonh if (flag == 0) 22282501Ssheldonh break; 22355857Ssheldonh 22455857Ssheldonh for (i = 0; i < table->num_columns; i++) { 22555857Ssheldonh int w; 226285612Sdelphij struct column_data *c = table->columns[i]; 227285612Sdelphij 228285612Sdelphij w = c->width; 229289999Sglebius 230289999Sglebius if ((c->flags & RTBL_ALIGN_RIGHT) == 0) 231289999Sglebius w = -w; 232285612Sdelphij fprintf (f, "%s", get_column_prefix (table, c)); 233285612Sdelphij if (c->num_rows <= j) 234285612Sdelphij fprintf (f, "%*s", w, ""); 235285612Sdelphij else 236285612Sdelphij fprintf (f, "%*s", w, c->rows[j].data); 237285612Sdelphij } 238285612Sdelphij fprintf (f, "\n"); 239285612Sdelphij } 240285612Sdelphij return 0; 241285612Sdelphij} 242285612Sdelphij 243285612Sdelphij#ifdef TEST 244285612Sdelphijint 245285612Sdelphijmain (int argc, char **argv) 246285612Sdelphij{ 247285612Sdelphij rtbl_t table; 248285612Sdelphij unsigned int a, b, c, d; 24982501Ssheldonh 25082501Ssheldonh table = rtbl_create (); 25182501Ssheldonh rtbl_add_column (table, "Issued", 0, &a); 25282501Ssheldonh rtbl_add_column (table, "Expires", 0, &b); 253285612Sdelphij rtbl_add_column (table, "Foo", RTBL_ALIGN_RIGHT, &d); 25460588Ssheldonh rtbl_add_column (table, "Principal", 0, &c); 25582501Ssheldonh 25655857Ssheldonh rtbl_add_column_entry (table, a, "Jul 7 21:19:29"); 25782501Ssheldonh rtbl_add_column_entry (table, b, "Jul 8 07:19:29"); 25882501Ssheldonh rtbl_add_column_entry (table, d, "73"); 259285612Sdelphij rtbl_add_column_entry (table, d, "0"); 260285612Sdelphij rtbl_add_column_entry (table, d, "-2000"); 26182501Ssheldonh rtbl_add_column_entry (table, c, "krbtgt/NADA.KTH.SE@NADA.KTH.SE"); 26282501Ssheldonh 263285612Sdelphij rtbl_add_column_entry (table, a, "Jul 7 21:19:29"); 264285612Sdelphij rtbl_add_column_entry (table, b, "Jul 8 07:19:29"); 265158688Spav rtbl_add_column_entry (table, c, "afs/pdc.kth.se@NADA.KTH.SE"); 266285612Sdelphij 267285612Sdelphij rtbl_add_column_entry (table, a, "Jul 7 21:19:29"); 268285612Sdelphij rtbl_add_column_entry (table, b, "Jul 8 07:19:29"); 269285612Sdelphij rtbl_add_column_entry (table, c, "afs@NADA.KTH.SE"); 270285612Sdelphij 271285612Sdelphij rtbl_set_prefix (table, " "); 272285612Sdelphij rtbl_set_column_prefix (table, a, ""); 273285612Sdelphij 274285612Sdelphij rtbl_format (table, stdout); 275285612Sdelphij 276285612Sdelphij rtbl_destroy (table); 277285612Sdelphij 278285612Sdelphij} 27955857Ssheldonh 28055857Ssheldonh#endif 28168965Sru