]> mj.ucw.cz Git - libucw.git/blob - lib/conf-dump.c
ee137ab147615c797c4c7e14f2ebc49863d74bc2
[libucw.git] / lib / conf-dump.c
1 /*
2  *      UCW Library -- Configuration files: dumping
3  *
4  *      (c) 2001--2006 Robert Spalek <robert@ucw.cz>
5  *      (c) 2003--2006 Martin Mares <mj@ucw.cz>
6  *
7  *      This software may be freely distributed and used according to the terms
8  *      of the GNU Lesser General Public License.
9  */
10
11 #include "lib/lib.h"
12 #include "lib/conf.h"
13 #include "lib/getopt.h"
14 #include "lib/conf-internal.h"
15 #include "lib/clists.h"
16 #include "lib/fastbuf.h"
17
18 static void
19 spaces(struct fastbuf *fb, uns nr)
20 {
21   for (uns i=0; i<nr; i++)
22     bputs(fb, "  ");
23 }
24
25 static void
26 dump_basic(struct fastbuf *fb, void *ptr, enum cf_type type, union cf_union *u)
27 {
28   switch (type) {
29     case CT_INT:        bprintf(fb, "%d ", *(uns*)ptr); break;
30     case CT_U64:        bprintf(fb, "%llu ", *(u64*)ptr); break;
31     case CT_DOUBLE:     bprintf(fb, "%lg ", *(double*)ptr); break;
32     case CT_IP:         bprintf(fb, "%08x ", *(uns*)ptr); break;
33     case CT_STRING:
34       if (*(byte**)ptr)
35         bprintf(fb, "'%s' ", *(byte**)ptr);
36       else
37         bprintf(fb, "NULL ");
38       break;
39     case CT_LOOKUP:     bprintf(fb, "%s ", *(int*)ptr >= 0 ? u->lookup[ *(int*)ptr ] : (byte*) "???"); break;
40     case CT_USER:
41       if (u->utype->dumper)
42         u->utype->dumper(fb, ptr);
43       else
44         bprintf(fb, "??? ");
45       break;
46   }
47 }
48
49 static void dump_section(struct fastbuf *fb, struct cf_section *sec, int level, void *ptr);
50
51 static byte *class_names[] = { "end", "static", "dynamic", "parser", "section", "list" };
52 static byte *type_names[] = { "int", "u64", "double", "ip", "string", "lookup", "user" };
53
54 static void
55 dump_item(struct fastbuf *fb, struct cf_item *item, int level, void *ptr)
56 {
57   ptr += (addr_int_t) item->ptr;
58   enum cf_type type = item->type;
59   uns size = cf_type_size(item->type, item->u.utype);
60   int i;
61   spaces(fb, level);
62   bprintf(fb, "%s: C%s #", item->name, class_names[item->cls]);
63   if (item->number == CF_ANY_NUM)
64     bputs(fb, "any ");
65   else
66     bprintf(fb, "%d ", item->number);
67   if (item->cls == CC_STATIC || item->cls == CC_DYNAMIC) {
68     bprintf(fb, "T%s ", type_names[type]);
69     if (item->type == CT_USER)
70       bprintf(fb, "U%s S%d ", item->u.utype->name, size);
71   }
72   if (item->cls == CC_STATIC) {
73     for (i=0; i<item->number; i++)
74       dump_basic(fb, ptr + i * size, type, &item->u);
75   } else if (item->cls == CC_DYNAMIC) {
76     ptr = * (void**) ptr;
77     if (ptr) {
78       int real_nr = DARY_LEN(ptr);
79       bprintf(fb, "N%d ", real_nr);
80       for (i=0; i<real_nr; i++)
81         dump_basic(fb, ptr + i * size, type, &item->u);
82     } else
83       bprintf(fb, "NULL ");
84   }
85   bputc(fb, '\n');
86   if (item->cls == CC_SECTION)
87     dump_section(fb, item->u.sec, level+1, ptr);
88   else if (item->cls == CC_LIST) {
89     uns idx = 0;
90     CLIST_FOR_EACH(cnode *, n, * (clist*) ptr) {
91       spaces(fb, level+1);
92       bprintf(fb, "item %d\n", ++idx);
93       dump_section(fb, item->u.sec, level+2, n);
94     }
95   }
96 }
97
98 static void
99 dump_section(struct fastbuf *fb, struct cf_section *sec, int level, void *ptr)
100 {
101   spaces(fb, level);
102   bprintf(fb, "S%d F%x:\n", sec->size, sec->flags);
103   for (struct cf_item *item=sec->cfg; item->cls; item++)
104     dump_item(fb, item, level, ptr);
105 }
106
107 void
108 cf_dump_sections(struct fastbuf *fb)
109 {
110   dump_section(fb, &cf_sections, 0, NULL);
111 }
112