summaryrefslogtreecommitdiff
path: root/common/ini/ini_config.h
blob: 2c906e476edf61a26949af351f284aeedb49143c (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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*
    INI LIBRARY

    Header file for reading configuration from INI file
    and storing as a collection.

    Copyright (C) Dmitri Pal <dpal@redhat.com> 2009

    INI Library is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    INI Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with INI Library.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef INI_CONFIG_H
#define INI_CONFIG_H

#include <limits.h>
#include <stdio.h>
#include "collection.h"

/* Name of the default (missing section in the INI file */
#define INI_DEFAULT_SECTION "default"

/* Collection classes used in INI processing */
#define COL_CLASS_INI_BASE        20000
#define COL_CLASS_INI_CONFIG      COL_CLASS_INI_BASE + 0 /* Class for configuration collection. Implies a collection of sections */
#define COL_CLASS_INI_SECTION     COL_CLASS_INI_BASE + 1 /* A one level collection of key value pairs where values are always stings */
#define COL_CLASS_INI_PERROR      COL_CLASS_INI_BASE + 2 /* A one level collection of parse errors - store parse_error structs */
#define COL_CLASS_INI_PESET       COL_CLASS_INI_BASE + 3 /* A one level collection of parse error collections */
#define COL_CLASS_INI_GERROR      COL_CLASS_INI_BASE + 4 /* A one level collection of grammar errors - store parse_error structs */
#define COL_CLASS_INI_VERROR      COL_CLASS_INI_BASE + 5 /* A one level collection of validation errors - store parse_error structs */
#define COL_CLASS_INI_LINES       COL_CLASS_INI_BASE + 6 /* A one level collection of lines in INI file */


/* Error levels */
#define INI_STOP_ON_ANY     0   /* Fail if any problem is detected */
#define INI_STOP_ON_NONE    1   /* Best effort - do not fail */
#define INI_STOP_ON_ERROR   2   /* Fail on errors only */


/* Parsing errors and warnings */
#define ERR_LONGDATA        1   /* Error */
#define ERR_NOCLOSESEC      2   /* Error */
#define ERR_NOSECTION       3   /* Error */
#define ERR_SECTIONLONG     4   /* Error */
#define ERR_NOEQUAL         5   /* Warning */
#define ERR_NOKEY           6   /* Warning */
#define ERR_LONGKEY         7   /* Warning */

#define ERR_MAXPARSE        ERR_LONGKEY

/* Grammar errors and warnings */
/* Placeholder for now... */
#define ERR_MAXGRAMMAR      0

/* Validation errors and warnings */
/* Placeholder for now... */
#define ERR_MAXVALID        0


struct parse_error {
    unsigned line;
    int error;
};

/* Function to return parsing error */
const char *parsing_error_str(int parsing_error);

/* Function to return grammar error in template.
 * This error is returned when the template
 * is translated into the grammar object.
 */
const char *grammar_error_str(int parsing_error);

/* Function to return validation error.
 * This is the error that it is returned when
 * the INI file is validated against the
 * grammar object.
 */
const char *validation_error_str(int parsing_error);

/* Read configuration information from a file */
int config_from_file(const char *application,               /* Name of the application - will be used as name of the collection */
                     const char *config_filename,           /* Name of the config file - if NULL the collection will be empty */
                     struct collection_item **ini_config,   /* If *ini_config is NULL a new ini object will be allocated, */
                                                            /* otherwise the one that is pointed to will be updated. */
                     int error_level,                       /* Error level - break for errors, warnings or best effort (don't break) */
                     struct collection_item **error_list);  /* List of errors for a file */

/* Read configuration information from a file descriptor */
int config_from_fd(const char *application,              /* Name of the application - will be used as name of the collection */
                   int fd,                               /* Previously opened file descriptor for the config file */
                   const char *config_source,            /* Name of the file being parsed, for use when printing the error list */
                   struct collection_item **ini_config,  /* If *ini_config is NULL a new ini object will be allocated*/
                   int error_level,                      /* Error level - break for errors, warnings or best effort (don't break) */
                   struct collection_item **error_list); /* List of errors for a file */


/* Read configuration information from a file with extra collection of line numbers */
int config_from_file_with_lines(
                     const char *application,               /* Name of the application - will be used as name of the collection */
                     const char *config_filename,           /* Name of the config file - if NULL the collection will be empty */
                     struct collection_item **ini_config,   /* If *ini_config is NULL a new ini object will be allocated, */
                                                            /* otherwise the one that is pointed to will be updated. */
                     int error_level,                       /* Error level - break for errors, warnings or best effort (don't break) */
                     struct collection_item **error_list,   /* List of errors for a file */
                     struct collection_item **lines);       /* Collection of pairs where key is the key and value is line number */

/* Read configuration information from a file descriptor with extra collection of line numbers */
int config_from_fd_with_lines(
                   const char *application,               /* Name of the application - will be used as name of the collection */
                   int fd,                                /* Previously opened file descriptor for the config file */
                   const char *config_source,             /* Name of the file being parsed, for use when printing the error list */
                   struct collection_item **ini_config,   /* If *ini_config is NULL a new ini object will be allocated, */
                                                          /* otherwise the one that is pointed to will be updated. */
                   int error_level,                       /* Error level - break for errors, warnings or best effort (don't break) */
                   struct collection_item **error_list,   /* List of errors for a file */
                   struct collection_item **lines);       /* Collection of pairs where key is the key and value is line number */


/* Read default config file and then overwrite it with a specific one from the directory */
int config_for_app(const char *application,               /* Name of the application that will be used to get config for */
                   const char *config_file,               /* Name of the configuration file with default settings for all apps */
                   const char *config_dir,                /* Name of the directory where the configuration files for different apps will be dropped */
                   struct collection_item **ini_config,   /* New config object */
                   int error_level,                       /* Level of error tolerance */
                   struct collection_item **error_set);   /* Collection of collections of parsing errors */

/* Function to free configuration */
void free_ini_config(struct collection_item *ini_config);

/* Function to free configuration error list */
void free_ini_config_errors(struct collection_item *error_set);

/* Function to free configuration line list */
void free_ini_config_lines(struct collection_item *lines);

/* Print errors and warnings that were detected while parsing one file */
/* Use this function to print results of the config_from_file() call */
void print_file_parsing_errors(FILE *file,                           /* File to send errors to */
                               struct collection_item *error_list);  /* List of parsing errors */


/* Print errors and warnings that were detected while
 * checking grammar of the template.
 */
void print_grammar_errors(FILE *file,                           /* File to send errors to */
                          struct collection_item *error_list);  /* List of grammar errors */

/* Print errors and warnings that were detected while
 * checking INI file against grammar object.
 */
void print_validation_errors(FILE *file,                           /* File to send errors to */
                             struct collection_item *error_list);  /* List of validation errors */

/* Print errors and warnings that were detected parsing configuration as a whole */
/* Use this function to print results of the config_for_app() call */
void print_config_parsing_errors(FILE *file,                           /* File to send errors to */
                                 struct collection_item *error_list);  /* Collection of collections of errors */

/* Get list of sections from the config collection as an array of strings.
 * Function allocates memory for the array of the sections.
 */
char **get_section_list(struct collection_item *ini_config, int *size, int *error);

/* The section array should be freed using this function */
void free_section_list(char **section_list);

/* Get list of attributes in a section as an array of strings.
 * Function allocates memory for the array of attributes.
 */
char **get_attribute_list(struct collection_item *ini_config, const char *section, int *size, int *error);

/* The attribute array should be freed using this function */
void free_attribute_list(char **attr_list);

/* Get a configuration item form the configuration */
int get_config_item(const char *section,                    /* Section. If NULL assumed default */
                    const char *name,                       /* Name of the property to look up */
                    struct collection_item *ini_config,     /* Collection to search */
                    struct collection_item **item);         /* Item returned. Will be NULL is not found. */

/* Conversion functions for the configuration item.
 * Sets error to EINVAL if the item is bad.
 * Sets error to EIO if the conversion failed.
 * These functions do not allocate memory.
 * They always return best effort conversion value.
 * In case of error they return provided default.
 * It is up to the caller to check an error and take an action.
 */
/* If "strict" parameter is non zero the function will fail if there are more
 * characters after last digit.
 */
int get_int_config_value(struct collection_item *item, int strict, int def, int *error);
long get_long_config_value(struct collection_item *item, int strict, long def, int *error);
unsigned get_unsigned_config_value(struct collection_item *item, int strict, unsigned def, int *error);
unsigned long get_ulong_config_value(struct collection_item *item, int strict, unsigned long def, int *error);
double get_double_config_value(struct collection_item *item, int strict, double def, int *error);
unsigned char get_bool_config_value(struct collection_item *item, unsigned char def, int *error);

/* Function get_string_config_value returns a newly allocated pointer to the string out of item.*/
char *get_string_config_value(struct collection_item *item, int *error);
/* Function returns the string stored in the item */
const char *get_const_string_config_value(struct collection_item *item, int *error);

/* A get_bin_value and get_xxx_array functions allocate memory.
 * It is the responsibility of the caller to free it after use.
 * free_xxx convenience wrappers are provided for this purpose.
 * Functions will return NULL if conversion failed.
 */
/* A special hex format is assumed.
 * The string should be taken in single quotes
 * and consist of hex encoded value two hex digits per byte.
 * Example: '0A2BFECC'
 * Case does not matter.
 */
char *get_bin_config_value(struct collection_item *item, int *length, int *error);
void free_bin_config_value(char *);

/* Array of stings.
 * Separator string includes up to three different separators. If NULL comma is assumed.
 * The spaces are trimmed automatically around separators in the string.
 * The function drops empty tokens from the list.
 * This means that the string like this: "apple, ,banana, ,orange ,"
 * will be translated into the list of three items: "apple","banana" and "orange".
 *
 * The length of the allocated array is returned in "size".
 * Size and error parameters can be NULL.
 * Use free_string_config_array() to free the array after use.
 */
char **get_string_config_array(struct collection_item *item,
                               const char *sep, int *size, int *error);

/* This function is same as above but does not omit empty tokens.
 * This means that the string like this: "apple, ,banana, ,orange ,"
 * will be translated into the items: "apple", "", "banana", "", "orange", "".
 * This function is useful when the configuration parameter
 * holds a positionally sensitive list.
 * Use free_string_config_array() to free the array after use.
 */
char **get_raw_string_config_array(struct collection_item *item,
                                   const char *sep, int *size, int *error);

/* Array of long values - separators are detected automatically. */
/* The length of the allocated array is returned in "size". */
/* Size and error parameters can be NULL. */
long *get_long_config_array(struct collection_item *item, int *size, int *error);
/* Array of double values - separators are detected automatically. */
/* The length of the allocated array is returned in "size" */
/* Size and error parameters can be NULL. */
double *get_double_config_array(struct collection_item *item, int *size, int *error);

/* Special function to free string config array */
void free_string_config_array(char **str_config);
/* Special function to free long config array */
void free_long_config_array(long *array);
/* Special function to free double config array */
void free_double_config_array(double *array);

#endif