NCL Website header
NCL Home > Documentation > Graphics

Resource database


Overview

A program often needs a variety of options in the NCL/HLU environment (for example, fonts, colors, and dash patterns). Specifying all of these options on the command line is awkward because users may want to customize many aspects of the program and need a convenient way to establish these customizations as the default setting. The resource database is provided for this purpose. Resource specifications are stored in human-readable files.

The resource database is different than most database systems. In most database systems, you perform a query using an imprecise specification, and you get back a set of records. The resource database, however, allows you to specify a large set of values with an imprecise specification, to query the database with a precise specification, and to get back only a single value. This should be used by applications that need to know what the user prefers for colors, fonts, and other resources.

As an example of how the resource database works, consider the ap01c example program that displays a TextItem object. NCL and the HLU library are designed so that programs use a hierarchy of objects all the way down to each individual object. This is called the instance hierarchy. Each of these objects can be assigned a name, and is a member of a class, and therefore has a class name. The instance hierarchy along with the name and class of each object can be used to generate a fully qualified name and class for each object. Fully qualified names or classes can have arbitrary numbers of component names, but a fully qualified name always has the same number of component names as a fully qualified class.

For example, the ap01c program has a top-level App object named "ap01", which has a class name of "appClass". Each name and class finally has an attribute (for example "txFont" or "Font"). By convention, the first character of name attributes are in lowercase, and the first character of class attributes are capitalized. If each object is properly assigned a name and class, it is easy for the user to specify attributes of any portion of the application.

Example ap01c creates an XWorkstation object child of the App object with a name of "x" and a class name of "xWorkstationClass". ap01c creates a TextItem object child of "x" with a name of "tx1" and a class name of "textItemClass". This object has a fully qualified name, "ap01.x.tx1", and a fully qualified class, "appClass.xWorkstationClass.textItemClass". Its fully qualified name is the fully qualified name of its parent, "ap01.x", followed by its name, "tx1". Its fully qualified class name, is the fully qualified class name of its parent, "appClass.xWorkstationClass", followed by its particular class name, "textItemClass". The fully qualified name of a resource is the attribute's name appended to the object's fully qualified name, and the fully qualified class is its class appended to the object's class.

The TextItem object needs the following resources: String, Font, and Color. Each resource is an attribute of the TextItem object and, as such, has a name and a class. For example, the String attribute is name txString, and its class is TxString.

When an object looks up a resource (for example, a color), it passes the complete name and complete class of the resource to a lookup routine. The resource database compares this complete specification against the incomplete specification of entries in the database, finds the best match, and returns the corresponding value for that entry.

Resource file syntax

The syntax of a resource file is a sequence of resource lines terminated by newline characters or end-of-file. The syntax of an individual resource line is:
ResourceLine	= Comment|IncludeFile|ResourceSpec|<empty line>
Comment		= "!" {<any character except null or newline>}
IncludeFile	= "#" WhiteSpace "include" WhiteSpace FileName WhiteSpace
FileName	= <valid filename for operating system>
ResourceSpec	= WhiteSpace ResourceName WhiteSpace ":" WhiteSpace Value
ResourceName	= [Binding] {Component Binding} ComponentName
Binding		= "."|"*"
WhiteSpace	= {<space>|<horizontal tab>}
Component	= "?"|ComponentName
ComponentName	= NameChar {NameChar}
NameChar	= "a"-"z"|"A"-"Z"|"0"-"9"|"_"|"-"
Value		= {<any character except null or unescaped newline>}

Elements separated by vertical bar (|) are alternatives. Curly braces ({...}) indicate zero or more repetitions of the enclosed elements. Square brackets ([...]) indicate that the enclosed element is optional. Quotes ("...") are used around literal characters.

IncludeFile lines are interpreted by replacing the line with the contents of the specified file. The word "include" must be in lowercase. The filename is interpreted relative to the directory of the file in which the line occurs (for example, if the filename contains no directory or contains a relative directory specification).

If a ResourceName contains a contiguous sequence of two or more Binding characters, the sequence will be replaced with a single "." character if the sequence contains only "." characters, otherwise the sequence will be replaced with a single "*" character.

A resource database never contains more than one entry for a given ResourceName. If a resource file contains multiple lines with the same ResourceName, the last line in the file is used.

Any whitespace characters before or after the name or colon in a ResourceSpec are ignored. To allow a Value to begin with whitespace, the two-character sequence "\space" (backslash followed by space) is recognized and replaced by a space character, and the two-character sequence "\tab" (backslash followed by horizontal tab) is recognized and replaced by a horizontal tab character. To allow a Value to contain embedded newline characters, the two-character sequence "\n" is recognized and replaced by a newline character. To allow a Value to contain arbitrary character codes, the four-character sequence "\xxx", where each x is a digit character in the range of "0" to "7", is recognized and replaced with a single byte that contains the octal value specified by the sequence. Finally, the two-character sequence "\\" is recognized and replaced with a single backslash.

As an example of these sequences, the following resource line contains a value consisting of four characters: a backslash, a null, a "z", and a newline:

    
    magic.value:	\\\000\
    z\n
    
    

Resource matching rules

The algorithm for determining which resource database entry matches a given query is the heart of the resource database. All queries must fully specify the name and class of the desired resource (use of "*" and "?" are not permitted). The library supports up to 100 components in a full name or class. Resources are stored in the database with only partially specified names and classes, using pattern matching constructs. An asterisk (*) is a loose binding and is used to represent any number of intervening components, including none. A period (.) is a tight binding and is used to separate immediately adjacent components. A question mark (?) is used to match any single component name or class. A database entry cannot end in a loose binding; the final component (which cannot be "?") must be specified. The lookup algorithm searches the database for the entry that most closely matches (is most specific for) the full name and class being queried. When more than one database entry matches the full name and class, precedence rules are used to select just one.

The full name and class are scanned from left to right (from highest level in the hierarchy to lowest), one component at a time. At each level, the corresponding component and/or binding of each matching entry is determined, and these matching components and bindings are compared according to precedence rules. Each of the rules is applied at each level, before moving to the next level, until a rule selects a single entry over all others. The rules (in order of precedence) are:

  1. An entry that contains a matching component (whether name, class, or "?") takes precedence over entries that elide the level (that is, entries that match the level in a loose binding).
  2. An entry with a matching name takes precedence over both entries with a matching class and entries that match using "?". An entry with a matching class takes precedence over entries that match using "?".
  3. An entry preceded by a tight binding takes precedence over entries preceded by a loose binding.
To illustrate these rules, consider following the resource database entries for example ap01:
    ap01*xWorkstationClass*txFont:	default		(entry A)
    *tx1.Font:			helvetica	(entry B)
    ap01.x*textItemClass*txFont:	times-bold	(entry C)
    ap01.x*?.Font:			courier		(entry D)
    ap01.x*textItemClass.txFont:	courier-bold	(entry E)
    
When NCL or the HLU library tries to determine a default for the Font to use for "tx1", they will query for the resource:
    ap01.x.tx1.txFont				(name)
    appClass.xWorkstationClass.textItemClass.Font	(class)
    
At the first level (ap01, appClass), rule 1 eliminates entry B. At the second level (x, xWorkstationClass), rule 2 eliminates entry A. At the third level (tx1, textItemClass), rule 2 eliminates entry D. At the fourth level (txFont, Font), rule 3 eliminates entry C. Therefore, "tx1" should display its string using a Font of courier-bold.

Note: Most of the resource database software was originally taken from the MIT X11R5 distribution. Also, most of the documentation in this file is taken from the MIT X11R5 distribution. These were modified as needed for use in NCL and the HLU library. This is with the permission granted from the following:

    Documentation

    The X Window System is a trademark of MIT.
    TekHVC is a trademark of Tektronix, Inc.
    Copyright 1985,1986,1987,1988,1989,1990,1991 by Massachusetts Institute of Technology, Cambridge, Massachusetts, and Digital Equipment Corporation, Maynard, Massachusetts.
    Portions Copyright 1990,1991 by Tektronix, Inc.
    Permission to use, copy, modify and distribute this documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in all copies, and that the names of MIT, Digital, and Tektronix not be used in advertising or publicity pertaining to this documentation without specific, written prior permission. MIT, Digital, and Tektronix makes no representations about the suitability of this documentation for any purpose. It is provided "as is" without express or implied warranty.

    Code

    Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard, Massachusetts, and the Massachusetts Institute of Technology, Cambridge, Massachusetts.

    			All Rights Reserved
    
    Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Digital or MIT not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission.

    DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.