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

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

unix.superglobalmegacorp.com

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