ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/table.C
Revision: 1.6
Committed: Sun Sep 16 18:54:45 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +7 -2 lines
Log Message:
#defines to enum

File Contents

# User Rev Content
1 pippijn 1.1 /*
2     * table.C: Table rendering class.
3 pippijn 1.6 *
4     * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
5     * Rights to this code are as documented in COPYING.
6 pippijn 1.1 *
7     * NOTE: This is a work in progress and will probably change considerably
8     * later on.
9     *
10 pippijn 1.6 *
11     * Portions of this file were derived from sources bearing the following license:
12     * Rights to this code are documented in doc/pod/license.pod.
13 pippijn 1.4 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
14 pippijn 1.1 */
15    
16 pippijn 1.6 static char const rcsid[] = "$Id: table.C,v 1.5 2007-08-30 19:56:26 pippijn Exp $";
17 pippijn 1.1
18     #include "atheme.h"
19    
20     static void
21     table_destroy (void *obj)
22     {
23     table_t *table = (table_t *) obj;
24     node_t *n, *tn;
25    
26     return_if_fail (table != NULL);
27    
28     LIST_FOREACH_SAFE (n, tn, table->rows.head)
29     {
30     table_row_t *r = (table_row_t *) n->data;
31     node_t *n2, *tn2;
32    
33     return_if_fail (r != NULL);
34    
35     LIST_FOREACH_SAFE (n2, tn2, r->cells.head)
36     {
37     table_cell_t *c = (table_cell_t *) n2->data;
38    
39 pippijn 1.4 sfree (c->name);
40     sfree (c->value);
41     delete c;
42 pippijn 1.1 node_del (n2, &r->cells);
43     node_free (n2);
44     }
45    
46 pippijn 1.4 delete r;
47 pippijn 1.1
48     node_del (n, &table->rows);
49     node_free (n);
50     }
51    
52 pippijn 1.4 delete table;
53 pippijn 1.1 }
54    
55     /*
56 pippijn 1.4 * table_new(char const * const fmt, ...)
57 pippijn 1.1 *
58     * Table constructor.
59     *
60     * Inputs:
61     * - printf-style string to name the table with.
62     *
63     * Outputs:
64     * - a table object.
65     *
66     * Side Effects:
67     * - none
68     */
69     table_t *
70 pippijn 1.4 table_new (char const * const fmt, ...)
71 pippijn 1.1 {
72     va_list vl;
73     char *buf;
74     table_t *out;
75    
76     return_val_if_fail (fmt != NULL, NULL);
77    
78     va_start (vl, fmt);
79     vasprintf (&buf, fmt, vl);
80     va_end (vl);
81    
82 pippijn 1.4 out = new table_t;
83 pippijn 1.1 object_init (&out->parent, buf, table_destroy);
84 pippijn 1.4 sfree (buf);
85 pippijn 1.1
86     return out;
87     }
88    
89     /*
90     * table_row_new
91     *
92     * Creates a table row. This isn't an object.
93     *
94     * Inputs:
95     * - table to associate to.
96     *
97     * Outputs:
98     * - a table row
99     *
100     * Side Effects:
101     * - none
102     */
103     table_row_t *
104     table_row_new (table_t * t)
105     {
106     table_row_t *out;
107    
108     return_val_if_fail (t != NULL, NULL);
109    
110 pippijn 1.4 out = new table_row_t;
111 pippijn 1.1
112     node_add (out, node_create (), &t->rows);
113    
114     return out;
115     }
116    
117     /*
118     * table_cell_associate
119     *
120     * Associates a cell with a row.
121     *
122     * Inputs:
123     * - row to add cell to.
124     *
125     * Outputs:
126     * - nothing
127     *
128     * Side Effects:
129     * - none
130     */
131     void
132 pippijn 1.4 table_cell_associate (table_row_t * r, char const * const name, char const * const value)
133 pippijn 1.1 {
134     table_cell_t *c;
135    
136     return_if_fail (r != NULL);
137     return_if_fail (name != NULL);
138     return_if_fail (value != NULL);
139    
140 pippijn 1.4 c = new table_cell_t;
141 pippijn 1.1
142     c->name = sstrdup (name);
143     c->value = sstrdup (value);
144    
145     node_add (c, node_create (), &r->cells);
146     }
147    
148     /*
149     * table_render
150     *
151     * Renders a table. This is a two-pass operation, the first one to find out
152     * the width of each cell, and then the second to render the data.
153     *
154     * Inputs:
155     * - a table
156     * - a callback function
157     * - opaque data
158     *
159     * Outputs:
160     * - none
161     *
162     * Side Effects:
163     * - a callback function is called for each row of the table.
164     */
165     void
166 pippijn 1.4 table_render (table_t * t, void (*callback) (char const * const line, void *data), void *data)
167 pippijn 1.1 {
168     node_t *n;
169     table_row_t *f;
170     size_t bufsz = 0;
171     char *buf = NULL;
172     char *p;
173     int i;
174    
175     return_if_fail (t != NULL);
176     return_if_fail (callback != NULL);
177    
178     f = (table_row_t *) t->rows.head->data;
179    
180     LIST_FOREACH (n, t->rows.head)
181     {
182     table_row_t *r = (table_row_t *) n->data;
183     node_t *n2, *rn;
184    
185     /* we, uhh... we don't provide a macro for dealing with two lists at once ;) */
186     for (n2 = r->cells.head, rn = f->cells.head; n2 != NULL && rn != NULL; n2 = n2->next, rn = rn->next)
187     {
188     table_cell_t *c, *rc;
189     size_t sz;
190    
191     c = (table_cell_t *) n2->data;
192     rc = (table_cell_t *) rn->data;
193    
194     if ((sz = strlen (c->name)) > (size_t) rc->width)
195     rc->width = sz;
196    
197     if ((sz = strlen (c->value)) > (size_t) rc->width)
198     rc->width = sz;
199     }
200     }
201    
202     /* now total up the result. */
203     LIST_FOREACH (n, f->cells.head)
204     {
205     table_cell_t *c = (table_cell_t *) n->data;
206     bufsz += c->width + 1;
207     }
208    
209 pippijn 1.5 buf = salloc<char> (bufsz);
210 pippijn 1.1 *buf = '\0';
211    
212     /* start outputting the header. */
213     callback (asobject (t)->name, data);
214     LIST_FOREACH (n, f->cells.head)
215     {
216     table_cell_t *c = (table_cell_t *) n->data;
217     char fmtbuf[12];
218     char buf2[1024];
219    
220     /* dynamically generate the format string based on width. */
221     snprintf (fmtbuf, 12, n->next != NULL ? "%%-%ds " : "%%s", c->width);
222     snprintf (buf2, 1024, fmtbuf, c->name);
223    
224     strlcat (buf, buf2, bufsz);
225     }
226     callback (buf, data);
227     *buf = '\0';
228    
229     /* separator line */
230     p = buf;
231     LIST_FOREACH (n, f->cells.head)
232     {
233     table_cell_t *c = (table_cell_t *) n->data;
234    
235     if (n->next != NULL)
236     {
237     for (i = 0; i < c->width; i++)
238     *p++ = '-';
239     *p++ = ' ';
240     }
241     else
242     for (i = 0; i < (int) strlen (c->name); i++)
243     *p++ = '-';
244     }
245     *p = '\0';
246     callback (buf, data);
247     *buf = '\0';
248    
249     LIST_FOREACH (n, t->rows.head)
250     {
251     table_row_t *r = (table_row_t *) n->data;
252     node_t *n2, *rn;
253    
254     for (n2 = r->cells.head, rn = f->cells.head; n2 != NULL && rn != NULL; n2 = n2->next, rn = rn->next)
255     {
256     table_cell_t *c, *rc;
257     char fmtbuf[12];
258     char buf2[1024];
259    
260     c = (table_cell_t *) n2->data;
261     rc = (table_cell_t *) rn->data;
262    
263     /* dynamically generate the format string based on width. */
264     snprintf (fmtbuf, 12, n2->next != NULL ? "%%-%ds " : "%%s", rc->width);
265     snprintf (buf2, 1024, fmtbuf, c->value);
266    
267     strlcat (buf, buf2, bufsz);
268     }
269     callback (buf, data);
270     *buf = '\0';
271     }
272    
273     /* separator line */
274     p = buf;
275     LIST_FOREACH (n, f->cells.head)
276     {
277     table_cell_t *c = (table_cell_t *) n->data;
278    
279     if (n->next != NULL)
280     {
281     for (i = 0; i < c->width; i++)
282     *p++ = '-';
283     *p++ = ' ';
284     }
285     else
286     for (i = 0; i < (int) strlen (c->name); i++)
287     *p++ = '-';
288     }
289     *p = '\0';
290     callback (buf, data);
291     *buf = '\0';
292     }
293    
294     /* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs
295     * vim:ts=8
296     * vim:sw=8
297     * vim:noexpandtab
298     */