:TUCS:
Home
Users' Guide
Developers' Guide
Specs>
API
F.A.Q.
Homepage
|
TUCS Technical Specifications
Last modified: January 29, 2001.
Version: 0.1.14.
- Definition. A setting tree is a hierarchical structure used by TUCS
to organise settings.
- The leaves of a setting tree are simple settings.
- The nodes of a setting tree are container settings, which are
special settings.
- There is a single abstract setting tree in a system.
- 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.
- There can be multiple scopes is a system.
Example: 'system' and 'user.henrik' are different scopes.
- A setting is the basic element of a setting tree.
- A setting is an entity with a name, type,
value and other attributes.
- The name of a setting is used to refer to the settings or
its value.
- The type of a setting defines the set of possible values,
and how the value is stored.
- The name and type of a setting is fixed, while its value is variable.
- A setting can be a simple settings or a container settings
(group, list).
- 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.
- A locator of a setting identifies unambiguously the setting
within its setting tree.
- A locator of a setting is also called full name of the setting.
- 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.
- The locator is denoted as a list of setting group names, from
least-to-most specific, delimited by a dot character,
('.').
- The last element is a setting locator is the name of the setting itself.
- 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'.
- 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'.
- 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'.
- 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'
- A base locator is used when all the settings of interest are within one
setting group.
- A scope maps an abstract setting locator to an absolute setting locator.
- Scopes allow several analogous abstract setting trees to coexist.
- Example: 'system' and 'user.henrik' are two different scopes.
- Scopes can have different access rights.
- 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.
- Scope Search List.
- 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.
- The Scope Search List consists of a list of scopes in the order of
which to look through them.
- The list is represented as a list of scopes, separated by a colon (':').
- Example: "user.current:system".
- 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.
- 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.
- There are two built-in scopes: system and user.
- 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.
- 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.
- 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.
- The name of a setting is the attribute used to uniquely identify the setting
whithin its setting group.
- No repeated names within the same group are allowed.
- A setting name is a single word, consisting of letters, digits,
and the underscore character ('_').
- A setting name must start with a letter. Exception: name of list groups.
- Setting names are treated case-insensitive.
- A simple setting has a single value associated with it.
- 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.
- Simple settings have one of the following types:
- 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.
- Integer. An integer number.
The maximum range is from -231 to 231-1.
- Character. A single character. The character is stored as a number
in the range -128 to 127.
- Boolean. A single bit type.
This type can have one of two values, true (1) or false (0).
- 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?).
- 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.
- A container setting can have any number of settings of any type
defined underneath it.
- 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.
- A group is container setting, used to organise the settings into a tree.
- 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.
- For any operation on the a setting, the setting must be identified first.
- A setting can be identified using a setting handle, or its locator (name).
- 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.
- 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.
- Setting operations.
TUCS provides the following methods for declaring, creating,
and destroying settings.
- 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.
- 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.
- Release Handle. This allows TUCS to reclaim any memory used by
unreferenced handles. It does not necessarily do so, however.
- 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.
- Operations on attributes of a setting, specified by handle or name.
- Get Value. Obtain the current value of the setting.
- 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.
- Get Type. Obtain the type of the setting.
The type of an existing setting cannot be changed.
- Get Description. Obtain the description of the setting (if it exists).
- Set Description. Set the description of the setting.
- Get Name. Obtain the name of a setting, given its handle.
The name of an existing setting cannot be changed.
- Get Locator. Obtain the locator (full name) of a setting given
its handle.
- Get Current Scope. Obtain the current scope of the setting.
This is the scope used in the last get/set operation.
- TUCS is vertically separated into two layers:
- the generic layer
- and the storage layer
- There can be different storage methods.
- The generic layer is independent of the storage medium and method.
- The generic layer is responsible for:
- maintaining a working memory of settings;
- dealing with multiple scopes;
- type and range checking;
- meta-settings.
- The storage layer is responsible for:
- setting and retrieving settings on/from non-volatile storage.
- 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.
- 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.
- 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.
- 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.
- 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 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.
- The application will have methods to control any caching in the high level.
The caching will provide at least two methods of caching:
- caching on demand - values are kept in memory until the application
specifically requests the cache be flushed.
- no caching - values are stored as soon as they are set. Everything is
syncrhonized.
- The application will have methods to force a flush of the caching
mentioned above.
- 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.
- 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.
- Information from the meta-setting can be used by intelligent configuration
editors in the absence of the original application.
- TUCS provides facilities to:
- create meta-setting records fom a setting, on request or automatically;
- access meta-setting info of a setting;
- update/create settings from thier meta-setting info.
- Every setting can have zero or one corresponding meta-setting, which is a group.
- The follwing meta-setting fields are defined.
Besides the name of each meta-setting, its type is listed in parantheses.
- Name - name of the setting (string type).
- Type - one of 'string', 'integer', 'real', 'boolean', 'group',
'list', or 'binary' (string type).
- 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.
- Description - description (string type).
- _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'
- Other defined optional fields (not used by TUCS):
- RegExpFormat - for string types, a regular expression of valid values
(string type).
- MinValue - for numerical types, the minimum allowed value
(same as Type).
- MaxValue - for numerical types, the maximum allowed value (same as Type).
- Meta-settings have no meta-meta-settings (to avoid infinite regression).
- 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.
- Under this storage method, settings are stored in several ASCII files.
- It is possible to read and edit files using any text editor.
- A single file contains all the settings from one setting group.
- Naming Conventions
- 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.)
- The name of a files indicates the group that all settings inside
the file reside in.
- 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.
- 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.
- Any setting whose parent group is mapped to a directory will
reside in a special file named ".settings".
- 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.
- 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.
- 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).
- 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.
- For each setting, a name, type, and value is stored.
- Settings are stored using ASCII characters.
- Name, type, and value is separated by white space (space, tab, newline).
- The type is be stored after the name of the setting.
- Settings should be separated from each other by white space containing
at least one newline.
- An integer number is stored using digits and an optional sign.
- A real number is stored using digits, an optional sign, an optional
decimal point and decimal part.
- 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"
- 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"
- 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
}
- 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
)
- 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).
- 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.
- Open issues: different character sets in string value.
- 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 {
/home/adam/doc.rtf
/home/adam/frams/sources/testconv.cpp
/home/adam/frams/sources/test5.cpp
/home/adam/frams/gdk/list.h
/home/adam/frams/gdk/list.cpp
}
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"
- TUCS provides a command-line utility for accessing TUCS settings.
- Name. It is called 'tucs'.
- 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
- Results are returned on standard output, settings formatted using
the text file format.
- 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 |
- 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). |
- Examples:
tucs get app.myedit.linewidth
tucs set app.myedit.linewidth 40
tucs d app.myedit > first.tucs
tucs l app.myedit < first.tucs
- 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. |