|
@@ -117,6 +117,108 @@ struct simple_settings simple_settings_root = {
|
117
|
117
|
/** Root settings block */
|
118
|
118
|
#define settings_root simple_settings_root.settings
|
119
|
119
|
|
|
120
|
+/**
|
|
121
|
+ * Find child named settings block
|
|
122
|
+ *
|
|
123
|
+ * @v parent Parent settings block
|
|
124
|
+ * @v name Name within this parent
|
|
125
|
+ * @ret settings Settings block, or NULL
|
|
126
|
+ */
|
|
127
|
+static struct settings * find_child_settings ( struct settings *parent,
|
|
128
|
+ const char *name ) {
|
|
129
|
+ struct settings *settings;
|
|
130
|
+
|
|
131
|
+ /* Treat empty name as meaning "this block" */
|
|
132
|
+ if ( ! *name )
|
|
133
|
+ return parent;
|
|
134
|
+
|
|
135
|
+ /* Look for child with matching name */
|
|
136
|
+ list_for_each_entry ( settings, &parent->children, siblings ) {
|
|
137
|
+ if ( strcmp ( settings->name, name ) == 0 )
|
|
138
|
+ return settings;
|
|
139
|
+ }
|
|
140
|
+
|
|
141
|
+ return NULL;
|
|
142
|
+}
|
|
143
|
+
|
|
144
|
+/**
|
|
145
|
+ * Find or create child named settings block
|
|
146
|
+ *
|
|
147
|
+ * @v parent Parent settings block
|
|
148
|
+ * @v name Name within this parent
|
|
149
|
+ * @ret settings Settings block, or NULL
|
|
150
|
+ */
|
|
151
|
+static struct settings * autovivify_child_settings ( struct settings *parent,
|
|
152
|
+ const char *name ) {
|
|
153
|
+ struct {
|
|
154
|
+ struct simple_settings simple;
|
|
155
|
+ char name[ strlen ( name ) + 1 /* NUL */ ];
|
|
156
|
+ } *new_child;
|
|
157
|
+ struct settings *settings;
|
|
158
|
+
|
|
159
|
+ /* Return existing settings, if existent */
|
|
160
|
+ if ( ( settings = find_child_settings ( parent, name ) ) != NULL )
|
|
161
|
+ return settings;
|
|
162
|
+
|
|
163
|
+ /* Create new simple settings block */
|
|
164
|
+ new_child = zalloc ( sizeof ( *new_child ) );
|
|
165
|
+ if ( ! new_child ) {
|
|
166
|
+ DBGC ( parent, "Settings %p could not create child %s\n",
|
|
167
|
+ parent, name );
|
|
168
|
+ return NULL;
|
|
169
|
+ }
|
|
170
|
+ memcpy ( new_child->name, name, sizeof ( new_child->name ) );
|
|
171
|
+ simple_settings_init ( &new_child->simple, NULL, new_child->name );
|
|
172
|
+ settings = &new_child->simple.settings;
|
|
173
|
+ register_settings ( settings, parent );
|
|
174
|
+ return settings;
|
|
175
|
+}
|
|
176
|
+
|
|
177
|
+/**
|
|
178
|
+ * Parse settings block name
|
|
179
|
+ *
|
|
180
|
+ * @v name Name
|
|
181
|
+ * @v get_child Function to find or create child settings block
|
|
182
|
+ * @ret settings Settings block, or NULL
|
|
183
|
+ */
|
|
184
|
+static struct settings *
|
|
185
|
+parse_settings_name ( const char *name,
|
|
186
|
+ struct settings * ( * get_child ) ( struct settings *,
|
|
187
|
+ const char * ) ) {
|
|
188
|
+ struct settings *settings = &settings_root;
|
|
189
|
+ char name_copy[ strlen ( name ) + 1 ];
|
|
190
|
+ char *subname;
|
|
191
|
+ char *remainder;
|
|
192
|
+
|
|
193
|
+ /* Create modifiable copy of name */
|
|
194
|
+ memcpy ( name_copy, name, sizeof ( name_copy ) );
|
|
195
|
+ remainder = name_copy;
|
|
196
|
+
|
|
197
|
+ /* Parse each name component in turn */
|
|
198
|
+ while ( remainder ) {
|
|
199
|
+ subname = remainder;
|
|
200
|
+ remainder = strchr ( subname, '.' );
|
|
201
|
+ if ( remainder )
|
|
202
|
+ *(remainder++) = '\0';
|
|
203
|
+ settings = get_child ( settings, subname );
|
|
204
|
+ if ( ! settings )
|
|
205
|
+ break;
|
|
206
|
+ }
|
|
207
|
+
|
|
208
|
+ return settings;
|
|
209
|
+}
|
|
210
|
+
|
|
211
|
+/**
|
|
212
|
+ * Find named settings block
|
|
213
|
+ *
|
|
214
|
+ * @v name Name
|
|
215
|
+ * @ret settings Settings block, or NULL
|
|
216
|
+ */
|
|
217
|
+struct settings * find_settings ( const char *name ) {
|
|
218
|
+
|
|
219
|
+ return parse_settings_name ( name, find_child_settings );
|
|
220
|
+}
|
|
221
|
+
|
120
|
222
|
/**
|
121
|
223
|
* Apply all settings
|
122
|
224
|
*
|
|
@@ -228,52 +330,6 @@ void unregister_settings ( struct settings *settings ) {
|
228
|
330
|
apply_settings();
|
229
|
331
|
}
|
230
|
332
|
|
231
|
|
-/**
|
232
|
|
- * Find child named settings block
|
233
|
|
- *
|
234
|
|
- * @v parent Parent settings block
|
235
|
|
- * @v name Name within this parent
|
236
|
|
- * @ret settings Settings block, or NULL
|
237
|
|
- */
|
238
|
|
-struct settings * find_child_settings ( struct settings *parent,
|
239
|
|
- const char *name ) {
|
240
|
|
- struct settings *settings;
|
241
|
|
- size_t len;
|
242
|
|
-
|
243
|
|
- /* NULL parent => add to settings root */
|
244
|
|
- if ( parent == NULL )
|
245
|
|
- parent = &settings_root;
|
246
|
|
-
|
247
|
|
- /* Look for a child whose name matches the initial component */
|
248
|
|
- list_for_each_entry ( settings, &parent->children, siblings ) {
|
249
|
|
- len = strlen ( settings->name );
|
250
|
|
- if ( strncmp ( name, settings->name, len ) != 0 )
|
251
|
|
- continue;
|
252
|
|
- if ( name[len] == 0 )
|
253
|
|
- return settings;
|
254
|
|
- if ( name[len] == '.' )
|
255
|
|
- return find_child_settings ( settings,
|
256
|
|
- ( name + len + 1 ) );
|
257
|
|
- }
|
258
|
|
-
|
259
|
|
- return NULL;
|
260
|
|
-}
|
261
|
|
-
|
262
|
|
-/**
|
263
|
|
- * Find named settings block
|
264
|
|
- *
|
265
|
|
- * @v name Name
|
266
|
|
- * @ret settings Settings block, or NULL
|
267
|
|
- */
|
268
|
|
-struct settings * find_settings ( const char *name ) {
|
269
|
|
-
|
270
|
|
- /* If name is empty, use the root */
|
271
|
|
- if ( ! *name )
|
272
|
|
- return &settings_root;
|
273
|
|
-
|
274
|
|
- return find_child_settings ( &settings_root, name );
|
275
|
|
-}
|
276
|
|
-
|
277
|
333
|
/******************************************************************************
|
278
|
334
|
*
|
279
|
335
|
* Core settings routines
|
|
@@ -641,6 +697,7 @@ static struct setting_type * find_setting_type ( const char *name ) {
|
641
|
697
|
* Parse setting name
|
642
|
698
|
*
|
643
|
699
|
* @v name Name of setting
|
|
700
|
+ * @v get_child Function to find or create child settings block
|
644
|
701
|
* @v settings Settings block to fill in
|
645
|
702
|
* @v setting Setting to fill in
|
646
|
703
|
* @ret rc Return status code
|
|
@@ -649,8 +706,11 @@ static struct setting_type * find_setting_type ( const char *name ) {
|
649
|
706
|
* "[settings_name/]tag_name[:type_name]" and fills in the appropriate
|
650
|
707
|
* fields.
|
651
|
708
|
*/
|
652
|
|
-static int parse_setting_name ( const char *name, struct settings **settings,
|
653
|
|
- struct setting *setting ) {
|
|
709
|
+static int
|
|
710
|
+parse_setting_name ( const char *name,
|
|
711
|
+ struct settings * ( * get_child ) ( struct settings *,
|
|
712
|
+ const char * ),
|
|
713
|
+ struct settings **settings, struct setting *setting ) {
|
654
|
714
|
char tmp_name[ strlen ( name ) + 1 ];
|
655
|
715
|
char *settings_name;
|
656
|
716
|
char *setting_name;
|
|
@@ -677,7 +737,7 @@ static int parse_setting_name ( const char *name, struct settings **settings,
|
677
|
737
|
|
678
|
738
|
/* Identify settings block, if specified */
|
679
|
739
|
if ( settings_name ) {
|
680
|
|
- *settings = find_settings ( settings_name );
|
|
740
|
+ *settings = parse_settings_name ( settings_name, get_child );
|
681
|
741
|
if ( *settings == NULL ) {
|
682
|
742
|
DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n",
|
683
|
743
|
settings_name, name );
|
|
@@ -731,7 +791,8 @@ int storef_named_setting ( const char *name, const char *value ) {
|
731
|
791
|
struct setting setting;
|
732
|
792
|
int rc;
|
733
|
793
|
|
734
|
|
- if ( ( rc = parse_setting_name ( name, &settings, &setting ) ) != 0 )
|
|
794
|
+ if ( ( rc = parse_setting_name ( name, autovivify_child_settings,
|
|
795
|
+ &settings, &setting ) ) != 0 )
|
735
|
796
|
return rc;
|
736
|
797
|
return storef_setting ( settings, &setting, value );
|
737
|
798
|
}
|
|
@@ -749,7 +810,8 @@ int fetchf_named_setting ( const char *name, char *buf, size_t len ) {
|
749
|
810
|
struct setting setting;
|
750
|
811
|
int rc;
|
751
|
812
|
|
752
|
|
- if ( ( rc = parse_setting_name ( name, &settings, &setting ) ) != 0 )
|
|
813
|
+ if ( ( rc = parse_setting_name ( name, find_child_settings,
|
|
814
|
+ &settings, &setting ) ) != 0 )
|
753
|
815
|
return rc;
|
754
|
816
|
return fetchf_setting ( settings, &setting, buf, len );
|
755
|
817
|
}
|