# The runtime config system in librnd

## grouping - flat vs. tree

The original settings and HID attribute system in pcb were both flat: basically a list of type:key=val triplets. All settings in a few big bags; which bag sometimes doesn't depend on some logical categorizing, but historical reasons (e.g. which part of the code needs the given setting).

This works well for a small amount of settings but lack of categories or hierarchy (or sets or groups) makes it harder to understand what setting does what and orients users to just accept defaults. After a while it also makes programmers think twice before adding a new setting, increasing the crowd in a bag. This in turn results in a less configurable system.

Introducing a hierarchy of settings can solve these problems by grouping and categorizing settings. If the user is interested in how footprints are searched, they can ignore the settings the editor/ subtree has. It is also easier to save and reload selectively: when the hierarchy is done right, closely related settings end up in the same category (thus the same subtree). Thus saving or loading a subtree can fully save or restore a property of the program, even if that property is affected by multiple settings.

## librnd config tree

The config tree, the full tree is, something that exists in memory. Actual config files often contain only a subset of the tree. Multiple config files (e.g. system level, user level, settings from the board file) are loaded and merged to form the final config tree. The hierarchy of the tree is represented by setting groups, which are like directories on a file system. Actual settings are always leaves of the tree, placed in a specific group at any level (just like in file systems). A full path to a setting is written like a path on a file system: group1/group2/item, where group1 and group2 are names of setting groups and item is the name of the setting. Note: unlike with real file systems, the leading slash (representing the root) is omitted.

Details/constraints: A valid path unambiguously identifies a setting (or a setting group). Settings and groups always have exactly one parent (except for the root group that has no parent). There is only one root of the config tree.

The main groups in the logical tree are:

  (root) |  | (config root)
  +- rc | run control (program startup)
  | | +- path | paths automatically set up by the program at startup - do not specify these
  +- design | some default settings of a new design; minimum/maximum value of some design settings (app specific)
  +- editor | how the pcb editor behaves - independent of HIDs or the GUI
  | | +- view | default view parameters
  +- appearance | how the GUI looks like - common to all GUI HIDs
  | | +- color | layer colors, GUI colors, misc design colors
  +- plugins | dynamic subtree for various plugin settings
  | | +- foo | all settings of the imaginary foo plugin are registered in this group
  +- utils | dynamic subtree for various plugin settings
  | +- bar | all settings of the imaginary bar utility are registered in this group

## dynamic subtrees

The plugins/ and utils/ subtree are dynamic, which means their contents are not defined by core pcb.

In plugins/ each plugin should create a group for its own settings. What this subtree should contain depends on what plugins are actually loaded. The benefit of this approach is that plugins can use the central config infrastructure instead of inventing their own config files. This makes user's life easier on many levels: single config syntax to learn; uniform GUI (preferences dialog) to change all settings; uniform way to save/restore parts of the settings.

The utils/ subtree is very similar in all aspects except that it is for external utility programs. Some utils that are closely related to pcb-rnd, such as gsch2pcb-rnd, should work from the same configuration. If they already load the pcb-rnd config files it's easier to keep their settings in the same tree, in the same format.

No warning is generated for unrecognized settings in dynamic subtrees. This lets the user configure plugins that are not always loaded and let util settings sit in their subtree.

## what happens to all these settings

After loading all config files they are merged: if the same setting is described in multiple files, the higher priority wins or if the setting is a list (e.g. library search paths) the items are merged in a final list. At this point the full logical config tree is built. Next the textual values from the logical tree are converted into binary (native C values like "long int" or "double") and are saved in C variables for the code to access them directly.