configfile.h 4.89 KB
Newer Older
Philip Carns's avatar
Philip Carns committed
1
2
3
4
5
6
/*
 * Copyright (C) 2013 University of Chicago.
 * See COPYRIGHT notice in top-level directory.
 *
 */

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#ifndef SRC_COMMON_MODELCONFIG_CONFIGFILE_H
#define SRC_COMMON_MODELCONFIG_CONFIGFILE_H

#include <stddef.h>  /* size_t */
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif


/**
 * A config file is contains (possibly nested) sections, 
 * where each section groups entries. 
 * An entry is either another section, a key or a multikey.
 *
 * A key is a (name, value) string pair, while a multikey is a 
 * (name, value, value, value, ...) tuple.
 */
typedef void * SectionHandle;


enum { SE_SECTION  = 1,
       SE_KEY      = 2,
       SE_MULTIKEY = 3
     };

typedef struct
{
   char * name;
   unsigned int type;
} SectionEntry;

#define ROOT_SECTION ((SectionHandle) 0)

42
struct ConfigVTable
43
{
44
45
46
47
   /* File path of the configuration file. Used in computing the relative path
    * of file fields */
    char * config_dir;

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
   /* Returns number of characters in key or < 0 if an error occured 
    * (such as key is missing) 
    *
    * Calling this function with a NULL buf ptr and 0 bufsize will
    * return the keysize, not including terminating 0.
    *
    * */
   int (*getKey) (void *  handle, SectionHandle section, const char * key,
         char * buf, size_t bufsize);

   /*
    * Reads list entries: after the function returns, buf will be set to 
    * a pointer pointing to an array of e char * pointers.
    * Needs to be freed with free() (array + pointers) 
    * Returns < 0 if error */
   int (*getMultiKey) (void * handle, SectionHandle section, const char * key,
         char *** buf, size_t * e);
   /*
    * Outputs number of entries written in maxentries, retrieves at most
    * maxentries (input val).
    * Returns total number of entries in section. 
    */
   int (*listSection) (void * handle, SectionHandle section, 
         SectionEntry * entries, size_t * maxentries);

   /* Returns -1 if failed, >=0 if ok */
   int (*openSection) (void * handle, SectionHandle section, const char *
         sectionname, SectionHandle * newsection);

   /* Return the number of entries in a section in count,
    * return code is <0 if error */
   int (*getSectionSize) (void * handle, SectionHandle section, unsigned int *
         count);

   /* Returns < 0 if error */
   int (*closeSection) (void * handle, SectionHandle section);

   /* Returns < 0 if error */
   int (*createSection) (void * handle, SectionHandle section, const
         char * name, SectionHandle * newsection);

   /* Returns < 0 if error */
   int (*createKey) (void * handle, SectionHandle section, const char * key,
         const char ** data, unsigned int count); 

   void (*free) (void * handle);

   void * data; 

97
}; 
98
99
100
101
102

/* utility debug function: write config tree to stdout;
 * If all OK: ret >= 0, otherwise ret < 0 and *err is set
 * to error message
 * */
103
int cf_dump (struct ConfigVTable * cf, SectionHandle h, char ** err);
104
105

/* Compare two config trees: return true if equal, false if not */
106
int cf_equal (struct ConfigVTable * h1, struct ConfigVTable * h2);
107

108
static inline int cf_free (struct ConfigVTable * cf)
109
110
111
112
113
114
115
116
117
{
   if (!cf)
      return 1;

   cf->free (cf->data);
   free (cf);
   return 1;
}

118
static inline int cf_getSectionSize (struct ConfigVTable * cf, SectionHandle section, 
119
120
121
122
123
      unsigned int * count)
{
   return cf->getSectionSize (cf->data, section, count); 
}

124
static inline int cf_closeSection (struct ConfigVTable * cf, SectionHandle section)
125
126
127
128
{
   return cf->closeSection (cf->data, section);
}

129
static inline int cf_openSection (struct ConfigVTable * cf, SectionHandle section, 
130
131
132
133
134
      const char * sectionname, SectionHandle * newsection)
{
   return cf->openSection (cf->data, section, sectionname, newsection);
}

135
static inline int cf_getKey (struct ConfigVTable * cf, SectionHandle section, 
136
137
138
139
140
      const char * keyname, char * buf, size_t maxbuf)
{
   return cf->getKey (cf->data, section, keyname, buf, maxbuf);
}

141
static inline int cf_getMultiKey (struct ConfigVTable * cf, SectionHandle section,
142
143
144
145
146
      const char * keyname, char *** buf, size_t * e)
{
   return cf->getMultiKey (cf->data, section, keyname, buf, e);
}

147
static inline int cf_listSection (struct ConfigVTable * cf, SectionHandle section, 
148
149
150
151
152
         SectionEntry * entries, size_t * maxentries)
{
   return cf->listSection (cf->data, section, entries, maxentries);
}

153
static inline int cf_createSection (struct ConfigVTable * handle, SectionHandle
154
155
156
157
158
159
      section, const char * name, SectionHandle * newsection)
{
   return handle->createSection (handle->data, section, name, 
         newsection);
}

160
static inline int cf_createKey (struct ConfigVTable * handle, SectionHandle section,
161
162
163
164
165
166
167
168
169
170
      const char * key, const char ** data, unsigned int count)
{
   return handle->createKey (handle->data, section, key, data, count);
}

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif
Philip Carns's avatar
Philip Carns committed
171
172
173
174
175
176
177
178
179

/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 *
 * vim: ts=8 sts=4 sw=4 expandtab
 */