]> mj.ucw.cz Git - libucw.git/blob - lib/conf2.h
- added prototypes of memory allocation and journal functions
[libucw.git] / lib / conf2.h
1 /*
2  *      UCW Library -- Reading of configuration files
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 #ifndef _UCW_CONF2_H
12 #define _UCW_CONF2_H
13
14 enum cf_type {
15   CT_END,                               // end of list
16   CT_INT, CT_U64, CT_DOUBLE,            // number types
17   CT_STRING,                            // string type
18   CT_PARSER,                            // arbitrary parser function
19   CT_SECTION,                           // section appears exactly once
20   CT_LIST                               // list with 0..many nodes
21 };
22
23 typedef byte *cf_hook(void *ptr);
24   /* An init- or commit-hook gets a pointer to the section or NULL if this
25    * is the global section.  It returns an error message or NULL if everything
26    * is all right.  */
27 typedef byte *cf_parser(uns number, byte **pars, void *ptr);
28   /* A parser function an array of strings and stores the parsed value in any
29    * way it likes into *ptr.  It returns an error message or NULL if everything
30    * is all right.  */
31
32 struct cf_section;
33 struct cf_item {
34   enum cf_type type;
35   byte *name;
36   int number;                           // number of values: k>=0 means exactly k, k<0 means at most -k
37   void *ptr;                            // pointer to a global variable or an offset in a section
38   union {
39     struct cf_section *sub;             // declaration of a section or a list
40     cf_parser *par;                     // parser function
41   } ptr2;
42 };
43
44 struct cf_section {
45   uns size;                             // 0 for a global block, sizeof(struct) for a section
46   cf_hook *init;                        // fills in default values
47   cf_hook *commit;                      // verifies parsed data and checks ranges (optional)
48   struct cf_item *cfg;                  // CT_END-terminated array of items
49 };
50
51 /* Declaration of cf_section */
52 #define CF_TYPE(s)      .size = sizeof(s),
53 #define CF_INIT(f)      .init = (cf_hook*) f,
54 #define CF_COMMIT(f)    .commit = (cf_hook*) f,
55 #define CF_ITEMS(i)     .cfg = ( struct cf_item[] ) { i { .type = CT_END } },
56 /* Configuration items for single variables */
57 #define CF_INT(n,p)     { .type = CT_INT, .name = n, .number = 1, .ptr = CHECK_PTR_TYPE(p,int*) },
58 #define CF_U64(n,p)     { .type = CT_U64, .name = n, .number = 1, .ptr = CHECK_PTR_TYPE(p,u64*) },
59 #define CF_DOUBLE(n,p)  { .type = CT_DOUBLE, .name = n, .number = 1, .ptr = CHECK_PTR_TYPE(p,double*) },
60 #define CF_STRING(n,p)  { .type = CT_STRING, .name = n, .number = 1, .ptr = CHECK_PTR_TYPE(p,byte**) },
61 /* Configuration items for arrays of variables */
62 #define CF_INT_ARY(n,p,c)       { .type = CT_INT, .name = n, .number = c, .ptr = CHECK_PTR_TYPE(p,int**) },
63 #define CF_U64_ARY(n,p,c)       { .type = CT_U64, .name = n, .number = c, .ptr = CHECK_PTR_TYPE(p,u64**) },
64 #define CF_DOUBLE_ARY(n,p,c)    { .type = CT_DOUBLE, .name = n, .number = c, .ptr = CHECK_PTR_TYPE(p,double**) },
65 #define CF_STRING_ARY(n,p,c)    { .type = CT_STRING, .name = n, .number = c, .ptr = CHECK_PTR_TYPE(p,byte***) },
66
67 #define ARRAY_ALLOC(type,len,val...) (type[]) { (type)len, ##val } + 1
68   // creates an array with an allocated space in the front for the (Pascal-like) length
69 #define ARRAY_LEN(a) *(uns*)(a-1)
70   // length of the array
71
72 /* Configuration items for sections, lists, and parsed items */
73 struct clist;
74 #define CF_PARSER(n,p,f,c)      { .type = CT_PARSER, .name = n, .number = c, .ptr = p, .ptr2.par = (cf_parser*) f },
75 #define CF_SECTION(n,p,s)       { .type = CT_SECTION, .name = n, .number = 1, .ptr = p, .ptr2.sub = s },
76 #define CF_LIST(n,p,s)          { .type = CT_LIST, .name = n, .number = 1, .ptr = CHECK_PTR_TYPE(p,struct clist*), .ptr2.sub = s },
77
78 /* Memory allocation */
79 void *cf_malloc(uns size);
80 void *cf_malloc_zero(uns size);
81 byte *cf_strdup(byte *s);
82 byte *cf_printf(char *fmt, ...);
83
84 /* Undo journal for error recovery */
85 uns cf_journal_active(uns flag);
86 void cf_journal_block(void *ptr, uns len);
87
88 #endif