summaryrefslogtreecommitdiff
path: root/string-table.c
diff options
context:
space:
mode:
Diffstat (limited to 'string-table.c')
-rw-r--r--string-table.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/string-table.c b/string-table.c
new file mode 100644
index 00000000..5eda1ac5
--- /dev/null
+++ b/string-table.c
@@ -0,0 +1,151 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "string-table.h"
+
+/*
+ * This function create an array of char * which will represent a table
+ */
+struct string_table *table_create(int columns, int rows)
+{
+ struct string_table *tab;
+ int size;
+
+ size = sizeof(struct string_table) + rows * columns * sizeof(char*);
+ tab = calloc(1, size);
+
+ if (!tab)
+ return NULL;
+
+ tab->ncols = columns;
+ tab->nrows = rows;
+
+ return tab;
+}
+
+/*
+ * This function is like a vprintf, but store the results in a cell of
+ * the table.
+ * If fmt starts with '<', the text is left aligned; if fmt starts with
+ * '>' the text is right aligned. If fmt is equal to '=' the text will
+ * be replaced by a '=====' dimensioned on the basis of the column width
+ */
+char *table_vprintf(struct string_table *tab, int column, int row,
+ char *fmt, va_list ap)
+{
+ int idx = tab->ncols * row + column;
+ char *msg = calloc(100, 1);
+
+ if (!msg)
+ return NULL;
+
+ if (tab->cells[idx])
+ free(tab->cells[idx]);
+ tab->cells[idx] = msg;
+ vsnprintf(msg, 99, fmt, ap);
+
+ return msg;
+}
+
+/*
+ * This function is like a printf, but store the results in a cell of
+ * the table.
+ */
+__attribute__ ((format (printf, 4, 5)))
+char *table_printf(struct string_table *tab, int column, int row,
+ char *fmt, ...)
+{
+ va_list ap;
+ char *ret;
+
+ va_start(ap, fmt);
+ ret = table_vprintf(tab, column, row, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+/*
+ * This function dumps the table. Every "=" string will be replaced by
+ * a "=======" length as the column
+ */
+void table_dump(struct string_table *tab)
+{
+ int sizes[tab->ncols];
+ int i, j;
+
+ for (i = 0; i < tab->ncols; i++) {
+ sizes[i] = 0;
+ for (j = 0; j < tab->nrows; j++) {
+ int idx = i + j * tab->ncols;
+ int len;
+
+ if (!tab->cells[idx])
+ continue;
+
+ len = strlen(tab->cells[idx]) - 1;
+ if (len == 0 || tab->cells[idx][0] == '*')
+ continue;
+
+ if (len > sizes[i])
+ sizes[i] = len;
+ }
+ }
+
+ for (j = 0; j < tab->nrows; j++) {
+ for (i = 0; i < tab->ncols; i++) {
+ int idx = i + j * tab->ncols;
+ char *cell = tab->cells[idx];
+
+ if (!cell || !strlen(cell)) {
+ printf("%*s", sizes[i], "");
+ } else if (cell && cell[0] == '*' && cell[1]) {
+ int k = sizes[i];
+
+ while (k--)
+ putchar(cell[1]);
+ } else {
+ printf("%*s",
+ cell[0] == '<' ? -sizes[i] : sizes[i],
+ cell + 1);
+ }
+ if (i != (tab->ncols - 1))
+ putchar(' ');
+ }
+ putchar('\n');
+ }
+}
+
+/*
+ * Deallocate a table and all of its content
+ */
+void table_free(struct string_table *tab)
+{
+ int i, count;
+
+ count = tab->ncols * tab->nrows;
+
+ for (i = 0; i < count; i++)
+ if (tab->cells[i])
+ free(tab->cells[i]);
+
+ free(tab);
+}