Provided by: radare2_6.0.7+ds-1_amd64 bug

NAME

       r_config — Configuration management library for radare2

SYNOPSIS

       #include <r_config.h>

DESCRIPTION

       The  r_config  API  implements the configuration registry used by radare2 and its subcommands.  It stores
       named configuration keys (strings, integers and booleans), metadata (description, options  and  read-only
       flags),  and  supports  setters/getters  so  components  can react to configuration changes.  Common uses
       include global defaults (architecture, bits),  binding  config  keys  to  internal  variables,  temporary
       overrides for an operation and serializing configuration into project files.

       The  primary container is struct r_config_t, which keeps a list and hash table of struct r_config_node_t,
       each node holding the key name, value, type flags, optional callbacks and a human-readable description.

INITIALIZATION

       Create and destroy configuration objects.  An `RConfig` is typically attached to a  higher-level  context
       (for  example a `RCore` instance keeps one `RConfig`).  Cloning produces a shallow copy of nodes suitable
       for temporary manipulation.

             /* prototypes */
             RConfig *r_config_new(void *user);
             RConfig *r_config_clone(RConfig *cfg);
             void r_config_free(RConfig *cfg);

             RConfig *cfg = r_config_new (core);
             /* ... use cfg ... */
             r_config_free (cfg);

SETTING VALUES

       Setters update or create nodes and  may  call  a  node  setter  callback.   Use  the  `_cb`  variants  or
       `r_config_set_setter*`  helpers  to  bind  a  setter  to  propagate  the  change  to  internal state (see
       `libr/config/callback.c`).

             /* prototypes */
             RConfigNode *r_config_set(RConfig *cfg, const char *name, const char *value);
             RConfigNode *r_config_set_i(RConfig *cfg, const char *name, const ut64 i);
             RConfigNode *r_config_set_b(RConfig *cfg, const char *name, bool b);
             RConfigNode *r_config_set_cb(RConfig *cfg, const char *name, const char *value, RConfigCallback cb);
             RConfigNode *r_config_set_i_cb(RConfig *cfg, const char *name, int ivalue, RConfigCallback cb);
             RConfigNode *r_config_set_b_cb(RConfig *cfg, const char *name, bool bvalue, RConfigCallback cb);
             bool r_config_set_setter(RConfig *cfg, const char *key, RConfigCallback cb);

       Notes: - When a node has a setter, it is invoked after the new value is parsed.
         If the setter returns false the previous value is restored.  - The `r_config_set*` helpers create nodes
       if they do not exist; use
         `r_config_node_new` for manual node construction when you need to
         populate options or a long description first.

             /* example: CLI-style configuration used in many binaries */
             r_config_set (cfg, "asm.arch", "x86");
             r_config_set_i (cfg, "asm.bits", 64);
             r_config_set_b (cfg, "scr.interactive", false);

GETTING VALUES

       Accessors return the current effective value for a key.  If a node has an attached getter callback it may
       compute values on demand.

             /* prototypes */
             const char *r_config_get(RConfig *cfg, const char *name);
             ut64 r_config_get_i(RConfig *cfg, const char *name);
             bool r_config_get_b(RConfig *cfg, const char *name);
             bool r_config_toggle(RConfig *cfg, const char *name);
             bool r_config_rm(RConfig *cfg, const char *name);

             const char *arch = r_config_get (cfg, "asm.arch");
             ut64 bits = r_config_get_i (cfg, "asm.bits");
             bool pseudo = r_config_get_b (cfg, "asm.pseudo");
             r_config_toggle (cfg, "asm.pseudo");

ADVANCED FEATURES

       This section covers higher-level utilities used in real radare2 code: locks, short expression  evaluation
       (used  by CLI option parsers), bulk listing and the hold/restore pattern which captures values to restore
       them later.

             /* prototypes */
             void r_config_lock(RConfig *cfg, bool lock);
             char *r_config_eval(RConfig *cfg, const char *str, bool many, bool *error);
             RConfigHold *r_config_hold_new(RConfig *cfg);
             bool r_config_hold(RConfigHold *h, ...);
             void r_config_hold_restore(RConfigHold *h);
             void r_config_hold_free(RConfigHold *h);
             void r_config_bump(RConfig *cfg, const char *key);
             char *r_config_list(RConfig *cfg, const char *str, int rad);

       Behavior and tips: - `r_config_lock` sorts nodes and flips a lock flag (useful before
         serializing a stable snapshot).  - `r_config_eval` understands `key=value` to set keys, `key.` to list
         matching keys, and colon-separated lists when `many` is true; this
         mirrors how CLI handlers parse compact config expressions.   -  `r_config_hold_new`  +  `r_config_hold`
       capture current values for a list
         of keys; `r_config_hold_restore` restores them.  This mirrors patterns
         used when temporarily switching architectures or analysis depth.

             /* hold/restore example (used in several core components) */
             RConfigHold *hold = r_config_hold_new (cfg);
             r_config_hold (hold, "asm.arch", "asm.bits", NULL);
             /* temporarily override */
             r_config_set (cfg, "asm.arch", "arm");
             r_config_set_i (cfg, "asm.bits", 32);
             /* restore original */
             r_config_hold_restore (hold);
             r_config_hold_free (hold);

NODE MANAGEMENT

       Direct node manipulation is useful when registering a config key with a long description, a collection of
       valid  options  or  custom  setter/getter  callbacks.  Most callers use the `r_config_set*` helpers which
       create nodes implicitly; use the node API for more control.

             /* prototypes */
             RConfigNode *r_config_node_new(const char *name, const char *value);
             RConfigNode *r_config_node_get(RConfig *cfg, const char *name);
             RConfigNode *r_config_node_desc(RConfigNode *node, const char *desc);
             void r_config_node_add_option(RConfigNode *node, const char *option);
             void r_config_node_purge_options(RConfigNode *node);
             char *r_config_node_tostring(RConfigNode *node);
             void r_config_node_free(void *n);

             /* create a node with options and description */
             RConfigNode *node = r_config_node_new ("custom.var", "default");
             r_config_node_desc (node, "Description for UI and help output");
             r_config_node_add_option (node, "opt1");
             r_config_node_add_option (node, "opt2");
             /* attach node into cfg (internal helpers in libr/config do this) */
             r_config_node_free (node);

SERIALIZATION

       Serialize  and  unserialize  configuration  into  an  `Sdb`  database.   These  routines  are  used  when
       saving/loading projects so configuration survives between sessions.

             /* prototypes */
             void r_config_serialize(RConfig * R_NONNULL config, Sdb * R_NONNULL db);
             bool r_config_unserialize(RConfig * R_NONNULL config, Sdb * R_NONNULL db, char ** R_NULLABLE err);

             Sdb *db = sdb_new0 ();
             r_config_serialize (cfg, db);
             /* write sdb to disk via sdb API */
             sdb_free (db);

EXAMPLES

       Examples  below  demonstrate  patterns  taken  from  real radare2 code: binding config keys to variables,
       temporary overrides, and evaluating compact config expressions.

             #include <r_config.h>

             int main(void) {
                 RConfig *cfg = r_config_new (NULL);

                 /* common set/get pattern used in many binaries */
                 r_config_set (cfg, "asm.arch", "x86");
                 r_config_set_i (cfg, "asm.bits", 64);
                 printf ("Arch: %s0, r_config_get (cfg, "asm.arch"));

                 /* bind a config key to a C variable using setter helpers (see
                  * libr/config/callback.c for the implementation used in the tree): */
                 int term_color = 0;
                 r_config_set_setter_i (cfg, "scr.color", &term_color);
                 r_config_set_i (cfg, "scr.color", 2); /* updates term_color */

                 /* temporarily override and restore: */
                 RConfigHold *hold = r_config_hold_new (cfg);
                 r_config_hold (hold, "asm.arch", "asm.bits", NULL);
                 r_config_set (cfg, "asm.arch", "arm");
                 r_config_set_i (cfg, "asm.bits", 32);
                 r_config_hold_restore (hold);
                 r_config_hold_free (hold);

                 /* evaluate a compact CLI expression (used in CLI parsing code): */
                 char *res = r_config_eval (cfg, "asm.arch=arm:asm.bits=32", true, NULL);
                 free (res);

                 r_config_free (cfg);
                 return 0;
             }

SEE ALSO

       r_core(3), r_util(3)

Debian                                         September 21, 2025                                    R_CONFIG(3)