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