DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T X

⟦9ce9bade1⟧ TextFile

    Length: 13919 (0x365f)
    Types: TextFile
    Names: »Xrm.c«

Derivation

└─⟦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« 

TextFile

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