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