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 // Destroy subtree (all children)
159 CZMQ_EXPORT void
160 zconfig_remove_subtree (zconfig_t *self);
161
162 // *** Draft method, for development use, may change without warning ***
163 // Destroy node and subtree (all children)
164 CZMQ_EXPORT void
165 zconfig_remove (zconfig_t **self_p);
166
167 #endif // CZMQ_BUILD_DRAFT_API
168 Please add '@interface' section in './../src/zconfig.c'.
169
171 Lets applications load, work with, and save configuration files. This
172 implements rfc.zeromq.org/spec:4/ZPL, which is a simple structured text
173 format for configuration files.
174
175 Here is an example ZPL stream and corresponding config structure:
176
177 context
178 iothreads = 1
179 verbose = 1 # Ask for a trace
180 main
181 type = zqueue # ZMQ_DEVICE type
182 frontend
183 option
184 hwm = 1000
185 swap = 25000000 # 25MB
186 bind = 'inproc://addr1'
187 bind = 'ipc://addr2'
188 backend
189 bind = inproc://addr3
190
191 root Down = child
192 | Across = next
193 v
194 context-->main
195 | |
196 | v
197 | type=queue-->frontend-->backend
198 | | |
199 | | v
200 | | bind=inproc://addr3
201 | v
202 | option-->bind=inproc://addr1-->bind=ipc://addr2
203 | |
204 | v
205 | hwm=1000-->swap=25000000
206 v
207 iothreads=1-->verbose=false
208
210 From zconfig_test method.
211
212 const char *SELFTEST_DIR_RW = "src/selftest-rw";
213
214 const char *testbasedir = ".test_zconfig";
215 const char *testfile = "test.cfg";
216 char *basedirpath = NULL; // subdir in a test, under SELFTEST_DIR_RW
217 char *filepath = NULL; // pathname to testfile in a test, in dirpath
218
219 basedirpath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, testbasedir);
220 assert (basedirpath);
221 filepath = zsys_sprintf ("%s/%s", basedirpath, testfile);
222 assert (filepath);
223
224 // Make sure old aborted tests do not hinder us
225 zdir_t *dir = zdir_new (basedirpath, NULL);
226 if (dir) {
227 zdir_remove (dir, true);
228 zdir_destroy (&dir);
229 }
230 zsys_file_delete (filepath);
231 zsys_dir_delete (basedirpath);
232
233 // Create temporary directory for test files
234 zsys_dir_create (basedirpath);
235
236 zconfig_t *root = zconfig_new ("root", NULL);
237 assert (root);
238 zconfig_t *section, *item;
239
240 section = zconfig_new ("headers", root);
241 assert (section);
242 item = zconfig_new ("email", section);
243 assert (item);
244 zconfig_set_value (item, "some@random.com");
245 item = zconfig_new ("name", section);
246 assert (item);
247 zconfig_set_value (item, "Justin Kayce");
248 zconfig_putf (root, "/curve/secret-key", "%s", "Top Secret");
249 zconfig_set_comment (root, " CURVE certificate");
250 zconfig_set_comment (root, " -----------------");
251 assert (zconfig_comments (root));
252 zconfig_save (root, filepath);
253 zconfig_destroy (&root);
254 root = zconfig_load (filepath);
255 if (verbose)
256 zconfig_save (root, "-");
257 assert (streq (zconfig_filename (root), filepath));
258
259 char *email = zconfig_get (root, "/headers/email", NULL);
260 assert (email);
261 assert (streq (email, "some@random.com"));
262 char *passwd = zconfig_get (root, "/curve/secret-key", NULL);
263 assert (passwd);
264 assert (streq (passwd, "Top Secret"));
265
266 zconfig_savef (root, "%s/%s", basedirpath, testfile);
267 assert (!zconfig_has_changed (root));
268 int rc = zconfig_reload (&root);
269 assert (rc == 0);
270 assert (!zconfig_has_changed (root));
271 zconfig_destroy (&root);
272
273 // Test chunk load/save
274 root = zconfig_new ("root", NULL);
275 assert (root);
276 section = zconfig_new ("section", root);
277 assert (section);
278 item = zconfig_new ("value", section);
279 assert (item);
280 zconfig_set_value (item, "somevalue");
281 zconfig_t *search = zconfig_locate (root, "section/value");
282 assert (search == item);
283 zchunk_t *chunk = zconfig_chunk_save (root);
284 assert (strlen ((char *) zchunk_data (chunk)) == 32);
285 char *string = zconfig_str_save (root);
286 assert (string);
287 assert (streq (string, (char *) zchunk_data (chunk)));
288 freen (string);
289 assert (chunk);
290 zconfig_destroy (&root);
291
292 root = zconfig_chunk_load (chunk);
293 assert (root);
294 char *value = zconfig_get (root, "/section/value", NULL);
295 assert (value);
296 assert (streq (value, "somevalue"));
297
298 // Test config can't be saved to a file in a path that doesn't
299 // exist or isn't writable
300 rc = zconfig_savef (root, "%s/path/that/doesnt/exist/%s", basedirpath, testfile);
301 assert (rc == -1);
302
303 zconfig_destroy (&root);
304 zchunk_destroy (&chunk);
305
306 // Test str_load
307 zconfig_t *config = zconfig_str_load (
308 "malamute\n"
309 " endpoint = ipc://@/malamute\n"
310 " producer = STREAM\n"
311 " consumer\n"
312 " STREAM2 = .*\n"
313 " STREAM3 = HAM\n"
314 "server\n"
315 " verbose = true\n"
316 );
317 assert (config);
318 assert (streq (zconfig_get (config, "malamute/endpoint", NULL), "ipc://@/malamute"));
319 assert (streq (zconfig_get (config, "malamute/producer", NULL), "STREAM"));
320 assert (zconfig_locate (config, "malamute/consumer"));
321
322 zconfig_t *c = zconfig_child (zconfig_locate (config, "malamute/consumer"));
323 assert (c);
324 assert (streq (zconfig_name (c), "STREAM2"));
325 assert (streq (zconfig_value (c), ".*"));
326
327 c = zconfig_next (c);
328 assert (c);
329 assert (streq (zconfig_name (c), "STREAM3"));
330 assert (streq (zconfig_value (c), "HAM"));
331
332 c = zconfig_next (c);
333 assert (!c);
334
335 assert (streq (zconfig_get (config, "server/verbose", NULL), "true"));
336
337 zconfig_destroy (&config);
338
339 // Test subtree removal
340 {
341 zconfig_t *root = zconfig_str_load (
342 "context\n"
343 " iothreads = 1\n"
344 " verbose = 1 # Ask for a trace\n"
345 "main\n"
346 " type = zqueue # ZMQ_DEVICE type\n"
347 " frontend\n"
348 " option\n"
349 " hwm = 1000\n"
350 " swap = 25000000 # 25MB\n"
351 " bind = 'inproc://addr1'\n"
352 " bind = 'ipc://addr2'\n"
353 " backend\n"
354 " bind = inproc://addr3\n"
355 );
356
357 // no subtree
358 zconfig_t *to_delete = zconfig_locate (root, "context/iothreads");
359 assert (to_delete);
360
361 zconfig_remove_subtree (to_delete);
362
363 zconfig_t *check = zconfig_locate (root, "context/iothreads");
364 assert (check);
365 assert (streq (zconfig_value (check), "1"));
366
367 check = zconfig_locate (root, "context/verbose");
368 assert (check);
369 assert (streq (zconfig_value (check), "1"));
370
371 // existing subtree
372 to_delete = zconfig_locate (root, "main/frontend/option");
373 assert (to_delete);
374
375 zconfig_remove_subtree (to_delete);
376
377 check = zconfig_locate (root, "main/frontend/option/hwm");
378 assert (check == NULL);
379 check = zconfig_locate (root, "main/frontend/option/swap");
380 assert (check == NULL);
381 check = zconfig_locate (root, "main/frontend/option");
382 assert (check);
383 assert (streq (zconfig_value (check), ""));
384 check = zconfig_next (check);
385 assert (check);
386 assert (streq (zconfig_name (check), "bind"));
387 assert (streq (zconfig_value (check), "inproc://addr1"));
388 check = zconfig_next (check);
389 assert (check);
390 assert (streq (zconfig_name (check), "bind"));
391 assert (streq (zconfig_value (check), "ipc://addr2"));
392 assert (zconfig_next (check) == NULL);
393
394 to_delete = zconfig_locate (root, "main/frontend");
395 assert (to_delete);
396
397 zconfig_remove_subtree (to_delete);
398
399 check = zconfig_locate (root, "main/frontend/option/hwm");
400 assert (check == NULL);
401 check = zconfig_locate (root, "main/frontend/option/swap");
402 assert (check == NULL);
403 check = zconfig_locate (root, "main/frontend/option");
404 assert (check == NULL);
405 check = zconfig_locate (root, "main/frontend/bind");
406 assert (check == NULL);
407 check = zconfig_locate (root, "main/frontend");
408 assert (check);
409 assert (streq (zconfig_value (check), ""));
410 assert (zconfig_child (check) == NULL);
411 check = zconfig_next (check);
412 assert (check);
413 assert (streq (zconfig_name (check), "backend"));
414 assert (streq (zconfig_value (check), ""));
415
416 to_delete = zconfig_locate (root, "main");
417 assert (to_delete);
418
419 zconfig_remove_subtree (to_delete);
420
421 check = zconfig_locate (root, "main/type");
422 assert (check == NULL);
423 check = zconfig_locate (root, "main/frontend");
424 assert (check == NULL);
425 check = zconfig_locate (root, "main/backend");
426 assert (check == NULL);
427 check = zconfig_locate (root, "main");
428 assert (check);
429
430 // root
431 zconfig_remove_subtree (root);
432
433 assert (root);
434 assert (zconfig_child (root) == NULL);
435 check = zconfig_locate (root, "main");
436 assert (check == NULL);
437 check = zconfig_locate (root, "context");
438 assert (check == NULL);
439
440 zconfig_destroy (&root);
441 }
442
443 // Test node and subtree removal
444 {
445 zconfig_t *root = zconfig_str_load (
446 "A1 = abc\n"
447 " x\n"
448 " 1\n"
449 " 2\n"
450 " y = 1 # Ask for a trace\n"
451 "A2\n"
452 " B1 = zqueue # ZMQ_DEVICE type\n"
453 " B2\n"
454 " C1\n"
455 " hwm = 1000\n"
456 " swap = 25000000 # 25MB\n"
457 " C2 = 50\n"
458 " C3\n"
459 " bind = addr3\n"
460 " B3\n"
461 " bind = inproc://addr4\n"
462 " B4 = Ignac\n"
463 " z = 5\n"
464 "A3\n"
465 "A4\n"
466 );
467
468 zconfig_t *to_delete = zconfig_locate (root, "A2/B2/C3");
469 assert (to_delete);
470
471 zconfig_remove (&to_delete);
472
473 zconfig_t *check = zconfig_locate (root, "A2/B2/C2");
474 assert (check);
475 assert (streq (zconfig_value (check), "50"));
476 assert (zconfig_next (check) == NULL);
477 assert (zconfig_locate (root, "A2/B2/C3/bind") == NULL);
478 assert (zconfig_locate (root, "A2/B2/C3") == NULL);
479
480 to_delete = zconfig_locate (root, "A2/B2");
481 assert (to_delete);
482
483 zconfig_remove (&to_delete);
484
485 check = zconfig_locate (root, "A2");
486 assert (check);
487 check = zconfig_child (check);
488 assert (check);
489 assert (streq (zconfig_name (check), "B1"));
490 assert (streq (zconfig_value (check), "zqueue"));
491 check = zconfig_next (check);
492 assert (check);
493 assert (streq (zconfig_name (check), "B3"));
494 assert (streq (zconfig_value (check), ""));
495 assert (zconfig_locate (root, "A2/B2/C1") == NULL);
496 assert (zconfig_locate (root, "A2/B2/C2") == NULL);
497 assert (zconfig_locate (root, "A2/B2") == NULL);
498 assert (zconfig_locate (root, "A2/B4"));
499
500 to_delete = zconfig_locate (root, "A2/B1");
501 assert (to_delete);
502
503 zconfig_remove (&to_delete);
504
505 check = zconfig_locate (root, "A2");
506 assert (check);
507 check = zconfig_child (check);
508 assert (check);
509 assert (streq (zconfig_name (check), "B3"));
510 assert (streq (zconfig_value (check), ""));
511 check = zconfig_next (check);
512 assert (check);
513 assert (streq (zconfig_name (check), "B4"));
514 assert (streq (zconfig_value (check), "Ignac"));
515 assert (zconfig_next (check) == NULL);
516 assert (zconfig_locate (root, "A2/B1") == NULL);
517 assert (zconfig_locate (root, "A2/B2") == NULL);
518
519 to_delete = zconfig_locate (root, "A2/B3");
520 assert (to_delete);
521
522 zconfig_remove (&to_delete);
523
524 check = zconfig_locate (root, "A2");
525 assert (check);
526 check = zconfig_child (check);
527 assert (check);
528 assert (streq (zconfig_name (check), "B4"));
529 assert (streq (zconfig_value (check), "Ignac"));
530 assert (zconfig_next (check) == NULL);
531
532 to_delete = zconfig_locate (root, "A2");
533 assert (to_delete);
534
535 zconfig_remove (&to_delete);
536
537 check = zconfig_locate (root, "A1");
538 assert (check);
539 check = zconfig_next (check);
540 assert (check);
541 assert (streq (zconfig_name (check), "A3"));
542 assert (zconfig_locate (root, "A2/B4") == NULL);
543 assert (zconfig_locate (root, "A2") == NULL);
544
545 to_delete = zconfig_locate (root, "A1");
546 assert (to_delete);
547
548 zconfig_remove (&to_delete);
549
550 check = zconfig_child (root);
551 assert (check);
552 assert (streq (zconfig_name (check), "A3"));
553 assert (zconfig_locate (root, "A1/x/1") == NULL);
554 assert (zconfig_locate (root, "A1/x") == NULL);
555 assert (zconfig_locate (root, "A1/y") == NULL);
556 assert (zconfig_locate (root, "A3"));
557 assert (zconfig_locate (root, "A4"));
558
559 // called on root should be equivalent to zconfig_destroy (&root)
560 zconfig_remove (&root);
561 }
562
563 // Delete all test files
564 dir = zdir_new (basedirpath, NULL);
565 assert (dir);
566 zdir_remove (dir, true);
567 zdir_destroy (&dir);
568
569 zstr_free (&basedirpath);
570 zstr_free (&filepath);
571
572 #if defined (__WINDOWS__)
573 zsys_shutdown();
574 #endif
575
576
578 The czmq manual was written by the authors in the AUTHORS file.
579
581 Main web site:
582
583 Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>
584
586 Copyright (c) the Contributors as noted in the AUTHORS file. This file
587 is part of CZMQ, the high-level C binding for 0MQ:
588 http://czmq.zeromq.org. This Source Code Form is subject to the terms
589 of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
590 distributed with this file, You can obtain one at
591 http://mozilla.org/MPL/2.0/. LICENSE included with the czmq
592 distribution.
593
595 1. zeromq-dev@lists.zeromq.org
596 mailto:zeromq-dev@lists.zeromq.org
597
598
599
600CZMQ 4.1.1 01/31/2019 ZCONFIG(3)