[BACK]Return to rpc_scan.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / rpcgen

Annotation of src/usr.bin/rpcgen/rpc_scan.c, Revision 1.1

1.1     ! deraadt     1: /*     $NetBSD: rpc_scan.c,v 1.4 1995/06/11 21:50:02 pk Exp $  */
        !             2: /*
        !             3:  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
        !             4:  * unrestricted use provided that this legend is included on all tape
        !             5:  * media and as a part of the software program in whole or part.  Users
        !             6:  * may copy or modify Sun RPC without charge, but are not authorized
        !             7:  * to license or distribute it to anyone else except as part of a product or
        !             8:  * program developed by the user or with the express written consent of
        !             9:  * Sun Microsystems, Inc.
        !            10:  *
        !            11:  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
        !            12:  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
        !            13:  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
        !            14:  *
        !            15:  * Sun RPC is provided with no support and without any obligation on the
        !            16:  * part of Sun Microsystems, Inc. to assist in its use, correction,
        !            17:  * modification or enhancement.
        !            18:  *
        !            19:  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
        !            20:  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
        !            21:  * OR ANY PART THEREOF.
        !            22:  *
        !            23:  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
        !            24:  * or profits or other special, indirect and consequential damages, even if
        !            25:  * Sun has been advised of the possibility of such damages.
        !            26:  *
        !            27:  * Sun Microsystems, Inc.
        !            28:  * 2550 Garcia Avenue
        !            29:  * Mountain View, California  94043
        !            30:  */
        !            31:
        !            32: #ifndef lint
        !            33: static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI";
        !            34: #endif
        !            35:
        !            36: /*
        !            37:  * rpc_scan.c, Scanner for the RPC protocol compiler
        !            38:  * Copyright (C) 1987, Sun Microsystems, Inc.
        !            39:  */
        !            40: #include <sys/cdefs.h>
        !            41: #include <stdlib.h>
        !            42: #include <stdio.h>
        !            43: #include <ctype.h>
        !            44: #include <string.h>
        !            45: #include "rpc_scan.h"
        !            46: #include "rpc_parse.h"
        !            47: #include "rpc_util.h"
        !            48:
        !            49: static unget_token __P((token *tokp));
        !            50: static findstrconst __P((char **, char **));
        !            51: static findchrconst __P((char **, char **));
        !            52: static findconst __P((char **, char **));
        !            53: static findkind __P((char **, token *));
        !            54: static cppline __P((char *));
        !            55: static directive __P((char *));
        !            56: static printdirective __P((char *));
        !            57: static docppline __P((char *, int *, char **));
        !            58:
        !            59: #define startcomment(where) (where[0] == '/' && where[1] == '*')
        !            60: #define endcomment(where) (where[-1] == '*' && where[0] == '/')
        !            61:
        !            62: static int pushed = 0; /* is a token pushed */
        !            63: static token lasttok;  /* last token, if pushed */
        !            64:
        !            65: /*
        !            66:  * scan expecting 1 given token
        !            67:  */
        !            68: void
        !            69: scan(expect, tokp)
        !            70:        tok_kind expect;
        !            71:        token *tokp;
        !            72: {
        !            73:        get_token(tokp);
        !            74:        if (tokp->kind != expect) {
        !            75:                expected1(expect);
        !            76:        }
        !            77: }
        !            78:
        !            79: /*
        !            80:  * scan expecting any of the 2 given tokens
        !            81:  */
        !            82: void
        !            83: scan2(expect1, expect2, tokp)
        !            84:        tok_kind expect1;
        !            85:        tok_kind expect2;
        !            86:        token *tokp;
        !            87: {
        !            88:        get_token(tokp);
        !            89:        if (tokp->kind != expect1 && tokp->kind != expect2) {
        !            90:                expected2(expect1, expect2);
        !            91:        }
        !            92: }
        !            93:
        !            94: /*
        !            95:  * scan expecting any of the 3 given token
        !            96:  */
        !            97: void
        !            98: scan3(expect1, expect2, expect3, tokp)
        !            99:        tok_kind expect1;
        !           100:        tok_kind expect2;
        !           101:        tok_kind expect3;
        !           102:        token *tokp;
        !           103: {
        !           104:        get_token(tokp);
        !           105:        if (tokp->kind != expect1 && tokp->kind != expect2
        !           106:            && tokp->kind != expect3) {
        !           107:                expected3(expect1, expect2, expect3);
        !           108:        }
        !           109: }
        !           110:
        !           111: /*
        !           112:  * scan expecting a constant, possibly symbolic
        !           113:  */
        !           114: void
        !           115: scan_num(tokp)
        !           116:        token *tokp;
        !           117: {
        !           118:        get_token(tokp);
        !           119:        switch (tokp->kind) {
        !           120:        case TOK_IDENT:
        !           121:                break;
        !           122:        default:
        !           123:                error("constant or identifier expected");
        !           124:        }
        !           125: }
        !           126:
        !           127: /*
        !           128:  * Peek at the next token
        !           129:  */
        !           130: void
        !           131: peek(tokp)
        !           132:        token *tokp;
        !           133: {
        !           134:        get_token(tokp);
        !           135:        unget_token(tokp);
        !           136: }
        !           137:
        !           138: /*
        !           139:  * Peek at the next token and scan it if it matches what you expect
        !           140:  */
        !           141: int
        !           142: peekscan(expect, tokp)
        !           143:        tok_kind expect;
        !           144:        token *tokp;
        !           145: {
        !           146:        peek(tokp);
        !           147:        if (tokp->kind == expect) {
        !           148:                get_token(tokp);
        !           149:                return (1);
        !           150:        }
        !           151:        return (0);
        !           152: }
        !           153:
        !           154: /*
        !           155:  * Get the next token, printing out any directive that are encountered.
        !           156:  */
        !           157: void
        !           158: get_token(tokp)
        !           159:        token *tokp;
        !           160: {
        !           161:        int commenting;
        !           162:
        !           163:        if (pushed) {
        !           164:                pushed = 0;
        !           165:                *tokp = lasttok;
        !           166:                return;
        !           167:        }
        !           168:        commenting = 0;
        !           169:        for (;;) {
        !           170:                if (*where == 0) {
        !           171:                        for (;;) {
        !           172:                                if (!fgets(curline, MAXLINESIZE, fin)) {
        !           173:                                        tokp->kind = TOK_EOF;
        !           174:                                        *where = 0;
        !           175:                                        return;
        !           176:                                }
        !           177:                                linenum++;
        !           178:                                if (commenting) {
        !           179:                                        break;
        !           180:                                } else if (cppline(curline)) {
        !           181:                                        docppline(curline, &linenum,
        !           182:                                                  &infilename);
        !           183:                                } else if (directive(curline)) {
        !           184:                                        printdirective(curline);
        !           185:                                } else {
        !           186:                                        break;
        !           187:                                }
        !           188:                        }
        !           189:                        where = curline;
        !           190:                } else if (isspace(*where)) {
        !           191:                        while (isspace(*where)) {
        !           192:                                where++;        /* eat */
        !           193:                        }
        !           194:                } else if (commenting) {
        !           195:                        for (where++; *where; where++) {
        !           196:                                if (endcomment(where)) {
        !           197:                                        where++;
        !           198:                                        commenting--;
        !           199:                                        break;
        !           200:                                }
        !           201:                        }
        !           202:                } else if (startcomment(where)) {
        !           203:                        where += 2;
        !           204:                        commenting++;
        !           205:                } else {
        !           206:                        break;
        !           207:                }
        !           208:        }
        !           209:
        !           210:        /*
        !           211:         * 'where' is not whitespace, comment or directive Must be a token!
        !           212:         */
        !           213:        switch (*where) {
        !           214:        case ':':
        !           215:                tokp->kind = TOK_COLON;
        !           216:                where++;
        !           217:                break;
        !           218:        case ';':
        !           219:                tokp->kind = TOK_SEMICOLON;
        !           220:                where++;
        !           221:                break;
        !           222:        case ',':
        !           223:                tokp->kind = TOK_COMMA;
        !           224:                where++;
        !           225:                break;
        !           226:        case '=':
        !           227:                tokp->kind = TOK_EQUAL;
        !           228:                where++;
        !           229:                break;
        !           230:        case '*':
        !           231:                tokp->kind = TOK_STAR;
        !           232:                where++;
        !           233:                break;
        !           234:        case '[':
        !           235:                tokp->kind = TOK_LBRACKET;
        !           236:                where++;
        !           237:                break;
        !           238:        case ']':
        !           239:                tokp->kind = TOK_RBRACKET;
        !           240:                where++;
        !           241:                break;
        !           242:        case '{':
        !           243:                tokp->kind = TOK_LBRACE;
        !           244:                where++;
        !           245:                break;
        !           246:        case '}':
        !           247:                tokp->kind = TOK_RBRACE;
        !           248:                where++;
        !           249:                break;
        !           250:        case '(':
        !           251:                tokp->kind = TOK_LPAREN;
        !           252:                where++;
        !           253:                break;
        !           254:        case ')':
        !           255:                tokp->kind = TOK_RPAREN;
        !           256:                where++;
        !           257:                break;
        !           258:        case '<':
        !           259:                tokp->kind = TOK_LANGLE;
        !           260:                where++;
        !           261:                break;
        !           262:        case '>':
        !           263:                tokp->kind = TOK_RANGLE;
        !           264:                where++;
        !           265:                break;
        !           266:
        !           267:        case '"':
        !           268:                tokp->kind = TOK_STRCONST;
        !           269:                findstrconst(&where, &tokp->str);
        !           270:                break;
        !           271:        case '\'':
        !           272:                tokp->kind = TOK_CHARCONST;
        !           273:                findchrconst(&where, &tokp->str);
        !           274:                break;
        !           275:
        !           276:        case '-':
        !           277:        case '0':
        !           278:        case '1':
        !           279:        case '2':
        !           280:        case '3':
        !           281:        case '4':
        !           282:        case '5':
        !           283:        case '6':
        !           284:        case '7':
        !           285:        case '8':
        !           286:        case '9':
        !           287:                tokp->kind = TOK_IDENT;
        !           288:                findconst(&where, &tokp->str);
        !           289:                break;
        !           290:
        !           291:        default:
        !           292:                if (!(isalpha(*where) || *where == '_')) {
        !           293:                        char buf[100];
        !           294:                        char *p;
        !           295:
        !           296:                        s_print(buf, "illegal character in file: ");
        !           297:                        p = buf + strlen(buf);
        !           298:                        if (isprint(*where)) {
        !           299:                                s_print(p, "%c", *where);
        !           300:                        } else {
        !           301:                                s_print(p, "%d", *where);
        !           302:                        }
        !           303:                        error(buf);
        !           304:                }
        !           305:                findkind(&where, tokp);
        !           306:                break;
        !           307:        }
        !           308: }
        !           309:
        !           310: static
        !           311: unget_token(tokp)
        !           312:        token *tokp;
        !           313: {
        !           314:        lasttok = *tokp;
        !           315:        pushed = 1;
        !           316: }
        !           317:
        !           318: static
        !           319: findstrconst(str, val)
        !           320:        char **str;
        !           321:        char **val;
        !           322: {
        !           323:        char *p;
        !           324:        int size;
        !           325:
        !           326:        p = *str;
        !           327:        do {
        !           328:                *p++;
        !           329:        } while (*p && *p != '"');
        !           330:        if (*p == 0) {
        !           331:                error("unterminated string constant");
        !           332:        }
        !           333:        p++;
        !           334:        size = p - *str;
        !           335:        *val = alloc(size + 1);
        !           336:        (void) strncpy(*val, *str, size);
        !           337:        (*val)[size] = 0;
        !           338:        *str = p;
        !           339: }
        !           340:
        !           341: static
        !           342: findchrconst(str, val)
        !           343:        char **str;
        !           344:        char **val;
        !           345: {
        !           346:        char *p;
        !           347:        int size;
        !           348:
        !           349:        p = *str;
        !           350:        do {
        !           351:                *p++;
        !           352:        } while (*p && *p != '\'');
        !           353:        if (*p == 0) {
        !           354:                error("unterminated string constant");
        !           355:        }
        !           356:        p++;
        !           357:        size = p - *str;
        !           358:        if (size != 3) {
        !           359:                error("empty char string");
        !           360:        }
        !           361:        *val = alloc(size + 1);
        !           362:        (void) strncpy(*val, *str, size);
        !           363:        (*val)[size] = 0;
        !           364:        *str = p;
        !           365: }
        !           366:
        !           367: static
        !           368: findconst(str, val)
        !           369:        char **str;
        !           370:        char **val;
        !           371: {
        !           372:        char *p;
        !           373:        int size;
        !           374:
        !           375:        p = *str;
        !           376:        if (*p == '0' && *(p + 1) == 'x') {
        !           377:                p++;
        !           378:                do {
        !           379:                        p++;
        !           380:                } while (isxdigit(*p));
        !           381:        } else {
        !           382:                do {
        !           383:                        p++;
        !           384:                } while (isdigit(*p));
        !           385:        }
        !           386:        size = p - *str;
        !           387:        *val = alloc(size + 1);
        !           388:        (void) strncpy(*val, *str, size);
        !           389:        (*val)[size] = 0;
        !           390:        *str = p;
        !           391: }
        !           392:
        !           393: static token symbols[] = {
        !           394:                          {TOK_CONST, "const"},
        !           395:                          {TOK_UNION, "union"},
        !           396:                          {TOK_SWITCH, "switch"},
        !           397:                          {TOK_CASE, "case"},
        !           398:                          {TOK_DEFAULT, "default"},
        !           399:                          {TOK_STRUCT, "struct"},
        !           400:                          {TOK_TYPEDEF, "typedef"},
        !           401:                          {TOK_ENUM, "enum"},
        !           402:                          {TOK_OPAQUE, "opaque"},
        !           403:                          {TOK_BOOL, "bool"},
        !           404:                          {TOK_VOID, "void"},
        !           405:                          {TOK_CHAR, "char"},
        !           406:                          {TOK_INT, "int"},
        !           407:                          {TOK_UNSIGNED, "unsigned"},
        !           408:                          {TOK_SHORT, "short"},
        !           409:                          {TOK_LONG, "long"},
        !           410:                          {TOK_FLOAT, "float"},
        !           411:                          {TOK_DOUBLE, "double"},
        !           412:                          {TOK_STRING, "string"},
        !           413:                          {TOK_PROGRAM, "program"},
        !           414:                          {TOK_VERSION, "version"},
        !           415:                          {TOK_EOF, "??????"},
        !           416: };
        !           417:
        !           418: static
        !           419: findkind(mark, tokp)
        !           420:        char **mark;
        !           421:        token *tokp;
        !           422: {
        !           423:        int len;
        !           424:        token *s;
        !           425:        char *str;
        !           426:
        !           427:        str = *mark;
        !           428:        for (s = symbols; s->kind != TOK_EOF; s++) {
        !           429:                len = strlen(s->str);
        !           430:                if (strncmp(str, s->str, len) == 0) {
        !           431:                        if (!isalnum(str[len]) && str[len] != '_') {
        !           432:                                tokp->kind = s->kind;
        !           433:                                tokp->str = s->str;
        !           434:                                *mark = str + len;
        !           435:                                return;
        !           436:                        }
        !           437:                }
        !           438:        }
        !           439:        tokp->kind = TOK_IDENT;
        !           440:        for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
        !           441:        tokp->str = alloc(len + 1);
        !           442:        (void) strncpy(tokp->str, str, len);
        !           443:        tokp->str[len] = 0;
        !           444:        *mark = str + len;
        !           445: }
        !           446:
        !           447: static
        !           448: cppline(line)
        !           449:        char *line;
        !           450: {
        !           451:        return (line == curline && *line == '#');
        !           452: }
        !           453:
        !           454: static
        !           455: directive(line)
        !           456:        char *line;
        !           457: {
        !           458:        return (line == curline && *line == '%');
        !           459: }
        !           460:
        !           461: static
        !           462: printdirective(line)
        !           463:        char *line;
        !           464: {
        !           465:        f_print(fout, "%s", line + 1);
        !           466: }
        !           467:
        !           468: static
        !           469: docppline(line, lineno, fname)
        !           470:        char *line;
        !           471:        int *lineno;
        !           472:        char **fname;
        !           473: {
        !           474:        char *file;
        !           475:        int num;
        !           476:        char *p;
        !           477:
        !           478:        line++;
        !           479:        while (isspace(*line)) {
        !           480:                line++;
        !           481:        }
        !           482:        num = atoi(line);
        !           483:        while (isdigit(*line)) {
        !           484:                line++;
        !           485:        }
        !           486:        while (isspace(*line)) {
        !           487:                line++;
        !           488:        }
        !           489:        if (*line != '"') {
        !           490:                error("preprocessor error");
        !           491:        }
        !           492:        line++;
        !           493:        p = file = alloc(strlen(line) + 1);
        !           494:        while (*line && *line != '"') {
        !           495:                *p++ = *line++;
        !           496:        }
        !           497:        if (*line == 0) {
        !           498:                error("preprocessor error");
        !           499:        }
        !           500:        *p = 0;
        !           501:        if (*file == 0) {
        !           502:                *fname = NULL;
        !           503:        } else {
        !           504:                *fname = file;
        !           505:        }
        !           506:        *lineno = num - 1;
        !           507: }