aboutsummaryrefslogtreecommitdiffstats
path: root/src/config.h
blob: c35dcd89adbd3069e77ffd141c4b27245e38ad34 (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
#ifndef DISCOVERY_CONFIG_H
#define DISCOVERY_CONFIG_H

/**
 * @file  config.h
 * @brief Simple key=value configuration file parser.
 *
 * Parses configuration files with one key=value pair per line.
 * Lines starting with '#' are comments.  Blank lines are ignored.
 */

#include <stddef.h>

/**
 * @brief A single key=value entry from a config file.
 *
 * Both key and value are heap-allocated, null-terminated strings
 * with leading/trailing whitespace trimmed.
 */
typedef struct
{
  char *key;
  char *value;
} config_entry;

/**
 * @brief A parsed configuration file.
 *
 * Holds a dynamic array of config_entry items.
 */
typedef struct
{
  config_entry *entries;
  size_t count;
  size_t capacity;
} config;

/**
 * @brief Parses a configuration file into a config structure.
 *
 * Each non-blank, non-comment line must contain '=' separating key
 * and value.  Whitespace is trimmed around both key and value.
 *
 * @param path  Path to the configuration file.
 * @param cfg   Output: the parsed configuration.  Must be freed
 *              with config_free() when no longer needed.
 * @return 0 on success, -1 on error (logged via UA_LOG_ERROR).
 */
int config_load (const char *path, config *cfg);

/**
 * @brief Looks up a single-valued key.
 *
 * Returns the value of the first entry matching @p key, or NULL
 * if the key is not present.
 *
 * @param cfg  The parsed configuration.
 * @param key  The key to search for.
 * @return The value string (owned by cfg), or NULL.
 */
const char *config_get (const config *cfg, const char *key);

/**
 * @brief Looks up a required single-valued key.
 *
 * Like config_get(), but logs a FATAL error and returns NULL when
 * the key is missing.
 *
 * @param cfg      The parsed configuration.
 * @param key      The key to search for.
 * @param program  Program name (for error messages).
 * @return The value string (owned by cfg), or NULL if missing.
 */
const char *config_require (const config *cfg, const char *key,
                            const char *program);

/**
 * @brief Looks up a required integer-valued key.
 *
 * Parses the value of @p key as an integer.  If the key is
 * missing or the value is not a valid integer, logs a FATAL
 * error and returns -1.
 *
 * @param cfg      The parsed configuration.
 * @param key      The key to search for.
 * @param program  Program name (for error messages).
 * @return The parsed integer, or -1 on error.
 */
int config_require_int (const config *cfg, const char *key,
                        const char *program);

/**
 * @brief Frees all memory owned by a config structure.
 *
 * After this call the config is zeroed and must not be used
 * unless config_load() is called again.
 *
 * @param cfg  The configuration to free.
 */
void config_free (config *cfg);

#endif /* DISCOVERY_CONFIG_H */