1ini.h 2===== 3 4Library: [ini.h](../ini.h) 5 6 7Examples 8======== 9 10Loading an ini file and retrieving values 11----------------------------------------- 12 13```cpp 14#define INI_IMPLEMENTATION 15#include "ini.h" 16 17#include <stdio.h> 18#include <stdlib.h> 19 20int main() 21 { 22 FILE* fp = fopen( "test.ini", "r" ); 23 fseek( fp, 0, SEEK_END ); 24 int size = ftell( fp ); 25 fseek( fp, 0, SEEK_SET ); 26 char* data = (char*) malloc( size + 1 ); 27 fread( data, 1, size, fp ); 28 data[ size ] = '\0'; 29 fclose( fp ); 30 31 ini_t* ini = ini_load( data ); 32 free( data ); 33 int second_index = ini_find_property( ini, INI_GLOBAL_SECTION, "SecondSetting" ); 34 char const* second = ini_property_value( ini, INI_GLOBAL_SECTION, second_index ); 35 printf( "%s=%s\n", "SecondSetting", second ); 36 int section = ini_find_section( ini, "MySection" ); 37 int third_index = ini_find_property( ini, section, "ThirdSetting" ); 38 char const* third = ini_property_value( ini, section, third_index ); 39 printf( "%s=%s\n", "ThirdSetting", third ); 40 ini_destroy( ini ); 41 42 return 0; 43 } 44``` 45 46Creating a new ini file 47----------------------- 48 49```cpp 50#define INI_IMPLEMENTATION 51#include "ini.h" 52 53#include <stdio.h> 54#include <stdlib.h> 55 56int main() 57 { 58 ini_t* ini = ini_create(); 59 ini_property_add( ini, INI_GLOBAL_SECTION, "FirstSetting", "Test" ); 60 ini_property_add( ini, INI_GLOBAL_SECTION, "SecondSetting", "2" ); 61 int section = ini_section_add( ini, "MySection" ); 62 ini_property_add( ini, section, "ThirdSetting", "Three" ); 63 64 int size = ini_save( ini, NULL, 0 ); // Find the size needed 65 char* data = (char*) malloc( size ); 66 size = ini_save( ini, data, size ); // Actually save the file 67 ini_destroy( ini ); 68 69 FILE* fp = fopen( "test.ini", "w" ); 70 fwrite( data, 1, size, fp ); 71 fclose( fp ); 72 free( data ); 73 74 return 0; 75 } 76``` 77 78 79API Documentation 80================= 81 82ini.h is a small library for reading classic .ini files. It is a single-header library, and does not need any .lib files 83or other binaries, or any build scripts. To use it, you just include ini.h to get the API declarations. To get the 84definitions, you must include ini.h from *one* single C or C++ file, and #define the symbol `INI_IMPLEMENTATION` before 85you do. 86 87 88Customization 89------------- 90There are a few different things in ini.h which are configurable by #defines. The customizations only affect the 91implementation, so will only need to be defined in the file where you have the #define INI_IMPLEMENTATION. 92 93Note that if all customizations are utilized, ini.h will include no external files whatsoever, which might be useful 94if you need full control over what code is being built. 95 96 97### Custom memory allocators 98 99To store the internal data structures, ini.h needs to do dynamic allocation by calling `malloc`. Programs might want to 100keep track of allocations done, or use custom defined pools to allocate memory from. ini.h allows for specifying custom 101memory allocation functions for `malloc` and `free`. 102This is done with the following code: 103 104 #define INI_IMPLEMENTATION 105 #define INI_MALLOC( ctx, size ) ( my_custom_malloc( ctx, size ) ) 106 #define INI_FREE( ctx, ptr ) ( my_custom_free( ctx, ptr ) ) 107 #include "ini.h" 108 109where `my_custom_malloc` and `my_custom_free` are your own memory allocation/deallocation functions. The `ctx` parameter 110is an optional parameter of type `void*`. When `ini_create` or `ini_load` is called, you can pass in a `memctx` 111parameter, which can be a pointer to anything you like, and which will be passed through as the `ctx` parameter to every 112`INI_MALLOC`/`INI_FREE` call. For example, if you are doing memory tracking, you can pass a pointer to your tracking 113data as `memctx`, and in your custom allocation/deallocation function, you can cast the `ctx` param back to the 114right type, and access the tracking data. 115 116If no custom allocator is defined, ini.h will default to `malloc` and `free` from the C runtime library. 117 118 119### Custom C runtime function 120 121The library makes use of three additional functions from the C runtime library, and for full flexibility, it allows you 122to substitute them for your own. Here's an example: 123 124 #define INI_IMPLEMENTATION 125 #define INI_MEMCPY( dst, src, cnt ) ( my_memcpy_func( dst, src, cnt ) ) 126 #define INI_STRLEN( s ) ( my_strlen_func( s ) ) 127 #define INI_STRICMP( s1, s2 ) ( my_stricmp_func( s1, s2 ) ) 128 #include "ini.h" 129 130If no custom function is defined, ini.h will default to the C runtime library equivalent. 131 132 133ini_create 134---------- 135 136 ini_t* ini_create( void* memctx ) 137 138Instantiates a new, empty ini structure, which can be manipulated with other API calls, to fill it with data. To save it 139out to an ini-file string, use `ini_save`. When no longer needed, it can be destroyed by calling `ini_destroy`. 140`memctx` is a pointer to user defined data which will be passed through to the custom INI_MALLOC/INI_FREE calls. It can 141be NULL if no user defined data is needed. 142 143 144ini_load 145-------- 146 147 ini_t* ini_load( char const* data, void* memctx ) 148 149Parse the zero-terminated string `data` containing an ini-file, and create a new ini_t instance containing the data. 150The instance can be manipulated with other API calls to enumerate sections/properties and retrieve values. When no 151longer needed, it can be destroyed by calling `ini_destroy`. `memctx` is a pointer to user defined data which will be 152passed through to the custom INI_MALLOC/INI_FREE calls. It can be NULL if no user defined data is needed. 153 154 155ini_save 156-------- 157 158 int ini_save( ini_t const* ini, char* data, int size ) 159 160Saves an ini structure as a zero-terminated ini-file string, into the specified buffer. Returns the number of bytes 161written, including the zero terminator. If `data` is NULL, nothing is written, but `ini_save` still returns the number 162of bytes it would have written. If the size of `data`, as specified in the `size` parameter, is smaller than that 163required, only part of the ini-file string will be written. `ini_save` still returns the number of bytes it would have 164written had the buffer been large enough. 165 166 167ini_destroy 168----------- 169 170 void ini_destroy( ini_t* ini ) 171 172Destroy an `ini_t` instance created by calling `ini_load` or `ini_create`, releasing the memory allocated by it. No 173further API calls are valid on an `ini_t` instance after calling `ini_destroy` on it. 174 175 176ini_section_count 177----------------- 178 179 int ini_section_count( ini_t const* ini ) 180 181Returns the number of sections in an ini file. There's at least one section in an ini file (the global section), but 182there can be many more, each specified in the file by the section name wrapped in square brackets [ ]. 183 184 185ini_section_name 186---------------- 187 188 char const* ini_section_name( ini_t const* ini, int section ) 189 190Returns the name of the section with the specified index. `section` must be non-negative and less than the value 191returned by `ini_section_count`, or `ini_section_name` will return NULL. The defined constant `INI_GLOBAL_SECTION` can 192be used to indicate the global section. 193 194 195ini_property_count 196------------------ 197 198 int ini_property_count( ini_t const* ini, int section ) 199 200Returns the number of properties belonging to the section with the specified index. `section` must be non-negative and 201less than the value returned by `ini_section_count`, or `ini_section_name` will return 0. The defined constant 202`INI_GLOBAL_SECTION` can be used to indicate the global section. Properties are declared in the ini-file on he format 203`name=value`. 204 205 206ini_property_name 207----------------- 208 209 char const* ini_property_name( ini_t const* ini, int section, int property ) 210 211Returns the name of the property with the specified index `property` in the section with the specified index `section`. 212`section` must be non-negative and less than the value returned by `ini_section_count`, and `property` must be 213non-negative and less than the value returned by `ini_property_count`, or `ini_property_name` will return NULL. The 214defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. 215 216 217ini_property_value 218------------------ 219 220 char const* ini_property_value( ini_t const* ini, int section, int property ) 221 222Returns the value of the property with the specified index `property` in the section with the specified index `section`. 223`section` must be non-negative and less than the value returned by `ini_section_count`, and `property` must be 224non-negative and less than the value returned by `ini_property_count`, or `ini_property_value` will return NULL. The 225defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. 226 227 228ini_find_section 229---------------- 230 231 int ini_find_section( ini_t const* ini, char const* name, int name_length ) 232 233Finds the section with the specified name, and returns its index. `name_length` specifies the number of characters in 234`name`, which does not have to be zero-terminated. If `name_length` is zero, the length is determined automatically, but 235in this case `name` has to be zero-terminated. If no section with the specified name could be found, the value 236`INI_NOT_FOUND` is returned. 237 238 239ini_find_property 240----------------- 241 242 int ini_find_property( ini_t const* ini, int section, char const* name, int name_length ) 243 244Finds the property with the specified name, within the section with the specified index, and returns the index of the 245property. `name_length` specifies the number of characters in `name`, which does not have to be zero-terminated. If 246`name_length` is zero, the length is determined automatically, but in this case `name` has to be zero-terminated. If no 247property with the specified name could be found within the specified section, the value `INI_NOT_FOUND` is returned. 248`section` must be non-negative and less than the value returned by `ini_section_count`, or `ini_find_property` will 249return `INI_NOT_FOUND`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. 250 251 252ini_section_add 253--------------- 254 255 int ini_section_add( ini_t* ini, char const* name, int length ) 256 257Adds a section with the specified name, and returns the index it was added at. There is no check done to see if a 258section with the specified name already exists - multiple sections of the same name are allowed. `length` specifies the 259number of characters in `name`, which does not have to be zero-terminated. If `length` is zero, the length is determined 260automatically, but in this case `name` has to be zero-terminated. 261 262 263ini_property_add 264---------------- 265 266 void ini_property_add( ini_t* ini, int section, char const* name, int name_length, char const* value, int value_length ) 267 268Adds a property with the specified name and value to the specified section, and returns the index it was added at. There 269is no check done to see if a property with the specified name already exists - multiple properties of the same name are 270allowed. `name_length` and `value_length` specifies the number of characters in `name` and `value`, which does not have 271to be zero-terminated. If `name_length` or `value_length` is zero, the length is determined automatically, but in this 272case `name`/`value` has to be zero-terminated. `section` must be non-negative and less than the value returned by 273`ini_section_count`, or the property will not be added. The defined constant `INI_GLOBAL_SECTION` can be used to 274indicate the global section. 275 276 277ini_section_remove 278------------------ 279 280 void ini_section_remove( ini_t* ini, int section ) 281 282Removes the section with the specified index, and all properties within it. `section` must be non-negative and less than 283the value returned by `ini_section_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global 284section. Note that removing a section will shuffle section indices, so that section indices you may have stored will no 285longer indicate the same section as it did before the remove. Use the find functions to update your indices. 286 287 288ini_property_remove 289------------------- 290 291 void ini_property_remove( ini_t* ini, int section, int property ) 292 293Removes the property with the specified index from the specified section. `section` must be non-negative and less than 294the value returned by `ini_section_count`, and `property` must be non-negative and less than the value returned by 295`ini_property_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. Note that 296removing a property will shuffle property indices within the specified section, so that property indices you may have 297stored will no longer indicate the same property as it did before the remove. Use the find functions to update your 298indices. 299 300 301ini_section_name_set 302-------------------- 303 304 void ini_section_name_set( ini_t* ini, int section, char const* name, int length ) 305 306Change the name of the section with the specified index. `section` must be non-negative and less than the value returned 307by `ini_section_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. `length` 308specifies the number of characters in `name`, which does not have to be zero-terminated. If `length` is zero, the length 309is determined automatically, but in this case `name` has to be zero-terminated. 310 311 312ini_property_name_set 313--------------------- 314 315 void ini_property_name_set( ini_t* ini, int section, int property, char const* name, int length ) 316 317Change the name of the property with the specified index in the specified section. `section` must be non-negative and 318less than the value returned by `ini_section_count`, and `property` must be non-negative and less than the value 319returned by `ini_property_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. 320`length` specifies the number of characters in `name`, which does not have to be zero-terminated. If `length` is zero, 321the length is determined automatically, but in this case `name` has to be zero-terminated. 322 323 324ini_property_value_set 325---------------------- 326 327 void ini_property_value_set( ini_t* ini, int section, int property, char const* value, int length ) 328 329Change the value of the property with the specified index in the specified section. `section` must be non-negative and 330less than the value returned by `ini_section_count`, and `property` must be non-negative and less than the value 331returned by `ini_property_count`. The defined constant `INI_GLOBAL_SECTION` can be used to indicate the global section. 332`length` specifies the number of characters in `value`, which does not have to be zero-terminated. If `length` is zero, 333the length is determined automatically, but in this case `value` has to be zero-terminated. 334