Annotation of 43BSDTahoe/new/X/Xlib/XGetDefault.c, revision 1.1

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

unix.superglobalmegacorp.com

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