15e9cd1aeSAssar Westerlund /*
2*ae771770SStanislav Sedov * Copyright (c) 2000, 2002, 2004 Kungliga Tekniska Högskolan
35e9cd1aeSAssar Westerlund * (Royal Institute of Technology, Stockholm, Sweden).
45e9cd1aeSAssar Westerlund * All rights reserved.
55e9cd1aeSAssar Westerlund *
65e9cd1aeSAssar Westerlund * Redistribution and use in source and binary forms, with or without
75e9cd1aeSAssar Westerlund * modification, are permitted provided that the following conditions
85e9cd1aeSAssar Westerlund * are met:
95e9cd1aeSAssar Westerlund *
105e9cd1aeSAssar Westerlund * 1. Redistributions of source code must retain the above copyright
115e9cd1aeSAssar Westerlund * notice, this list of conditions and the following disclaimer.
125e9cd1aeSAssar Westerlund *
135e9cd1aeSAssar Westerlund * 2. Redistributions in binary form must reproduce the above copyright
145e9cd1aeSAssar Westerlund * notice, this list of conditions and the following disclaimer in the
155e9cd1aeSAssar Westerlund * documentation and/or other materials provided with the distribution.
165e9cd1aeSAssar Westerlund *
175e9cd1aeSAssar Westerlund * 3. Neither the name of the Institute nor the names of its contributors
185e9cd1aeSAssar Westerlund * may be used to endorse or promote products derived from this software
195e9cd1aeSAssar Westerlund * without specific prior written permission.
205e9cd1aeSAssar Westerlund *
215e9cd1aeSAssar Westerlund * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
225e9cd1aeSAssar Westerlund * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
235e9cd1aeSAssar Westerlund * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
245e9cd1aeSAssar Westerlund * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
255e9cd1aeSAssar Westerlund * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
265e9cd1aeSAssar Westerlund * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
275e9cd1aeSAssar Westerlund * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
285e9cd1aeSAssar Westerlund * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
295e9cd1aeSAssar Westerlund * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
305e9cd1aeSAssar Westerlund * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
315e9cd1aeSAssar Westerlund * SUCH DAMAGE.
325e9cd1aeSAssar Westerlund */
335e9cd1aeSAssar Westerlund
345e9cd1aeSAssar Westerlund #include <config.h>
35*ae771770SStanislav Sedov
365e9cd1aeSAssar Westerlund #include "roken.h"
375e9cd1aeSAssar Westerlund #include "rtbl.h"
385e9cd1aeSAssar Westerlund
395e9cd1aeSAssar Westerlund struct column_entry {
405e9cd1aeSAssar Westerlund char *data;
415e9cd1aeSAssar Westerlund };
425e9cd1aeSAssar Westerlund
435e9cd1aeSAssar Westerlund struct column_data {
445e9cd1aeSAssar Westerlund char *header;
455e9cd1aeSAssar Westerlund char *prefix;
465e9cd1aeSAssar Westerlund int width;
475e9cd1aeSAssar Westerlund unsigned flags;
485e9cd1aeSAssar Westerlund size_t num_rows;
495e9cd1aeSAssar Westerlund struct column_entry *rows;
50c19800e8SDoug Rabson unsigned int column_id;
51c19800e8SDoug Rabson char *suffix;
525e9cd1aeSAssar Westerlund };
535e9cd1aeSAssar Westerlund
545e9cd1aeSAssar Westerlund struct rtbl_data {
555e9cd1aeSAssar Westerlund char *column_prefix;
565e9cd1aeSAssar Westerlund size_t num_columns;
575e9cd1aeSAssar Westerlund struct column_data **columns;
58c19800e8SDoug Rabson unsigned int flags;
59c19800e8SDoug Rabson char *column_separator;
605e9cd1aeSAssar Westerlund };
615e9cd1aeSAssar Westerlund
62*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION rtbl_t ROKEN_LIB_CALL
rtbl_create(void)635e9cd1aeSAssar Westerlund rtbl_create (void)
645e9cd1aeSAssar Westerlund {
655e9cd1aeSAssar Westerlund return calloc (1, sizeof (struct rtbl_data));
665e9cd1aeSAssar Westerlund }
675e9cd1aeSAssar Westerlund
68*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
rtbl_set_flags(rtbl_t table,unsigned int flags)69c19800e8SDoug Rabson rtbl_set_flags (rtbl_t table, unsigned int flags)
70c19800e8SDoug Rabson {
71c19800e8SDoug Rabson table->flags = flags;
72c19800e8SDoug Rabson }
73c19800e8SDoug Rabson
74*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION unsigned int ROKEN_LIB_CALL
rtbl_get_flags(rtbl_t table)75c19800e8SDoug Rabson rtbl_get_flags (rtbl_t table)
76c19800e8SDoug Rabson {
77c19800e8SDoug Rabson return table->flags;
78c19800e8SDoug Rabson }
79c19800e8SDoug Rabson
80c19800e8SDoug Rabson static struct column_data *
rtbl_get_column_by_id(rtbl_t table,unsigned int id)81c19800e8SDoug Rabson rtbl_get_column_by_id (rtbl_t table, unsigned int id)
82c19800e8SDoug Rabson {
83*ae771770SStanislav Sedov size_t i;
84c19800e8SDoug Rabson for(i = 0; i < table->num_columns; i++)
85c19800e8SDoug Rabson if(table->columns[i]->column_id == id)
86c19800e8SDoug Rabson return table->columns[i];
87c19800e8SDoug Rabson return NULL;
88c19800e8SDoug Rabson }
89c19800e8SDoug Rabson
905e9cd1aeSAssar Westerlund static struct column_data *
rtbl_get_column(rtbl_t table,const char * column)915e9cd1aeSAssar Westerlund rtbl_get_column (rtbl_t table, const char *column)
925e9cd1aeSAssar Westerlund {
93*ae771770SStanislav Sedov size_t i;
945e9cd1aeSAssar Westerlund for(i = 0; i < table->num_columns; i++)
955e9cd1aeSAssar Westerlund if(strcmp(table->columns[i]->header, column) == 0)
965e9cd1aeSAssar Westerlund return table->columns[i];
975e9cd1aeSAssar Westerlund return NULL;
985e9cd1aeSAssar Westerlund }
995e9cd1aeSAssar Westerlund
100*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
rtbl_destroy(rtbl_t table)1015e9cd1aeSAssar Westerlund rtbl_destroy (rtbl_t table)
1025e9cd1aeSAssar Westerlund {
103*ae771770SStanislav Sedov size_t i, j;
1045e9cd1aeSAssar Westerlund
1055e9cd1aeSAssar Westerlund for (i = 0; i < table->num_columns; i++) {
1065e9cd1aeSAssar Westerlund struct column_data *c = table->columns[i];
1075e9cd1aeSAssar Westerlund
1085e9cd1aeSAssar Westerlund for (j = 0; j < c->num_rows; j++)
1095e9cd1aeSAssar Westerlund free (c->rows[j].data);
1100cadf2f4SJacques Vidrine free (c->rows);
1115e9cd1aeSAssar Westerlund free (c->header);
1125e9cd1aeSAssar Westerlund free (c->prefix);
113c19800e8SDoug Rabson free (c->suffix);
1145e9cd1aeSAssar Westerlund free (c);
1155e9cd1aeSAssar Westerlund }
1165e9cd1aeSAssar Westerlund free (table->column_prefix);
117c19800e8SDoug Rabson free (table->column_separator);
1185e9cd1aeSAssar Westerlund free (table->columns);
1190cadf2f4SJacques Vidrine free (table);
1205e9cd1aeSAssar Westerlund }
1215e9cd1aeSAssar Westerlund
122*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rtbl_add_column_by_id(rtbl_t table,unsigned int id,const char * header,unsigned int flags)123c19800e8SDoug Rabson rtbl_add_column_by_id (rtbl_t table, unsigned int id,
124c19800e8SDoug Rabson const char *header, unsigned int flags)
1255e9cd1aeSAssar Westerlund {
1265e9cd1aeSAssar Westerlund struct column_data *col, **tmp;
1275e9cd1aeSAssar Westerlund
1285e9cd1aeSAssar Westerlund tmp = realloc (table->columns, (table->num_columns + 1) * sizeof (*tmp));
1295e9cd1aeSAssar Westerlund if (tmp == NULL)
1305e9cd1aeSAssar Westerlund return ENOMEM;
1315e9cd1aeSAssar Westerlund table->columns = tmp;
1325e9cd1aeSAssar Westerlund col = malloc (sizeof (*col));
1335e9cd1aeSAssar Westerlund if (col == NULL)
1345e9cd1aeSAssar Westerlund return ENOMEM;
1355e9cd1aeSAssar Westerlund col->header = strdup (header);
1365e9cd1aeSAssar Westerlund if (col->header == NULL) {
1375e9cd1aeSAssar Westerlund free (col);
1385e9cd1aeSAssar Westerlund return ENOMEM;
1395e9cd1aeSAssar Westerlund }
1405e9cd1aeSAssar Westerlund col->prefix = NULL;
1415e9cd1aeSAssar Westerlund col->width = 0;
1425e9cd1aeSAssar Westerlund col->flags = flags;
1435e9cd1aeSAssar Westerlund col->num_rows = 0;
1445e9cd1aeSAssar Westerlund col->rows = NULL;
145c19800e8SDoug Rabson col->column_id = id;
146c19800e8SDoug Rabson col->suffix = NULL;
1475e9cd1aeSAssar Westerlund table->columns[table->num_columns++] = col;
1485e9cd1aeSAssar Westerlund return 0;
1495e9cd1aeSAssar Westerlund }
1505e9cd1aeSAssar Westerlund
151*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rtbl_add_column(rtbl_t table,const char * header,unsigned int flags)152c19800e8SDoug Rabson rtbl_add_column (rtbl_t table, const char *header, unsigned int flags)
153c19800e8SDoug Rabson {
154c19800e8SDoug Rabson return rtbl_add_column_by_id(table, 0, header, flags);
155c19800e8SDoug Rabson }
156c19800e8SDoug Rabson
157*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rtbl_new_row(rtbl_t table)158c19800e8SDoug Rabson rtbl_new_row(rtbl_t table)
159c19800e8SDoug Rabson {
160c19800e8SDoug Rabson size_t max_rows = 0;
161c19800e8SDoug Rabson size_t c;
162c19800e8SDoug Rabson for (c = 0; c < table->num_columns; c++)
163c19800e8SDoug Rabson if(table->columns[c]->num_rows > max_rows)
164c19800e8SDoug Rabson max_rows = table->columns[c]->num_rows;
165c19800e8SDoug Rabson for (c = 0; c < table->num_columns; c++) {
166c19800e8SDoug Rabson struct column_entry *tmp;
167c19800e8SDoug Rabson
168c19800e8SDoug Rabson if(table->columns[c]->num_rows == max_rows)
169c19800e8SDoug Rabson continue;
170c19800e8SDoug Rabson tmp = realloc(table->columns[c]->rows,
171c19800e8SDoug Rabson max_rows * sizeof(table->columns[c]->rows));
172c19800e8SDoug Rabson if(tmp == NULL)
173c19800e8SDoug Rabson return ENOMEM;
174c19800e8SDoug Rabson table->columns[c]->rows = tmp;
175c19800e8SDoug Rabson while(table->columns[c]->num_rows < max_rows) {
176c19800e8SDoug Rabson if((tmp[table->columns[c]->num_rows++].data = strdup("")) == NULL)
177c19800e8SDoug Rabson return ENOMEM;
178c19800e8SDoug Rabson }
179c19800e8SDoug Rabson }
180c19800e8SDoug Rabson return 0;
181c19800e8SDoug Rabson }
182c19800e8SDoug Rabson
1835e9cd1aeSAssar Westerlund static void
column_compute_width(rtbl_t table,struct column_data * column)184c19800e8SDoug Rabson column_compute_width (rtbl_t table, struct column_data *column)
1855e9cd1aeSAssar Westerlund {
186*ae771770SStanislav Sedov size_t i;
1875e9cd1aeSAssar Westerlund
188c19800e8SDoug Rabson if(table->flags & RTBL_HEADER_STYLE_NONE)
189c19800e8SDoug Rabson column->width = 0;
190c19800e8SDoug Rabson else
1915e9cd1aeSAssar Westerlund column->width = strlen (column->header);
1925e9cd1aeSAssar Westerlund for (i = 0; i < column->num_rows; i++)
193*ae771770SStanislav Sedov column->width = max (column->width, (int) strlen (column->rows[i].data));
1945e9cd1aeSAssar Westerlund }
1955e9cd1aeSAssar Westerlund
196c19800e8SDoug Rabson /* DEPRECATED */
197*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rtbl_set_prefix(rtbl_t table,const char * prefix)1985e9cd1aeSAssar Westerlund rtbl_set_prefix (rtbl_t table, const char *prefix)
1995e9cd1aeSAssar Westerlund {
2005e9cd1aeSAssar Westerlund if (table->column_prefix)
2015e9cd1aeSAssar Westerlund free (table->column_prefix);
2025e9cd1aeSAssar Westerlund table->column_prefix = strdup (prefix);
2035e9cd1aeSAssar Westerlund if (table->column_prefix == NULL)
2045e9cd1aeSAssar Westerlund return ENOMEM;
2055e9cd1aeSAssar Westerlund return 0;
2065e9cd1aeSAssar Westerlund }
2075e9cd1aeSAssar Westerlund
208*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rtbl_set_separator(rtbl_t table,const char * separator)209c19800e8SDoug Rabson rtbl_set_separator (rtbl_t table, const char *separator)
210c19800e8SDoug Rabson {
211c19800e8SDoug Rabson if (table->column_separator)
212c19800e8SDoug Rabson free (table->column_separator);
213c19800e8SDoug Rabson table->column_separator = strdup (separator);
214c19800e8SDoug Rabson if (table->column_separator == NULL)
215c19800e8SDoug Rabson return ENOMEM;
216c19800e8SDoug Rabson return 0;
217c19800e8SDoug Rabson }
218c19800e8SDoug Rabson
219*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rtbl_set_column_prefix(rtbl_t table,const char * column,const char * prefix)2205e9cd1aeSAssar Westerlund rtbl_set_column_prefix (rtbl_t table, const char *column,
2215e9cd1aeSAssar Westerlund const char *prefix)
2225e9cd1aeSAssar Westerlund {
2235e9cd1aeSAssar Westerlund struct column_data *c = rtbl_get_column (table, column);
2245e9cd1aeSAssar Westerlund
2255e9cd1aeSAssar Westerlund if (c == NULL)
2265e9cd1aeSAssar Westerlund return -1;
2275e9cd1aeSAssar Westerlund if (c->prefix)
2285e9cd1aeSAssar Westerlund free (c->prefix);
2295e9cd1aeSAssar Westerlund c->prefix = strdup (prefix);
2305e9cd1aeSAssar Westerlund if (c->prefix == NULL)
2315e9cd1aeSAssar Westerlund return ENOMEM;
2325e9cd1aeSAssar Westerlund return 0;
2335e9cd1aeSAssar Westerlund }
2345e9cd1aeSAssar Westerlund
235*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rtbl_set_column_affix_by_id(rtbl_t table,unsigned int id,const char * prefix,const char * suffix)236c19800e8SDoug Rabson rtbl_set_column_affix_by_id(rtbl_t table, unsigned int id,
237c19800e8SDoug Rabson const char *prefix, const char *suffix)
238c19800e8SDoug Rabson {
239c19800e8SDoug Rabson struct column_data *c = rtbl_get_column_by_id (table, id);
240c19800e8SDoug Rabson
241c19800e8SDoug Rabson if (c == NULL)
242c19800e8SDoug Rabson return -1;
243c19800e8SDoug Rabson if (c->prefix)
244c19800e8SDoug Rabson free (c->prefix);
245c19800e8SDoug Rabson if(prefix == NULL)
246c19800e8SDoug Rabson c->prefix = NULL;
247c19800e8SDoug Rabson else {
248c19800e8SDoug Rabson c->prefix = strdup (prefix);
249c19800e8SDoug Rabson if (c->prefix == NULL)
250c19800e8SDoug Rabson return ENOMEM;
251c19800e8SDoug Rabson }
252c19800e8SDoug Rabson
253c19800e8SDoug Rabson if (c->suffix)
254c19800e8SDoug Rabson free (c->suffix);
255c19800e8SDoug Rabson if(suffix == NULL)
256c19800e8SDoug Rabson c->suffix = NULL;
257c19800e8SDoug Rabson else {
258c19800e8SDoug Rabson c->suffix = strdup (suffix);
259c19800e8SDoug Rabson if (c->suffix == NULL)
260c19800e8SDoug Rabson return ENOMEM;
261c19800e8SDoug Rabson }
262c19800e8SDoug Rabson return 0;
263c19800e8SDoug Rabson }
264c19800e8SDoug Rabson
2655e9cd1aeSAssar Westerlund
2665e9cd1aeSAssar Westerlund static const char *
get_column_prefix(rtbl_t table,struct column_data * c)2675e9cd1aeSAssar Westerlund get_column_prefix (rtbl_t table, struct column_data *c)
2685e9cd1aeSAssar Westerlund {
2695e9cd1aeSAssar Westerlund if (c == NULL)
2705e9cd1aeSAssar Westerlund return "";
2715e9cd1aeSAssar Westerlund if (c->prefix)
2725e9cd1aeSAssar Westerlund return c->prefix;
2735e9cd1aeSAssar Westerlund if (table->column_prefix)
2745e9cd1aeSAssar Westerlund return table->column_prefix;
2755e9cd1aeSAssar Westerlund return "";
2765e9cd1aeSAssar Westerlund }
2775e9cd1aeSAssar Westerlund
278c19800e8SDoug Rabson static const char *
get_column_suffix(rtbl_t table,struct column_data * c)279c19800e8SDoug Rabson get_column_suffix (rtbl_t table, struct column_data *c)
280c19800e8SDoug Rabson {
281c19800e8SDoug Rabson if (c && c->suffix)
282c19800e8SDoug Rabson return c->suffix;
283c19800e8SDoug Rabson return "";
284c19800e8SDoug Rabson }
285c19800e8SDoug Rabson
286c19800e8SDoug Rabson static int
add_column_entry(struct column_data * c,const char * data)287c19800e8SDoug Rabson add_column_entry (struct column_data *c, const char *data)
2885e9cd1aeSAssar Westerlund {
2895e9cd1aeSAssar Westerlund struct column_entry row, *tmp;
2905e9cd1aeSAssar Westerlund
2915e9cd1aeSAssar Westerlund row.data = strdup (data);
2925e9cd1aeSAssar Westerlund if (row.data == NULL)
2935e9cd1aeSAssar Westerlund return ENOMEM;
2945e9cd1aeSAssar Westerlund tmp = realloc (c->rows, (c->num_rows + 1) * sizeof (*tmp));
2955e9cd1aeSAssar Westerlund if (tmp == NULL) {
2965e9cd1aeSAssar Westerlund free (row.data);
2975e9cd1aeSAssar Westerlund return ENOMEM;
2985e9cd1aeSAssar Westerlund }
2995e9cd1aeSAssar Westerlund c->rows = tmp;
3005e9cd1aeSAssar Westerlund c->rows[c->num_rows++] = row;
3015e9cd1aeSAssar Westerlund return 0;
3025e9cd1aeSAssar Westerlund }
3035e9cd1aeSAssar Westerlund
304*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rtbl_add_column_entry_by_id(rtbl_t table,unsigned int id,const char * data)305c19800e8SDoug Rabson rtbl_add_column_entry_by_id (rtbl_t table, unsigned int id, const char *data)
306c19800e8SDoug Rabson {
307c19800e8SDoug Rabson struct column_data *c = rtbl_get_column_by_id (table, id);
308c19800e8SDoug Rabson
309c19800e8SDoug Rabson if (c == NULL)
310c19800e8SDoug Rabson return -1;
311c19800e8SDoug Rabson
312c19800e8SDoug Rabson return add_column_entry(c, data);
313c19800e8SDoug Rabson }
314c19800e8SDoug Rabson
315*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rtbl_add_column_entryv_by_id(rtbl_t table,unsigned int id,const char * fmt,...)316c19800e8SDoug Rabson rtbl_add_column_entryv_by_id (rtbl_t table, unsigned int id,
317c19800e8SDoug Rabson const char *fmt, ...)
318c19800e8SDoug Rabson {
319c19800e8SDoug Rabson va_list ap;
320c19800e8SDoug Rabson char *str;
321c19800e8SDoug Rabson int ret;
322c19800e8SDoug Rabson
323c19800e8SDoug Rabson va_start(ap, fmt);
324c19800e8SDoug Rabson ret = vasprintf(&str, fmt, ap);
325c19800e8SDoug Rabson va_end(ap);
326c19800e8SDoug Rabson if (ret == -1)
327c19800e8SDoug Rabson return -1;
328c19800e8SDoug Rabson ret = rtbl_add_column_entry_by_id(table, id, str);
329c19800e8SDoug Rabson free(str);
330c19800e8SDoug Rabson return ret;
331c19800e8SDoug Rabson }
332c19800e8SDoug Rabson
333*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rtbl_add_column_entry(rtbl_t table,const char * column,const char * data)334c19800e8SDoug Rabson rtbl_add_column_entry (rtbl_t table, const char *column, const char *data)
335c19800e8SDoug Rabson {
336c19800e8SDoug Rabson struct column_data *c = rtbl_get_column (table, column);
337c19800e8SDoug Rabson
338c19800e8SDoug Rabson if (c == NULL)
339c19800e8SDoug Rabson return -1;
340c19800e8SDoug Rabson
341c19800e8SDoug Rabson return add_column_entry(c, data);
342c19800e8SDoug Rabson }
343c19800e8SDoug Rabson
344*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rtbl_add_column_entryv(rtbl_t table,const char * column,const char * fmt,...)345c19800e8SDoug Rabson rtbl_add_column_entryv (rtbl_t table, const char *column, const char *fmt, ...)
346c19800e8SDoug Rabson {
347c19800e8SDoug Rabson va_list ap;
348c19800e8SDoug Rabson char *str;
349c19800e8SDoug Rabson int ret;
350c19800e8SDoug Rabson
351c19800e8SDoug Rabson va_start(ap, fmt);
352c19800e8SDoug Rabson ret = vasprintf(&str, fmt, ap);
353c19800e8SDoug Rabson va_end(ap);
354c19800e8SDoug Rabson if (ret == -1)
355c19800e8SDoug Rabson return -1;
356c19800e8SDoug Rabson ret = rtbl_add_column_entry(table, column, str);
357c19800e8SDoug Rabson free(str);
358c19800e8SDoug Rabson return ret;
359c19800e8SDoug Rabson }
360c19800e8SDoug Rabson
361c19800e8SDoug Rabson
362*ae771770SStanislav Sedov ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rtbl_format(rtbl_t table,FILE * f)3635e9cd1aeSAssar Westerlund rtbl_format (rtbl_t table, FILE * f)
3645e9cd1aeSAssar Westerlund {
365*ae771770SStanislav Sedov size_t i, j;
3665e9cd1aeSAssar Westerlund
3675e9cd1aeSAssar Westerlund for (i = 0; i < table->num_columns; i++)
368c19800e8SDoug Rabson column_compute_width (table, table->columns[i]);
369c19800e8SDoug Rabson if((table->flags & RTBL_HEADER_STYLE_NONE) == 0) {
3705e9cd1aeSAssar Westerlund for (i = 0; i < table->num_columns; i++) {
3715e9cd1aeSAssar Westerlund struct column_data *c = table->columns[i];
3725e9cd1aeSAssar Westerlund
373c19800e8SDoug Rabson if(table->column_separator != NULL && i > 0)
374c19800e8SDoug Rabson fprintf (f, "%s", table->column_separator);
3755e9cd1aeSAssar Westerlund fprintf (f, "%s", get_column_prefix (table, c));
376c19800e8SDoug Rabson if(i == table->num_columns - 1 && c->suffix == NULL)
377c19800e8SDoug Rabson /* last column, so no need to pad with spaces */
378c19800e8SDoug Rabson fprintf (f, "%-*s", 0, c->header);
379c19800e8SDoug Rabson else
3805e9cd1aeSAssar Westerlund fprintf (f, "%-*s", (int)c->width, c->header);
381c19800e8SDoug Rabson fprintf (f, "%s", get_column_suffix (table, c));
3825e9cd1aeSAssar Westerlund }
3835e9cd1aeSAssar Westerlund fprintf (f, "\n");
384c19800e8SDoug Rabson }
3855e9cd1aeSAssar Westerlund
3865e9cd1aeSAssar Westerlund for (j = 0;; j++) {
3875e9cd1aeSAssar Westerlund int flag = 0;
3885e9cd1aeSAssar Westerlund
389c19800e8SDoug Rabson /* are there any more rows left? */
3905e9cd1aeSAssar Westerlund for (i = 0; flag == 0 && i < table->num_columns; ++i) {
3915e9cd1aeSAssar Westerlund struct column_data *c = table->columns[i];
3925e9cd1aeSAssar Westerlund
3935e9cd1aeSAssar Westerlund if (c->num_rows > j) {
3945e9cd1aeSAssar Westerlund ++flag;
3955e9cd1aeSAssar Westerlund break;
3965e9cd1aeSAssar Westerlund }
3975e9cd1aeSAssar Westerlund }
3985e9cd1aeSAssar Westerlund if (flag == 0)
3995e9cd1aeSAssar Westerlund break;
4005e9cd1aeSAssar Westerlund
4015e9cd1aeSAssar Westerlund for (i = 0; i < table->num_columns; i++) {
4025e9cd1aeSAssar Westerlund int w;
4035e9cd1aeSAssar Westerlund struct column_data *c = table->columns[i];
4045e9cd1aeSAssar Westerlund
405c19800e8SDoug Rabson if(table->column_separator != NULL && i > 0)
406c19800e8SDoug Rabson fprintf (f, "%s", table->column_separator);
407c19800e8SDoug Rabson
4085e9cd1aeSAssar Westerlund w = c->width;
4095e9cd1aeSAssar Westerlund
410c19800e8SDoug Rabson if ((c->flags & RTBL_ALIGN_RIGHT) == 0) {
411c19800e8SDoug Rabson if(i == table->num_columns - 1 && c->suffix == NULL)
412c19800e8SDoug Rabson /* last column, so no need to pad with spaces */
413c19800e8SDoug Rabson w = 0;
414c19800e8SDoug Rabson else
4155e9cd1aeSAssar Westerlund w = -w;
416c19800e8SDoug Rabson }
4175e9cd1aeSAssar Westerlund fprintf (f, "%s", get_column_prefix (table, c));
4185e9cd1aeSAssar Westerlund if (c->num_rows <= j)
4195e9cd1aeSAssar Westerlund fprintf (f, "%*s", w, "");
4205e9cd1aeSAssar Westerlund else
4215e9cd1aeSAssar Westerlund fprintf (f, "%*s", w, c->rows[j].data);
422c19800e8SDoug Rabson fprintf (f, "%s", get_column_suffix (table, c));
4235e9cd1aeSAssar Westerlund }
4245e9cd1aeSAssar Westerlund fprintf (f, "\n");
4255e9cd1aeSAssar Westerlund }
4265e9cd1aeSAssar Westerlund return 0;
4275e9cd1aeSAssar Westerlund }
4285e9cd1aeSAssar Westerlund
4295e9cd1aeSAssar Westerlund #ifdef TEST
4305e9cd1aeSAssar Westerlund int
main(int argc,char ** argv)4315e9cd1aeSAssar Westerlund main (int argc, char **argv)
4325e9cd1aeSAssar Westerlund {
4335e9cd1aeSAssar Westerlund rtbl_t table;
4345e9cd1aeSAssar Westerlund
4355e9cd1aeSAssar Westerlund table = rtbl_create ();
436c19800e8SDoug Rabson rtbl_add_column_by_id (table, 0, "Issued", 0);
437c19800e8SDoug Rabson rtbl_add_column_by_id (table, 1, "Expires", 0);
438c19800e8SDoug Rabson rtbl_add_column_by_id (table, 2, "Foo", RTBL_ALIGN_RIGHT);
439c19800e8SDoug Rabson rtbl_add_column_by_id (table, 3, "Principal", 0);
4405e9cd1aeSAssar Westerlund
441c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 0, "Jul 7 21:19:29");
442c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 1, "Jul 8 07:19:29");
443c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 2, "73");
444c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 2, "0");
445c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 2, "-2000");
446c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 3, "krbtgt/NADA.KTH.SE@NADA.KTH.SE");
4475e9cd1aeSAssar Westerlund
448c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 0, "Jul 7 21:19:29");
449c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 1, "Jul 8 07:19:29");
450c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 3, "afs/pdc.kth.se@NADA.KTH.SE");
4515e9cd1aeSAssar Westerlund
452c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 0, "Jul 7 21:19:29");
453c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 1, "Jul 8 07:19:29");
454c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 3, "afs@NADA.KTH.SE");
4555e9cd1aeSAssar Westerlund
456c19800e8SDoug Rabson rtbl_set_separator (table, " ");
4575e9cd1aeSAssar Westerlund
4585e9cd1aeSAssar Westerlund rtbl_format (table, stdout);
4595e9cd1aeSAssar Westerlund
4605e9cd1aeSAssar Westerlund rtbl_destroy (table);
4615e9cd1aeSAssar Westerlund
462c19800e8SDoug Rabson printf("\n");
463c19800e8SDoug Rabson
464c19800e8SDoug Rabson table = rtbl_create ();
465c19800e8SDoug Rabson rtbl_add_column_by_id (table, 0, "Column A", 0);
466c19800e8SDoug Rabson rtbl_set_column_affix_by_id (table, 0, "<", ">");
467c19800e8SDoug Rabson rtbl_add_column_by_id (table, 1, "Column B", 0);
468c19800e8SDoug Rabson rtbl_set_column_affix_by_id (table, 1, "[", "]");
469c19800e8SDoug Rabson rtbl_add_column_by_id (table, 2, "Column C", 0);
470c19800e8SDoug Rabson rtbl_set_column_affix_by_id (table, 2, "(", ")");
471c19800e8SDoug Rabson
472c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 0, "1");
473c19800e8SDoug Rabson rtbl_new_row(table);
474c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 1, "2");
475c19800e8SDoug Rabson rtbl_new_row(table);
476c19800e8SDoug Rabson rtbl_add_column_entry_by_id (table, 2, "3");
477c19800e8SDoug Rabson rtbl_new_row(table);
478c19800e8SDoug Rabson
479c19800e8SDoug Rabson rtbl_set_separator (table, " ");
480c19800e8SDoug Rabson rtbl_format (table, stdout);
481c19800e8SDoug Rabson
482c19800e8SDoug Rabson rtbl_destroy (table);
483c19800e8SDoug Rabson
484c19800e8SDoug Rabson return 0;
4855e9cd1aeSAssar Westerlund }
4865e9cd1aeSAssar Westerlund
4875e9cd1aeSAssar Westerlund #endif
488