btrfs-progs: fix unaligned access calculating raid56 data
[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 *tab;
30         int size;
31
32         size = sizeof(struct string_table) + rows * columns * sizeof(char*);
33         tab = calloc(1, size);
34
35         if (!tab)
36                 return NULL;
37
38         tab->ncols = columns;
39         tab->nrows = rows;
40
41         return tab;
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, 1);
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  * This function is like a printf, but store the results in a cell of
70  * the table.
71  */
72 __attribute__ ((format (printf, 4, 5)))
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 len;
100
101                         if (!tab->cells[idx])
102                                 continue;
103
104                         len = strlen(tab->cells[idx]) - 1;
105                         if (len == 0 || tab->cells[idx][0] == '*')
106                                 continue;
107
108                         if (len > sizes[i])
109                                 sizes[i] = len;
110                 }
111         }
112
113         for (j = 0; j < tab->nrows; j++) {
114                 for (i = 0; i < tab->ncols; i++) {
115                         int idx = i + j * tab->ncols;
116                         char *cell = tab->cells[idx];
117
118                         if (!cell || !strlen(cell)) {
119                                 printf("%*s", sizes[i], "");
120                         } else if (cell && cell[0] == '*' && cell[1]) {
121                                 int k = sizes[i];
122
123                                 while (k--)
124                                         putchar(cell[1]);
125                         } else {
126                                 printf("%*s",
127                                         cell[0] == '<' ? -sizes[i] : sizes[i],
128                                         cell + 1);
129                         }
130                         if (i != (tab->ncols - 1))
131                                 putchar(' ');
132                 }
133                 putchar('\n');
134         }
135 }
136
137 /*
138  *  Deallocate a table and all of its content
139  */
140 void table_free(struct string_table *tab)
141 {
142         int i, count;
143
144         count = tab->ncols * tab->nrows;
145
146         for (i = 0; i < count; i++)
147                 if (tab->cells[i])
148                         free(tab->cells[i]);
149
150         free(tab);
151 }