Annotation of cci/usr/src/bin/cdb/tk.c, revision 1.1.1.1

1.1       root        1: static char sccsid[] = "@(#)tk.c       2.6";
                      2: 
                      3: #include <ctype.h>
                      4: #include "cdb.h"
                      5: 
                      6: #define        chTab   '\t'
                      7: #define        chSpace ' '
                      8: #define chUnder        '_'
                      9: #define chDollar '$'
                     10: #define        chBackSlash '\\'
                     11: 
                     12: export int     vcbTok, vcbPeek;
                     13: export TKE     vtk, vtkPeek;
                     14: export char    vsbTok[100], vsbTokPeek[100];
                     15: export LCE     vlc;    /* the current language which has precedence */
                     16: 
                     17: #define icmdMax 20
                     18: int    vicmdMac;
                     19: char   *vrgCmd[icmdMax];       /* where we push command pointers */
                     20: 
                     21: typedef struct {       /* keyword */
                     22:        char    *sbKey;
                     23:        short   tk;
                     24: } 
                     25: KWR, *pKWR;
                     26: #define cbKWR  sizeof(KWR)
                     27: #define kwNil ((pKWR)0)
                     28: 
                     29: KWR vrgKwCdb[] = {
                     30:        "$in",  tkInside,
                     31: };
                     32: #define ikwCdbMax (sizeof(vrgKwCdb)/cbKWR)
                     33: 
                     34: KWR vrgKwC[] = {
                     35:        "sizeof",       tkSizeof,
                     36: };
                     37: #define ikwCMax (sizeof(vrgKwC)/cbKWR)
                     38: 
                     39: KWR vrgKwFor[] = {
                     40:        ".NE.", tkNotEqual,
                     41:        ".EQ.", tkEqual,
                     42:        ".LT.", tkLT,
                     43:        ".LE.", tkLE,
                     44:        ".GT.", tkGT,
                     45:        ".GE.", tkGE,
                     46: };
                     47: #define ikwForMax (sizeof(vrgKwFor)/cbKWR)
                     48: 
                     49: KWR vrgKwPas[] = {
                     50:        "and",  tkLAND,
                     51:        "or",   tkLOR,
                     52:        "not",  tkBang,
                     53:        "div",  tkDiv,
                     54:        "mod",  tkModulo,
                     55: };
                     56: #define ikwPasMax (sizeof(vrgKwPas)/cbKWR)
                     57: 
                     58: #define isodigit(ch) (isdigit(ch) && (ch!='8') && (ch!='9'))
                     59: 
                     60: 
                     61: /* T K   F   K W */
                     62: 
                     63: export void TkFKw(ptk, sbKey, rgKw, ikwMax)
                     64: TKE    *ptk;
                     65: char   *sbKey;
                     66: pKWR   rgKw;
                     67: int    ikwMax;
                     68: {
                     69:        int             i;
                     70:        for (i=0; i < ikwMax; i++) {
                     71:                if (FSbCmp(sbKey, rgKw[i].sbKey)) {
                     72:                        *ptk = rgKw[i].tk;
                     73:                        return;
                     74:                }
                     75:        }
                     76: } /* TkFKw */
                     77: 
                     78: 
                     79: /* C H   F   E S C A P E */
                     80: 
                     81: local char ChFEscape(psbIn)
                     82: char   **psbIn;
                     83: {
                     84:        int             i, val;
                     85:        char    ch;
                     86: 
                     87:        ch = **psbIn;
                     88:        (*psbIn)++;
                     89:        if (ch != chBackSlash)
                     90:                return(ch);     /* vanilla flavored char */
                     91:        ch = **psbIn;
                     92:        (*psbIn)++;
                     93:        switch (ch) {
                     94:        case 'b':       
                     95:                return('\b');
                     96:        case 'f':       
                     97:                return('\f');
                     98:        case 'n':       
                     99:                return('\n');
                    100:        case 'r':       
                    101:                return('\r');
                    102:        case 't':       
                    103:                return('\t');
                    104:        case '\\':      
                    105:                return('\\');
                    106:        case '\'':      
                    107:                return('\'');
                    108:        case '0': 
                    109:        case '1': 
                    110:        case '2': 
                    111:        case '3':
                    112:        case '4': 
                    113:        case '5': 
                    114:        case '6': 
                    115:        case '7':
                    116:                /* it is an arbitrary 1-3 octal digit thingie */
                    117:                val = 0;
                    118:                for (i=0; i<3; i++) {
                    119:                        val = (val * 8) + (ch - '0');
                    120:                        ch = **psbIn;   /* look at NEXT character */
                    121:                        if (!isodigit(ch))
                    122:                                break;
                    123:                        (*psbIn)++;     /* is good digit, advance str pointer */
                    124:                } /* for */
                    125:                return(val);
                    126:        } /* switch */
                    127:        return(ch);     /* by default we just ignore the backslash */
                    128: } /* ChFEscape */
                    129: 
                    130: 
                    131: /* T K   F   S T R */
                    132: 
                    133: export TKE TkFStr(psbCmd, sbTok, pcb)
                    134: char   **psbCmd, *sbTok;
                    135: int    *pcb;
                    136: {
                    137:        int             i;
                    138:        char    ch, *sbCmd, *sbStart, sbT[10];
                    139:        TKE             tk;
                    140: 
                    141:        /* given a string, copy first token to safe place and advance string */
                    142: 
                    143:        sbCmd = *psbCmd;
                    144:        if (sbCmd == sbNil)
                    145:                return(tkNil);
                    146: 
                    147:        while (*sbCmd != chNull AND *sbCmd == chTab OR *sbCmd == chSpace)
                    148:                sbCmd++;        /* eat leading tabs and spaces */
                    149:        if (*sbCmd == chNull) {
                    150:                *pcb = 0;
                    151:                sbTok[0] = chNull;
                    152:                return(tkNil);
                    153:        } /* if */
                    154: 
                    155:        sbStart = sbCmd; /* remember where we started */
                    156: 
                    157:        tk = tkNil;
                    158:        ch = *sbCmd++;
                    159:        if (isalpha(ch)
                    160:            OR (ch == chUnder)
                    161:            OR (ch == chDollar)) {  /* string (var|command) token */
                    162:                tk = tkStr;
                    163:                while (isalnum(*sbCmd)
                    164:                    OR *sbCmd == chUnder) 
                    165:                        sbCmd++;
                    166:        } 
                    167:        else if (isdigit(ch)) { /* number */
                    168:                tk = tkNumber;
                    169:                if ((ch == '0') AND (*sbCmd == 'x')) {
                    170:                        sbCmd++; /* it's a hex number */
                    171:                        while (isxdigit(*sbCmd))
                    172:                                sbCmd++;
                    173:                } 
                    174:                else {
                    175:                        while (isdigit(*sbCmd))
                    176:                                sbCmd++;
                    177:                } /* if */
                    178:        } 
                    179:        else if (ispunct(ch)) {
                    180:                /* hopefully an interesting operator or something */
                    181:                switch (ch) {
                    182:                case '[':       
                    183:                        tk = tkLSB;     
                    184:                        break;
                    185:                case ']':       
                    186:                        tk = tkRSB;     
                    187:                        break;
                    188:                case '(':       
                    189:                        tk = tkLP;      
                    190:                        break;
                    191:                case ')':       
                    192:                        tk = tkRP;      
                    193:                        break;
                    194:                case '{':       
                    195:                        tk = tkLCB;     
                    196:                        break;
                    197:                case '}':       
                    198:                        tk = tkRCB;     
                    199:                        break;
                    200:                case '?':       
                    201:                        tk = tkQuest;   
                    202:                        break;
                    203:                case '@':       
                    204:                        tk = tkAt;      
                    205:                        break;
                    206:                case '$':       
                    207:                        tk = tkDollar;  
                    208:                        break;
                    209:                case '#':       
                    210:                        tk = tkHash;    
                    211:                        break;
                    212:                case ';':       
                    213:                        tk = tkSemi;    
                    214:                        break;
                    215:                case ',':       
                    216:                        tk = tkComma;   
                    217:                        break;
                    218:                case '_':       
                    219:                        tk = tkUnderScore; 
                    220:                        break;
                    221:                case '\\':      
                    222:                        tk = tkBackSlash; 
                    223:                        break;
                    224:                case '\'':      
                    225:                        tk = tkCharConstant;
                    226:                        sbTok[0] = ChFEscape(&sbCmd);
                    227:                        if (*sbCmd != '\'')
                    228:                                UError("Character constant is missing ending '");
                    229:                        sbCmd++;
                    230:                        *pcb = 1;
                    231:                        goto special;
                    232:                case '"':       
                    233:                        tk = tkStrConstant;
                    234:                        i = 0;
                    235:                        while ((*sbCmd != chNull) AND (*sbCmd != '"')) {
                    236:                                sbTok[i] = ChFEscape(&sbCmd);
                    237:                                i++;
                    238:                        } /* while */
                    239:                        if (*sbCmd != '"')
                    240:                                UError("String constant is missing ending \"");
                    241:                        sbCmd++;
                    242:                        *pcb = i;
                    243:                        goto special;
                    244:                case '.':       
                    245:                        tk = tkDot;
                    246:                        if (vlc != lcFortran)
                    247:                                break;
                    248:                        if (sbCmd[2] == '.') {
                    249:                                /* we have '.XX.' - might be a relop */
                    250:                                strncpy(sbT, sbCmd-1, 4); /* get the whole thing */
                    251:                                TkFKw(&tk, sbT, vrgKwFor, ikwForMax);
                    252:                                if (tk != tkDot) {
                    253:                                        /* we have a hit */
                    254:                                        sbCmd += 3;
                    255:                                }
                    256:                        }
                    257:                        break;
                    258:                case ':':       
                    259:                        tk = tkColon;
                    260:                        if (*sbCmd == '=') {
                    261:                                sbCmd++;
                    262:                                tk = tkAssign;
                    263:                        } /* if */
                    264:                        break;
                    265:                case '+':       
                    266:                        tk = tkPlus;
                    267:                        if (*sbCmd == '=') {
                    268:                                sbCmd++;
                    269:                                tk = tkAssPlus;
                    270:                        } /* if */
                    271:                        break;
                    272:                case '-':       
                    273:                        tk = tkMinus;
                    274:                        if (*sbCmd == '>') {
                    275:                                sbCmd++;
                    276:                                tk = tkPtr;
                    277:                        } 
                    278:                        else if (*sbCmd == '=') {
                    279:                                sbCmd++;
                    280:                                tk = tkAssMinus;
                    281:                        } /* if */
                    282:                        break;
                    283:                case '*':       
                    284:                        tk = tkStar;
                    285:                        if (*sbCmd == '=') {
                    286:                                sbCmd++;
                    287:                                tk = tkAssMult;
                    288:                        } /* if */
                    289:                        break;
                    290:                case '/':       
                    291:                        tk = tkSlash;
                    292:                        if (*sbCmd == '/') {
                    293:                                sbCmd++;
                    294:                                tk = tkDiv;
                    295:                                if (*sbCmd == '=') {
                    296:                                        sbCmd++;
                    297:                                        tk = tkAssDiv;
                    298:                                } /* if */
                    299:                        } /* if */
                    300:                        break;
                    301:                case '%':       
                    302:                        tk = tkModulo;
                    303:                        if (*sbCmd == '=') {
                    304:                                sbCmd++;
                    305:                                tk = tkAssMod;
                    306:                        } /* if */
                    307:                        break;
                    308:                case '&':       
                    309:                        tk = tkBitAnd;
                    310:                        if (*sbCmd == '&') {
                    311:                                sbCmd++;
                    312:                                tk = tkLAND;
                    313:                        } 
                    314:                        else if (*sbCmd == '=') {
                    315:                                sbCmd++;
                    316:                                tk = tkAssBAND;
                    317:                        } /* if */
                    318:                        break;
                    319:                case '|':       
                    320:                        tk = tkBitOr;
                    321:                        if (*sbCmd == '|') {
                    322:                                sbCmd++;
                    323:                                tk = tkLOR;
                    324:                        } 
                    325:                        else if (*sbCmd == '=') {
                    326:                                sbCmd++;
                    327:                                tk = tkAssBOR;
                    328:                        } /* if */
                    329:                        break;
                    330:                case '^':       
                    331:                        tk = tkXOR;
                    332:                        if (*sbCmd == '=') {
                    333:                                sbCmd++;
                    334:                                tk = tkAssXOR;
                    335:                        } 
                    336:                        else if (*sbCmd == '.') {
                    337:                                if (vlc == lcPascal) {
                    338:                                        sbCmd++;
                    339:                                        tk = tkPtr;
                    340:                                }
                    341:                        } /* if */
                    342:                        break;
                    343:                case '~':       
                    344:                        tk = tkTilda;
                    345:                        break;
                    346:                case '!':       
                    347:                        tk = tkBang;
                    348:                        if (*sbCmd == '=') {
                    349:                                sbCmd++;
                    350:                                tk = tkNotEqual;
                    351:                        } /* if */
                    352:                        break;
                    353:                case '=':       
                    354:                        if (vlc == lcPascal) {
                    355:                                tk = tkEqual;
                    356:                        } 
                    357:                        else {
                    358:                                tk = tkAssign;
                    359:                                if (*sbCmd == '=') {
                    360:                                        sbCmd++;
                    361:                                        tk = tkEqual;
                    362:                                } /* if */
                    363:                        }
                    364:                        break;
                    365:                case '<':       
                    366:                        tk = tkLT;
                    367:                        if (*sbCmd == '=') {
                    368:                                sbCmd++;
                    369:                                tk = tkLE;
                    370:                        } 
                    371:                        else if (*sbCmd =='<') {
                    372:                                sbCmd++;
                    373:                                tk = tkLShift;
                    374:                                if (*sbCmd == '=') {
                    375:                                        sbCmd++;
                    376:                                        tk = tkAssLeft;
                    377:                                } /* if */
                    378:                        } 
                    379:                        else if (*sbCmd == '>') {
                    380:                                sbCmd++;
                    381:                                tk = tkNotEqual;
                    382:                        } /* if */
                    383:                        break;
                    384:                case '>':       
                    385:                        tk = tkGT;
                    386:                        if (*sbCmd == '=') {
                    387:                                sbCmd++;
                    388:                                tk = tkGE;
                    389:                        } 
                    390:                        else if (*sbCmd =='>') {
                    391:                                sbCmd++;
                    392:                                tk = tkRShift;
                    393:                                if (*sbCmd == '=') {
                    394:                                        sbCmd++;
                    395:                                        tk = tkAssRight;
                    396:                                } /* if */
                    397:                        } /* if */
                    398:                        break;
                    399:                } /* switch */
                    400:        } 
                    401:        else { /* it's  <something else> !! */
                    402:                tk = tkOther;
                    403:        } /* if */
                    404: 
                    405:        *pcb = sbCmd - sbStart;
                    406:        strncpy(sbTok, sbStart, *pcb);
                    407: 
                    408: special:       /* used by character and string constant routines */
                    409:        sbTok[*pcb] = chNull;
                    410:        *psbCmd = sbCmd;
                    411: 
                    412:        if (tk == tkStr) {
                    413:                TkFKw(&tk, sbTok, vrgKwCdb, ikwCdbMax);
                    414:                switch (vlc) {
                    415:                case lcC:               
                    416:                        TkFKw(&tk, sbTok, vrgKwC, ikwCMax); 
                    417:                        break;
                    418:                case lcPascal:  
                    419:                        TkFKw(&tk, sbTok, vrgKwPas, ikwPasMax); 
                    420:                        break;
                    421:                case lcFortran: 
                    422:                        TkFKw(&tk, sbTok, vrgKwFor, ikwForMax); 
                    423:                        break;
                    424:                } /* switch */
                    425:        }
                    426: 
                    427:        return(tk);
                    428: } /* TkFStr */
                    429: 
                    430: 
                    431: /* P O P   C M D */
                    432: 
                    433: export char * PopCmd()
                    434: {
                    435:        if (vicmdMac == 0)
                    436:                return(sbNil);
                    437:        return(vrgCmd[--vicmdMac]);
                    438: } /* PopCmd */
                    439: 
                    440: 
                    441: /* P U S H   C M D */
                    442: 
                    443: export void PushCmd(sbCmd)
                    444: char   *sbCmd;
                    445: {
                    446:        if (sbCmd == sbNil OR *sbCmd == chNull)
                    447:                return;
                    448:        if (vicmdMac >= icmdMax) {
                    449:                vicmdMac = 0;
                    450:                Panic("Too much command nesting - flushing everything");
                    451:        } /* if */
                    452:        vrgCmd[vicmdMac++] = sbCmd;
                    453: } /* PushCmd */
                    454: 
                    455: 
                    456: /* T K   P E E K */
                    457: 
                    458: export TKE TkPeek()
                    459: {
                    460:        char    *sbCmd;
                    461:        /* used to peek at next token in global command line */
                    462:        sbCmd = vsbCmd;
                    463:        vtkPeek = TkFStr(&sbCmd, vsbTokPeek, &vcbPeek);
                    464:        return(vtkPeek);
                    465: } /* TkPeek */
                    466: 
                    467: 
                    468: /* T K   N E X T */
                    469: 
                    470: export TKE TkNext()
                    471: {
                    472:        /* used by most routines to eat next token in the global command line */
                    473:        while ((vtk = TkFStr(&vsbCmd, vsbTok, &vcbTok)) == tkNil) {
                    474:                if (vicmdMac == 0)
                    475:                        return(tkNil);
                    476:                vsbCmd = PopCmd();
                    477:        } /* while */
                    478:        return(vtk);
                    479: } /* TkNext */

unix.superglobalmegacorp.com

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