|
1 /* |
|
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
|
3 * |
|
4 * Copyright 2024 Mike Becker, Olaf Wintermann All rights reserved. |
|
5 * |
|
6 * Redistribution and use in source and binary forms, with or without |
|
7 * modification, are permitted provided that the following conditions are met: |
|
8 * |
|
9 * 1. Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * |
|
12 * 2. Redistributions in binary form must reproduce the above copyright |
|
13 * notice, this list of conditions and the following disclaimer in the |
|
14 * documentation and/or other materials provided with the distribution. |
|
15 * |
|
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
26 * POSSIBILITY OF SUCH DAMAGE. |
|
27 */ |
|
28 /** |
|
29 * \file properties.h |
|
30 * \brief Interface for parsing data from properties files. |
|
31 * \author Mike Becker |
|
32 * \author Olaf Wintermann |
|
33 * \copyright 2-Clause BSD License |
|
34 */ |
|
35 |
|
36 #ifndef UCX_PROPERTIES |
|
37 #define UCX_PROPERTIES |
|
38 |
|
39 #include "common.h" |
|
40 #include "string.h" |
|
41 |
|
42 struct cx_properties_config_s { |
|
43 /** |
|
44 * The key/value delimiter that shall be used. |
|
45 * This is '=' by default. |
|
46 */ |
|
47 char delimiter; |
|
48 |
|
49 /** |
|
50 * The character, when appearing at the end of a line, continues that line. |
|
51 * This is '\' by default. |
|
52 */ |
|
53 char continuation; |
|
54 |
|
55 /** |
|
56 * The first comment character. |
|
57 * This is '#' by default. |
|
58 */ |
|
59 char comment1; |
|
60 |
|
61 /** |
|
62 * The second comment character. |
|
63 * This is not set by default. |
|
64 */ |
|
65 char comment2; |
|
66 |
|
67 /** |
|
68 * The third comment character. |
|
69 * This is not set by default. |
|
70 */ |
|
71 char comment3; |
|
72 }; |
|
73 |
|
74 /** |
|
75 * Typedef for the properties config. |
|
76 */ |
|
77 typedef struct cx_properties_config_s CxPropertiesConfig; |
|
78 |
|
79 /** |
|
80 * Default properties configuration. |
|
81 */ |
|
82 extern const CxPropertiesConfig cx_properties_config_default; |
|
83 |
|
84 /** |
|
85 * Status codes for the properties interface. |
|
86 */ |
|
87 enum cx_properties_status { |
|
88 /** |
|
89 * Everything is fine. |
|
90 */ |
|
91 CX_PROPERTIES_NO_ERROR, |
|
92 /** |
|
93 * The input buffer does not contain more data. |
|
94 */ |
|
95 CX_PROPERTIES_NO_DATA, |
|
96 /** |
|
97 * The input ends unexpectedly. |
|
98 * |
|
99 * This either happens when the last line does not terminate with a line |
|
100 * break, or when the input ends with a parsed key but no value. |
|
101 */ |
|
102 CX_PROPERTIES_INCOMPLETE_DATA, |
|
103 /** |
|
104 * Input buffer is \c NULL. |
|
105 */ |
|
106 CX_PROPERTIES_NULL_INPUT, |
|
107 }; |
|
108 |
|
109 /** |
|
110 * Interface for working with properties data. |
|
111 */ |
|
112 struct cx_properties_s { |
|
113 /** |
|
114 * The configuration. |
|
115 */ |
|
116 CxPropertiesConfig config; |
|
117 |
|
118 /** |
|
119 * The text buffer. |
|
120 */ |
|
121 const char *text; |
|
122 |
|
123 /** |
|
124 * Length of the text buffer. |
|
125 */ |
|
126 size_t text_len; |
|
127 |
|
128 /** |
|
129 * Position in the text buffer. |
|
130 */ |
|
131 size_t text_pos; |
|
132 }; |
|
133 |
|
134 /** |
|
135 * Typedef for the properties interface. |
|
136 */ |
|
137 typedef struct cx_properties_s CxProperties; |
|
138 |
|
139 |
|
140 /** |
|
141 * Initialize a properties parser. |
|
142 * |
|
143 * @param prop the properties interface |
|
144 * @param config the properties configuration |
|
145 * @see cxPropertiesInitDefault() |
|
146 */ |
|
147 __attribute__((__nonnull__)) |
|
148 static inline void cxPropertiesInit( |
|
149 CxProperties *prop, |
|
150 CxPropertiesConfig config |
|
151 ) { |
|
152 prop->config = config; |
|
153 prop->text = NULL; |
|
154 } |
|
155 |
|
156 /** |
|
157 * Initialize a properties parser with the default configuration. |
|
158 * |
|
159 * @param prop the properties interface |
|
160 * @see cxPropertiesInit() |
|
161 */ |
|
162 #define cxPropertiesInitDefault(prop) \ |
|
163 cxPropertiesInit(prop, cx_properties_config_default) |
|
164 |
|
165 /** |
|
166 * Sets an input buffer. |
|
167 * |
|
168 * After calling this function, you can parse the data by calling |
|
169 * cxPropertiesNext() until the status is #CX_PROPERTIES_NO_DATA. |
|
170 * |
|
171 * @param prop the properties interface |
|
172 * @param buf a pointer to data |
|
173 * @param len the length of the data |
|
174 */ |
|
175 __attribute__((__nonnull__)) |
|
176 static inline void cxPropertiesInput( |
|
177 CxProperties *prop, |
|
178 const void *buf, |
|
179 size_t len |
|
180 ) { |
|
181 prop->text = buf; |
|
182 prop->text_len = len; |
|
183 prop->text_pos = 0; |
|
184 } |
|
185 |
|
186 /** |
|
187 * Retrieves the next key/value-pair. |
|
188 * |
|
189 * This function returns zero as long as there are key/value-pairs |
|
190 * found. If no more key/value-pairs are found, #CX_PROPERTIES_NO_DATA |
|
191 * is returned. You may refill the input buffer with cxPropertiesInput(). |
|
192 * |
|
193 * When an invalid line is encountered, #CX_PROPERTIES_INVALID_LINE is returned |
|
194 * and the position of the input buffer will be the start of the affected line. |
|
195 * |
|
196 * @param prop the properties interface |
|
197 * @param name a pointer to the cxstring that shall contain the property name |
|
198 * @param value a pointer to the cxstring that shall contain the property value |
|
199 * @return Nonzero, if a key/value-pair was successfully retrieved |
|
200 * @see ucx_properties_fill() |
|
201 */ |
|
202 enum cx_properties_status cxPropertiesNext( |
|
203 CxProperties *prop, |
|
204 cxstring *name, |
|
205 cxstring *value |
|
206 ); |
|
207 |
|
208 #endif // UCX_PROPERTIES |