<<>> <> <> <> <> <<>> 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 : . 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. 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 | ResourceSpec = ResourceName ":" Value ResourceName = [Binding] ComponentName {Binding ComponentName} Binding = "." | "*" | "?" ComponentName = { "a"-"z" | "A"-"Z" | "0"-"9" | "_" | "-"} Value = String String = {} 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) ==> no match found "(commandtool) (Container) (size)" => 23 precedence rule 3 3. The Interface AnyString: TYPE = REF; --Either ROPE or REF TEXT <> <<>> <> <<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.>> <<>> <> <<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.>> <<>> <<>> <> DBreadonly: TYPE = REF READONLY DBRec; DB: TYPE = REF DBRec; <> DBRec: PRIVATE TYPE; CreateDB: PROC [] RETURNS [DB]; <> UpdateDB: PROC [db: DB, stream: IO.STREAM] RETURNS [errors: ROPE]; < and merge database entries into . If a specification is identical to one that already exists, the later one takes precedence. >> <<>> UpdateDBString: PROC [db: DB, string: AnyString] RETURNS [errors: ROPE]; < and and merge database entries into . >> <<>> UpdateDBExplicite: PROC [db: DB, key: AnyString, value: REF] RETURNS [errors: ROPE]; < and add as database entry into . >> <> <<>> UpdateDBFromFile: PROC [file: REF, inputDb: DB _ NIL] RETURNS [db: DB, errors: ROPE]; < is updated and returned again. a STREAM or a string (string is interpreted as a file name). Not found files are reported like syntax errors in the data base.>> <> DoQuery: PROC [db: DBreadonly, query: Query] RETURNS [REF]; < with . >> DoQueryString: PROC [db: DBreadonly, string: AnyString _ NIL] RETURNS [REF]; <> < strings.>> <> Query: TYPE = REF QueryRep; QueryRep: TYPE; <> QueryState: PROC [query: Query] RETURNS [state: NAT]; < of query in construction. Meaning of numerical value is private. >> NewQuery: PROC [reserve: NAT _ 16, useMemory: Query _ NIL] RETURNS [Query]; <> <<: allocates enough memory for about steps or options.>> ResetQuery: PROC [query: Query, state: NAT _ 0]; <. =0 means reset to empty.>> CopyQuery: PROC [query: Query, reserve: NAT _ 0] RETURNS [Query]; <> << is a guess: allocates enough memory to append about more steps or options.>> <<>> AppendStepOnly: PROC [query: Query] RETURNS [Query]; <; The new step has no options yet.>> < or new query if new memory allocation needed.>> <<>> AppendOptionOnly: PROC [query: Query, option: AnyString _ NIL] RETURNS [Query]; <. >> << must not be empty.>> < or new query if new memory allocation needed.>> <<>> AppendStep: PROC [query: Query, val1, val2: AnyString _ NIL] RETURNS [Query]; <> <; Also appends up to two options to new step.>> < or new query if new memory allocation needed.>> <<>> FreeQuery: PRIVATE PROC [query: Query]; <> <> ParseQuery: PROC [string: AnyString _ NIL] RETURNS [Query]; < into a query. >> <> 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! <> 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. <> 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?. <<>>