Annotation of researchv9/X11/src/X.V11R1/lib/Xtk/Xrm.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char rcsid[] = "$Header: Xrm.c,v 1.3 87/09/11 21:25:15 haynes Rel $";
                      3: #endif lint
                      4: 
                      5: /*
                      6:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
                      7:  * 
                      8:  *                         All Rights Reserved
                      9:  * 
                     10:  * Permission to use, copy, modify, and distribute this software and its 
                     11:  * documentation for any purpose and without fee is hereby granted, 
                     12:  * provided that the above copyright notice appear in all copies and that
                     13:  * both that copyright notice and this permission notice appear in 
                     14:  * supporting documentation, and that the name of Digital Equipment
                     15:  * Corporation not be used in advertising or publicity pertaining to
                     16:  * distribution of the software without specific, written prior permission.  
                     17:  * 
                     18:  * 
                     19:  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     20:  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     21:  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     22:  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     23:  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     24:  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     25:  * SOFTWARE.
                     26:  */
                     27: #include       "Xlib.h"
                     28: #include       "Xlibos.h"
                     29: #include       "Xresource.h"
                     30: #include       "XrmConvert.h"
                     31: #include       "Quarks.h"
                     32: #include       <stdio.h>
                     33: #include       <ctype.h>
                     34: 
                     35: extern void bcopy();
                     36: 
                     37: typedef        void (*DBEnumProc)();
                     38: 
                     39: #define HASHSIZE       64
                     40: #define HASHMASK       63
                     41: #define HashIndex(quark)       (quark & HASHMASK)
                     42: 
                     43: /*
                     44: typedef struct _XrmHashBucketRec       *XrmHashBucket;
                     45: */
                     46: typedef struct _XrmHashBucketRec {
                     47:     XrmHashBucket              next;
                     48:     XrmQuark           quark;
                     49:     XrmResourceDataBase        db;
                     50: } XrmHashBucketRec;
                     51: 
                     52: /*
                     53: typedef XrmHashBucket  *XrmHashTable;
                     54: */
                     55: 
                     56: /*
                     57: typedef XrmHashTable XrmSearchList[];
                     58: */
                     59: 
                     60: typedef struct _XrmResourceDataBase {
                     61:     XrmRepresentation  type;
                     62:     XrmValue           val;
                     63:     XrmHashBucket      *hashTable;
                     64:     } XrmResourceDataBaseRec;
                     65: 
                     66: 
                     67: static XrmResourceDataBase rdb = NULL;
                     68: 
                     69: static Bool FindName(quark, hashTable, ppBucket)
                     70:     register   XrmQuark                quark;
                     71:                XrmHashTable    hashTable;
                     72:                XrmHashBucket   **ppBucket;
                     73: {
                     74: /*  search hashTable (which must be non-NULL) for quark.
                     75:     If found, *ppBucket is the address of the XrmHashBucket that points to it.
                     76:     If not,   *ppBucket is the address of the hashTable entry that should 
                     77:              point to a new XrmHashBucket; **ppBucket is the XrmHashBucket it 
                     78:              should point to.
                     79: */
                     80: 
                     81:     register XrmHashBucket *pBucket, *pStartBucket;
                     82:     
                     83:     pBucket = pStartBucket = &hashTable[HashIndex(quark)];
                     84: 
                     85:     while ((*pBucket) != NULL) {
                     86:        if ((*pBucket)->quark == quark) {
                     87:            *ppBucket = pBucket;
                     88:            return True;
                     89:        }
                     90:        pBucket = &((*pBucket)->next);
                     91:     }
                     92:     *ppBucket = pStartBucket;
                     93:     return False;
                     94: }
                     95: 
                     96: 
                     97: static void SetValue(type, val, pdb)
                     98:     XrmRepresentation  type;
                     99:     XrmValue           val;
                    100:     XrmResourceDataBase        *pdb;
                    101: {
                    102:     register   XrmResourceDataBase db = *pdb;
                    103: 
                    104:    if (db == NULL) {
                    105:        *pdb = db = (XrmResourceDataBase) Xmalloc (sizeof(XrmResourceDataBaseRec));
                    106:        db->type = NULLQUARK;
                    107:        db->val.addr = NULL;
                    108:        db->val.size = 0;
                    109:        db->hashTable = NULL;
                    110:     }
                    111: 
                    112:     db->type = type;
                    113:     if (db->val.addr != NULL)
                    114:         Xfree((char *)db->val.addr);
                    115:     db->val.addr = (caddr_t) Xmalloc(val.size);
                    116:     bcopy((char *)val.addr, (char *)db->val.addr, (int) val.size);
                    117:     db->val.size = val.size;
                    118: }
                    119: 
                    120: static void MakeNewDb(quarks, type, val, pdb)
                    121:     register XrmQuarkList      quarks;
                    122:             XrmRepresentation  type;
                    123:             XrmValue           val;
                    124:             XrmResourceDataBase *pdb;
                    125: {
                    126:     register   XrmResourceDataBase db;
                    127:     register   XrmHashBucket       *pBucket, bucket;
                    128: 
                    129:     /* make a new database tree rooted at *pdb, initialized with quark/val */
                    130:     /* quarks[0] can be NULLQUARK, in which case just set the value */
                    131: 
                    132:     for (; *quarks != NULLQUARK; quarks++) {
                    133:        db = *pdb = (XrmResourceDataBase) Xmalloc(sizeof(XrmResourceDataBaseRec));
                    134:        db->type = NULLQUARK;
                    135:        db->val.size = 0;
                    136:        db->val.addr = NULL;
                    137:        db->hashTable = (XrmHashTable) Xmalloc(sizeof(XrmHashBucket) * HASHSIZE);
                    138:        bzero((char *) db->hashTable, sizeof(XrmHashBucket) * HASHSIZE);
                    139:        pBucket = &(db->hashTable[HashIndex(*quarks)]);
                    140:        *pBucket = bucket = (XrmHashBucket) Xmalloc(sizeof(XrmHashBucketRec));
                    141:        bucket->next = NULL;
                    142:        bucket->quark = *quarks;
                    143:        bucket->db = NULL;
                    144:        pdb = &(bucket->db);
                    145:     }
                    146: 
                    147:     SetValue(type, val, pdb);
                    148: }
                    149: 
                    150: static void AddNameToLevel(quarks, pBucket, type, val)
                    151:     XrmQuarkList               quarks;
                    152:     XrmHashBucket              *pBucket;
                    153:     XrmRepresentation  type;
                    154:     XrmValue           val;
                    155: {
                    156:     /* add a new bucket to this level at pBucket */
                    157: 
                    158:     register XrmHashBucket bucket;
                    159: 
                    160:     /* Prepend new bucket to front of list */
                    161:     bucket = (XrmHashBucket) Xmalloc(sizeof(XrmHashBucketRec));
                    162:     bucket->next = *pBucket;
                    163:     *pBucket = bucket;
                    164:     bucket->quark = *quarks;
                    165:     bucket->db = NULL;
                    166: 
                    167:     MakeNewDb(&quarks[1], type, val, &(bucket->db));
                    168: 
                    169: }
                    170: 
                    171: static void PutEntry(quarks, type, val, db)
                    172:     register XrmQuarkList      quarks;
                    173:             XrmRepresentation  type;
                    174:             XrmValue           val;
                    175:     register XrmResourceDataBase       *db;
                    176: {
                    177:     XrmHashBucket *pBucket;
                    178: 
                    179:     for (; *quarks != NULLQUARK; quarks++) {
                    180:        if (*db == NULL) {
                    181:            MakeNewDb(quarks, type, val, db);
                    182:            return;
                    183:        }
                    184:        if (! FindName(*quarks, (*db)->hashTable, &pBucket)) {
                    185:            AddNameToLevel(quarks, pBucket, type, val);
                    186:            return;
                    187:            }
                    188:        db = &((*pBucket)->db);
                    189:        }
                    190: 
                    191:     /* update value for entry i */
                    192:     SetValue(type, val, db);
                    193: 
                    194: }
                    195: 
                    196: static Bool GetEntry(names, classes, type, val, hashTable)
                    197:     register XrmNameList        names;
                    198:     register XrmClassList       classes;
                    199:             XrmRepresentation  *type;
                    200:             XrmValue          *val;
                    201:     register XrmHashTable         hashTable;
                    202: {
                    203:     register XrmHashBucket      bucket;
                    204:     register XrmHashTable       nextHashTable;
                    205: 
                    206:     for (; *names != NULLQUARK; names++, classes++) {
                    207:        bucket = hashTable[HashIndex(*names)];
                    208:        while (bucket != NULL) {
                    209:            if (bucket->quark == *names) {
                    210:                if (names[1] == NULLQUARK) {
                    211:                    *val = bucket->db->val;
                    212:                    /* Must be leaf node with data, else doesn't really match */
                    213:                    if ((*val).addr) {
                    214:                        *type = bucket->db->type;
                    215:                        return True;
                    216:                    } else
                    217:                        return False;
                    218:                } else if ((nextHashTable = bucket->db->hashTable)
                    219:                 && GetEntry(names+1, classes+1, type, val, nextHashTable)) {
                    220:                    return True;
                    221:                } else {
                    222:                    break;
                    223:                }
                    224:            }
                    225:            bucket = bucket->next;
                    226:        }
                    227:        bucket = hashTable[HashIndex(*classes)];
                    228:        while (bucket != NULL) {
                    229:            if (bucket->quark == *classes) {
                    230:                if (classes[1] == NULLQUARK) {
                    231:                    *val = bucket->db->val;
                    232:                    /* Must be leaf node with data, else doesn't really match */
                    233:                    if ((*val).addr) {
                    234:                        *type = bucket->db->type;
                    235:                        return True;
                    236:                    } else
                    237:                        return False;
                    238:                } else if ((nextHashTable = bucket->db->hashTable)
                    239:                 && GetEntry(names+1, classes+1, type, val, nextHashTable)) {
                    240:                    return True;
                    241:                } else {
                    242:                    break;
                    243:                }
                    244:            }
                    245:            bucket = bucket->next;
                    246:        }
                    247:     }
                    248:     return False;
                    249: }
                    250: 
                    251: 
                    252: static int searchListCount;
                    253: 
                    254: static void GetSearchList(names, classes, searchList, hashTable)
                    255:     register XrmNameList  names;
                    256:     register XrmClassList classes;
                    257:     XrmSearchList               searchList;
                    258:     register XrmHashTable       hashTable;
                    259: {
                    260:     register XrmHashBucket      bucket;
                    261:     register XrmHashTable       nextHashTable;
                    262: 
                    263:     for (; *names != NULLQUARK; names++, classes++) {
                    264:        bucket = hashTable[HashIndex(*names)];
                    265:        while (bucket != NULL) {
                    266:            if (bucket->quark == *names) {
                    267:                nextHashTable = bucket->db->hashTable;
                    268:                if (nextHashTable) {
                    269:                    if (names[1] != NULLQUARK)
                    270:                        GetSearchList(names+1,classes+1, 
                    271:                         searchList,nextHashTable);
                    272:                    searchList[searchListCount++] = nextHashTable;
                    273:                }
                    274:                break;
                    275:            }
                    276:            bucket = bucket->next;
                    277:        }
                    278:        bucket = hashTable[HashIndex(*classes)];
                    279:        while (bucket != NULL) {
                    280:            if (bucket->quark == *classes) {
                    281:                nextHashTable = bucket->db->hashTable;
                    282:                if (nextHashTable) {
                    283:                    if (classes[1] != NULLQUARK)
                    284:                        GetSearchList(names+1,classes+1,
                    285:                         searchList,nextHashTable);
                    286:                    searchList[searchListCount++] = nextHashTable;
                    287:                }
                    288:                break;
                    289:            }
                    290:            bucket = bucket->next;
                    291:        }
                    292:     }
                    293: }
                    294: 
                    295: void XrmGetSearchList(names, classes, searchList)
                    296:     XrmNameList  names;
                    297:     XrmClassList classes;
                    298:     XrmSearchList      searchList;     /* RETURN */
                    299: {
                    300:     searchListCount = 0;
                    301:     if (rdb && rdb->hashTable) {
                    302:         GetSearchList(names, classes, searchList, rdb->hashTable);
                    303:         searchList[searchListCount++] = rdb->hashTable;
                    304:     }
                    305:     searchList[searchListCount] = NULL;
                    306: }
                    307: 
                    308: void XrmGetSearchResource(dpy, searchList, name, class, type, pVal)
                    309:             Display    *dpy;
                    310:     register XrmSearchList     searchList;
                    311:     register XrmName   name;
                    312:     register XrmClass  class;
                    313:             XrmRepresentation  type;
                    314:             XrmValue   *pVal;  /* RETURN */
                    315: {
                    316:     register XrmHashBucket     bucket;
                    317:     register int       nameHash = HashIndex(name);
                    318:     register int       classHash = HashIndex(class);
                    319: 
                    320:     for (; (*searchList) != NULL; searchList++) {
                    321:        bucket = (*searchList)[nameHash];
                    322:        while (bucket != NULL) {
                    323:            if (bucket->quark == name) {
                    324:                if (bucket->db->val.addr != NULL) {
                    325:                    /* Leaf node, it really matches */
                    326:                    _XrmConvert(dpy, bucket->db->type, bucket->db->val,
                    327:                         type, pVal);
                    328:                    return;
                    329:                }
                    330:                break;
                    331:            }
                    332:            bucket = bucket->next;
                    333:        }
                    334:        bucket = (*searchList)[classHash];
                    335:        while (bucket != NULL) {
                    336:            if (bucket->quark == class) {
                    337:                if (bucket->db->val.addr != NULL) {
                    338:                    /* Leaf node, it really matches */
                    339:                    _XrmConvert(dpy, bucket->db->type, bucket->db->val,
                    340:                               type, pVal);
                    341:                    return;
                    342:                }
                    343:                break;
                    344:            }
                    345:            bucket = bucket->next;
                    346:        }
                    347:     }
                    348:     (*pVal).addr = NULL;
                    349:     (*pVal).size = 0;
                    350: }
                    351: 
                    352: 
                    353: void XrmPutResource(quarks, type, value)
                    354:     XrmQuarkList               quarks;
                    355:     XrmRepresentation  type;
                    356:     XrmValue           value;
                    357: {
                    358:     PutEntry(quarks, type, value, &rdb);
                    359: }
                    360: 
                    361: void XrmSetCurrentDataBase(db)
                    362:     XrmResourceDataBase        db;
                    363: {
                    364:     rdb = db;
                    365: }
                    366: 
                    367: void XrmGetCurrentDataBase(db)
                    368:     XrmResourceDataBase        *db;
                    369: {
                    370:     if (db != NULL)
                    371:        *db = rdb;
                    372: }
                    373: 
                    374: void XrmGetDataBase(magicCookie, db)
                    375:     FILE               *magicCookie;
                    376:     XrmResourceDataBase        *db;
                    377: {
                    378:     char               buf[1000], *s, *valStr;
                    379:     XrmQuark           nl[100];
                    380:     int                        i;
                    381:     XrmResourceDataBase        odb = rdb;
                    382:     XrmValue           val;
                    383: 
                    384:     *db = NULL;
                    385:     if (magicCookie == NULL)
                    386:        return;
                    387: 
                    388:     rdb = NULL;
                    389:     for (;;) {
                    390:        s = fgets(buf, sizeof(buf), magicCookie);
                    391:        if (s == NULL) break;
                    392:        for (; isspace(s[0]); s++) ;
                    393:        if ((s[0] == '\0') || (s[0] == '#')) continue;
                    394:        i = strlen(s);
                    395:        if (s[i-1] == '\n') s[i-1] = '\0';
                    396:        for (i=0 ; ; i++) {
                    397:            if (s[i] == '\0') {
                    398:                valStr = "";
                    399:                break;
                    400:            }
                    401:            if ((s[i] == ':') || isspace(s[i])) {
                    402:                valStr = &s[i+1];
                    403:                for (; isspace(valStr[0]); valStr++) ;
                    404:                s[i] = '\0';
                    405:                break;
                    406:            }
                    407:        }
                    408:        XrmStringToQuarkList(s, nl);
                    409:        val.size = strlen(valStr)+1;
                    410:        val.addr = (caddr_t) valStr;
                    411:        XrmPutResource(&nl[0], XrmQString, val);
                    412:     }
                    413:     *db = rdb;
                    414:     rdb = odb;
                    415: }
                    416: 
                    417: static void Enum(quarks, count, db, cd, proc)
                    418:     XrmQuarkList       quarks;
                    419:     unsigned   count;
                    420:     XrmResourceDataBase db;
                    421:     unspecified cd;
                    422:     DBEnumProc  proc;
                    423: {
                    424:     unsigned int       i;
                    425:     XrmHashBucket bucket;
                    426: 
                    427:     if (db == NULL) return;
                    428:     if (db->hashTable != NULL) {
                    429:        quarks[count+1] = NULLQUARK;
                    430:        for (i=0; i < HASHSIZE; i++) {
                    431:            bucket = db->hashTable[i];
                    432:            while (bucket != NULL) {
                    433:                quarks[count] = bucket->quark;
                    434:                Enum(quarks, count+1, bucket->db, cd, proc);
                    435:                bucket = bucket->next;
                    436:            }
                    437:        }
                    438:     }
                    439:     quarks[count] = NULLQUARK;
                    440:     if (db->val.addr != NULL) proc(quarks, db->type, db->val, cd);
                    441:     }
                    442: 
                    443: static void EnumerateDataBase(db, cd, proc)
                    444:     XrmResourceDataBase        db;
                    445:     unspecified        cd;
                    446:     DBEnumProc proc;
                    447:     {
                    448:     XrmQuark   nl[100];
                    449:     Enum(nl, 0, db, cd, proc);
                    450: }
                    451: 
                    452: void PrintQuark(quark)
                    453:     XrmQuark   quark;
                    454: {
                    455:     (void) printf("%s", XrmQuarkToAtom(quark));
                    456: }
                    457: 
                    458: void PrintQuarkList(quarks)
                    459:     XrmQuarkList       quarks;
                    460: {
                    461:     Bool       firstNameSeen;
                    462: 
                    463:     for (firstNameSeen = False; (*quarks) != NULLQUARK; quarks++) {
                    464:         if (firstNameSeen) (void) printf(".");
                    465:        firstNameSeen = True;
                    466:        PrintQuark(*quarks);
                    467:     }
                    468: }
                    469: 
                    470: static void DumpEntry(quarks, stream, type, val)
                    471:     XrmQuarkList            quarks;
                    472:     XrmRepresentation type;
                    473:     XrmValue        val;
                    474:     FILE            *stream;
                    475: {
                    476: 
                    477:     register unsigned int      i;
                    478: 
                    479:     for (i=0; quarks[i] != NULLQUARK; i++) {
                    480:        if (i != 0) (void) fprintf(stream, ".");
                    481:        (void) fprintf(stream, "%s", XrmQuarkToAtom(*quarks));
                    482:     }
                    483:     if (type == XrmQString) {
                    484:        (void) fprintf(stream, ":\t%s\n", val.addr);
                    485:     } else {
                    486:        (void) fprintf(stream, "!%s:\t", XrmRepresentationToAtom(type));
                    487:        for (i = 0; i < val.size; i++)
                    488:            (void) fprintf(stream, "%02x", (int) val.addr[i]);
                    489:         (void) fprintf(stream, "\n");
                    490:     }
                    491: }
                    492: 
                    493: void XrmPutDataBase(magicCookie, db)
                    494:     FILE               *magicCookie;
                    495:     XrmResourceDataBase        db;
                    496: {
                    497:     EnumerateDataBase(db, (unspecified) magicCookie, DumpEntry);
                    498: }
                    499: 
                    500: void XrmMergeDataBases(new, into)
                    501:     XrmResourceDataBase        new, *into;
                    502: {
                    503:     EnumerateDataBase(new, (unspecified) into, PutEntry);
                    504: }
                    505: 
                    506: void XrmGetResource(dpy, names, classes, destType, val)
                    507:     Display            *dpy;
                    508:     XrmNameList                names;
                    509:     XrmClassList       classes;
                    510:     XrmRepresentation  destType;
                    511:     XrmValue           *val;
                    512:     {
                    513:     XrmRepresentation  fromType;
                    514:     XrmValue           from;
                    515: 
                    516:     if (rdb && rdb->hashTable
                    517:      && GetEntry(names, classes, &fromType, &from, rdb->hashTable)) {
                    518:        _XrmConvert(dpy, fromType, from, destType, val);
                    519:     } else {
                    520:        (*val).addr = NULL;
                    521:        (*val).size = 0;
                    522:     }
                    523: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.