Annotation of researchv9/X11/src/X.V11R1/lib/X/XGetDflt.c, revision 1.1

1.1     ! root        1: #include <copyright.h>
        !             2: 
        !             3: /* $Header: XGetDflt.c,v 10.14 87/09/11 23:19:14 sun Exp $ */
        !             4: /* Copyright (c) 1985, Massachusetts Institute of Technology */
        !             5: 
        !             6: /*
        !             7:  * This routine returns options out of the X user preferences file
        !             8:  * found in XDEFAULT, possibly modified by the .Xdefaults in the user's home
        !             9:  * directory.  It either returns a pointer to
        !            10:  * the option or returns NULL if option not set.  It is patterned after
        !            11:  * Andrew's file format (why be different for the sake of being different?).
        !            12:  * Andrew's code was NOT examined before writing this routine.
        !            13:  * It parses lines of the format "progname.option:value" and returns a pointer
        !            14:  * to value.
        !            15:  */
        !            16: 
        !            17: #include <stdio.h>
        !            18: #include <strings.h>
        !            19: #include <ctype.h>
        !            20: #include "Xlib.h"
        !            21: #include "Xutil.h"
        !            22: #include "Xlibos.h"
        !            23: /* #include "Xdefault.h" */
        !            24: #define XDEFAULTS "/usr/lib/X11/Xdefaults"
        !            25: 
        !            26: #define XOPTIONFILE "/.Xdefaults"      /* name in home directory of options
        !            27:                                           file. */
        !            28: #define XOPTIONFILE2 "/.X11defaults"   /* additional hack; look here first */
        !            29: 
        !            30: static struct ent {
        !            31:        struct ent *left;               /* next option to left          */
        !            32:        struct ent *right;              /* next option to right         */
        !            33:        char *oname;                    /* option name                  */
        !            34:        char *value;                    /* value for that option        */
        !            35:        char bal;                       /* for avl use                  */
        !            36: } *head;
        !            37: 
        !            38: /*ARGSUSED*/
        !            39: char *XGetDefault(dpy, prog, name)
        !            40:        Display *dpy;                   /* display to talk to */
        !            41:        char *prog;                     /* name of program for option   */
        !            42:        register char *name;            /* name of option program wants */
        !            43: {                                      /* to get, for example, "font"  */
        !            44:        static nent = -1;               /* have we been here before?    */
        !            45:        register struct ent *cur;       /* current entry being examined */
        !            46:        register int cmp;
        !            47:        char namebuf[64];
        !            48:        register char *pv = namebuf;
        !            49: 
        !            50:        strncpy(namebuf, name, sizeof(namebuf));
        !            51:        while (*pv) {                   /* convert upper to lower       */
        !            52:                if (isupper(*pv))  *pv += 040;
        !            53:                pv++;
        !            54:        }
        !            55:        if (nent == -1)
        !            56:                nent = ReadFile(prog);/* if not, parse the file.*/
        !            57:        if (nent == 0)
        !            58:                return(NULL);
        !            59:        cur = head;
        !            60:        do {
        !            61:                if ((cmp = strcmp(namebuf, cur->oname)) == 0)
        !            62:                        return(cur->value);
        !            63:                cur = cmp > 0 ? cur->right : cur->left;
        !            64:        } while (cur != NULL);
        !            65:        return(NULL);                   /* if no match, let him know    */
        !            66: }
        !            67: 
        !            68: static ReadFile(prog)
        !            69:        char *prog;                     /* program name to match            */
        !            70: {
        !            71:        register char *point,*colon;    /* where in the line the keys are   */
        !            72:        register char *oname, *val;     /* new memory for valid option line */
        !            73:        register FILE *fptr = NULL;     /* preferences file                 */
        !            74:        register char *pv;              /* pointer to value for lowering    */
        !            75:        register int len;
        !            76:        register int nentries = 0;      /* number of entries found          */
        !            77:        register int first;
        !            78:        char fname[BUFSIZ];             /* longer than any conceivable size */
        !            79:        char line[BUFSIZ];              /* line buffer for each line of file*/
        !            80:        char *getenv();
        !            81:        char *home = getenv("HOME");
        !            82: 
        !            83:        if ((pv = rindex(prog,'/')) != NULL)
        !            84:                prog = pv + 1;  /* if full path, get last component */
        !            85:     for(first = 2 ; first >= 0 ; first--) {
        !            86:        switch (first) {
        !            87:          case 2: /* Use any defaults in XDEFAULTS. */
        !            88:                fptr = fopen(XDEFAULTS, "r");
        !            89:                break;
        !            90: 
        !            91:          case 1:
        !            92:                if (home != NULL) {
        !            93:                  strcpy(fname, home);    /* form full path name of file  */
        !            94:                  strcat(fname, XOPTIONFILE);
        !            95:                  fptr = fopen(fname, "r");
        !            96:                } else
        !            97:                  fptr = NULL;
        !            98:                break;
        !            99: 
        !           100:           case 0:
        !           101:                /* read this in last, so entries supercede */
        !           102:                if (home != NULL) {             /* try home directory */
        !           103:                  strcpy(fname, home);    /* form full path name of file  */
        !           104:                  strcat(fname, XOPTIONFILE2);
        !           105:                  fptr = fopen(fname, "r");
        !           106:                } else
        !           107:                  fptr = NULL;
        !           108:        }
        !           109:        if(fptr == NULL)
        !           110:                continue;
        !           111:        while ( fgets(line, sizeof(line), fptr) != NULL ) {
        !           112:                if (line[0] == '#') continue;           /* comment?     */
        !           113:                point = index(line,'.');
        !           114:                colon = index(line,':');
        !           115:                if ( (point == NULL) || (colon == NULL) || (colon < point) )
        !           116:                        continue;       /* both . and : required on line*/
        !           117:                *point = 0;
        !           118:                if ( point != line )    /* check all chars up to '.'    */
        !           119:                        if (strcmp(line, prog) != 0)
        !           120:                                continue;
        !           121: 
        !           122:                /* 
        !           123:                 * ok, we've passed all the tests, so it is a valid option for
        !           124:                 * this program, or is global option.
        !           125:                 */
        !           126: 
        !           127:                len = strlen(colon);
        !           128:                if(colon[len-1] == '\n')
        !           129:                        colon[len-1] = '\0';    /* braindamaged fgets call */
        !           130:                /*
        !           131:                 * allocate space for text
        !           132:                 */
        !           133:                point++;
        !           134:                len = colon - point;
        !           135:                for(colon++ ; isspace(*colon) ; colon++); /* skip over spaces */
        !           136:                if((oname = (char *)Xmalloc(len + strlen(colon) + 2)) == NULL) {
        !           137:                        fprintf(stderr, "ReadFile: Out of memory\n");
        !           138:                        exit(1);
        !           139:                }
        !           140:                strncpy(oname, point, len);
        !           141:                oname[len] = 0;
        !           142:                pv = oname;
        !           143:                while (*pv) {           /* convert upper to lower       */
        !           144:                        if (isupper(*pv))
        !           145:                                *pv += 040;
        !           146:                        pv++;
        !           147:                }
        !           148:                val = oname + len + 1;
        !           149:                strcpy(val, colon);
        !           150:                insert(oname, val, &head);
        !           151:                nentries++;
        !           152:        }
        !           153:        fclose(fptr);
        !           154:     }
        !           155:        return(nentries);
        !           156: }
        !           157: 
        !           158: /*
        !           159:  * Modified from "Algorithms + Data Structures = Programs", Niklaus Wirth,
        !           160:  * 1976, section 4.4.7 Balanced Tree Insertion, page 220-221.
        !           161:  */
        !           162: #define        L_EQUILIBRATED  2
        !           163: #define        LEFTSLANTED     1
        !           164: #define        L_REBALANCE     0
        !           165: 
        !           166: #define        R_EQUILIBRATED  0
        !           167: #define        RIGHTSLANTED    1
        !           168: #define        R_REBALANCE     2
        !           169: 
        !           170: static insert(name, val, ent)
        !           171: register char *name, *val;
        !           172: register struct ent **ent;
        !           173: {
        !           174:        register struct ent *ent1, *ent2;
        !           175:        register int cmp;
        !           176: 
        !           177:        if(*ent == NULL) {      /* not in tree, insert it */
        !           178:                if((*ent = (struct ent *)Xcalloc(1, sizeof(struct ent))) ==
        !           179:                 NULL) {
        !           180:                        fprintf(stderr, "insert: Out of memory\n");
        !           181:                        exit(1);
        !           182:                }
        !           183:                (*ent)->oname = name;
        !           184:                (*ent)->value = val;
        !           185:                (*ent)->bal = LEFTSLANTED;
        !           186:                return(1);
        !           187:        }
        !           188:        if((cmp = strcmp(name, (*ent)->oname)) == 0) {  /* match */
        !           189:                free((*ent)->oname);
        !           190:                (*ent)->oname = name;
        !           191:                (*ent)->value = val;
        !           192:                return(0);
        !           193:        }
        !           194:        if(cmp < 0) {
        !           195:                if(!insert(name, val, &(*ent)->left))
        !           196:                        return(0);
        !           197:                /* left branch has grown higher */
        !           198:                switch((*ent)->bal) {
        !           199:                 case L_EQUILIBRATED:
        !           200:                        (*ent)->bal = LEFTSLANTED;
        !           201:                        return(0);
        !           202:                 case LEFTSLANTED:
        !           203:                        (*ent)->bal = L_REBALANCE;
        !           204:                        return(1);
        !           205:                 case L_REBALANCE:      /* rebalance */
        !           206:                        if((ent1 = (*ent)->left)->bal == L_REBALANCE) {
        !           207:                          /* single LL rotation */
        !           208:                                (*ent)->left = ent1->right;
        !           209:                                ent1->right = *ent;
        !           210:                                (*ent)->bal = LEFTSLANTED;
        !           211:                                *ent = ent1;
        !           212:                        } else {
        !           213:                          /* double LR rotation */
        !           214:                                ent2 = ent1->right;
        !           215:                                ent1->right = ent2->left;
        !           216:                                ent2->left = ent1;
        !           217:                                (*ent)->left = ent2->right;
        !           218:                                ent2->right = *ent;
        !           219:                                (*ent)->bal = (ent2->bal == L_REBALANCE) ?
        !           220:                                 L_EQUILIBRATED : LEFTSLANTED;
        !           221:                                ent1->bal = (ent2->bal == L_EQUILIBRATED) ?
        !           222:                                 L_REBALANCE : LEFTSLANTED;
        !           223:                                *ent = ent2;
        !           224:                        }
        !           225:                        (*ent)->bal = LEFTSLANTED;
        !           226:                        return(0);
        !           227:                }
        !           228:        }
        !           229:        if(!insert(name, val, &(*ent)->right))
        !           230:                return(0);
        !           231:        /* right branch has grown higher */
        !           232:        switch((*ent)->bal) {
        !           233:         case R_EQUILIBRATED:
        !           234:                (*ent)->bal = RIGHTSLANTED;
        !           235:                return(0);
        !           236:         case RIGHTSLANTED:
        !           237:                (*ent)->bal = R_REBALANCE;
        !           238:                return(1);
        !           239:         case R_REBALANCE:      /* rebalance */
        !           240:                if((ent1 = (*ent)->right)->bal == R_REBALANCE) {
        !           241:                  /* single RR rotation */
        !           242:                        (*ent)->right = ent1->left;
        !           243:                        ent1->left = *ent;
        !           244:                        (*ent)->bal = RIGHTSLANTED;
        !           245:                        *ent = ent1;
        !           246:                } else {
        !           247:                  /* double RL rotation */
        !           248:                        ent2 = ent1->left;
        !           249:                        ent1->left = ent2->right;
        !           250:                        ent2->right = ent1;
        !           251:                        (*ent)->right = ent2->left;
        !           252:                        ent2->left = *ent;
        !           253:                        (*ent)->bal = (ent2->bal == R_REBALANCE) ?
        !           254:                         R_EQUILIBRATED : RIGHTSLANTED;
        !           255:                        ent1->bal = (ent2->bal == R_EQUILIBRATED) ?
        !           256:                         R_REBALANCE : RIGHTSLANTED;
        !           257:                        *ent = ent2;
        !           258:                }
        !           259:                (*ent)->bal = RIGHTSLANTED;
        !           260:                return(0);
        !           261:        }
        !           262: }

unix.superglobalmegacorp.com

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