Users' Guide
Developers' Guide

TUCS Technical Specifications

Last modified: January 29, 2001.

Version: 0.1.14.

Setting Tree

  1. Definition. A setting tree is a hierarchical structure used by TUCS to organise settings.
  2. The leaves of a setting tree are simple settings.
  3. The nodes of a setting tree are container settings, which are special settings.
  4. There is a single abstract setting tree in a system.
  5. A setting tree can be scoped, if it is inside a specific scope. This is called an scoped or absolute setting tree. Example; 'system' can be a scope.
  6. There can be multiple scopes is a system. Example: 'system' and 'user.henrik' are different scopes.


  1. A setting is the basic element of a setting tree.
  2. A setting is an entity with a name, type, value and other attributes.
  3. The name of a setting is used to refer to the settings or its value.
  4. The type of a setting defines the set of possible values, and how the value is stored.
  5. The name and type of a setting is fixed, while its value is variable.
  6. A setting can be a simple settings or a container settings (group, list).
  7. Description. The description of a setting is a human readbale string that gives clues to the meaning (semantics) of the setting. The description is an optional attribute. It can be made up of ASCII characters.

Setting Locator

  1. A locator of a setting identifies unambiguously the setting within its setting tree.
  2. A locator of a setting is also called full name of the setting.
  3. The locator of a setting is obtained by traversing the setting tree from the root to the setting, and joining the names of all the subgroups.
  4. The locator is denoted as a list of setting group names, from least-to-most specific, delimited by a dot character, ('.').
  5. The last element is a setting locator is the name of the setting itself.
  6. Example: 'app.myeditor.font.size' is a setting within the setting subgroup 'app.myeditor.font', which is a within the setting group 'app.myeditor', which is a within the setting group 'app'.
  7. Abstract locator. A locator which is relative to the root note of the abstract setting tree is an abstract locator. Example: 'app.myeditor.font.size'.
  8. Absolute locator. A locator which includes a scope and an abstract locator is an absolute locator. Absolute locators start with a leading dot. Example: '.system.app.myeditor.font.size'.
  9. Relative locator. A locator can be relative to a group other that the root group. In this case the locator is relative, and its base is the base locator. An abstract locator can be otained by concatenating the base locator and the relative locator (with a dot). Example: if 'font.size' is a locator relative to 'app.myeditor', it refers to 'app.myeditor.font.size'
  10. A base locator is used when all the settings of interest are within one setting group.

Setting Scope

  1. A scope maps an abstract setting locator to an absolute setting locator.
  2. Scopes allow several analogous abstract setting trees to coexist.
  3. Example: 'system' and 'user.henrik' are two different scopes.
  4. Scopes can have different access rights.
  5. A setting tree found under a scope may be incomplete, but must be analoguous to other setting trees (which is the abstract setting tree). Settings with the same abstract locator must have the same type. Example: suppose '.system.app.wordwrap' is a boolean setting. Setting '.user.henrik.app.myeditor.wordwrap' may be absent, but if it is present, it must be a boolean setting.
  6. Scope Search List.
    1. Whenever an abstract locator needs to be mapped to an absolute one, a list of scopes is used to find the setting in a scope.
    2. The Scope Search List consists of a list of scopes in the order of which to look through them.
    3. The list is represented as a list of scopes, separated by a colon (':').
    4. Example: "user.current:system".
    5. When a setting is accessed for reading, the scopes are searched in the order of their apparence in the list. The first scope where the setting exists is used.
    6. When a setting is accessed for writing, the scopes are searched in the order of their apparence in the list. The first scope where the setting can be written is used.
    7. There are two built-in scopes: system and user.
    8. The system scope, denoted as 'system', is at least partially readable by every user, and fully writable by the administrator user (root). It contains all default shared settings that a user starts out with.
    9. The user scope, denoted as '.user.<username>' contains user-specific settings. The <username> is the login name of the user. The user name can have the special value 'current', in which case it refers to the effective user currently executing the TUCS library.
    10. The default search list is "user.current:system". This means that first the user scope is searched, and only if it does not contain a setting is the system scope used. This is set during initialisation time of the TUCS library, and can be overriden later.

Setting Name

  1. The name of a setting is the attribute used to uniquely identify the setting whithin its setting group.
  2. No repeated names within the same group are allowed.
  3. A setting name is a single word, consisting of letters, digits, and the underscore character ('_').
  4. A setting name must start with a letter. Exception: name of list groups.
  5. Setting names are treated case-insensitive.

Simple Setting

  1. A simple setting has a single value associated with it.
  2. The value of a setting is the changeable part of the setting. It gives meaning to the setting. The value is stored in memory as an element of the primitive type that best represents the actual type.
  3. Simple settings have one of the following types:
    1. String. A string setting can have any number of ASCII characters as its value. The string type is the default setting type, since it is usually stored verbatim in any storage method.
    2. Integer. An integer number. The maximum range is from -231 to 231-1.
    3. Character. A single character. The character is stored as a number in the range -128 to 127.
    4. Boolean. A single bit type. This type can have one of two values, true (1) or false (0).
    5. Real. A floating point number, stored as a double type in C language. The maximum range of this floating point number is from (does anyone know the range of a double?).
    6. Binary. This item is binary string of arbitrary length. Its only requirement is that the number of bits must be a multiple of 8 (1 byte). If not, the value is automatically padded to the nearest byte using '0' bits.

Container Setting

  1. A container setting can have any number of settings of any type defined underneath it.
  2. The value of a container is defined as the set of member settings. TUCS represents this as an abstract data structure, and provides functions to operate on.
  3. A group is container setting, used to organise the settings into a tree.
  4. A list is a special group, with members without names and of the same type. Lists are useful when the application designer wants to have a group of similar settings, but wants to address them by index not by name, or does not want to name them. The list type has a sub-type associated with it, and that is the type of all the settings the list contains. The list is only allowed to contain that type of setting. If a list of lists is defined, the sub-type is only a list, and each sub-list may be a different list type. When referring to a list element using a locator, the element of the locator that would normally have the name of the element would be replaced with the index number of the element, starting at 0.

Manipulating Settings

  1. For any operation on the a setting, the setting must be identified first.
  2. A setting can be identified using a setting handle, or its locator (name).
  3. Reference by setting handle. A setting handle is an implementaional shortcut for specifying a setting without using locators. A handle is first obtained from a setting locator. Once a handle is obtained, it can be used to reference the setting until the handle is released. There is one special handle known as the invalid setting handle that is used to indicate error conditions. Applications are not allowed to exploit how a handle is represented internally, because that might change with future versions.
  4. Reference by setting name. Functions that use the setting name instead of a handle will be implemented by obtaining a setting nahdle, using the handle to perform the work, and then releasing the handle. For efficiency considerations, reference by handle is the preferred method.
  5. Setting operations. TUCS provides the following methods for declaring, creating, and destroying settings.
    1. Declare a setting. If the setting exists in the storage, it is accessed. If not, a new record is created. The locator, type, and default value must all be specified. If the setting exists in the storage, it is accessed, and its type must agree with the specified one. If nothing already exists, a new setting is created with the value being the default value. The new setting will not be stored until its value has been changed at least once from the default value. A handle to the setting is returned for futher reference.
    2. Get handle of existing setting given its locator. Return a handle to the setting, which must exist already in storage. This can be used for porbing for the existence of settings.
    3. Release Handle. This allows TUCS to reclaim any memory used by unreferenced handles. It does not necessarily do so, however.
    4. Destroy Setting. Eliminates a setting from storage and its handle from memory. If the handle being destroyed is a group, then all settings underneath the group are destroyed as well. Referencing these handles (except to release them) will return an error. If the setting being destroyed exists in more than one scope, then it will only be destroyed in the first writable scope found.
  6. Operations on attributes of a setting, specified by handle or name.
    1. Get Value. Obtain the current value of the setting.
    2. Set Value. Sets the current value of the setting. This is only valid for simple settings. Lists can be manipulated using the special list manipulation functions, and groups are changed by obtaining setting handles for member settings underneath them.

      Only the first writable scope is used if the setting exists in more than one scope.

    3. Get Type. Obtain the type of the setting. The type of an existing setting cannot be changed.
    4. Get Description. Obtain the description of the setting (if it exists).
    5. Set Description. Set the description of the setting.
    6. Get Name. Obtain the name of a setting, given its handle. The name of an existing setting cannot be changed.
    7. Get Locator. Obtain the locator (full name) of a setting given its handle.
    8. Get Current Scope. Obtain the current scope of the setting. This is the scope used in the last get/set operation.

TUCS Architecture

  1. TUCS is vertically separated into two layers:
    • the generic layer
    • and the storage layer
  2. There can be different storage methods.
  3. The generic layer is independent of the storage medium and method.
  4. The generic layer is responsible for:
    • maintaining a working memory of settings;
    • dealing with multiple scopes;
    • type and range checking;
    • meta-settings.
  5. The storage layer is responsible for:
    • setting and retrieving settings on/from non-volatile storage.

Storage Layer Specifications

  1. The storage layer is required to store the name, type, and value of a setting. It is not required to store the description, but it is provided to the storage layer regardless.
  2. The interface to the storage layer will be by passing a setting handle. The storage layer will be required to synchronize all data underneath a storage handle.
    1. On a get, the storage layer will get the setting specified by the handle, and if the setting is a container, all settings directly underneath the container will also be fetched into the working memory.
    2. On a set, the setting specified by the handle and all settings underneath the setting, if it is a container, will be checked for synchronization. If the settings have been changed, they will be stored, if not, they will be left alone.
  3. The storage layer will not deal with scope at all. It will be provided with the exact scope to use. The scope searching is implemented in the layer above.

Caching Specifications

  1. Caching will be performed at the highest level if necessary. That is, in the layer that the application interfaces with. Caching will be implemented through keeping settings in memory until required to flush them to storage. The storage layer is REQUIRED to save all settings passed to it to its medium, and is REQUIRED to load all settings directly from the medium.
  2. The application will have methods to control any caching in the high level. The caching will provide at least two methods of caching:
    1. caching on demand - values are kept in memory until the application specifically requests the cache be flushed.
    2. no caching - values are stored as soon as they are set. Everything is syncrhonized.
  3. The application will have methods to force a flush of the caching mentioned above.
  4. The storage layer may use a caching system to increase performance only if the cache itself is stored in a non-volatile location (i.e. not in RAM) and the cache is only used if it is newer than the actual storage location.

Group Iterators


    1. A meta-setting stores basic information (name, type) and additional information (default value, description, other attributes) about a setting, embedded in the setting tree, at a related location. The meta-config stores additional information attached, but without burdening the config itself.
    2. Information from the meta-setting can be used by intelligent configuration editors in the absence of the original application.
    3. TUCS provides facilities to:
      1. create meta-setting records fom a setting, on request or automatically;
      2. access meta-setting info of a setting;
      3. update/create settings from thier meta-setting info.
    4. Every setting can have zero or one corresponding meta-setting, which is a group.
    5. The follwing meta-setting fields are defined. Besides the name of each meta-setting, its type is listed in parantheses.
      1. Name - name of the setting (string type).
      2. Type - one of 'string', 'integer', 'real', 'boolean', 'group', 'list', or 'binary' (string type).
      3. DefaultValue - the default value of the setting, type corresponds to 'Type'. This default is only a suggestion, but it expected to reflect the same value as the default used by the application in the abscense of an actual value. Its main purpose is to allow the user to know what the default was without erasing the current value.
      4. Description - description (string type).
      5. _Meta_ - for group settings, a list of the member settings. Each element of the list is a group corresponding to one member setting (list of groups type). Example: Consider setting 'mainwindow.size.width'. In this case:
        _meta_.mainwindow.type = 'group'
        _meta_.mainwindow._main_.size.type = 'group'
        _meta_.mainwindow._main_.size._meta_.width.type = 'int'
    6. Other defined optional fields (not used by TUCS):
      1. RegExpFormat - for string types, a regular expression of valid values (string type).
      2. MinValue - for numerical types, the minimum allowed value (same as Type).
      3. MaxValue - for numerical types, the maximum allowed value (same as Type).
    7. Meta-settings have no meta-meta-settings (to avoid infinite regression).
    8. Locator of a meta-setting. The locator of a meta-setting is automatically computed from the locator of the original setting. The details of how this is accomplished should be hidden from users. However, it is given here.
      The locator of the meta-setting of setting 'a.b. <...> .c' is '_meta_.a._meta_.b. <...> ._meta_.c'.
      Careful consideration reveals that this follows from the property of the '_meta_' meta-setting, described above.

    Text File Storage Layer

    1. Under this storage method, settings are stored in several ASCII files.
    2. It is possible to read and edit files using any text editor.
    3. A single file contains all the settings from one setting group.
    4. Naming Conventions
      1. Filenames are generated automatically. When accessing settings through TUCS, the user does not need to know the names of the files. (The generic TUCS layer does not know about filenames.)
      2. The name of a files indicates the group that all settings inside the file reside in.
      3. The name of a directories is identical to the group that all the groups represented by the files in that directory are stored in. Exceptions are the root directories, which are named by the library itself.
    5. The root directory is set when Tucs is deployed. The two roots that the text library defines are the system root, and the user root. The system root is one directory, while the user root is built using the user's name. The library by default uses '/etc/tucs' as the system root and '~username/.tucs' as the user root.
    6. Any setting whose parent group is mapped to a directory will reside in a special file named ".settings".
    7. When a setting is accessed, its location within the fileststem depends on its locator and the existing structure.

      If any ancestor group that the setting is a part of exists as a file, the setting is added to that file (with the corresponding relative locator prepended).

      Example. upon creation of 'app.myeditor.wordwrap' file '[...]/app/teditor' will be used. However, if '[...]/app' exists as a file, it will be used.

      If all of the ancestor group that the setting is a part of are all directories, a file will be created inside the directory corresponding to the ancestor group.

      If some ancestor groups don't exist neither as a file or a directory, they will be created as directories. A file will be created inside the directory corresponding to the ancestor group.

    8. Post comment: The current scheme does not actually use the base path (it's not provided), but it uses only the current 'ancestor group'. The only way to ensure that the file will correspond to the base group by default, is that when the first access happens, the ancestor group is the base path.

      Example. There are no files, init tucs with base 'app.myapp'. When you first access 'sett', its full locator is 'app.myapp.sett'. So a file will be created at app/myapp, with sett inside it.

      However, when you first access 'grp.sett', its full locator is 'app.myapp.grp.sett'. So a file will be created at app/myapp/grp, with sett inside it. Not quite what you want.

    Text File Storage Format

    1. This format is used by the text file storage layer, which is the default storage layer. It is also used by utilities in cases where the storage layer is bypassed (e.g., output to screen).
    2. Rules expressed with 'should' mean that TUCS will observe them when it writes files, but it will also process existing files which do not follow the rule.
    3. For each setting, a name, type, and value is stored.
    4. Settings are stored using ASCII characters.
    5. Name, type, and value is separated by white space (space, tab, newline).
    6. The type is be stored after the name of the setting.
    7. Settings should be separated from each other by white space containing at least one newline.
    8. An integer number is stored using digits and an optional sign.
    9. A real number is stored using digits, an optional sign, an optional decimal point and decimal part.
    10. A binary value is stored as a list of 2-character hexadecimal values, separated by spaces. For example:
      binary key "05 a2 5c 80 21 0d"
    11. A string is stored verbatim. If it includes whitespace, the string is enclosed between double quotes ('quoted'). Some special characters must be represented as two non-special characters ('escaped'), accroding to C standards. These are: quote(\"), backslash (\\), new line (\n), tab (\t).
      Message string "This is a string with a \\ slash"
    12. A group is stored as: Name, 'group', '{' opening curly bracket, list of member settings (indented), '}' closing curly bracket. Example:

      font group {
        family string "courier"
        size   int    12
    13. A list is stored as: Name, 'list, type of elements, '(' opening round bracket, list of member values (only values), ')' closing round bracket.

      Colors list string ( White Red )

    14. Comments. A portion of line following a '#' (hash, sharp) is treated as a comment (up to and including the first newline character). Comments are ignored but preserved (not implemented yet).
    15. Description. Description (and possibly other informative) fields should be included as a comment before the setting they refer to. The description should start with the characters '#desc'. This signifies to the parser that this line is the description of the variable, and not just a normal comment.
    16. Open issues: different character sets in string value.
    17. A complete example.
      # MyEdit Config File
      font group {
       family string courier
       size   int    12
       dpi    int    75
      print group {
       command    string   "enscript -2rG"
       selection  boolean  false
       raw        boolean  true
      recently_opened_files list string {
      toolbar_on  boolean true
      default_url string  "ftp://localhost/welcome.msg"
      mailcmd     string  "=mail -s \"%s\""
      # I changed this to yellowish, I don't like white (joe)
      bgcolor       string  "#ffffdd"
      backupcopies  boolean  true
      statusbar     boolean  true
      width         integer  726
      wordwrap      boolean  true
      fillcolumn    integer  79
      usefillcolumn boolean  true
      height        integer  528
      toolbar_position string Left
      forecolor     string   "#000000"

    Command Line Utility

    1. TUCS provides a command-line utility for accessing TUCS settings.
    2. Name. It is called 'tucs'.
    3. Syntax:
      tucs op settings [value] [options]

      op - a one letter or one word operation code (similar to tar)

      setting - the setting (group) name to work with

      options - other options

    4. Results are returned on standard output, settings formatted using the text file format.
    5. Operations:
      g, get return the value of the settings (must be non-container)
      d, dump return all the settings (with values) under the specified setting group
      s, set set the value of a setting -- must be non-container. value must be specified
      l, load set (create) all settings under the specified group. The standard input is expected to provide a valid setting group file
      p, print print the name, value, type, and all other available information of the setting, in a human-readable form. Meta-config is accessed, if available. Setting can be a container, but members will not be recursed.
      m, meta dump the meta-setting corresponding to the setting (see 'dump'). If meta-setting does not exist, a minimal one is created on the fly
      i, install set all the settings, as specified by a meta-setting. Works as 'load', but expects to get a meta-setting as input.
      v, version output TUCS library version
    6. Options:
      -s scope scope search list. Used if setting is not absolute (does not start with a '.'). If not specified, default is "user.current:system" (TUCS default).
    7. Examples:
      tucs get app.myedit.linewidth
      tucs set app.myedit.linewidth 40
      tucs d app.myedit > first.tucs
      tucs l app.myedit < first.tucs
    8. An install script typically uses 'load' or 'install' to install a setting group, depending on whether the default settings are supplied as a settings file, or a meta-settings file.

    This document is maintained by the TUCS team. See the online homepage at http://tucs.sourceforge.net.