1ZCONFIG(3) CZMQ Manual ZCONFIG(3)
2
3
4
6 zconfig - Class for work with config files written in
7 rfc.zeromq.org/spec:4/ZPL.
8
10 // This is a stable class, and may not change except for emergencies. It
11 // is provided in stable builds.
12 // This class has draft methods, which may change over time. They are not
13 // in stable releases, by default. Use --enable-drafts to enable.
14 //
15 typedef int (zconfig_fct) (
16 zconfig_t *self, void *arg, int level);
17
18 // Create new config item
19 CZMQ_EXPORT zconfig_t *
20 zconfig_new (const char *name, zconfig_t *parent);
21
22 // Load a config tree from a specified ZPL text file; returns a zconfig_t
23 // reference for the root, if the file exists and is readable. Returns NULL
24 // if the file does not exist.
25 CZMQ_EXPORT zconfig_t *
26 zconfig_load (const char *filename);
27
28 // Equivalent to zconfig_load, taking a format string instead of a fixed
29 // filename.
30 CZMQ_EXPORT zconfig_t *
31 zconfig_loadf (const char *format, ...) CHECK_PRINTF (1);
32
33 // Destroy a config item and all its children
34 CZMQ_EXPORT void
35 zconfig_destroy (zconfig_t **self_p);
36
37 // Return name of config item
38 CZMQ_EXPORT char *
39 zconfig_name (zconfig_t *self);
40
41 // Return value of config item
42 CZMQ_EXPORT char *
43 zconfig_value (zconfig_t *self);
44
45 // Insert or update configuration key with value
46 CZMQ_EXPORT void
47 zconfig_put (zconfig_t *self, const char *path, const char *value);
48
49 // Equivalent to zconfig_put, accepting a format specifier and variable
50 // argument list, instead of a single string value.
51 CZMQ_EXPORT void
52 zconfig_putf (zconfig_t *self, const char *path, const char *format, ...) CHECK_PRINTF (3);
53
54 // Get value for config item into a string value; leading slash is optional
55 // and ignored.
56 CZMQ_EXPORT char *
57 zconfig_get (zconfig_t *self, const char *path, const char *default_value);
58
59 // Set config item name, name may be NULL
60 CZMQ_EXPORT void
61 zconfig_set_name (zconfig_t *self, const char *name);
62
63 // Set new value for config item. The new value may be a string, a printf
64 // format, or NULL. Note that if string may possibly contain '%', or if it
65 // comes from an insecure source, you must use '%s' as the format, followed
66 // by the string.
67 CZMQ_EXPORT void
68 zconfig_set_value (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2);
69
70 // Find our first child, if any
71 CZMQ_EXPORT zconfig_t *
72 zconfig_child (zconfig_t *self);
73
74 // Find our first sibling, if any
75 CZMQ_EXPORT zconfig_t *
76 zconfig_next (zconfig_t *self);
77
78 // Find a config item along a path; leading slash is optional and ignored.
79 CZMQ_EXPORT zconfig_t *
80 zconfig_locate (zconfig_t *self, const char *path);
81
82 // Locate the last config item at a specified depth
83 CZMQ_EXPORT zconfig_t *
84 zconfig_at_depth (zconfig_t *self, int level);
85
86 // Execute a callback for each config item in the tree; returns zero if
87 // successful, else -1.
88 CZMQ_EXPORT int
89 zconfig_execute (zconfig_t *self, zconfig_fct handler, void *arg);
90
91 // Add comment to config item before saving to disk. You can add as many
92 // comment lines as you like. If you use a null format, all comments are
93 // deleted.
94 CZMQ_EXPORT void
95 zconfig_set_comment (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2);
96
97 // Return comments of config item, as zlist.
98 CZMQ_EXPORT zlist_t *
99 zconfig_comments (zconfig_t *self);
100
101 // Save a config tree to a specified ZPL text file, where a filename
102 // "-" means dump to standard output.
103 CZMQ_EXPORT int
104 zconfig_save (zconfig_t *self, const char *filename);
105
106 // Equivalent to zconfig_save, taking a format string instead of a fixed
107 // filename.
108 CZMQ_EXPORT int
109 zconfig_savef (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2);
110
111 // Report filename used during zconfig_load, or NULL if none
112 CZMQ_EXPORT const char *
113 zconfig_filename (zconfig_t *self);
114
115 // Reload config tree from same file that it was previously loaded from.
116 // Returns 0 if OK, -1 if there was an error (and then does not change
117 // existing data).
118 CZMQ_EXPORT int
119 zconfig_reload (zconfig_t **self_p);
120
121 // Load a config tree from a memory chunk
122 CZMQ_EXPORT zconfig_t *
123 zconfig_chunk_load (zchunk_t *chunk);
124
125 // Save a config tree to a new memory chunk
126 CZMQ_EXPORT zchunk_t *
127 zconfig_chunk_save (zconfig_t *self);
128
129 // Load a config tree from a null-terminated string
130 // Caller owns return value and must destroy it when done.
131 CZMQ_EXPORT zconfig_t *
132 zconfig_str_load (const char *string);
133
134 // Save a config tree to a new null terminated string
135 // Caller owns return value and must destroy it when done.
136 CZMQ_EXPORT char *
137 zconfig_str_save (zconfig_t *self);
138
139 // Return true if a configuration tree was loaded from a file and that
140 // file has changed in since the tree was loaded.
141 CZMQ_EXPORT bool
142 zconfig_has_changed (zconfig_t *self);
143
144 // Print the config file to open stream
145 CZMQ_EXPORT void
146 zconfig_fprint (zconfig_t *self, FILE *file);
147
148 // Print properties of object
149 CZMQ_EXPORT void
150 zconfig_print (zconfig_t *self);
151
152 // Self test of this class
153 CZMQ_EXPORT void
154 zconfig_test (bool verbose);
155
156 #ifdef CZMQ_BUILD_DRAFT_API
157 // *** Draft method, for development use, may change without warning ***
158 // Create copy of zconfig, caller MUST free the value
159 // Create copy of config, as new zconfig object. Returns a fresh zconfig_t
160 // object. If config is null, or memory was exhausted, returns null.
161 // Caller owns return value and must destroy it when done.
162 CZMQ_EXPORT zconfig_t *
163 zconfig_dup (zconfig_t *self);
164
165 // *** Draft method, for development use, may change without warning ***
166 // Destroy subtree (all children)
167 CZMQ_EXPORT void
168 zconfig_remove_subtree (zconfig_t *self);
169
170 // *** Draft method, for development use, may change without warning ***
171 // Destroy node and subtree (all children)
172 CZMQ_EXPORT void
173 zconfig_remove (zconfig_t **self_p);
174
175 #endif // CZMQ_BUILD_DRAFT_API
176 Please add '@interface' section in './../src/zconfig.c'.
177
179 Lets applications load, work with, and save configuration files. This
180 implements rfc.zeromq.org/spec:4/ZPL, which is a simple structured text
181 format for configuration files.
182
183 Here is an example ZPL stream and corresponding config structure:
184
185 context
186 iothreads = 1
187 verbose = 1 # Ask for a trace
188 main
189 type = zqueue # ZMQ_DEVICE type
190 frontend
191 option
192 hwm = 1000
193 swap = 25000000 # 25MB
194 bind = 'inproc://addr1'
195 bind = 'ipc://addr2'
196 backend
197 bind = inproc://addr3
198
199 root Down = child
200 | Across = next
201 v
202 context-->main
203 | |
204 | v
205 | type=queue-->frontend-->backend
206 | | |
207 | | v
208 | | bind=inproc://addr3
209 | v
210 | option-->bind=inproc://addr1-->bind=ipc://addr2
211 | |
212 | v
213 | hwm=1000-->swap=25000000
214 v
215 iothreads=1-->verbose=false
216
218 From zconfig_test method.
219
220 const char *SELFTEST_DIR_RW = "src/selftest-rw";
221
222 const char *testbasedir = ".test_zconfig";
223 const char *testfile = "test.cfg";
224 char *basedirpath = NULL; // subdir in a test, under SELFTEST_DIR_RW
225 char *filepath = NULL; // pathname to testfile in a test, in dirpath
226
227 basedirpath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, testbasedir);
228 assert (basedirpath);
229 filepath = zsys_sprintf ("%s/%s", basedirpath, testfile);
230 assert (filepath);
231
232 // Make sure old aborted tests do not hinder us
233 zdir_t *dir = zdir_new (basedirpath, NULL);
234 if (dir) {
235 zdir_remove (dir, true);
236 zdir_destroy (&dir);
237 }
238 zsys_file_delete (filepath);
239 zsys_dir_delete (basedirpath);
240
241 // Create temporary directory for test files
242 zsys_dir_create (basedirpath);
243
244 zconfig_t *root = zconfig_new ("root", NULL);
245 assert (root);
246 zconfig_t *section, *item;
247
248 section = zconfig_new ("headers", root);
249 assert (section);
250 item = zconfig_new ("email", section);
251 assert (item);
252 zconfig_set_value (item, "some@random.com");
253 item = zconfig_new ("name", section);
254 assert (item);
255 zconfig_set_value (item, "Justin Kayce");
256 zconfig_putf (root, "/curve/secret-key", "%s", "Top Secret");
257 zconfig_set_comment (root, " CURVE certificate");
258 zconfig_set_comment (root, " -----------------");
259 assert (zconfig_comments (root));
260 zconfig_save (root, filepath);
261 zconfig_destroy (&root);
262 root = zconfig_load (filepath);
263 if (verbose)
264 zconfig_save (root, "-");
265 assert (streq (zconfig_filename (root), filepath));
266
267 char *email = zconfig_get (root, "/headers/email", NULL);
268 assert (email);
269 assert (streq (email, "some@random.com"));
270 char *passwd = zconfig_get (root, "/curve/secret-key", NULL);
271 assert (passwd);
272 assert (streq (passwd, "Top Secret"));
273
274 zconfig_savef (root, "%s/%s", basedirpath, testfile);
275 assert (!zconfig_has_changed (root));
276 int rc = zconfig_reload (&root);
277 assert (rc == 0);
278 assert (!zconfig_has_changed (root));
279 zconfig_destroy (&root);
280
281 // Test chunk load/save
282 root = zconfig_new ("root", NULL);
283 assert (root);
284 section = zconfig_new ("section", root);
285 assert (section);
286 item = zconfig_new ("value", section);
287 assert (item);
288 zconfig_set_value (item, "somevalue");
289 zconfig_t *search = zconfig_locate (root, "section/value");
290 assert (search == item);
291 zchunk_t *chunk = zconfig_chunk_save (root);
292 assert (strlen ((char *) zchunk_data (chunk)) == 32);
293 char *string = zconfig_str_save (root);
294 assert (string);
295 assert (streq (string, (char *) zchunk_data (chunk)));
296 freen (string);
297 assert (chunk);
298 zconfig_destroy (&root);
299
300 root = zconfig_chunk_load (chunk);
301 assert (root);
302 char *value = zconfig_get (root, "/section/value", NULL);
303 assert (value);
304 assert (streq (value, "somevalue"));
305
306 // Test config can't be saved to a file in a path that doesn't
307 // exist or isn't writable
308 rc = zconfig_savef (root, "%s/path/that/doesnt/exist/%s", basedirpath, testfile);
309 assert (rc == -1);
310
311 zconfig_destroy (&root);
312 zchunk_destroy (&chunk);
313
314 // Test str_load
315 zconfig_t *config = zconfig_str_load (
316 "malamute\n"
317 " endpoint = ipc://@/malamute\n"
318 " producer = STREAM\n"
319 " consumer\n"
320 " STREAM2 = .*\n"
321 " STREAM3 = HAM\n"
322 "server\n"
323 " verbose = true\n"
324 );
325 assert (config);
326 assert (streq (zconfig_get (config, "malamute/endpoint", NULL), "ipc://@/malamute"));
327 assert (streq (zconfig_get (config, "malamute/producer", NULL), "STREAM"));
328 assert (zconfig_locate (config, "malamute/consumer"));
329
330 zconfig_t *c = zconfig_child (zconfig_locate (config, "malamute/consumer"));
331 assert (c);
332 assert (streq (zconfig_name (c), "STREAM2"));
333 assert (streq (zconfig_value (c), ".*"));
334
335 c = zconfig_next (c);
336 assert (c);
337 assert (streq (zconfig_name (c), "STREAM3"));
338 assert (streq (zconfig_value (c), "HAM"));
339
340 c = zconfig_next (c);
341 assert (!c);
342
343 assert (streq (zconfig_get (config, "server/verbose", NULL), "true"));
344
345 zconfig_t *dup = zconfig_dup (config);
346 assert (dup);
347 assert (streq (zconfig_get (dup, "server/verbose", NULL), "true"));
348 zconfig_destroy (&dup);
349
350 zconfig_destroy (&config);
351
352 // Test subtree removal
353 {
354 zconfig_t *root = zconfig_str_load (
355 "context\n"
356 " iothreads = 1\n"
357 " verbose = 1 # Ask for a trace\n"
358 "main\n"
359 " type = zqueue # ZMQ_DEVICE type\n"
360 " frontend\n"
361 " option\n"
362 " hwm = 1000\n"
363 " swap = 25000000 # 25MB\n"
364 " bind = 'inproc://addr1'\n"
365 " bind = 'ipc://addr2'\n"
366 " backend\n"
367 " bind = inproc://addr3\n"
368 );
369
370 // no subtree
371 zconfig_t *to_delete = zconfig_locate (root, "context/iothreads");
372 assert (to_delete);
373
374 zconfig_remove_subtree (to_delete);
375
376 zconfig_t *check = zconfig_locate (root, "context/iothreads");
377 assert (check);
378 assert (streq (zconfig_value (check), "1"));
379
380 check = zconfig_locate (root, "context/verbose");
381 assert (check);
382 assert (streq (zconfig_value (check), "1"));
383
384 // existing subtree
385 to_delete = zconfig_locate (root, "main/frontend/option");
386 assert (to_delete);
387
388 zconfig_remove_subtree (to_delete);
389
390 check = zconfig_locate (root, "main/frontend/option/hwm");
391 assert (check == NULL);
392 check = zconfig_locate (root, "main/frontend/option/swap");
393 assert (check == NULL);
394 check = zconfig_locate (root, "main/frontend/option");
395 assert (check);
396 assert (streq (zconfig_value (check), ""));
397 check = zconfig_next (check);
398 assert (check);
399 assert (streq (zconfig_name (check), "bind"));
400 assert (streq (zconfig_value (check), "inproc://addr1"));
401 check = zconfig_next (check);
402 assert (check);
403 assert (streq (zconfig_name (check), "bind"));
404 assert (streq (zconfig_value (check), "ipc://addr2"));
405 assert (zconfig_next (check) == NULL);
406
407 to_delete = zconfig_locate (root, "main/frontend");
408 assert (to_delete);
409
410 zconfig_remove_subtree (to_delete);
411
412 check = zconfig_locate (root, "main/frontend/option/hwm");
413 assert (check == NULL);
414 check = zconfig_locate (root, "main/frontend/option/swap");
415 assert (check == NULL);
416 check = zconfig_locate (root, "main/frontend/option");
417 assert (check == NULL);
418 check = zconfig_locate (root, "main/frontend/bind");
419 assert (check == NULL);
420 check = zconfig_locate (root, "main/frontend");
421 assert (check);
422 assert (streq (zconfig_value (check), ""));
423 assert (zconfig_child (check) == NULL);
424 check = zconfig_next (check);
425 assert (check);
426 assert (streq (zconfig_name (check), "backend"));
427 assert (streq (zconfig_value (check), ""));
428
429 to_delete = zconfig_locate (root, "main");
430 assert (to_delete);
431
432 zconfig_remove_subtree (to_delete);
433
434 check = zconfig_locate (root, "main/type");
435 assert (check == NULL);
436 check = zconfig_locate (root, "main/frontend");
437 assert (check == NULL);
438 check = zconfig_locate (root, "main/backend");
439 assert (check == NULL);
440 check = zconfig_locate (root, "main");
441 assert (check);
442
443 // root
444 zconfig_remove_subtree (root);
445
446 assert (root);
447 assert (zconfig_child (root) == NULL);
448 check = zconfig_locate (root, "main");
449 assert (check == NULL);
450 check = zconfig_locate (root, "context");
451 assert (check == NULL);
452
453 zconfig_destroy (&root);
454 }
455
456 // Test node and subtree removal
457 {
458 zconfig_t *root = zconfig_str_load (
459 "A1 = abc\n"
460 " x\n"
461 " 1\n"
462 " 2\n"
463 " y = 1 # Ask for a trace\n"
464 "A2\n"
465 " B1 = zqueue # ZMQ_DEVICE type\n"
466 " B2\n"
467 " C1\n"
468 " hwm = 1000\n"
469 " swap = 25000000 # 25MB\n"
470 " C2 = 50\n"
471 " C3\n"
472 " bind = addr3\n"
473 " B3\n"
474 " bind = inproc://addr4\n"
475 " B4 = Ignac\n"
476 " z = 5\n"
477 "A3\n"
478 "A4\n"
479 );
480
481 zconfig_t *to_delete = zconfig_locate (root, "A2/B2/C3");
482 assert (to_delete);
483
484 zconfig_remove (&to_delete);
485
486 zconfig_t *check = zconfig_locate (root, "A2/B2/C2");
487 assert (check);
488 assert (streq (zconfig_value (check), "50"));
489 assert (zconfig_next (check) == NULL);
490 assert (zconfig_locate (root, "A2/B2/C3/bind") == NULL);
491 assert (zconfig_locate (root, "A2/B2/C3") == NULL);
492
493 to_delete = zconfig_locate (root, "A2/B2");
494 assert (to_delete);
495
496 zconfig_remove (&to_delete);
497
498 check = zconfig_locate (root, "A2");
499 assert (check);
500 check = zconfig_child (check);
501 assert (check);
502 assert (streq (zconfig_name (check), "B1"));
503 assert (streq (zconfig_value (check), "zqueue"));
504 check = zconfig_next (check);
505 assert (check);
506 assert (streq (zconfig_name (check), "B3"));
507 assert (streq (zconfig_value (check), ""));
508 assert (zconfig_locate (root, "A2/B2/C1") == NULL);
509 assert (zconfig_locate (root, "A2/B2/C2") == NULL);
510 assert (zconfig_locate (root, "A2/B2") == NULL);
511 assert (zconfig_locate (root, "A2/B4"));
512
513 to_delete = zconfig_locate (root, "A2/B1");
514 assert (to_delete);
515
516 zconfig_remove (&to_delete);
517
518 check = zconfig_locate (root, "A2");
519 assert (check);
520 check = zconfig_child (check);
521 assert (check);
522 assert (streq (zconfig_name (check), "B3"));
523 assert (streq (zconfig_value (check), ""));
524 check = zconfig_next (check);
525 assert (check);
526 assert (streq (zconfig_name (check), "B4"));
527 assert (streq (zconfig_value (check), "Ignac"));
528 assert (zconfig_next (check) == NULL);
529 assert (zconfig_locate (root, "A2/B1") == NULL);
530 assert (zconfig_locate (root, "A2/B2") == NULL);
531
532 to_delete = zconfig_locate (root, "A2/B3");
533 assert (to_delete);
534
535 zconfig_remove (&to_delete);
536
537 check = zconfig_locate (root, "A2");
538 assert (check);
539 check = zconfig_child (check);
540 assert (check);
541 assert (streq (zconfig_name (check), "B4"));
542 assert (streq (zconfig_value (check), "Ignac"));
543 assert (zconfig_next (check) == NULL);
544
545 to_delete = zconfig_locate (root, "A2");
546 assert (to_delete);
547
548 zconfig_remove (&to_delete);
549
550 check = zconfig_locate (root, "A1");
551 assert (check);
552 check = zconfig_next (check);
553 assert (check);
554 assert (streq (zconfig_name (check), "A3"));
555 assert (zconfig_locate (root, "A2/B4") == NULL);
556 assert (zconfig_locate (root, "A2") == NULL);
557
558 to_delete = zconfig_locate (root, "A1");
559 assert (to_delete);
560
561 zconfig_remove (&to_delete);
562
563 check = zconfig_child (root);
564 assert (check);
565 assert (streq (zconfig_name (check), "A3"));
566 assert (zconfig_locate (root, "A1/x/1") == NULL);
567 assert (zconfig_locate (root, "A1/x") == NULL);
568 assert (zconfig_locate (root, "A1/y") == NULL);
569 assert (zconfig_locate (root, "A3"));
570 assert (zconfig_locate (root, "A4"));
571
572 // called on root should be equivalent to zconfig_destroy (&root)
573 zconfig_remove (&root);
574 }
575
576 // Delete all test files
577 dir = zdir_new (basedirpath, NULL);
578 assert (dir);
579 zdir_remove (dir, true);
580 zdir_destroy (&dir);
581
582 zstr_free (&basedirpath);
583 zstr_free (&filepath);
584
585 #if defined (__WINDOWS__)
586 zsys_shutdown();
587 #endif
588
589
591 The czmq manual was written by the authors in the AUTHORS file.
592
594 Main web site:
595
596 Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>
597
599 Copyright (c) the Contributors as noted in the AUTHORS file. This file
600 is part of CZMQ, the high-level C binding for 0MQ:
601 http://czmq.zeromq.org. This Source Code Form is subject to the terms
602 of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
603 distributed with this file, You can obtain one at
604 http://mozilla.org/MPL/2.0/. LICENSE included with the czmq
605 distribution.
606
608 1. zeromq-dev@lists.zeromq.org
609 mailto:zeromq-dev@lists.zeromq.org
610
611
612
613CZMQ 4.2.1 07/19/2023 ZCONFIG(3)