]> mj.ucw.cz Git - libucw.git/blob - ucw/conf-dump.c
Opt: Generalization of hooks
[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  *
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 <ucw/lib.h>
12 #include <ucw/conf.h>
13 #include <ucw/getopt.h>
14 #include <ucw/conf-internal.h>
15 #include <ucw/clists.h>
16 #include <ucw/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 ", (long long) *(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 (*(char**)ptr)
35         bprintf(fb, "'%s' ", *(char**)ptr);
36       else
37         bprintf(fb, "NULL ");
38       break;
39     case CT_LOOKUP:     bprintf(fb, "%s ", *(int*)ptr >= 0 ? u->lookup[ *(int*)ptr ] : "???"); 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 char *class_names[] = { "end", "static", "dynamic", "parser", "section", "list", "bitmap" };
52
53 static void
54 dump_item(struct fastbuf *fb, struct cf_item *item, int level, void *ptr)
55 {
56   ptr += (uintptr_t) item->ptr;
57   enum cf_type type = item->type;
58   uns size = cf_type_size(item->type, item->u.utype);
59   int i;
60   spaces(fb, level);
61   bprintf(fb, "%s: C%s #", item->name, class_names[item->cls]);
62   if (item->number == CF_ANY_NUM)
63     bputs(fb, "any ");
64   else
65     bprintf(fb, "%d ", item->number);
66   if (item->cls == CC_STATIC || item->cls == CC_DYNAMIC || item->cls == CC_BITMAP) {
67     bprintf(fb, "T%s ", cf_type_names[type]);
68     if (item->type == CT_USER)
69       bprintf(fb, "U%s S%d ", item->u.utype->name, size);
70   }
71   if (item->cls == CC_STATIC) {
72     for (i=0; i<item->number; i++)
73       dump_basic(fb, ptr + i * size, type, &item->u);
74   } else if (item->cls == CC_DYNAMIC) {
75     ptr = * (void**) ptr;
76     if (ptr) {
77       int real_nr = DARY_LEN(ptr);
78       bprintf(fb, "N%d ", real_nr);
79       for (i=0; i<real_nr; i++)
80         dump_basic(fb, ptr + i * size, type, &item->u);
81     } else
82       bprintf(fb, "NULL ");
83   } else if (item->cls == CC_BITMAP) {
84     u32 mask = * (u32*) ptr;
85     for (i=0; i<32; i++) {
86       if (item->type == CT_LOOKUP && !item->u.lookup[i])
87         break;
88       if (mask & (1<<i)) {
89         if (item->type == CT_INT)
90           bprintf(fb, "%d ", i);
91         else if (item->type == CT_LOOKUP)
92           bprintf(fb, "%s ", item->u.lookup[i]);
93       }
94     }
95   }
96   bputc(fb, '\n');
97   if (item->cls == CC_SECTION)
98     dump_section(fb, item->u.sec, level+1, ptr);
99   else if (item->cls == CC_LIST) {
100     uns idx = 0;
101     CLIST_FOR_EACH(cnode *, n, * (clist*) ptr) {
102       spaces(fb, level+1);
103       bprintf(fb, "item %d\n", ++idx);
104       dump_section(fb, item->u.sec, level+2, n);
105     }
106   }
107 }
108
109 static void
110 dump_section(struct fastbuf *fb, struct cf_section *sec, int level, void *ptr)
111 {
112   spaces(fb, level);
113   bprintf(fb, "S%d F%x:\n", sec->size, sec->flags);
114   for (struct cf_item *item=sec->cfg; item->cls; item++)
115     dump_item(fb, item, level, ptr);
116 }
117
118 void
119 cf_dump_sections(struct fastbuf *fb)
120 {
121   struct cf_context *cc = cf_get_context();
122   dump_section(fb, &cc->sections, 0, NULL);
123 }
124