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