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