summaryrefslogtreecommitdiffstats
path: root/osi/include/config.h
blob: d7c8ff9a2565cfad9641c2774a8f4794ffe2a586 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#pragma once

// This module implements a configuration parser. Clients can query the
// contents of a configuration file through the interface provided here.
// The current implementation is read-only; mutations are only kept in
// memory. This parser supports the INI file format.

// Implementation notes:
// - Key/value pairs that are not within a section are assumed to be under
//   the |CONFIG_DEFAULT_SECTION| section.
// - Multiple sections with the same name will be merged as if they were in
//   a single section.
// - Empty sections with no key/value pairs will be treated as if they do
//   not exist. In other words, |config_has_section| will return false for
//   empty sections.
// - Duplicate keys in a section will overwrite previous values.
// - All strings are case sensitive.

#include <stdbool.h>

// The default section name to use if a key/value pair is not defined within
// a section.
#define CONFIG_DEFAULT_SECTION "Global"

typedef struct config_t config_t;
typedef struct config_section_node_t config_section_node_t;

// Creates a new config object with no entries (i.e. not backed by a file).
// This function returns a config object or NULL on error. Clients must call
// |config_free| on the returned handle when it is no longer required.
config_t *config_new_empty(void);

// Loads the specified file and returns a handle to the config file. If there
// was a problem loading the file or allocating memory, this function returns
// NULL. Clients must call |config_free| on the returned handle when it is no
// longer required. |filename| must not be NULL and must point to a readable
// file on the filesystem.
config_t *config_new(const char *filename);

// Clones |src|, including all of it's sections, keys, and values.
// Returns a new config which is a copy and separated from the original;
// changes to the new config are not reflected in any way in the original.
//
// |src| must not be NULL
// This function will not return NULL.
// Clients must call config_free on the returned object.
config_t *config_new_clone(const config_t *src);

// Frees resources associated with the config file. No further operations may
// be performed on the |config| object after calling this function. |config|
// may be NULL.
void config_free(config_t *config);

// Returns true if the config file contains a section named |section|. If
// the section has no key/value pairs in it, this function will return false.
// |config| and |section| must not be NULL.
bool config_has_section(const config_t *config, const char *section);

// Returns true if the config file has a key named |key| under |section|.
// Returns false otherwise. |config|, |section|, and |key| must not be NULL.
bool config_has_key(const config_t *config, const char *section, const char *key);

// Returns the integral value for a given |key| in |section|. If |section|
// or |key| do not exist, or the value cannot be fully converted to an integer,
// this function returns |def_value|. |config|, |section|, and |key| must not
// be NULL.
int config_get_int(const config_t *config, const char *section, const char *key, int def_value);

// Returns the boolean value for a given |key| in |section|. If |section|
// or |key| do not exist, or the value cannot be converted to a boolean, this
// function returns |def_value|. |config|, |section|, and |key| must not be NULL.
bool config_get_bool(const config_t *config, const char *section, const char *key, bool def_value);

// Returns the string value for a given |key| in |section|. If |section| or
// |key| do not exist, this function returns |def_value|. The returned string
// is owned by the config module and must not be freed. |config|, |section|,
// and |key| must not be NULL. |def_value| may be NULL.
const char *config_get_string(const config_t *config, const char *section, const char *key, const char *def_value);

// Sets an integral value for the |key| in |section|. If |key| or |section| do
// not already exist, this function creates them. |config|, |section|, and |key|
// must not be NULL.
void config_set_int(config_t *config, const char *section, const char *key, int value);

// Sets a boolean value for the |key| in |section|. If |key| or |section| do
// not already exist, this function creates them. |config|, |section|, and |key|
// must not be NULL.
void config_set_bool(config_t *config, const char *section, const char *key, bool value);

// Sets a string value for the |key| in |section|. If |key| or |section| do
// not already exist, this function creates them. |config|, |section|, |key|, and
// |value| must not be NULL.
void config_set_string(config_t *config, const char *section, const char *key, const char *value);

// Removes |section| from the |config| (and, as a result, all keys in the section).
// Returns true if |section| was found and removed from |config|, false otherwise.
// Neither |config| nor |section| may be NULL.
bool config_remove_section(config_t *config, const char *section);

// Removes one specific |key| residing in |section| of the |config|. Returns true
// if the section and key were found and the key was removed, false otherwise.
// None of |config|, |section|, or |key| may be NULL.
bool config_remove_key(config_t *config, const char *section, const char *key);

// Returns an iterator to the first section in the config file. If there are no
// sections, the iterator will equal the return value of |config_section_end|.
// The returned pointer must be treated as an opaque handle and must not be freed.
// The iterator is invalidated on any config mutating operation. |config| may not
// be NULL.
const config_section_node_t *config_section_begin(const config_t *config);

// Returns an iterator to one past the last section in the config file. It does not
// represent a valid section, but can be used to determine if all sections have been
// iterated over. The returned pointer must be treated as an opaque handle and must
// not be freed and must not be iterated on (must not call |config_section_next| on
// it). |config| may not be NULL.
const config_section_node_t *config_section_end(const config_t *config);

// Moves |iter| to the next section. If there are no more sections, |iter| will
// equal the value of |config_section_end|. |iter| may not be NULL and must be
// a pointer returned by either |config_section_begin| or |config_section_next|.
const config_section_node_t *config_section_next(const config_section_node_t *iter);

// Returns the name of the section referred to by |iter|. The returned pointer is
// owned by the config module and must not be freed by the caller. The pointer will
// remain valid until |config_free| is called. |iter| may not be NULL and must not
// equal the value returned by |config_section_end|.
const char *config_section_name(const config_section_node_t *iter);

// Saves |config| to a file given by |filename|. Note that this could be a destructive
// operation: if |filename| already exists, it will be overwritten. The config
// module does not preserve comments or formatting so if a config file was opened
// with |config_new| and subsequently overwritten with |config_save|, all comments
// and special formatting in the original file will be lost. Neither |config| nor
// |filename| may be NULL.
bool config_save(const config_t *config, const char *filename);