]> mj.ucw.cz Git - libucw.git/blob - ucw/conf-dump.c
Merge branch 'dev-xml-ns'
[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     bprintf(fb, "T%s ", cf_type_names[type]);
73     if (item->type == CT_USER)
74       bprintf(fb, "U%s S%d ", item->u.utype->name, size);
75     else if (item->type == CT_XTYPE)
76       bprintf(fb, "X%s S%d ", item->u.xtype->name, size);
77   }
78   if (item->cls == CC_STATIC) {
79     for (i=0; i<item->number; i++)
80       dump_basic(fb, ptr + i * size, type, &item->u);
81   } else if (item->cls == CC_DYNAMIC) {
82     ptr = * (void**) ptr;
83     if (ptr) {
84       int real_nr = GARY_SIZE(ptr);
85       bprintf(fb, "N%d ", real_nr);
86       for (i=0; i<real_nr; i++)
87         dump_basic(fb, ptr + i * size, type, &item->u);
88     } else
89       bprintf(fb, "NULL ");
90   } else if (item->cls == CC_BITMAP) {
91     u32 mask = * (u32*) ptr;
92     for (i=0; i<32; i++) {
93       if (item->type == CT_LOOKUP && !item->u.lookup[i])
94         break;
95       if (mask & (1<<i)) {
96         if (item->type == CT_INT)
97           bprintf(fb, "%d ", i);
98         else if (item->type == CT_LOOKUP)
99           bprintf(fb, "%s ", item->u.lookup[i]);
100       }
101     }
102   }
103   bputc(fb, '\n');
104   if (item->cls == CC_SECTION)
105     dump_section(fb, item->u.sec, level+1, ptr);
106   else if (item->cls == CC_LIST) {
107     uint idx = 0;
108     CLIST_FOR_EACH(cnode *, n, * (clist*) ptr) {
109       spaces(fb, level+1);
110       bprintf(fb, "item %d\n", ++idx);
111       dump_section(fb, item->u.sec, level+2, n);
112     }
113   }
114 }
115
116 static void
117 dump_section(struct fastbuf *fb, struct cf_section *sec, int level, void *ptr)
118 {
119   spaces(fb, level);
120   bprintf(fb, "S%d F%x:\n", sec->size, sec->flags);
121   for (struct cf_item *item=sec->cfg; item->cls; item++)
122     dump_item(fb, item, level, ptr);
123 }
124
125 void
126 cf_dump_sections(struct fastbuf *fb)
127 {
128   struct cf_context *cc = cf_get_context();
129   dump_section(fb, &cc->sections, 0, NULL);
130 }
131