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
 */