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

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

unix.superglobalmegacorp.com

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