[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.13

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