Provided by: libczmq-dev_4.2.1-1_amd64 bug

NAME

       zconfig - Class for work with config files written in rfc.zeromq.org/spec:4/ZPL.

SYNOPSIS

       //  This is a stable class, and may not change except for emergencies. It
       //  is provided in stable builds.
       //  This class has draft methods, which may change over time. They are not
       //  in stable releases, by default. Use --enable-drafts to enable.
       //
       typedef int (zconfig_fct) (
           zconfig_t *self, void *arg, int level);

       //  Create new config item
       CZMQ_EXPORT zconfig_t *
           zconfig_new (const char *name, zconfig_t *parent);

       //  Load a config tree from a specified ZPL text file; returns a zconfig_t
       //  reference for the root, if the file exists and is readable. Returns NULL
       //  if the file does not exist.
       CZMQ_EXPORT zconfig_t *
           zconfig_load (const char *filename);

       //  Equivalent to zconfig_load, taking a format string instead of a fixed
       //  filename.
       CZMQ_EXPORT zconfig_t *
           zconfig_loadf (const char *format, ...) CHECK_PRINTF (1);

       //  Destroy a config item and all its children
       CZMQ_EXPORT void
           zconfig_destroy (zconfig_t **self_p);

       //  Return name of config item
       CZMQ_EXPORT char *
           zconfig_name (zconfig_t *self);

       //  Return value of config item
       CZMQ_EXPORT char *
           zconfig_value (zconfig_t *self);

       //  Insert or update configuration key with value
       CZMQ_EXPORT void
           zconfig_put (zconfig_t *self, const char *path, const char *value);

       //  Equivalent to zconfig_put, accepting a format specifier and variable
       //  argument list, instead of a single string value.
       CZMQ_EXPORT void
           zconfig_putf (zconfig_t *self, const char *path, const char *format, ...) CHECK_PRINTF (3);

       //  Get value for config item into a string value; leading slash is optional
       //  and ignored.
       CZMQ_EXPORT char *
           zconfig_get (zconfig_t *self, const char *path, const char *default_value);

       //  Set config item name, name may be NULL
       CZMQ_EXPORT void
           zconfig_set_name (zconfig_t *self, const char *name);

       //  Set new value for config item. The new value may be a string, a printf
       //  format, or NULL. Note that if string may possibly contain '%', or if it
       //  comes from an insecure source, you must use '%s' as the format, followed
       //  by the string.
       CZMQ_EXPORT void
           zconfig_set_value (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2);

       //  Find our first child, if any
       CZMQ_EXPORT zconfig_t *
           zconfig_child (zconfig_t *self);

       //  Find our first sibling, if any
       CZMQ_EXPORT zconfig_t *
           zconfig_next (zconfig_t *self);

       //  Find a config item along a path; leading slash is optional and ignored.
       CZMQ_EXPORT zconfig_t *
           zconfig_locate (zconfig_t *self, const char *path);

       //  Locate the last config item at a specified depth
       CZMQ_EXPORT zconfig_t *
           zconfig_at_depth (zconfig_t *self, int level);

       //  Execute a callback for each config item in the tree; returns zero if
       //  successful, else -1.
       CZMQ_EXPORT int
           zconfig_execute (zconfig_t *self, zconfig_fct handler, void *arg);

       //  Add comment to config item before saving to disk. You can add as many
       //  comment lines as you like. If you use a null format, all comments are
       //  deleted.
       CZMQ_EXPORT void
           zconfig_set_comment (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2);

       //  Return comments of config item, as zlist.
       CZMQ_EXPORT zlist_t *
           zconfig_comments (zconfig_t *self);

       //  Save a config tree to a specified ZPL text file, where a filename
       //  "-" means dump to standard output.
       CZMQ_EXPORT int
           zconfig_save (zconfig_t *self, const char *filename);

       //  Equivalent to zconfig_save, taking a format string instead of a fixed
       //  filename.
       CZMQ_EXPORT int
           zconfig_savef (zconfig_t *self, const char *format, ...) CHECK_PRINTF (2);

       //  Report filename used during zconfig_load, or NULL if none
       CZMQ_EXPORT const char *
           zconfig_filename (zconfig_t *self);

       //  Reload config tree from same file that it was previously loaded from.
       //  Returns 0 if OK, -1 if there was an error (and then does not change
       //  existing data).
       CZMQ_EXPORT int
           zconfig_reload (zconfig_t **self_p);

       //  Load a config tree from a memory chunk
       CZMQ_EXPORT zconfig_t *
           zconfig_chunk_load (zchunk_t *chunk);

       //  Save a config tree to a new memory chunk
       CZMQ_EXPORT zchunk_t *
           zconfig_chunk_save (zconfig_t *self);

       //  Load a config tree from a null-terminated string
       //  Caller owns return value and must destroy it when done.
       CZMQ_EXPORT zconfig_t *
           zconfig_str_load (const char *string);

       //  Save a config tree to a new null terminated string
       //  Caller owns return value and must destroy it when done.
       CZMQ_EXPORT char *
           zconfig_str_save (zconfig_t *self);

       //  Return true if a configuration tree was loaded from a file and that
       //  file has changed in since the tree was loaded.
       CZMQ_EXPORT bool
           zconfig_has_changed (zconfig_t *self);

       //  Print the config file to open stream
       CZMQ_EXPORT void
           zconfig_fprint (zconfig_t *self, FILE *file);

       //  Print properties of object
       CZMQ_EXPORT void
           zconfig_print (zconfig_t *self);

       //  Self test of this class
       CZMQ_EXPORT void
           zconfig_test (bool verbose);

       #ifdef CZMQ_BUILD_DRAFT_API
       //  *** Draft method, for development use, may change without warning ***
       //  Create copy of zconfig, caller MUST free the value
       //  Create copy of config, as new zconfig object. Returns a fresh zconfig_t
       //  object. If config is null, or memory was exhausted, returns null.
       //  Caller owns return value and must destroy it when done.
       CZMQ_EXPORT zconfig_t *
           zconfig_dup (zconfig_t *self);

       //  *** Draft method, for development use, may change without warning ***
       //  Destroy subtree (all children)
       CZMQ_EXPORT void
           zconfig_remove_subtree (zconfig_t *self);

       //  *** Draft method, for development use, may change without warning ***
       //  Destroy node and subtree (all children)
       CZMQ_EXPORT void
           zconfig_remove (zconfig_t **self_p);

       #endif // CZMQ_BUILD_DRAFT_API
       Please add '@interface' section in './../src/zconfig.c'.

DESCRIPTION

       Lets applications load, work with, and save configuration files. This implements
       rfc.zeromq.org/spec:4/ZPL, which is a simple structured text format for configuration
       files.

       Here is an example ZPL stream and corresponding config structure:

           context
               iothreads = 1
               verbose = 1      #   Ask for a trace
           main
               type = zqueue    #  ZMQ_DEVICE type
               frontend
                   option
                       hwm = 1000
                       swap = 25000000     #  25MB
                   bind = 'inproc://addr1'
                   bind = 'ipc://addr2'
               backend
                   bind = inproc://addr3

           root                    Down = child
           |                     Across = next
           v
           context-->main
           |         |
           |         v
           |       type=queue-->frontend-->backend
           |                      |          |
           |                      |          v
           |                      |        bind=inproc://addr3
           |                      v
           |                    option-->bind=inproc://addr1-->bind=ipc://addr2
           |                      |
           |                      v
           |                    hwm=1000-->swap=25000000
           v
           iothreads=1-->verbose=false

EXAMPLE

       From zconfig_test method.

           const char *SELFTEST_DIR_RW = "src/selftest-rw";

           const char *testbasedir  = ".test_zconfig";
           const char *testfile = "test.cfg";
           char *basedirpath = NULL;   // subdir in a test, under SELFTEST_DIR_RW
           char *filepath = NULL;      // pathname to testfile in a test, in dirpath

           basedirpath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, testbasedir);
           assert (basedirpath);
           filepath = zsys_sprintf ("%s/%s", basedirpath, testfile);
           assert (filepath);

           // Make sure old aborted tests do not hinder us
           zdir_t *dir = zdir_new (basedirpath, NULL);
           if (dir) {
               zdir_remove (dir, true);
               zdir_destroy (&dir);
           }
           zsys_file_delete (filepath);
           zsys_dir_delete  (basedirpath);

           //  Create temporary directory for test files
           zsys_dir_create (basedirpath);

           zconfig_t *root = zconfig_new ("root", NULL);
           assert (root);
           zconfig_t *section, *item;

           section = zconfig_new ("headers", root);
           assert (section);
           item = zconfig_new ("email", section);
           assert (item);
           zconfig_set_value (item, "some@random.com");
           item = zconfig_new ("name", section);
           assert (item);
           zconfig_set_value (item, "Justin Kayce");
           zconfig_putf (root, "/curve/secret-key", "%s", "Top Secret");
           zconfig_set_comment (root, "   CURVE certificate");
           zconfig_set_comment (root, "   -----------------");
           assert (zconfig_comments (root));
           zconfig_save (root, filepath);
           zconfig_destroy (&root);
           root = zconfig_load (filepath);
           if (verbose)
               zconfig_save (root, "-");
           assert (streq (zconfig_filename (root), filepath));

           char *email = zconfig_get (root, "/headers/email", NULL);
           assert (email);
           assert (streq (email, "some@random.com"));
           char *passwd = zconfig_get (root, "/curve/secret-key", NULL);
           assert (passwd);
           assert (streq (passwd, "Top Secret"));

           zconfig_savef (root, "%s/%s", basedirpath, testfile);
           assert (!zconfig_has_changed (root));
           int rc = zconfig_reload (&root);
           assert (rc == 0);
           assert (!zconfig_has_changed (root));
           zconfig_destroy (&root);

           //  Test chunk load/save
           root = zconfig_new ("root", NULL);
           assert (root);
           section = zconfig_new ("section", root);
           assert (section);
           item = zconfig_new ("value", section);
           assert (item);
           zconfig_set_value (item, "somevalue");
           zconfig_t *search = zconfig_locate (root, "section/value");
           assert (search == item);
           zchunk_t *chunk = zconfig_chunk_save (root);
           assert (strlen ((char *) zchunk_data (chunk)) == 32);
           char *string = zconfig_str_save (root);
           assert (string);
           assert (streq (string, (char *) zchunk_data (chunk)));
           freen (string);
           assert (chunk);
           zconfig_destroy (&root);

           root = zconfig_chunk_load (chunk);
           assert (root);
           char *value = zconfig_get (root, "/section/value", NULL);
           assert (value);
           assert (streq (value, "somevalue"));

           //  Test config can't be saved to a file in a path that doesn't
           //  exist or isn't writable
           rc = zconfig_savef (root, "%s/path/that/doesnt/exist/%s", basedirpath, testfile);
           assert (rc == -1);

           zconfig_destroy (&root);
           zchunk_destroy (&chunk);

           // Test str_load
           zconfig_t *config = zconfig_str_load (
               "malamute\n"
               "    endpoint = ipc://@/malamute\n"
               "    producer = STREAM\n"
               "    consumer\n"
               "        STREAM2 = .*\n"
               "        STREAM3 = HAM\n"
               "server\n"
               "    verbose = true\n"
               );
           assert (config);
           assert (streq (zconfig_get (config, "malamute/endpoint", NULL), "ipc://@/malamute"));
           assert (streq (zconfig_get (config, "malamute/producer", NULL), "STREAM"));
           assert (zconfig_locate (config, "malamute/consumer"));

           zconfig_t *c = zconfig_child (zconfig_locate (config, "malamute/consumer"));
           assert (c);
           assert (streq (zconfig_name (c), "STREAM2"));
           assert (streq (zconfig_value (c), ".*"));

           c = zconfig_next (c);
           assert (c);
           assert (streq (zconfig_name (c), "STREAM3"));
           assert (streq (zconfig_value (c), "HAM"));

           c = zconfig_next (c);
           assert (!c);

           assert (streq (zconfig_get (config, "server/verbose", NULL), "true"));

           zconfig_t *dup = zconfig_dup (config);
           assert (dup);
           assert (streq (zconfig_get (dup, "server/verbose", NULL), "true"));
           zconfig_destroy (&dup);

           zconfig_destroy (&config);

           //  Test subtree removal
                   {
                           zconfig_t *root = zconfig_str_load (
                                   "context\n"
                                   "    iothreads = 1\n"
                                   "    verbose = 1      #   Ask for a trace\n"
                                   "main\n"
                                   "    type = zqueue    #  ZMQ_DEVICE type\n"
                                   "    frontend\n"
                                   "        option\n"
                                   "            hwm = 1000\n"
                                   "            swap = 25000000     #  25MB\n"
                                   "        bind = 'inproc://addr1'\n"
                                   "        bind = 'ipc://addr2'\n"
                                   "    backend\n"
                                   "        bind = inproc://addr3\n"
                           );

               //  no subtree
               zconfig_t *to_delete = zconfig_locate (root, "context/iothreads");
               assert (to_delete);

               zconfig_remove_subtree (to_delete);

               zconfig_t *check = zconfig_locate (root, "context/iothreads");
               assert (check);
               assert (streq (zconfig_value (check), "1"));

               check = zconfig_locate (root, "context/verbose");
               assert (check);
               assert (streq (zconfig_value (check), "1"));

               //  existing subtree
               to_delete = zconfig_locate (root, "main/frontend/option");
               assert (to_delete);

               zconfig_remove_subtree (to_delete);

               check = zconfig_locate (root, "main/frontend/option/hwm");
               assert (check == NULL);
               check = zconfig_locate (root, "main/frontend/option/swap");
               assert (check == NULL);
               check = zconfig_locate (root, "main/frontend/option");
               assert (check);
               assert (streq (zconfig_value (check), ""));
               check = zconfig_next (check);
               assert (check);
               assert (streq (zconfig_name (check), "bind"));
               assert (streq (zconfig_value (check), "inproc://addr1"));
               check = zconfig_next (check);
               assert (check);
               assert (streq (zconfig_name (check), "bind"));
               assert (streq (zconfig_value (check), "ipc://addr2"));
               assert (zconfig_next (check) == NULL);

               to_delete = zconfig_locate (root, "main/frontend");
               assert (to_delete);

               zconfig_remove_subtree (to_delete);

               check = zconfig_locate (root, "main/frontend/option/hwm");
               assert (check == NULL);
               check = zconfig_locate (root, "main/frontend/option/swap");
               assert (check == NULL);
               check = zconfig_locate (root, "main/frontend/option");
               assert (check == NULL);
               check = zconfig_locate (root, "main/frontend/bind");
               assert (check == NULL);
               check = zconfig_locate (root, "main/frontend");
               assert (check);
               assert (streq (zconfig_value (check), ""));
               assert (zconfig_child (check) == NULL);
               check = zconfig_next (check);
               assert (check);
               assert (streq (zconfig_name (check), "backend"));
               assert (streq (zconfig_value (check), ""));

               to_delete = zconfig_locate (root, "main");
               assert (to_delete);

               zconfig_remove_subtree (to_delete);

               check = zconfig_locate (root, "main/type");
               assert (check == NULL);
               check = zconfig_locate (root, "main/frontend");
               assert (check == NULL);
               check = zconfig_locate (root, "main/backend");
               assert (check == NULL);
               check = zconfig_locate (root, "main");
               assert (check);

               //  root
               zconfig_remove_subtree (root);

               assert (root);
               assert (zconfig_child (root) == NULL);
               check = zconfig_locate (root, "main");
               assert (check == NULL);
               check = zconfig_locate (root, "context");
               assert (check == NULL);

               zconfig_destroy (&root);
           }

           //  Test node and subtree removal
                   {
                           zconfig_t *root = zconfig_str_load (
                                   "A1 = abc\n"
                                   "    x\n"
                                   "        1\n"
                                   "        2\n"
                                   "    y = 1      #   Ask for a trace\n"
                                   "A2\n"
                                   "    B1 = zqueue    #  ZMQ_DEVICE type\n"
                                   "    B2\n"
                                   "        C1\n"
                                   "            hwm = 1000\n"
                                   "            swap = 25000000     #  25MB\n"
                                   "        C2 = 50\n"
                                   "        C3\n"
                                   "            bind = addr3\n"
                                   "    B3\n"
                                   "        bind = inproc://addr4\n"
                                   "    B4 = Ignac\n"
                                   "        z = 5\n"
                                   "A3\n"
                                   "A4\n"
                           );

               zconfig_t *to_delete = zconfig_locate (root, "A2/B2/C3");
               assert (to_delete);

               zconfig_remove (&to_delete);

               zconfig_t *check = zconfig_locate (root, "A2/B2/C2");
               assert (check);
               assert (streq (zconfig_value (check), "50"));
               assert (zconfig_next (check) == NULL);
               assert (zconfig_locate (root, "A2/B2/C3/bind") == NULL);
               assert (zconfig_locate (root, "A2/B2/C3") == NULL);

               to_delete = zconfig_locate (root, "A2/B2");
               assert (to_delete);

               zconfig_remove (&to_delete);

               check = zconfig_locate (root, "A2");
               assert (check);
               check = zconfig_child (check);
               assert (check);
               assert (streq (zconfig_name (check), "B1"));
               assert (streq (zconfig_value (check), "zqueue"));
               check = zconfig_next (check);
               assert (check);
               assert (streq (zconfig_name (check), "B3"));
               assert (streq (zconfig_value (check), ""));
               assert (zconfig_locate (root, "A2/B2/C1") == NULL);
               assert (zconfig_locate (root, "A2/B2/C2") == NULL);
               assert (zconfig_locate (root, "A2/B2") == NULL);
               assert (zconfig_locate (root, "A2/B4"));

               to_delete = zconfig_locate (root, "A2/B1");
               assert (to_delete);

               zconfig_remove (&to_delete);

               check = zconfig_locate (root, "A2");
               assert (check);
               check = zconfig_child (check);
               assert (check);
               assert (streq (zconfig_name (check), "B3"));
               assert (streq (zconfig_value (check), ""));
               check = zconfig_next (check);
               assert (check);
               assert (streq (zconfig_name (check), "B4"));
               assert (streq (zconfig_value (check), "Ignac"));
               assert (zconfig_next (check) == NULL);
               assert (zconfig_locate (root, "A2/B1") == NULL);
               assert (zconfig_locate (root, "A2/B2") == NULL);

               to_delete = zconfig_locate (root, "A2/B3");
               assert (to_delete);

               zconfig_remove (&to_delete);

               check = zconfig_locate (root, "A2");
               assert (check);
               check = zconfig_child (check);
               assert (check);
               assert (streq (zconfig_name (check), "B4"));
               assert (streq (zconfig_value (check), "Ignac"));
               assert (zconfig_next (check) == NULL);

               to_delete = zconfig_locate (root, "A2");
               assert (to_delete);

               zconfig_remove (&to_delete);

               check = zconfig_locate (root, "A1");
               assert (check);
               check = zconfig_next (check);
               assert (check);
               assert (streq (zconfig_name (check), "A3"));
               assert (zconfig_locate (root, "A2/B4") == NULL);
               assert (zconfig_locate (root, "A2") == NULL);

               to_delete = zconfig_locate (root, "A1");
               assert (to_delete);

               zconfig_remove (&to_delete);

               check = zconfig_child (root);
               assert (check);
               assert (streq (zconfig_name (check), "A3"));
               assert (zconfig_locate (root, "A1/x/1") == NULL);
               assert (zconfig_locate (root, "A1/x") == NULL);
               assert (zconfig_locate (root, "A1/y") == NULL);
               assert (zconfig_locate (root, "A3"));
               assert (zconfig_locate (root, "A4"));

               //  called on root should be equivalent to zconfig_destroy (&root)
               zconfig_remove (&root);
           }

           //  Delete all test files
           dir = zdir_new (basedirpath, NULL);
           assert (dir);
           zdir_remove (dir, true);
           zdir_destroy (&dir);

           zstr_free (&basedirpath);
           zstr_free (&filepath);

           #if defined (__WINDOWS__)
           zsys_shutdown();
           #endif

AUTHORS

       The czmq manual was written by the authors in the AUTHORS file.

RESOURCES

       Main web site:

       Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>

COPYRIGHT

       Copyright (c) the Contributors as noted in the AUTHORS file. This file is part of CZMQ,
       the high-level C binding for 0MQ: http://czmq.zeromq.org. This Source Code Form is subject
       to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
       distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. LICENSE
       included with the czmq distribution.

NOTES

        1. zeromq-dev@lists.zeromq.org
           mailto:zeromq-dev@lists.zeromq.org