|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T X
Length: 13919 (0x365f)
Types: TextFile
Names: »Xrm.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
└─⟦eba4602b1⟧ »./isode-5.0.tar.Z«
└─⟦d3ac74d73⟧
└─⟦this⟧ »isode-5.0/others/max/Xrm.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z«
└─⟦de7628f85⟧
└─⟦this⟧ »isode-6.0/others/max/Xrm.c«
#ifndef lint
static char *sccsid = "@(#)Xrm.c 1.17 6/1/87";
#endif lint
/*
* Copyright 1987 by Digital Equipment Corporation, Maynard, 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 appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of Digital Equipment
* Corporation 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.
*/
#include <X/Xlib.h>
#include "Intrinsic.h"
#include "Xrm.h"
#include "XrmConvert.h"
#include "Quarks.h"
#include <stdio.h>
#include <ctype.h>
extern void bcopy();
typedef void (*DBEnumProc)();
#define HASHSIZE 64
#define HASHMASK 63
#define HashIndex(quark) (quark & HASHMASK)
typedef struct _HashBucketRec *HashBucket;
typedef struct _HashBucketRec {
HashBucket next;
XtQuark quark;
ResourceDataBase db;
} HashBucketRec;
typedef HashBucket *HashTable;
typedef struct _ResourceDataBase {
XtRepresentation type;
XrmValue val;
HashBucket *hashTable;
} ResourceDataBaseRec;
static ResourceDataBase rdb = NULL;
static Boolean FindName(quark, hashTable, ppBucket)
register XtQuark quark;
HashTable hashTable;
HashBucket **ppBucket;
{
/* search hashTable (which must be non-NULL) for quark.
If found, *ppBucket is the address of the HashBucket that points to it.
If not, *ppBucket is the address of the hashTable entry that should
point to a new HashBucket; **ppBucket is the HashBucket it
should point to.
*/
register HashBucket *pBucket, *pStartBucket;
pBucket = pStartBucket = &hashTable[HashIndex(quark)];
while ((*pBucket) != NULL) {
if ((*pBucket)->quark == quark) {
*ppBucket = pBucket;
return TRUE;
}
pBucket = &((*pBucket)->next);
}
*ppBucket = pStartBucket;
return FALSE;
}
static void SetValue(type, val, pdb)
XtRepresentation type;
XrmValue val;
ResourceDataBase *pdb;
{
register ResourceDataBase db = *pdb;
if (db == NULL) {
*pdb = db = (ResourceDataBase) XtMalloc (sizeof(ResourceDataBaseRec));
db->type = NULLQUARK;
db->val.addr = NULL;
db->val.size = 0;
db->hashTable = NULL;
}
db->type = type;
if (db->val.addr != NULL)
XtFree((char *)db->val.addr);
db->val.addr = (caddr_t) XtMalloc(val.size);
bcopy((char *)val.addr, (char *)db->val.addr, (int) val.size);
db->val.size = val.size;
}
static void MakeNewDb(quarks, type, val, pdb)
register XtQuarkList quarks;
XtRepresentation type;
XrmValue val;
ResourceDataBase *pdb;
{
register ResourceDataBase db;
register HashBucket *pBucket, bucket;
/* make a new database tree rooted at *pdb, initialized with quark/val */
/* quarks[0] can be NULLQUARK, in which case just set the value */
for (; *quarks != NULLQUARK; quarks++) {
db = *pdb = (ResourceDataBase) XtMalloc(sizeof(ResourceDataBaseRec));
db->type = NULLQUARK;
db->val.size = 0;
db->val.addr = NULL;
db->hashTable = (HashTable) XtMalloc(sizeof(HashBucket) * HASHSIZE);
bzero((char *) db->hashTable, sizeof(HashBucket) * HASHSIZE);
pBucket = &(db->hashTable[HashIndex(*quarks)]);
*pBucket = bucket = (HashBucket) XtMalloc(sizeof(HashBucketRec));
bucket->next = NULL;
bucket->quark = *quarks;
bucket->db = NULL;
pdb = &(bucket->db);
}
SetValue(type, val, pdb);
}
static void AddNameToLevel(quarks, pBucket, type, val)
XtQuarkList quarks;
HashBucket *pBucket;
XtRepresentation type;
XrmValue val;
{
/* add a new bucket to this level at pBucket */
register HashBucket bucket;
/* Prepend new bucket to front of list */
bucket = (HashBucket) XtMalloc(sizeof(HashBucketRec));
bucket->next = *pBucket;
*pBucket = bucket;
bucket->quark = *quarks;
bucket->db = NULL;
MakeNewDb(&quarks[1], type, val, &(bucket->db));
}
static void PutEntry(quarks, type, val, db)
register XtQuarkList quarks;
XtRepresentation type;
XrmValue val;
register ResourceDataBase *db;
{
HashBucket *pBucket;
for (; *quarks != NULLQUARK; quarks++) {
if (*db == NULL) {
MakeNewDb(quarks, type, val, db);
return;
}
if ((*db)->hashTable == NULL) {
(*db)->hashTable = (HashTable) XtMalloc(sizeof(HashBucket)
* HASHSIZE);
bzero((char *) (*db)->hashTable, sizeof(HashBucket) * HASHSIZE);
}
if (! FindName(*quarks, (*db)->hashTable, &pBucket)) {
AddNameToLevel(quarks, pBucket, type, val);
return;
}
db = &((*pBucket)->db);
}
/* update value for entry i */
SetValue(type, val, db);
}
static Boolean GetEntry(names, classes, type, val, hashTable)
register XtNameList names;
register XtClassList classes;
XtRepresentation *type;
XrmValue *val;
register HashTable hashTable;
{
register HashBucket bucket;
register HashTable nextHashTable;
for (; *names != NULLQUARK; names++, classes++) {
bucket = hashTable[HashIndex(*names)];
while (bucket != NULL) {
if (bucket->quark == *names) {
if (names[1] == NULLQUARK) {
*val = bucket->db->val;
/* Must be leaf node with data, else doesn't really match */
if ((*val).addr) {
*type = bucket->db->type;
return TRUE;
} else
return FALSE;
} else if ((nextHashTable = bucket->db->hashTable)
&& GetEntry(names+1, classes+1, type, val, nextHashTable)) {
return TRUE;
} else {
break;
}
}
bucket = bucket->next;
}
bucket = hashTable[HashIndex(*classes)];
while (bucket != NULL) {
if (bucket->quark == *classes) {
if (classes[1] == NULLQUARK) {
*val = bucket->db->val;
/* Must be leaf node with data, else doesn't really match */
if ((*val).addr) {
*type = bucket->db->type;
return TRUE;
} else
return FALSE;
} else if ((nextHashTable = bucket->db->hashTable)
&& GetEntry(names+1, classes+1, type, val, nextHashTable)) {
return TRUE;
} else {
break;
}
}
bucket = bucket->next;
}
}
return FALSE;
}
typedef HashTable *SearchList;
static int searchListCount;
static void GetSearchList(names, classes, searchList, hashTable)
register XtNameList names;
register XtClassList classes;
SearchList searchList;
register HashTable hashTable;
{
register HashBucket bucket;
register HashTable nextHashTable;
for (; *names != NULLQUARK; names++, classes++) {
bucket = hashTable[HashIndex(*names)];
while (bucket != NULL) {
if (bucket->quark == *names) {
nextHashTable = bucket->db->hashTable;
if (nextHashTable) {
if (names[1] != NULLQUARK)
GetSearchList(names+1,classes+1,
searchList,nextHashTable);
searchList[searchListCount++] = nextHashTable;
}
break;
}
bucket = bucket->next;
}
bucket = hashTable[HashIndex(*classes)];
while (bucket != NULL) {
if (bucket->quark == *classes) {
nextHashTable = bucket->db->hashTable;
if (nextHashTable) {
if (classes[1] != NULLQUARK)
GetSearchList(names+1,classes+1,
searchList,nextHashTable);
searchList[searchListCount++] = nextHashTable;
}
break;
}
bucket = bucket->next;
}
}
}
void XrmGetSearchList(names, classes, searchList)
XtNameList names;
XtClassList classes;
SearchList searchList; /* RETURN */
{
searchListCount = 0;
if (rdb && rdb->hashTable) {
GetSearchList(names, classes, searchList, rdb->hashTable);
searchList[searchListCount++] = rdb->hashTable;
}
searchList[searchListCount] = NULL;
}
void XrmGetSearchResource(searchList, name, class, type, pVal)
register SearchList searchList;
register XtName name;
register XtClass class;
XtAtom type;
XrmValue *pVal; /* RETURN */
{
register HashBucket bucket;
register int nameHash = HashIndex(name);
register int classHash = HashIndex(class);
for (; (*searchList) != NULL; searchList++) {
bucket = (*searchList)[nameHash];
while (bucket != NULL) {
if (bucket->quark == name) {
if (bucket->db->val.addr != NULL) {
/* Leaf node, it really matches */
XrmConvert(bucket->db->type, bucket->db->val,
XtAtomToRepresentation(type), pVal);
return;
}
break;
}
bucket = bucket->next;
}
bucket = (*searchList)[classHash];
while (bucket != NULL) {
if (bucket->quark == class) {
if (bucket->db->val.addr != NULL) {
/* Leaf node, it really matches */
XrmConvert(bucket->db->type, bucket->db->val,
XtAtomToRepresentation(type), pVal);
return;
}
break;
}
bucket = bucket->next;
}
}
(*pVal).addr = NULL;
(*pVal).size = 0;
}
void XrmPutResource(quarks, type, value)
XtQuarkList quarks;
XtRepresentation type;
XrmValue value;
{
PutEntry(quarks, type, value, &rdb);
}
void XtSetCurrentDataBase(db)
ResourceDataBase db;
{
rdb = db;
}
void XtGetCurrentDataBase(db)
ResourceDataBase *db;
{
*db = rdb;
}
void XtFreeDataBase (db)
ResourceDataBase db;
{
unsigned int i;
HashBucket b;
if (db == NULL)
return;
if (db -> hashTable != NULL) {
for (i = 0; i < HASHSIZE; i++)
for (b = db -> hashTable[i]; b != NULL; b = b -> next) {
XtFreeDataBase (b -> db);
XtFree ((char *) b);
}
}
if (db -> val.addr != NULL)
XtFree ((char *) db -> val.addr);
XtFree ((char *) db);
if (db == rdb)
rdb = NULL;
}
void XtGetDataBase(magicCookie, db)
FILE *magicCookie;
ResourceDataBase *db;
{
char buf[1000], *s, *valStr;
XtQuark nl[100];
int i;
ResourceDataBase odb = rdb;
XrmValue val;
*db = NULL;
rdb = NULL;
if (magicCookie == NULL) return;
for (;;) {
s = fgets(buf, sizeof(buf), magicCookie);
if (s == NULL) break;
for (; isspace(s[0]); s++) ;
if ((s[0] == '\0') || (s[0] == '#') ||
((s[0] == '\\') && (s[1] == '#'))) continue;
i = strlen(s);
if (s[i-1] == '\n') s[i-1] = '\0';
for (i=0 ; ; i++) {
if (s[i] == '\0') {
valStr = "";
break;
}
if ((s[i] == ':') || isspace(s[i])) {
valStr = &s[i+1];
for (; isspace(valStr[0]); valStr++) ;
s[i] = '\0';
break;
}
}
XtStringToQuarkList(s, nl);
val.size = strlen(valStr)+1;
val.addr = (caddr_t) valStr;
XrmPutResource(&nl[0], XtQString, val);
}
*db = rdb;
rdb = odb;
}
static void Enum(quarks, count, db, cd, proc)
XtQuarkList quarks;
unsigned count;
ResourceDataBase db;
unspecified cd;
DBEnumProc proc;
{
unsigned int i;
HashBucket bucket;
if (db == NULL) return;
if (db->hashTable != NULL) {
quarks[count+1] = NULLQUARK;
for (i=0; i < HASHSIZE; i++) {
bucket = db->hashTable[i];
while (bucket != NULL) {
quarks[count] = bucket->quark;
Enum(quarks, count+1, bucket->db, cd, proc);
bucket = bucket->next;
}
}
}
quarks[count] = NULLQUARK;
if (db->val.addr != NULL) (*(proc))(quarks, db->type, db->val, cd);
}
static void EnumerateDataBase(db, cd, proc)
ResourceDataBase db;
unspecified cd;
DBEnumProc proc;
{
XtQuark nl[100];
Enum(nl, 0, db, cd, proc);
}
void PrintQuark(quark)
XtQuark quark;
{
(void) printf("%s", XtQuarkToAtom(quark));
}
void PrintQuarkList(quarks)
XtQuarkList quarks;
{
Boolean firstNameSeen;
for (firstNameSeen = FALSE; (*quarks) != NULLQUARK; quarks++) {
if (firstNameSeen) (void) printf(".");
firstNameSeen = TRUE;
PrintQuark(*quarks);
}
}
static void DumpEntry(quarks, type, val, stream)
XtQuarkList quarks;
XtRepresentation type;
XrmValue val;
FILE *stream;
{
register unsigned int i;
register char *cp;
for (cp = "%s"; *quarks != NULLQUARK; cp = ".%s")
(void) fprintf(stream, cp, XtQuarkToAtom(*quarks++));
if (type == XtQString) {
(void) fprintf(stream, ":\t%s\n", val.addr);
} else {
(void) fprintf(stream, "!%s:\t", XtRepresentationToAtom(type));
for (i = 0; i < val.size; i++)
(void) fprintf(stream, "%02x", (int) val.addr[i]);
(void) fprintf(stream, "\n");
}
}
void XtPutDataBase(magicCookie, db)
FILE *magicCookie;
ResourceDataBase db;
{
EnumerateDataBase(db, (unspecified) magicCookie, DumpEntry);
}
void XtEnumDataBase(tag, proc, db)
caddr_t tag;
DBEnumProc proc;
ResourceDataBase db;
{
EnumerateDataBase(db, (unspecified) tag, proc);
}
void XtMergeDataBases(new, into)
ResourceDataBase new, *into;
{
EnumerateDataBase(new, (unspecified) into, PutEntry);
}
void XrmGetResource(names, classes, destType, val)
XtNameList names;
XtClassList classes;
XtRepresentation destType;
XrmValue *val;
{
XtRepresentation fromType;
XrmValue from;
if (rdb && rdb->hashTable
&& GetEntry(names, classes, &fromType, &from, rdb->hashTable)) {
XrmConvert(fromType, from, destType, val);
} else {
(*val).addr = NULL;
(*val).size = 0;
}
}