Home | History | Annotate | Download | only in include
      1 #pragma once
      2 
      3 // This module implements a configuration parser. Clients can query the
      4 // contents of a configuration file through the interface provided here.
      5 // The current implementation is read-only; mutations are only kept in
      6 // memory. This parser supports the INI file format.
      7 
      8 // Implementation notes:
      9 // - Key/value pairs that are not within a section are assumed to be under
     10 //   the |CONFIG_DEFAULT_SECTION| section.
     11 // - Multiple sections with the same name will be merged as if they were in
     12 //   a single section.
     13 // - Empty sections with no key/value pairs will be treated as if they do
     14 //   not exist. In other words, |config_has_section| will return false for
     15 //   empty sections.
     16 // - Duplicate keys in a section will overwrite previous values.
     17 // - All strings are case sensitive.
     18 
     19 #include <stdbool.h>
     20 
     21 // The default section name to use if a key/value pair is not defined within
     22 // a section.
     23 #define CONFIG_DEFAULT_SECTION "Global"
     24 
     25 typedef struct config_t config_t;
     26 typedef struct config_section_node_t config_section_node_t;
     27 
     28 // Creates a new config object with no entries (i.e. not backed by a file).
     29 // This function returns a config object or NULL on error. Clients must call
     30 // |config_free| on the returned handle when it is no longer required.
     31 config_t* config_new_empty(void);
     32 
     33 // Loads the specified file and returns a handle to the config file. If there
     34 // was a problem loading the file or allocating memory, this function returns
     35 // NULL. Clients must call |config_free| on the returned handle when it is no
     36 // longer required. |filename| must not be NULL and must point to a readable
     37 // file on the filesystem.
     38 config_t* config_new(const char* filename);
     39 
     40 // Clones |src|, including all of it's sections, keys, and values.
     41 // Returns a new config which is a copy and separated from the original;
     42 // changes to the new config are not reflected in any way in the original.
     43 //
     44 // |src| must not be NULL
     45 // This function will not return NULL.
     46 // Clients must call config_free on the returned object.
     47 config_t* config_new_clone(const config_t* src);
     48 
     49 // Frees resources associated with the config file. No further operations may
     50 // be performed on the |config| object after calling this function. |config|
     51 // may be NULL.
     52 void config_free(config_t* config);
     53 
     54 // Returns true if the config file contains a section named |section|. If
     55 // the section has no key/value pairs in it, this function will return false.
     56 // |config| and |section| must not be NULL.
     57 bool config_has_section(const config_t* config, const char* section);
     58 
     59 // Returns true if the config file has a key named |key| under |section|.
     60 // Returns false otherwise. |config|, |section|, and |key| must not be NULL.
     61 bool config_has_key(const config_t* config, const char* section,
     62                     const char* key);
     63 
     64 // Returns the integral value for a given |key| in |section|. If |section|
     65 // or |key| do not exist, or the value cannot be fully converted to an integer,
     66 // this function returns |def_value|. |config|, |section|, and |key| must not
     67 // be NULL.
     68 int config_get_int(const config_t* config, const char* section, const char* key,
     69                    int def_value);
     70 
     71 // Returns the boolean value for a given |key| in |section|. If |section|
     72 // or |key| do not exist, or the value cannot be converted to a boolean, this
     73 // function returns |def_value|. |config|, |section|, and |key| must not be
     74 // NULL.
     75 bool config_get_bool(const config_t* config, const char* section,
     76                      const char* key, bool def_value);
     77 
     78 // Returns the string value for a given |key| in |section|. If |section| or
     79 // |key| do not exist, this function returns |def_value|. The returned string
     80 // is owned by the config module and must not be freed. |config|, |section|,
     81 // and |key| must not be NULL. |def_value| may be NULL.
     82 const char* config_get_string(const config_t* config, const char* section,
     83                               const char* key, const char* def_value);
     84 
     85 // Sets an integral value for the |key| in |section|. If |key| or |section| do
     86 // not already exist, this function creates them. |config|, |section|, and |key|
     87 // must not be NULL.
     88 void config_set_int(config_t* config, const char* section, const char* key,
     89                     int value);
     90 
     91 // Sets a boolean value for the |key| in |section|. If |key| or |section| do
     92 // not already exist, this function creates them. |config|, |section|, and |key|
     93 // must not be NULL.
     94 void config_set_bool(config_t* config, const char* section, const char* key,
     95                      bool value);
     96 
     97 // Sets a string value for the |key| in |section|. If |key| or |section| do
     98 // not already exist, this function creates them. |config|, |section|, |key|,
     99 // and
    100 // |value| must not be NULL.
    101 void config_set_string(config_t* config, const char* section, const char* key,
    102                        const char* value);
    103 
    104 // Removes |section| from the |config| (and, as a result, all keys in the
    105 // section).
    106 // Returns true if |section| was found and removed from |config|, false
    107 // otherwise.
    108 // Neither |config| nor |section| may be NULL.
    109 bool config_remove_section(config_t* config, const char* section);
    110 
    111 // Removes one specific |key| residing in |section| of the |config|. Returns
    112 // true
    113 // if the section and key were found and the key was removed, false otherwise.
    114 // None of |config|, |section|, or |key| may be NULL.
    115 bool config_remove_key(config_t* config, const char* section, const char* key);
    116 
    117 // Returns an iterator to the first section in the config file. If there are no
    118 // sections, the iterator will equal the return value of |config_section_end|.
    119 // The returned pointer must be treated as an opaque handle and must not be
    120 // freed.
    121 // The iterator is invalidated on any config mutating operation. |config| may
    122 // not be NULL.
    123 const config_section_node_t* config_section_begin(const config_t* config);
    124 
    125 // Returns an iterator to one past the last section in the config file. It does
    126 // not represent a valid section, but can be used to determine if all sections
    127 // have been iterated over. The returned pointer must be treated as an opaque
    128 // handle and must not be freed and must not be iterated on (must not call
    129 // |config_section_next| on it). |config| may not be NULL.
    130 const config_section_node_t* config_section_end(const config_t* config);
    131 
    132 // Moves |iter| to the next section. If there are no more sections, |iter| will
    133 // equal the value of |config_section_end|. |iter| may not be NULL and must be
    134 // a pointer returned by either |config_section_begin| or |config_section_next|.
    135 const config_section_node_t* config_section_next(
    136     const config_section_node_t* iter);
    137 
    138 // Returns the name of the section referred to by |iter|. The returned pointer
    139 // is owned by the config module and must not be freed by the caller. The
    140 // pointer will remain valid until |config_free| is called. |iter| may not be
    141 // NULL and must not equal the value returned by |config_section_end|.
    142 const char* config_section_name(const config_section_node_t* iter);
    143 
    144 // Saves |config| to a file given by |filename|. Note that this could be a
    145 // destructive operation: if |filename| already exists, it will be overwritten.
    146 // The config module does not preserve comments or formatting so if a config
    147 // file was opened with |config_new| and subsequently overwritten with
    148 // |config_save|, all comments and special formatting in the original file will
    149 // be lost. Neither |config| nor |filename| may be NULL.
    150 bool config_save(const config_t* config, const char* filename);
    151