Mstdlib-1.24.0
m_ini.h
1/* The MIT License (MIT)
2 *
3 * Copyright (c) 2015 Monetra Technologies, LLC.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#ifndef __M_INI_H__
25#define __M_INI_H__
26
27/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28
29#include <mstdlib/base/m_list_str.h>
30#include <mstdlib/base/m_types.h>
31#include <mstdlib/base/m_fs.h>
32
33/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
34
35__BEGIN_DECLS
36
37/*! \addtogroup m_ini INI
38 * \ingroup m_formats
39 *
40 * Configurable handling for various formats. Such as # vs ; comment identifiers.
41 *
42 * For easier access functions that do not take a section use the key form
43 * 'section/key'. If multiple '/' characters are in the combined key the section
44 * is only up until the first '/'. Meaning: 'section/key/key_part'
45 *
46 * Can handle multiple or single values under a single key.
47 *
48 * Section names and keys cannot include the comment character. Values can, if
49 * they are quoted.
50 *
51 * Supports:
52 * - Read
53 * - Write
54 * - Modify
55 * - Merge
56 *
57 * Example:
58 *
59 * \code{.c}
60 * M_ini_t *ini = NULL;
61 * M_ini_settings_t *info = NULL;
62 * char *out;
63 * size_t errln = 0;
64 *
65 * info = M_ini_settings_create();
66 * M_ini_settings_set_quote_char(info, '"');
67 * M_ini_settings_set_escape_char(info, '"');
68 * M_ini_settings_set_padding(info, M_INI_PADDING_AFTER_COMMENT_CHAR);
69 * M_ini_settings_reader_set_dupkvs_handling(info, M_INI_DUPKVS_REMOVE);
70 * M_ini_settings_writer_set_multivals_handling(info, M_INI_MULTIVALS_USE_LAST);
71 *
72 * ini = M_ini_read_file("file.ini", info, M_TRUE, &errln, 0);
73 * if (ini == NULL) {
74 * M_printf("ini could not be parsed. Error line: %zu\n", errln);
75 * return M_FALSE;
76 * }
77 *
78 * M_ini_kv_set(ini, "s1/key1", "yes");
79 *
80 * out = M_ini_write(ini, info);
81 * M_printf("new ini=\n%s\n", out);
82 * M_free(out);
83 *
84 * M_ini_destroy(ini);
85 * M_ini_settings_destroy(info);
86 * \endcode
87 *
88 * @{
89 */
90
91struct M_ini;
92typedef struct M_ini M_ini_t;
93
94struct M_ini_settings;
95typedef struct M_ini_settings M_ini_settings_t;
96
97
98/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
99
100/*! Conflict handler function prototype.
101 *
102 * Ini merging can have conflicts resolved using a callback function. The use of the
103 * resolution callback is dependent on the appropriate merge flag being set.
104 *
105 * \param[in] key The key. If key is NULL then the values are they key. In this case if the value is NULL then
106 * the key doesn't exist for that location.
107 * \param[in] val_cur The value in the current ini.
108 * \param[in] val_new The new value.
109 *
110 * \return M_TRUE if the current value should be used. Otherwise, M_FALSE if the new value should be used.
111 */
112typedef M_bool (*M_ini_merge_resolver_t)(const char *key, const char *val_cur, const char *val_new);
113
114
115/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
116
117/*! Duplicate key, value pair handling where a key is encountered multiple times. */
118typedef enum {
119 M_INI_DUPKVS_COMMENT_PREV = 0, /*!< Turn previous kv into comments. Last wins.*/
120 M_INI_DUPKVS_REMOVE_PREV, /*!< Remove previous kv from the tree. Last wins. */
121 M_INI_DUPKVS_COMMENT, /*!< Turn the current kv into a comment. First wins. */
122 M_INI_DUPKVS_REMOVE, /*!< Remove the current kv from the tree. First wins. */
123 M_INI_DUPKVS_COLLECT /*!< Multiple kv are allowed and their values should be collected. All win. */
125
126
127/*! Control padding when between parts of elements.
128 * Primarily used for writing but also used for reading when a comment duplicate key flag is used. */
129typedef enum {
130 M_INI_PADDING_NONE = 0, /*!< No padding. */
131 M_INI_PADDING_BEFORE_KV_DELIM = 1 << 0, /*!< Put a space before the kv delimiter. */
132 M_INI_PADDING_AFTER_KV_DELIM = 1 << 1, /*!< Put a space after the kv delimiter. */
133 M_INI_PADDING_AFTER_KV_VAL = 1 << 2, /*!< Put a space after the kv val if followed by a comment. */
134 M_INI_PADDING_AFTER_COMMENT_CHAR = 1 << 3 /*!< Put a space after the comment character. */
136
137
138/*! Control how muli value keys are written. */
139typedef enum {
140 M_INI_MULTIVALS_USE_LAST = 0, /*!< Multi-value keys are not supported. Use the last value. */
141 M_INI_MULTIVALS_USE_FIRST, /*!< Multi-value keys are not supported. Use the first value. */
142 M_INI_MULTIVALS_KEEP_EXISTING, /*!< Multi-value keys are supported. Keep existing values in the same location
143 and place new values after. */
144 M_INI_MULTIVALS_MAINTAIN_ORDER /*!< Multi-value keys are supported. Remove all existing keys and write them all
145 together maintaining the current value order. */
147
148
149/*! Control how conflicts are handled during merge.
150 *
151 * These values all override the default behavior.
152 * Default behavior:
153 * - When a key is in new but not in cur and orig remove the key.
154 * - When the value (single) of cur is the same as orig but different than new use the new value.
155 * - When a key with multiple values has a value that is in cur and orig but not in new remove the value.
156 */
157typedef enum {
158 M_INI_MERGE_CALLBACK_FUNC = 0, /*!< Use a conflict resolution callback function to determine how to
159 handle conflicts. A callback function must be set otherwise
160 the default handling will be used. */
161 M_INI_MERGE_NEW_REMOVED_KEEP = 1 << 0, /*!< When a key is not in new but in cur and orig keep the key.
162 The default is to remove the key. */
163 M_INI_MERGE_NEW_CHANGED_USE_CUR = 1 << 1, /*!< When the value of cur is the same as orig but different than
164 new use the value from cur. Meaning the default value is set
165 but has changed. The default is to use the new value. */
166 M_INI_MERGE_MULTI_NEW_REMOVED_KEEP = 1 << 3 /*!< When a key with multiple values has a value that is in cur
167 and orig but not in new keep the value. The default is to remove
168 the value. */
170
171
172/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
173 * Helpers
174 */
175
176/*! Create a full key from individual parts.
177 *
178 * \param[in] section The section the key belongs to. Can be NULL if referencing a key not in a section.
179 * \param[in] key The key within the section. Can be NULL if referencing a section only.
180 *
181 * \return A string with the full key.
182 */
183M_API char *M_ini_full_key(const char *section, const char *key) M_MALLOC;
184
185
186
187/*! Split a full key into it's individual parts.
188 *
189 * \param[in] s The full key.
190 * \param[out] section The section part. Optional, pass NULL if not needed. May be returned as NULL.
191 * \param[out] key The key part. Optional, pass NULL if not needed. May be returned as NULL.
192 */
193M_API void M_ini_split_key(const char *s, char **section, char **key);
194
195
196/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
197 * Settings
198 *
199 * The settings object controls how an ini object is read, written, or merged. It controls
200 * aspects such as what characters are delimiters. How to handle certain situations
201 * that may arise.
202 *
203 * The same settings object can be used for read, write, and merge. A settings object augments
204 * but it not tied to a specific ini object or ini operation.
205 */
206
207/*! Create an ini settings object.
208 *
209 * \return an ini settings object.
210 */
212
213
214/*! Destroy an ini settings object.
215 *
216 * \param[in] info The settings object to destroy.
217 */
218M_API void M_ini_settings_destroy(M_ini_settings_t *info) M_FREE(1);
219
220
221/*! Get the element delimiter character.
222 *
223 * \param[in] info The settings.
224 *
225 * \return The element delimiter character. Default is "\n".
226 */
228
229
230/*! Get the quote character.
231 *
232 * \param[in] info The settings.
233 *
234 * \return The quote character. 0 if not set.
235 */
236M_API unsigned char M_ini_settings_get_quote_char(const M_ini_settings_t *info);
237
238
239/*! Get the quoting escape character.
240 *
241 * This can be the same character as the quote character which suggests CSV style quoting.
242 *
243 * \param[in] info The settings.
244 *
245 * \return The escape character. 0 if not set.
246 */
247M_API unsigned char M_ini_settings_get_escape_char(const M_ini_settings_t *info);
248
249
250/*! Get the comment character.
251 *
252 * \param[in] info The settings.
253 *
254 * \return The comment character. Default is "#".
255 */
256M_API unsigned char M_ini_settings_get_comment_char(const M_ini_settings_t *info);
257
258
259/*! Get the key, value delimiter character.
260 *
261 * \param[in] info The settings.
262 *
263 * \return The key, value delimiter character. Default is "=".
264 */
265M_API unsigned char M_ini_settings_get_kv_delim_char(const M_ini_settings_t *info);
266
267
268/*! Get the padding flags.
269 *
270 * \param[in] info The settings.
271 *
272 * \return The padding flags.
273 */
275
276
277/*! Get the duplicate key handling value used during reading.
278 *
279 * \param[in] info The settings.
280 *
281 * \return The duplicate key handling value.
282 */
284
285
286/*! Get the multiple value handling value used during writing.
287 *
288 * \param[in] info The settings.
289 *
290 * \return The multiple value handing value.
291 */
293
294
295/*! Get the line ending used when writing the ini.
296 *
297 * This is to allow multiple character line endings (Windows "\r\n"). This is an override of the
298 * element delim character that will be used if set. The line ending string will not be used
299 * when determining if quoting is necessary. The element delim is still used for this purpose even
300 * when the line ending is set.
301 *
302 * \param[in] info The settings.
303 *
304 * \return The line ending characters.
305 */
307
308
309/*! Get the conflict resolution flags used for merging.
310 *
311 * \param[in] info The settings.
312 *
313 * \return The conflict resolution flags. If 0 then either the default handing is going to be used or
314 * a custom resolution callback has been registered. Check if the call back is not NULL to
315 * know if the default handling will be used.
316 */
318
319/*! Get the conflict resolution function used for merging when the conflict flags are set to use
320 * a custom resolution callback.
321 *
322 * \param[in] info The settings.
323 *
324 * \return the resolution function. NULL if not set.
325 */
327
328
329/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
330
331/*! Set the element delimiter character.
332 *
333 * \param[in,out] info The settings.
334 * \param[in] val The value to set.
335 */
336M_API void M_ini_settings_set_element_delim_char(M_ini_settings_t *info, unsigned char val);
337
338
339/*! Set the quote character.
340 *
341 * \param[in,out] info The settings.
342 * \param[in] val The value to set.
343 */
344M_API void M_ini_settings_set_quote_char(M_ini_settings_t *info, unsigned char val);
345
346
347/*! Set the escape character.
348 *
349 * \param[in,out] info The settings.
350 * \param[in] val The value to set.
351 */
352M_API void M_ini_settings_set_escape_char(M_ini_settings_t *info, unsigned char val);
353
354
355/*! Set the comment character.
356 *
357 * \param[in,out] info The settings.
358 * \param[in] val The value to set.
359 */
360M_API void M_ini_settings_set_comment_char(M_ini_settings_t *info, unsigned char val);
361
362
363/*! Set the key value delimiter character.
364 *
365 * \param[in,out] info The settings.
366 * \param[in] val The value to set.
367 */
368M_API void M_ini_settings_set_kv_delim_char(M_ini_settings_t *info, unsigned char val);
369
370
371/*! Set the padding flags.
372 *
373 * \param[in,out] info The settings.
374 * \param[in] val The value to set.
375 */
376M_API void M_ini_settings_set_padding(M_ini_settings_t *info, M_uint32 val);
377
378
379/*! Set the duplicate key flags used for reading.
380 *
381 * \param[in,out] info The settings.
382 * \param[in] val The value to set.
383 */
385
386
387/*! Set the multiple value handling flags used for writing..
388 *
389 * \param[in,out] info The settings.
390 * \param[in] val The value to set.
391 */
393
394
395/*! Set the line ending used when writing the ini.
396 *
397 * This is to allow multiple character line endings (Windows "\r\n"). This is an override of the
398 * element delim character that will be used if set. The line ending string will not be used
399 * when determining if quoting is necessary. The element delim is still used for this purpose even
400 * when the line ending is set.
401 *
402 * \param[in,out] info The settings.
403 * \param[in] val The value to set.
404 */
406
407
408/*! Set the conflict resolution flags used for merging.
409 *
410 * \param[in,out] info The settings.
411 * \param[in] val The value to set.
412 */
414
415
416/*! Set the conflict resolution function.
417 *
418 * \param[in,out] info The settings.
419 * \param[in] val The value to set.
420 */
422
423
424/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
425 * Common
426 */
427
428/*! Create a new ini object.
429 *
430 * \param[in] ignore_whitespace Should whitespace be ignored when comparing section and key names.
431 *
432 * \return A new ini object.
433 */
434M_API M_ini_t *M_ini_create(M_bool ignore_whitespace) M_MALLOC;
435
436
437/*! Duplicate an ini.
438 *
439 * \param[in] ini The ini to duplicate
440 */
441M_API M_ini_t *M_ini_duplicate(const M_ini_t *ini);
442
443
444/*! Destroy the ini.
445 *
446 * \param[in] ini The ini to destroy.
447 */
448M_API void M_ini_destroy(M_ini_t *ini) M_FREE(1);
449
450
451/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
452 * Read
453 */
454
455/*! Parse a string into an ini object.
456 *
457 * \param[in] s The string to parse.
458 * \param[in] info The ini settings that control how the ini is structured and should be read.
459 * \param[in] ignore_whitespace Should whitespace be ignored for section and key comparison.
460 * \param[out] err_line If an error occurs the line the error is present on.
461 * Optional, pass NULL if not needed.
462 *
463 * \return An ini object. NULL if data could not be parsed.
464 */
465M_API M_ini_t *M_ini_read(const char *s, const M_ini_settings_t *info, M_bool ignore_whitespace, size_t *err_line) M_MALLOC;
466
467
468/*! Read a file based on file name into an ini object.
469 *
470 * \param[in] path The full file path to read.
471 * \param[in] info The ini settings that control how the ini is structured and should be read.
472 * \param[in] ignore_whitespace Should whitespace be ignored for section and key comparison.
473 * \param[out] err_line If an error occurs the line the error is present on.
474 * Optional, pass NULL if not needed.
475 * \param[in] max_read The maximum number of bytes to read.
476 *
477 * \return An ini object. NULL if the file could not be parsed.
478 */
479M_API M_ini_t *M_ini_read_file(const char *path, const M_ini_settings_t *info, M_bool ignore_whitespace, size_t *err_line, size_t max_read) M_MALLOC;
480
481
482/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
483 * Manipulate
484 *
485 * The ini stores keys in a flattened format. To differentiate keys with the same name in different
486 * sections the section is prepended to the key. E.g. "Section 1/key 1". All keys passed into a
487 * manipulate function must use this format. All keys returned by a manipulate function will use
488 * this format. Use The M_ini_full_key and M_ini_split_key functions to aid with the use of
489 * these functions.
490 */
491
492/*! Does the ini contain a given key.
493 *
494 * \param[in] ini The ini.
495 * \param[in] key The key to check.
496 *
497 * \return M_TRUE if the ini contains the key otherwise M_FALSE.
498 */
499M_API M_bool M_ini_kv_has_key(const M_ini_t *ini, const char *key);
500
501
502/*! Get a list of all keys contained in the ini.
503 *
504 * \param[in] ini The ini.
505 *
506 * \return A list of keys contained in the ini.
507 */
508M_API M_list_str_t *M_ini_kv_keys(const M_ini_t *ini) M_MALLOC;
509
510
511/*! Get a list of sections contained in the ini.
512 *
513 * \param[in] ini The ini.
514 *
515 * \return A list of sections contained in the ini.
516 */
517M_API M_list_str_t *M_ini_kv_sections(const M_ini_t *ini) M_MALLOC;
518
519
520/*! Rename a section or key in the ini.
521 *
522 * Renaming a section can move all keys under it. Renaming a key will move it to the new location if the
523 * section portion is different.
524 *
525 * Renaming will fail if the new name already exists. This applies to sections and keys.
526 *
527 * This can also be used to rename the "pretty name" for a section or key when ignore white space is in use.
528 * Or when the case needs to be changed.
529 * E.g. "section_1" -> "Section 1". These are equivalent when ignore whitespace is enabled and renaming
530 * will simply change the pretty name.
531 *
532 * \param[in,out] ini The ini.
533 * \param[in] key The section or key to rename.
534 * \param[in] new_key The new name.
535 *
536 * \return M_TRUE on success otherwise M_FALSE.
537 */
538M_API M_bool M_ini_kv_rename(M_ini_t *ini, const char *key, const char *new_key);
539
540
541/*! Add a key (without value) to the ini.
542 *
543 * \param[in,out] ini The ini.
544 * \param key The key to add.
545 *
546 * \return M_TRUE if added otherwise M_FALSE.
547 */
548M_API M_bool M_ini_kv_add_key(M_ini_t *ini, const char *key);
549
550
551/*! Set the value for the key to this value only.
552 *
553 * This will clear/replace any other values (even multiple) for the key.
554 *
555 * \param[in,out] ini The ini.
556 * \param[in] key The key.
557 * \param[in] val The vaule.
558 *
559 * \return M_TRUE on success otherwise M_FALSE.
560 */
561M_API M_bool M_ini_kv_set(M_ini_t *ini, const char *key, const char *val);
562
563
564/*! Insert the value into the values for key.
565 *
566 * This does not remove/replace the existing values for the key.
567 *
568 * \param[in,out] ini The ini.
569 * \param[in] key The key.
570 * \param[in] val The vaule.
571 *
572 * \return M_TRUE on success otherwise M_FALSE.
573 */
574M_API M_bool M_ini_kv_insert(M_ini_t *ini, const char *key, const char *val);
575
576
577/*! Remove the key from the ini.
578 *
579 * \param[in,out] ini The ini.
580 * \param[in] key The key.
581 *
582 * \return M_TRUE on success otherwise M_FALSE.
583 */
584M_API M_bool M_ini_kv_remove(M_ini_t *ini, const char *key);
585
586
587/*! Remove all values for a key but leave the key as part of the ini.
588 *
589 * \param[in,out] ini The ini.
590 * \param[in] key The key.
591 *
592 * \return M_TRUE on success otherwise M_FALSE.
593 */
594M_API M_bool M_ini_kv_remove_vals(M_ini_t *ini, const char *key);
595
596
597/*! Remove a specific value from the key.
598 *
599 * \param[in,out] ini The ini.
600 * \param[in] key The key.
601 * \param[in] idx The index of the value to remove.
602 *
603 * \return M_TRUE on success otherwise M_FALSE.
604 */
605M_API M_bool M_ini_kv_remove_val_at(M_ini_t *ini, const char *key, size_t idx);
606
607
608/*! Get the number of values for a given key.
609 *
610 * \param[in] ini The ini.
611 * \param[in] key The key.
612 *
613 * \return The number of values for a given key.
614 */
615M_API size_t M_ini_kv_len(const M_ini_t *ini, const char *key);
616
617
618/*! Get the value at the given index for the key.
619 *
620 * \param[in] ini The ini.
621 * \param[in] key The key.
622 * \param[in] idx The index of the value to get.
623 * \param[out] val The value. Can be NULL to check for value existence. Use M_ini_kv_has_key to determine key
624 * existence because a key can be part of of the ini and not have a value.
625 *
626 * \return M_TRUE if the value can be retrieved. Otherwise M_FALSE.
627 */
628M_API M_bool M_ini_kv_get(const M_ini_t *ini, const char *key, size_t idx, const char **val);
629
630
631/*! Get the value at the given index for the key.
632 *
633 * \param[in] ini The ini.
634 * \param[in] key The key.
635 * \param[in] idx The index of the value to get.
636 *
637 * \return The value.
638 */
639M_API const char *M_ini_kv_get_direct(const M_ini_t *ini, const char *key, size_t idx);
640
641
642/*! Get all values for the key.
643 *
644 * \param[in] ini The ini.
645 * \param[in] key The key.
646 *
647 * \return A string list of values or NULL.
648 */
649M_API M_list_str_t *M_ini_kv_get_vals(const M_ini_t *ini, const char *key);
650
651
652/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
653 * Write
654 */
655
656/*! Write the ini to a string.
657 *
658 * \param[in,out] ini The ini.
659 * \param[in] info Settings controlling how the ini should be written.
660 *
661 * \return The ini as a string.
662 */
663M_API char *M_ini_write(M_ini_t *ini, const M_ini_settings_t *info);
664
665
666/*! Write the ini directly to a file.
667 *
668 * \param[in,out] ini The ini.
669 * \param[in] path The file path to write the ini to. This will overwrite the data in the file at path if path is
670 * an existing file.
671 * \param[in] info Settings controlling how the ini should be written.
672 *
673 * \return Result.
674 */
675M_API M_fs_error_t M_ini_write_file(M_ini_t *ini, const char *path, const M_ini_settings_t *info);
676
677
678/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
679 * Merge
680 */
681
682/*! Merge a new ini into an existing ini.
683 *
684 * The merge processes is similar to a three way diff. The current values are compared to the values
685 * in new and the original. The merge process is:
686 *
687 * 1. Update keys.
688 * a. Only in new = in merged.
689 * b. Only in cur = in merged.
690 * c. In cur and new but not in orig = in merged.
691 * d. In orig and cur but not in new = flag handling (default: not in merged).
692 * e. In orig and new but not in cur = flag handling (default: not in merged).
693 * f. in cur, new and orig = in merged.
694 * 2. Update vals.
695 * a. Cur and orig the same but new different = flag handling (default: use new).
696 * b. Cur and new the same but orig different = use cur/new.
697 * c. New and orig the same but cur different = use cur
698 * d. All there are the same = use cur/new/orig.
699 * 3. Update multi-vals.
700 * a. In cur and new = use cur/new.
701 * b. Only in cur = use cur.
702 * c. In cur and orig but not in new = flag (default remove).
703 * d. In new but not in cur or orig = use new.
704 *
705 * \param[in] cur_ini The current ini. Contains user changes that differ from the original ini.
706 * \param[in] new_ini The new ini.
707 * \param[in] orig_ini The original ini that cur_ini is based on.
708 * \param[in] info Settings controlling how the ini should be merged.
709 */
710M_API M_ini_t *M_ini_merge(const M_ini_t *cur_ini, const M_ini_t *new_ini, const M_ini_t *orig_ini, const M_ini_settings_t *info);
711
712/*! @} */
713
714__END_DECLS
715
716#endif /* __M_INI_H__ */
M_fs_error_t
Definition: m_fs.h:154
M_ini_t * M_ini_create(M_bool ignore_whitespace) M_MALLOC
M_bool M_ini_kv_rename(M_ini_t *ini, const char *key, const char *new_key)
M_bool M_ini_kv_get(const M_ini_t *ini, const char *key, size_t idx, const char **val)
M_fs_error_t M_ini_write_file(M_ini_t *ini, const char *path, const M_ini_settings_t *info)
M_bool M_ini_kv_remove(M_ini_t *ini, const char *key)
void M_ini_settings_destroy(M_ini_settings_t *info) M_FREE(1)
void M_ini_settings_set_quote_char(M_ini_settings_t *info, unsigned char val)
void M_ini_settings_writer_set_multivals_handling(M_ini_settings_t *info, M_ini_multivals_t val)
M_list_str_t * M_ini_kv_keys(const M_ini_t *ini) M_MALLOC
unsigned char M_ini_settings_get_comment_char(const M_ini_settings_t *info)
size_t M_ini_kv_len(const M_ini_t *ini, const char *key)
void M_ini_settings_writer_set_line_ending(M_ini_settings_t *info, const char *val)
M_bool M_ini_kv_remove_val_at(M_ini_t *ini, const char *key, size_t idx)
M_ini_t * M_ini_read(const char *s, const M_ini_settings_t *info, M_bool ignore_whitespace, size_t *err_line) M_MALLOC
void M_ini_settings_merger_set_conflict_flags(M_ini_settings_t *info, M_uint32 val)
M_list_str_t * M_ini_kv_get_vals(const M_ini_t *ini, const char *key)
M_bool M_ini_kv_set(M_ini_t *ini, const char *key, const char *val)
M_ini_merge_conflict_t
Definition: m_ini.h:157
M_ini_dupkvs_t M_ini_settings_reader_get_dupkvs_handling(const M_ini_settings_t *info)
M_ini_t * M_ini_duplicate(const M_ini_t *ini)
void M_ini_settings_set_escape_char(M_ini_settings_t *info, unsigned char val)
M_list_str_t * M_ini_kv_sections(const M_ini_t *ini) M_MALLOC
M_bool M_ini_kv_add_key(M_ini_t *ini, const char *key)
unsigned char M_ini_settings_get_kv_delim_char(const M_ini_settings_t *info)
M_uint32 M_ini_settings_get_padding(const M_ini_settings_t *info)
M_uint32 M_ini_settings_merger_get_conflict_flags(const M_ini_settings_t *info)
void M_ini_settings_set_element_delim_char(M_ini_settings_t *info, unsigned char val)
void M_ini_settings_merger_set_resolver(M_ini_settings_t *info, M_ini_merge_resolver_t val)
unsigned char M_ini_settings_get_quote_char(const M_ini_settings_t *info)
void M_ini_settings_reader_set_dupkvs_handling(M_ini_settings_t *info, M_ini_dupkvs_t val)
unsigned char M_ini_settings_get_element_delim_char(const M_ini_settings_t *info)
void M_ini_destroy(M_ini_t *ini) M_FREE(1)
M_ini_t * M_ini_read_file(const char *path, const M_ini_settings_t *info, M_bool ignore_whitespace, size_t *err_line, size_t max_read) M_MALLOC
char * M_ini_full_key(const char *section, const char *key) M_MALLOC
const char * M_ini_settings_writer_get_line_ending(const M_ini_settings_t *info)
M_ini_merge_resolver_t M_ini_settings_merger_get_resolver(const M_ini_settings_t *info)
struct M_ini_settings M_ini_settings_t
Definition: m_ini.h:95
M_bool M_ini_kv_remove_vals(M_ini_t *ini, const char *key)
M_ini_padding_t
Definition: m_ini.h:129
M_bool(* M_ini_merge_resolver_t)(const char *key, const char *val_cur, const char *val_new)
Definition: m_ini.h:112
M_bool M_ini_kv_insert(M_ini_t *ini, const char *key, const char *val)
unsigned char M_ini_settings_get_escape_char(const M_ini_settings_t *info)
M_ini_dupkvs_t
Definition: m_ini.h:118
void M_ini_settings_set_kv_delim_char(M_ini_settings_t *info, unsigned char val)
M_ini_settings_t * M_ini_settings_create(void) M_MALLOC
M_ini_multivals_t M_ini_settings_writer_get_multivals_handling(const M_ini_settings_t *info)
const char * M_ini_kv_get_direct(const M_ini_t *ini, const char *key, size_t idx)
char * M_ini_write(M_ini_t *ini, const M_ini_settings_t *info)
M_ini_multivals_t
Definition: m_ini.h:139
struct M_ini M_ini_t
Definition: m_ini.h:92
M_ini_t * M_ini_merge(const M_ini_t *cur_ini, const M_ini_t *new_ini, const M_ini_t *orig_ini, const M_ini_settings_t *info)
void M_ini_settings_set_comment_char(M_ini_settings_t *info, unsigned char val)
M_bool M_ini_kv_has_key(const M_ini_t *ini, const char *key)
void M_ini_settings_set_padding(M_ini_settings_t *info, M_uint32 val)
void M_ini_split_key(const char *s, char **section, char **key)
@ M_INI_MERGE_NEW_CHANGED_USE_CUR
Definition: m_ini.h:163
@ M_INI_MERGE_NEW_REMOVED_KEEP
Definition: m_ini.h:161
@ M_INI_MERGE_CALLBACK_FUNC
Definition: m_ini.h:158
@ M_INI_MERGE_MULTI_NEW_REMOVED_KEEP
Definition: m_ini.h:166
@ M_INI_PADDING_AFTER_KV_VAL
Definition: m_ini.h:133
@ M_INI_PADDING_AFTER_KV_DELIM
Definition: m_ini.h:132
@ M_INI_PADDING_NONE
Definition: m_ini.h:130
@ M_INI_PADDING_AFTER_COMMENT_CHAR
Definition: m_ini.h:134
@ M_INI_PADDING_BEFORE_KV_DELIM
Definition: m_ini.h:131
@ M_INI_DUPKVS_REMOVE
Definition: m_ini.h:122
@ M_INI_DUPKVS_COLLECT
Definition: m_ini.h:123
@ M_INI_DUPKVS_REMOVE_PREV
Definition: m_ini.h:120
@ M_INI_DUPKVS_COMMENT_PREV
Definition: m_ini.h:119
@ M_INI_DUPKVS_COMMENT
Definition: m_ini.h:121
@ M_INI_MULTIVALS_USE_FIRST
Definition: m_ini.h:141
@ M_INI_MULTIVALS_USE_LAST
Definition: m_ini.h:140
@ M_INI_MULTIVALS_KEEP_EXISTING
Definition: m_ini.h:142
@ M_INI_MULTIVALS_MAINTAIN_ORDER
Definition: m_ini.h:144
struct M_list_str M_list_str_t
Definition: m_list_str.h:80