1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  */
4 #ifndef __OSI_CONFIG_H__
5 #define __OSI_CONFIG_H__
6 
7 // This module implements a configuration parser. Clients can query the
8 // contents of a configuration file through the interface provided here.
9 // The current implementation is read-only; mutations are only kept in
10 // memory. This parser supports the INI file format.
11 
12 // Implementation notes:
13 // - Key/value pairs that are not within a section are assumed to be under
14 //   the |CONFIG_DEFAULT_SECTION| section.
15 // - Multiple sections with the same name will be merged as if they were in
16 //   a single section.
17 // - Empty sections with no key/value pairs will be treated as if they do
18 //   not exist. In other words, |nvrec_config_has_section| will return false for
19 //   empty sections.
20 // - Duplicate keys in a section will overwrite previous values.
21 
22 #include <stdbool.h>
23 #include "list_ext.h"
24 // The default section name to use if a key/value pair is not defined within
25 // a section.
26 #define CONFIG_DEFAULT_SECTION "Global"
27 typedef struct {
28   char *key;
29   char *value;
30 } nvrec_entry_t;
31 
32 typedef struct {
33   char *name;
34   list_t *entries;
35 } nvrec_section_t;
36 
37 typedef struct nvrec_config {
38   list_t *sections;
39 }nvrec_config_t;
40 
41 // Loads the specified file and returns a handle to the config file. If there
42 // was a problem loading the file or allocating memory, this function returns
43 // NULL. Clients must call |nvrec_config_free| on the returned handle when it is no
44 // longer required. |filename| must not be NULL and must point to a readable
45 // file on the filesystem.
46 nvrec_config_t *nvrec_config_new(const char *filename);
47 
48 // Frees resources associated with the config file. No further operations may
49 // be performed on the |config| object after calling this function. |config|
50 // may be NULL.
51 void nvrec_config_free(nvrec_config_t *config);
52 
53 // Returns true if the config file contains a section named |section|. If
54 // the section has no key/value pairs in it, this function will return false.
55 // |config| and |section| must not be NULL.
56 bool nvrec_config_has_section(const nvrec_config_t *config, const char *section);
57 
58 // Returns true if the config file has a key named |key| under |section|.
59 // Returns false otherwise. |config|, |section|, and |key| must not be NULL.
60 bool nvrec_config_has_key(const nvrec_config_t *config, const char *section, const char *key);
61 
62 // Returns the integral value for a given |key| in |section|. If |section|
63 // or |key| do not exist, or the value cannot be fully converted to an integer,
64 // this function returns |def_value|. |config|, |section|, and |key| must not
65 // be NULL.
66 int nvrec_config_get_int(const nvrec_config_t *config, const char *section, const char *key, int def_value);
67 
68 // Returns the boolean value for a given |key| in |section|. If |section|
69 // or |key| do not exist, or the value cannot be converted to a boolean, this
70 // function returns |def_value|. |config|, |section|, and |key| must not be NULL.
71 bool nvrec_config_get_bool(const nvrec_config_t *config, const char *section, const char *key, bool def_value);
72 
73 // Returns the string value for a given |key| in |section|. If |section| or
74 // |key| do not exist, this function returns |def_value|. The returned string
75 // is owned by the config module and must not be freed. |config|, |section|,
76 // and |key| must not be NULL. |def_value| may be NULL.
77 const char *nvrec_config_get_string(const nvrec_config_t *config, const char *section, const char *key, const char *def_value);
78 
79 // Sets an integral value for the |key| in |section|. If |key| or |section| do
80 // not already exist, this function creates them. |config|, |section|, and |key|
81 // must not be NULL.
82 void nvrec_config_set_int(nvrec_config_t *config, const char *section, const char *key, int value);
83 
84 // Sets a boolean value for the |key| in |section|. If |key| or |section| do
85 // not already exist, this function creates them. |config|, |section|, and |key|
86 // must not be NULL.
87 void nvrec_config_set_bool(nvrec_config_t *config, const char *section, const char *key, bool value);
88 
89 // Sets a string value for the |key| in |section|. If |key| or |section| do
90 // not already exist, this function creates them. |config|, |section|, |key|, and
91 // |value| must not be NULL.
92 void nvrec_config_set_string(nvrec_config_t *config, const char *section, const char *key, const char *value);
93 nvrec_section_t *nvrec_section_find(const nvrec_config_t *config, const char *section);
94 void nvrec_entry_free(void *ptr);
95 #endif
96 
97