btrfs-progs: Add helpers functions to handle the printing of data in tabular format
[platform/upstream/btrfs-progs.git] / string-table.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public
4  * License v2 as published by the Free Software Foundation.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9  * General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public
12  * License along with this program; if not, write to the
13  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
14  * Boston, MA 021110-1307, USA.
15  */
16
17 #include <stdlib.h>
18 #include <string.h>
19 #include <stdio.h>
20 #include <stdarg.h>
21
22 #include "string-table.h"
23
24 /*
25  *  This function create an array of char * which will represent a table
26  */
27 struct string_table *table_create(int columns, int rows)
28 {
29         struct string_table *p;
30         int size;
31
32         size = sizeof( struct string_table ) +
33                 rows * columns* sizeof(char *);
34         p = calloc(1, size);
35
36         if (!p) return NULL;
37
38         p->ncols = columns;
39         p->nrows = rows;
40
41         return p;
42 }
43
44 /*
45  * This function is like a vprintf, but store the results in a cell of
46  * the table.
47  * If fmt  starts with '<', the text is left aligned; if fmt starts with
48  * '>' the text is right aligned. If fmt is equal to '=' the text will
49  * be replaced by a '=====' dimensioned on the basis of the column width
50  */
51 char *table_vprintf(struct string_table *tab, int column, int row,
52                           char *fmt, va_list ap)
53 {
54         int idx = tab->ncols*row+column;
55         char *msg = calloc(100, sizeof(char));
56
57         if (!msg)
58                 return NULL;
59
60         if (tab->cells[idx])
61                 free(tab->cells[idx]);
62         tab->cells[idx] = msg;
63         vsnprintf(msg, 99, fmt, ap);
64
65         return msg;
66 }
67
68
69 /*
70  * This function is like a printf, but store the results in a cell of
71  * the table.
72  */
73 char *table_printf(struct string_table *tab, int column, int row,
74                           char *fmt, ...)
75 {
76         va_list ap;
77         char *ret;
78
79         va_start(ap, fmt);
80         ret = table_vprintf(tab, column, row, fmt, ap);
81         va_end(ap);
82
83         return ret;
84 }
85
86 /*
87  * This function dumps the table. Every "=" string will be replaced by
88  * a "=======" length as the column
89  */
90 void table_dump(struct string_table *tab)
91 {
92         int     sizes[tab->ncols];
93         int     i, j;
94
95         for (i = 0 ; i < tab->ncols ; i++) {
96                 sizes[i] = 0;
97                 for (j = 0 ; j < tab->nrows ; j++) {
98                         int idx = i + j*tab->ncols;
99                         int s;
100
101                         if (!tab->cells[idx])
102                                 continue;
103
104                         s = strlen(tab->cells[idx]) - 1;
105                         if (s < 1 || tab->cells[idx][0] == '=')
106                                 continue;
107
108                         if (s > sizes[i])
109                                 sizes[i] = s;
110                 }
111         }
112
113
114         for (j = 0 ; j < tab->nrows ; j++) {
115                 for (i = 0 ; i < tab->ncols ; i++) {
116
117                         int idx = i + j*tab->ncols;
118                         char *s = tab->cells[idx];
119
120                         if (!s|| !strlen(s)) {
121                                 printf("%*s", sizes[i], "");
122                         } else if (s && s[0] == '=') {
123                                 int k = sizes[i];
124                                 while(k--)
125                                         putchar('=');
126                         } else {
127                                 printf("%*s",
128                                         s[0] == '<' ? -sizes[i] : sizes[i],
129                                         s+1);
130                         }
131                         if (i != (tab->ncols - 1))
132                                 putchar(' ');
133                 }
134                 putchar('\n');
135         }
136
137 }
138
139 /*
140  *  Deallocate a tabular and all its content
141  */
142
143 void table_free(struct string_table *tab)
144 {
145
146         int     i, count;
147
148         count = tab->ncols * tab->nrows;
149
150         for (i=0 ; i < count ; i++)
151                 if (tab->cells[i])
152                         free(tab->cells[i]);
153
154         free(tab);
155
156 }