CustomizeDoc.tioga
Copyright Ó 1989, 1991 by Xerox Corporation. All rights reserved.
Written by: Christian Jacobi
Christian Jacobi, November 22, 1991 3:40 pm PST
THE CUSTOMIZE INTERFACE
Customize
Documentation for the Customize Interface
Christian P. Jacobi
© Copyright 1989, 1991 Xerox Corporation. All rights reserved.
Abstract: The Customize interface defines a database manager, including queries. It serves similar purposes as a user profile would, however there is more expressive power and no restriction to a single file.
The data base file syntax and query precedence rules are a superset of the X-Window standard for resource files.
Created by: Christian P. Jacobi
Maintained by: Jacobi.pa
Keywords: customization, userprofile, xrdb, database, resources
XEROX   Xerox Corporation
    Palo Alto Research Center
    3333 Coyote Hill Road
    Palo Alto, California 94304

1. Introduction
What it does
Some people call this a database; I think of it more as a glorified userprofile.
This is kind of a simple data base system. The entries in this profile are of the form <key>: <value>. Queries are a subset of regular expressions; on a query the value is returned where its key matches; Very often several entries do match; there is a precedence order defined so the best match is returned. It is sort of unusual but quite interesting that queries don't have wildcards; but the database entries may have wildcards. This is handy in user-profile like applications where a database access should find a font, or a color: The query is well defined by the program requiring the value, but the database might be human written and contain all kinds of generalizations.
<COPY PAGES 324-327 OF THE X BOOK>
The interface has three parts:
Input and updating of databases.
Building queries.
Querying the data base.
Relationship to X Windows
The idea comes from X Windows. However this package in no way imports or implies X Windows..
This package can read unmodified X Window resource files. This makes it usefull in the X Window application, but its main advantage is: Go read the X Windows documentation; I don't have to write it. Heureka.
There are some features missing: The X Windows version does allow batching of similar queries for speed reasons. This has not been implemented here because we do pre-processing of the database when it is created. Furthermore, I believe typical queries will contain only small number of components. Query types are reusable, which allows to do multiple queries without memory allocations.
2. Formats
The database format
Whitespace <" "> or <"\t"> is ignored except in ComponentName and String
ResourceFile  = {ResourceLine ("\n" | "\l")}.
ResourceLine = Comment | ResourceSpec
Comment  = "!" String | <empty line>
ResourceSpec  = ResourceName ":" Value
ResourceName  = [Binding] ComponentName {Binding ComponentName}
Binding  = "." | "*" | "?"
ComponentName = { "a"-"z" | "A"-"Z" | "0"-"9" | "←" | "-"}
Value   = String
String   = {<any character not including "\n" or "\l">}
This is a superset of the standard X window xrdb format.
The query format
Query  = QueryStep { QueryStep }.
QueryStep  = "(" ComponentName {"|" ComponentName} ")".
The parsed format is more lenient. Restrict usage to the defined format to not get surprised on internal changes.
Precedence order:
1) Left components are more specific than right components.
2) Database entries with explicite component names are more specific then database entries using wildcards ("*", "?"). Database entries with "?" are more specific then database entries using "*"
3) ComponentName's names which occur to the left of other ComponentName's in the same QueryStep are more specific then ComponentName's to the right.
Examples
For the data base
!
! ExampleCustomize.xrdb
!
defaultFont:    Helvetica
otherFont:    TimesRoman
*scrollbar.color:   blue
mailtool*scrollbar.color:      red
mailtool?scrollbar.pixel:      276
mailtool.mainwindow.scrollbar.pixel:   275
mailtool.mainwindow.scrollbar.color:   green
commandtool*size:  23
*Container.size:   32
mailtool.mainwindow.pixel:     133
Some query results
"(defaultFont | otherFont) " ==> Helvetica
precedence rule 2
"(mailtool | tool) (mainwindow | Container) (scrollbar | Scrollbar) (color)" ==> green
precedence rule 1
"(mailtool | tool) (mumble | Container) (scrollbar | Scrollbar) (color | pixel)" ==> red
precedence rule 1
"(mailtool | tool) (mumble | Container) (foreground | Foo) ==> <NIL>
no match found
"(commandtool) (Container) (size)" => 23
precedence rule 3
3. The Interface
AnyString: TYPE = REF; --Either ROPE or REF TEXT
Programming hints
Errors: Four classes of errors are distinguished.
1) A database might have a syntax error. This is considered an user error; Customize tries to continue and returns just an error message to its caller.
2) A query might be malformed. This is a client error which causes an error to be raised.
3) A returned value might have an unexpected form. This is a user error, and the client application has to deal with that; Customize doesn't notice.
4) A type converter might raise an error. This is considered a client error. It is assumed that the conversion goal type sufficiently restrict type converters to the ones desired by the client application.
Multi-programming: The obvious care is recommended.
1) Constructing the same query, or, updating the same database from different threads is an error.
2) Querying a database while updating it might cause the query to miss an entry. The database itself is not affected.
3) Multiple queries on the same database need not be monitored.
4) Changing the query data while a query is in progress may cause the query to fail, but it will not affect the database. Do not use the same query concurrently on different databases.
Database creation
DBreadonly: TYPE = REF READONLY DBRec;
DB: TYPE = REF DBRec;
The database representation.
DBRec: PRIVATE TYPE;
CreateDB: PROC [] RETURNS [DB];
Creates new, empty DB.
UpdateDB: PROC [db: DB, stream: IO.STREAM] RETURNS [errors: ROPE];
Parse <stream> and merge database entries into <db>. If a specification is identical to one that already exists, the later one takes precedence.
UpdateDBString: PROC [db: DB, string: AnyString] RETURNS [errors: ROPE];
Parse <string> and and merge database entries into <db>.
UpdateDBExplicite: PROC [db: DB, key: AnyString, value: REF] RETURNS [errors: ROPE];
Parse <key> and add <value> as database entry into <db>.
Database values may be overwriten, but, they can't be removed.
UpdateDBFromFile: PROC [file: REF, inputDb: DBNIL] RETURNS [db: DB, errors: ROPE];
Conveniance procedure: <inputDb> is updated and returned again. <file> a STREAM or a string (string is interpreted as a file name). Not found files are reported like syntax errors in the data base.
Querying
DoQuery: PROC [db: DBreadonly, query: Query] RETURNS [REF];
Query the database <db> with <query>.
DoQueryString: PROC [db: DBreadonly, string: AnyString ← NIL] RETURNS [REF];
Conveniance procedure.
Query the database <db> strings.
Query construction
Query: TYPE = REF QueryRep;
QueryRep: TYPE;
Even doing queries might have side effects on QueryRep.
QueryState: PROC [query: Query] RETURNS [state: NAT];
Returns <state> of query in construction. Meaning of numerical value is private.
NewQuery: PROC [reserve: NAT ← 16, useMemory: Query ← NIL] RETURNS [Query];
Creates new empty query. Query does not yet have any steps or options.
<reserve>: allocates enough memory for about <reserve> steps or options.
ResetQuery: PROC [query: Query, state: NAT ← 0];
Resets state of query to <state>. <state>=0 means reset to empty.
CopyQuery: PROC [query: Query, reserve: NAT ← 0] RETURNS [Query];
Creates new copy which does not share memory with query.
<reserve> is a guess: allocates enough memory to append about <reserve> more steps or options.
AppendStepOnly: PROC [query: Query] RETURNS [Query];
Appends step to <query>; The new step has no options yet.
Returns <query> or new query if new memory allocation needed.
AppendOptionOnly: PROC [query: Query, option: AnyString ← NIL] RETURNS [Query];
Append query option to the current step of <query>.
<query> must not be empty.
Returns <query> or new query if new memory allocation needed.
AppendStep: PROC [query: Query, val1, val2: AnyString ← NIL] RETURNS [Query];
Conveniance proc
Appends step to <query>; Also appends up to two options to new step.
Returns <query> or new query if new memory allocation needed.
FreeQuery: PRIVATE PROC [query: Query];
Returns query for re-use. Caller asserts that he won't modify query anymore.
It is ok to not worry but leave query's to the garbage collector.
ParseQuery: PROC [string: AnyString ← NIL] RETURNS [Query];
Parses <string> into a query.
May raise error QueryError.
QueryError: ERROR [what: ROPE];
4. References
The thing inspiring this package
X WINDOW SYSTEM
C Library and Protocol Reference
Robert W. Scheifler, James Gettys, Ron Newman
Chapter 10.11. Using the Resource Manager describes the X Window version of this functionality. Pages 324 and 325 are interesting.
Chapter 10.11.1. Resource Manager Matching Rules [page 326 and 327] describes the format of the resource data base files.
These four pages should be scanned in, into this document.
5. Restrictions
Temporary restriction
Since I don't want to deal with all the DFS, UFS, TFS... until we have PFS, the procedure accessing a database from a file must be used with caution. It might not be implemented in some worlds.
6. Open Design Questions
What do you think?
Use SymTab instead of Atoms and RefTab for arquivalency?. Build a localized atom table which can be garbage collected together with the db? The interface does hide this!
Done November 22, 1991 3:31:13 pm PST
Have a default db [~user profile like]. Problem: thats NOT the one you want to use with X.
Extend the database format? like a symbol which matches exactly one component? X11R5 brought that.
Done November 22, 1991 3:31:13 pm PST
Extend query formats? Wildcards in query? Warning: Query must not be less efficient; otherwise I can't use it any more with X.
Is it worth while introducing Database operations? Copy a database?. Merge two data bases?
Is it worth while introducing any feature which won't really be used by the X software? Will it have other users?.