OSDN Git Service

ui: get version number from a separately-compiled file
[android-x86/external-parted.git] / parted / table.c
1 /*
2  * TODO: - make right and centered alignment possible
3  */
4 /*
5     parted - a frontend to libparted
6     Copyright (C) 2006-2010 Free Software Foundation, Inc.
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 3 of the License, or
11     (at your option) any later version.
12
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17
18     You should have received a copy of the GNU General Public License
19     along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22
23 #include <config.h>
24
25 #include <stdio.h>
26 #include <stdlib.h>
27
28 #include <assert.h>
29 #include <wchar.h>
30 #include <string.h>
31
32 #include "xalloc.h"
33 #include "strlist.h"
34
35 #ifdef ENABLE_NLS
36 #       define L_(str) L##str
37 #else
38 #       define L_(str) str
39 #       ifdef wchar_t
40 #               undef wchar_t
41 #       endif
42 #       define wchar_t char
43 #       define wcslen strlen
44 #       define wcswidth strnlen
45 #       define wcscat strcat
46 #       define wcsdup xstrdup
47 #endif
48
49
50 static const unsigned int       MAX_WIDTH = 512;
51 static const wchar_t*           DELIMITER = L_("  ");
52 static const wchar_t*           COLSUFFIX = L_("\n");
53
54 typedef struct
55 {
56         unsigned int    ncols;
57         unsigned int    nrows;
58         wchar_t***      rows;
59         int*            widths;
60 } Table;
61
62
63 Table* table_new(int ncols)
64 {
65         assert ( ncols >= 0 );
66
67         Table *t = xmalloc (sizeof(*t));
68
69         t->ncols = ncols;
70         t->nrows = 0;
71         t->rows = (wchar_t***)NULL;
72         t->widths = NULL;
73
74         return t;
75 }
76
77
78 void table_destroy (Table* t)
79 {
80         unsigned int r, c;
81
82         assert (t);
83         assert (t->ncols > 0);
84
85         for (r = 0; r < t->nrows; ++r)
86         {
87                 for (c = 0; c < t->ncols; ++c)
88                         free (t->rows[r][c]);
89                 free (t->rows[r]);
90         }
91
92         free (t->rows);
93         free (t->widths);
94         free (t);
95 }
96
97
98 static int max (int x, int y)
99 {
100         return x > y ? x : y;
101 }
102
103
104 static void table_calc_column_widths (Table* t)
105 {
106         unsigned int r, c;
107
108         assert(t);
109         assert(t->ncols > 0);
110
111         if (!t->widths)
112                 t->widths = xmalloc (t->ncols * sizeof(t->widths[0]));
113
114         for (c = 0; c < t->ncols; ++c)
115                 t->widths[c] = 0;
116
117         for (r = 0; r < t->nrows; ++r)
118                 for (c = 0; c < t->ncols; ++c)
119                 {
120                         t->widths[c] = max ( t->widths[c],
121                                              wcswidth(t->rows[r][c],
122                                                       MAX_WIDTH) );
123                 }
124 }
125
126
127 /*
128  * add a row which is a string array of ncols elements.
129  * 'row' will get freed by table_destroy;  you must not free it
130  * yourself.
131  */
132 void table_add_row (Table* t, wchar_t** row)
133 {
134         assert(t);
135
136         /*unsigned int i;
137         fputs ("adding row: ", stdout);
138         for (i = 0; i < t->ncols; ++i)
139                 printf("[%s]", row[i]);
140         putchar ('\n');*/
141
142         t->rows = xrealloc (t->rows, (t->nrows + 1) * sizeof(wchar_t***));
143
144         t->rows[t->nrows] = row;
145
146         ++t->nrows;
147
148         table_calc_column_widths (t);
149 }
150
151
152 void table_add_row_from_strlist (Table* t, StrList* list)
153 {
154         wchar_t** row = xmalloc (str_list_length(list) * sizeof(*row));
155         int i = 0;
156
157         while (list)
158         {
159                 row[i] = wcsdup (list->str);
160                 if (row[i] == NULL)
161                         xalloc_die ();
162
163
164                 list = list->next;
165                 ++i;
166         }
167
168         table_add_row (t, row);
169 }
170
171
172 /* render a row */
173 static void table_render_row (Table* t, int rownum, int ncols, wchar_t** s)
174 {
175         wchar_t** row = t->rows[rownum];
176         size_t len = 1, i;
177         size_t newsize;
178
179         assert(t);
180         assert(s != NULL);
181
182         for (i = 0; i < ncols; ++i)
183                 len += t->widths[i] + wcslen(DELIMITER);
184
185         len += wcslen(COLSUFFIX);
186
187         newsize = (wcslen(*s) + len + 1) * sizeof(wchar_t);
188         *s = xrealloc (*s, newsize);
189
190         for (i = 0; i < ncols; ++i)
191         {
192                 wcscat (*s, row[i]);
193                 if (ncols <= i + 1)
194                         break;
195
196                 int j;
197                 int nspaces = max(t->widths[i] - wcswidth(row[i], MAX_WIDTH),
198                                   0);
199                 wchar_t* pad = xmalloc ((nspaces + 1) * sizeof(*pad));
200
201                 for (j = 0; j < nspaces; ++j)
202                        pad[j] = L' ';
203
204                 pad[nspaces] = L_('\0');
205
206                 wcscat (*s, pad);
207                 if (i + 1 < ncols)
208                         wcscat (*s, DELIMITER);
209
210                 free (pad);
211         }
212
213         /* Remove any trailing blanks.  */
214         wchar_t *p = *s;
215         size_t k = wcslen (p);
216         while (k && p[k-1] == L_(' '))
217                 --k;
218         p[k] = L_('\0');
219
220
221         wcscat (*s, COLSUFFIX);
222 }
223
224
225 /*
226  * Render the rows.
227  * \p s must be a null-terminated string.
228  */
229 static void table_render_rows (Table* t, wchar_t** s)
230 {
231         unsigned int i;
232
233         assert (**s == L_('\0'));
234         for (i = 0; i < t->nrows; ++i)
235                 table_render_row (t, i, t->ncols, s);
236 }
237
238 /*
239  * Render the table to a string.
240  * You are responsible for freeing the returned string.
241  */
242 wchar_t* table_render(Table* t)
243 {
244         wchar_t* s = xmalloc (sizeof(*s));
245
246         *s = L_('\0');
247         table_render_rows (t, &s);
248         return s;
249 }