|
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; } }