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

Annotation of src/usr.bin/rpcgen/rpc_parse.c, Revision 1.1.1.1

1.1       deraadt     1: /*     $NetBSD: rpc_parse.c,v 1.5 1995/08/29 23:05:55 cgd 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_parse.c 1.8 89/02/22 (C) 1987 SMI";
                     34: #endif
                     35:
                     36: /*
                     37:  * rpc_parse.c, Parser for the RPC protocol compiler
                     38:  * Copyright (C) 1987 Sun Microsystems, Inc.
                     39:  */
                     40: #include <stdio.h>
                     41: #include <stdlib.h>
                     42: #include <string.h>
                     43: #include "rpc/types.h"
                     44: #include "rpc_scan.h"
                     45: #include "rpc_parse.h"
                     46: #include "rpc_util.h"
                     47:
                     48: #define ARGNAME "arg"
                     49:
                     50: static isdefined __P((definition *));
                     51: static def_struct __P((definition *));
                     52: static def_program __P((definition *));
                     53: static def_enum __P((definition *));
                     54: static def_const __P((definition *));
                     55: static def_union __P((definition *));
                     56: static def_typedef __P((definition *));
                     57: static get_declaration __P((declaration *, defkind));
                     58: static get_prog_declaration __P((declaration *, defkind, int));
                     59: static get_type __P((char **, char **, defkind));
                     60: static unsigned_dec __P((char **));
                     61:
                     62: /*
                     63:  * return the next definition you see
                     64:  */
                     65: definition *
                     66: get_definition()
                     67: {
                     68:        definition *defp;
                     69:        token tok;
                     70:
                     71:        defp = ALLOC(definition);
                     72:        get_token(&tok);
                     73:        switch (tok.kind) {
                     74:        case TOK_STRUCT:
                     75:                def_struct(defp);
                     76:                break;
                     77:        case TOK_UNION:
                     78:                def_union(defp);
                     79:                break;
                     80:        case TOK_TYPEDEF:
                     81:                def_typedef(defp);
                     82:                break;
                     83:        case TOK_ENUM:
                     84:                def_enum(defp);
                     85:                break;
                     86:        case TOK_PROGRAM:
                     87:                def_program(defp);
                     88:                break;
                     89:        case TOK_CONST:
                     90:                def_const(defp);
                     91:                break;
                     92:        case TOK_EOF:
                     93:                return (NULL);
                     94:        default:
                     95:                error("definition keyword expected");
                     96:        }
                     97:        scan(TOK_SEMICOLON, &tok);
                     98:        isdefined(defp);
                     99:        return (defp);
                    100: }
                    101:
                    102: static
                    103: isdefined(defp)
                    104:        definition *defp;
                    105: {
                    106:        STOREVAL(&defined, defp);
                    107: }
                    108:
                    109: static
                    110: def_struct(defp)
                    111:        definition *defp;
                    112: {
                    113:        token tok;
                    114:        declaration dec;
                    115:        decl_list *decls;
                    116:        decl_list **tailp;
                    117:
                    118:        defp->def_kind = DEF_STRUCT;
                    119:
                    120:        scan(TOK_IDENT, &tok);
                    121:        defp->def_name = tok.str;
                    122:        scan(TOK_LBRACE, &tok);
                    123:        tailp = &defp->def.st.decls;
                    124:        do {
                    125:                get_declaration(&dec, DEF_STRUCT);
                    126:                decls = ALLOC(decl_list);
                    127:                decls->decl = dec;
                    128:                *tailp = decls;
                    129:                tailp = &decls->next;
                    130:                scan(TOK_SEMICOLON, &tok);
                    131:                peek(&tok);
                    132:        } while (tok.kind != TOK_RBRACE);
                    133:        get_token(&tok);
                    134:        *tailp = NULL;
                    135: }
                    136:
                    137: static
                    138: def_program(defp)
                    139:        definition *defp;
                    140: {
                    141:        token tok;
                    142:        declaration dec;
                    143:        decl_list *decls;
                    144:        decl_list **tailp;
                    145:        version_list *vlist;
                    146:        version_list **vtailp;
                    147:        proc_list *plist;
                    148:        proc_list **ptailp;
                    149:        int num_args;
                    150:        bool_t isvoid = FALSE; /* whether first argument is void */
                    151:        defp->def_kind = DEF_PROGRAM;
                    152:        scan(TOK_IDENT, &tok);
                    153:        defp->def_name = tok.str;
                    154:        scan(TOK_LBRACE, &tok);
                    155:        vtailp = &defp->def.pr.versions;
                    156:        tailp = &defp->def.st.decls;
                    157:        scan(TOK_VERSION, &tok);
                    158:        do {
                    159:                scan(TOK_IDENT, &tok);
                    160:                vlist = ALLOC(version_list);
                    161:                vlist->vers_name = tok.str;
                    162:                scan(TOK_LBRACE, &tok);
                    163:                ptailp = &vlist->procs;
                    164:                do {
                    165:                        /* get result type */
                    166:                        plist = ALLOC(proc_list);
                    167:                        get_type(&plist->res_prefix, &plist->res_type,
                    168:                                 DEF_PROGRAM);
                    169:                        if (streq(plist->res_type, "opaque")) {
                    170:                                error("illegal result type");
                    171:                        }
                    172:                        scan(TOK_IDENT, &tok);
                    173:                        plist->proc_name = tok.str;
                    174:                        scan(TOK_LPAREN, &tok);
                    175:                        /* get args - first one*/
                    176:                        num_args = 1;
                    177:                        isvoid = FALSE;
                    178:                        /* type of DEF_PROGRAM in the first
                    179:                         * get_prog_declaration and DEF_STURCT in the next
                    180:                         * allows void as argument if it is the only argument
                    181:                         */
                    182:                        get_prog_declaration(&dec, DEF_PROGRAM, num_args);
                    183:                        if (streq(dec.type, "void"))
                    184:                          isvoid = TRUE;
                    185:                        decls = ALLOC(decl_list);
                    186:                        plist->args.decls = decls;
                    187:                        decls->decl = dec;
                    188:                        tailp = &decls->next;
                    189:                        /* get args */
                    190:                        while(peekscan(TOK_COMMA, &tok)) {
                    191:                          num_args++;
                    192:                          get_prog_declaration(&dec, DEF_STRUCT,
                    193:                                               num_args);
                    194:                          decls = ALLOC(decl_list);
                    195:                          decls->decl = dec;
                    196:                          *tailp = decls;
                    197:                          if (streq(dec.type, "void"))
                    198:                            isvoid = TRUE;
                    199:                          tailp = &decls->next;
                    200:                        }
                    201:                        /* multiple arguments are only allowed in newstyle */
                    202:                        if( !newstyle && num_args > 1 ) {
                    203:                          error("only one argument is allowed" );
                    204:                        }
                    205:                        if (isvoid && num_args > 1) {
                    206:                          error("illegal use of void in program definition");
                    207:                        }
                    208:                        *tailp = NULL;
                    209:                        scan(TOK_RPAREN, &tok);
                    210:                        scan(TOK_EQUAL, &tok);
                    211:                        scan_num(&tok);
                    212:                        scan(TOK_SEMICOLON, &tok);
                    213:                        plist->proc_num = tok.str;
                    214:                        plist->arg_num = num_args;
                    215:                        *ptailp = plist;
                    216:                        ptailp = &plist->next;
                    217:                        peek(&tok);
                    218:                } while (tok.kind != TOK_RBRACE);
                    219:                *ptailp = NULL;
                    220:                *vtailp = vlist;
                    221:                vtailp = &vlist->next;
                    222:                scan(TOK_RBRACE, &tok);
                    223:                scan(TOK_EQUAL, &tok);
                    224:                scan_num(&tok);
                    225:                vlist->vers_num = tok.str;
                    226:                /* make the argument structure name for each arg*/
                    227:                for(plist = vlist->procs; plist != NULL;
                    228:                    plist = plist->next) {
                    229:                        plist->args.argname = make_argname(plist->proc_name,
                    230:                                                           vlist->vers_num);
                    231:                        /* free the memory ??*/
                    232:                }
                    233:                scan(TOK_SEMICOLON, &tok);
                    234:                scan2(TOK_VERSION, TOK_RBRACE, &tok);
                    235:        } while (tok.kind == TOK_VERSION);
                    236:        scan(TOK_EQUAL, &tok);
                    237:        scan_num(&tok);
                    238:        defp->def.pr.prog_num = tok.str;
                    239:        *vtailp = NULL;
                    240: }
                    241:
                    242:
                    243: static
                    244: def_enum(defp)
                    245:        definition *defp;
                    246: {
                    247:        token tok;
                    248:        enumval_list *elist;
                    249:        enumval_list **tailp;
                    250:
                    251:        defp->def_kind = DEF_ENUM;
                    252:        scan(TOK_IDENT, &tok);
                    253:        defp->def_name = tok.str;
                    254:        scan(TOK_LBRACE, &tok);
                    255:        tailp = &defp->def.en.vals;
                    256:        do {
                    257:                scan(TOK_IDENT, &tok);
                    258:                elist = ALLOC(enumval_list);
                    259:                elist->name = tok.str;
                    260:                elist->assignment = NULL;
                    261:                scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
                    262:                if (tok.kind == TOK_EQUAL) {
                    263:                        scan_num(&tok);
                    264:                        elist->assignment = tok.str;
                    265:                        scan2(TOK_COMMA, TOK_RBRACE, &tok);
                    266:                }
                    267:                *tailp = elist;
                    268:                tailp = &elist->next;
                    269:        } while (tok.kind != TOK_RBRACE);
                    270:        *tailp = NULL;
                    271: }
                    272:
                    273: static
                    274: def_const(defp)
                    275:        definition *defp;
                    276: {
                    277:        token tok;
                    278:
                    279:        defp->def_kind = DEF_CONST;
                    280:        scan(TOK_IDENT, &tok);
                    281:        defp->def_name = tok.str;
                    282:        scan(TOK_EQUAL, &tok);
                    283:        scan2(TOK_IDENT, TOK_STRCONST, &tok);
                    284:        defp->def.co = tok.str;
                    285: }
                    286:
                    287: static
                    288: def_union(defp)
                    289:        definition *defp;
                    290: {
                    291:   token tok;
                    292:   declaration dec;
                    293:   case_list *cases,*tcase;
                    294:   case_list **tailp;
                    295:   int flag;
                    296:
                    297:   defp->def_kind = DEF_UNION;
                    298:   scan(TOK_IDENT, &tok);
                    299:   defp->def_name = tok.str;
                    300:   scan(TOK_SWITCH, &tok);
                    301:   scan(TOK_LPAREN, &tok);
                    302:   get_declaration(&dec, DEF_UNION);
                    303:   defp->def.un.enum_decl = dec;
                    304:   tailp = &defp->def.un.cases;
                    305:   scan(TOK_RPAREN, &tok);
                    306:   scan(TOK_LBRACE, &tok);
                    307:   scan(TOK_CASE, &tok);
                    308:   while (tok.kind == TOK_CASE) {
                    309:     scan2(TOK_IDENT, TOK_CHARCONST, &tok);
                    310:     cases = ALLOC(case_list);
                    311:     cases->case_name = tok.str;
                    312:     scan(TOK_COLON, &tok);
                    313:     /* now peek at next token */
                    314:     flag=0;
                    315:     if(peekscan(TOK_CASE,&tok))
                    316:       {
                    317:
                    318:        do
                    319:          {
                    320:            scan2(TOK_IDENT, TOK_CHARCONST, &tok);
                    321:            cases->contflag=1;  /* continued case statement */
                    322:            *tailp = cases;
                    323:            tailp = &cases->next;
                    324:            cases = ALLOC(case_list);
                    325:            cases->case_name = tok.str;
                    326:            scan(TOK_COLON, &tok);
                    327:
                    328:          }while(peekscan(TOK_CASE,&tok));
                    329:       }
                    330:     else
                    331:       if(flag)
                    332:        {
                    333:
                    334:          *tailp = cases;
                    335:          tailp = &cases->next;
                    336:          cases = ALLOC(case_list);
                    337:        };
                    338:
                    339:     get_declaration(&dec, DEF_UNION);
                    340:     cases->case_decl = dec;
                    341:     cases->contflag=0;         /* no continued case statement */
                    342:     *tailp = cases;
                    343:     tailp = &cases->next;
                    344:     scan(TOK_SEMICOLON, &tok);
                    345:
                    346:     scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
                    347:   }
                    348:   *tailp = NULL;
                    349:   if (tok.kind == TOK_DEFAULT) {
                    350:     scan(TOK_COLON, &tok);
                    351:     get_declaration(&dec, DEF_UNION);
                    352:     defp->def.un.default_decl = ALLOC(declaration);
                    353:     *defp->def.un.default_decl = dec;
                    354:     scan(TOK_SEMICOLON, &tok);
                    355:     scan(TOK_RBRACE, &tok);
                    356:   } else {
                    357:     defp->def.un.default_decl = NULL;
                    358:   }
                    359: }
                    360:
                    361: static char* reserved_words[] = {
                    362:        "array",
                    363:        "bytes",
                    364:        "destroy",
                    365:        "free",
                    366:        "getpos",
                    367:        "inline",
                    368:        "pointer",
                    369:        "reference",
                    370:        "setpos",
                    371:        "sizeof",
                    372:        "union",
                    373:        "vector",
                    374:        NULL
                    375: };
                    376:
                    377: static char* reserved_types[] = {
                    378:        "opaque",
                    379:        "string",
                    380:        NULL
                    381: };
                    382:
                    383: /* check that the given name is not one that would eventually result in
                    384:    xdr routines that would conflict with internal XDR routines. */
                    385: static check_type_name( name, new_type )
                    386: int new_type;
                    387: char* name;
                    388: {
                    389:   int i;
                    390:   char tmp[100];
                    391:
                    392:   for( i = 0; reserved_words[i] != NULL; i++ ) {
                    393:     if( strcmp( name, reserved_words[i] ) == 0 ) {
                    394:       sprintf(tmp,
                    395:              "illegal (reserved) name :\'%s\' in type definition", name );
                    396:       error(tmp);
                    397:     }
                    398:   }
                    399:   if( new_type ) {
                    400:     for( i = 0; reserved_types[i] != NULL; i++ ) {
                    401:       if( strcmp( name, reserved_types[i] ) == 0 ) {
                    402:        sprintf(tmp,
                    403:                "illegal (reserved) name :\'%s\' in type definition", name );
                    404:        error(tmp);
                    405:       }
                    406:     }
                    407:   }
                    408: }
                    409:
                    410: static
                    411: def_typedef(defp)
                    412:        definition *defp;
                    413: {
                    414:        declaration dec;
                    415:
                    416:        defp->def_kind = DEF_TYPEDEF;
                    417:        get_declaration(&dec, DEF_TYPEDEF);
                    418:        defp->def_name = dec.name;
                    419:        check_type_name( dec.name, 1 );
                    420:        defp->def.ty.old_prefix = dec.prefix;
                    421:        defp->def.ty.old_type = dec.type;
                    422:        defp->def.ty.rel = dec.rel;
                    423:        defp->def.ty.array_max = dec.array_max;
                    424: }
                    425:
                    426: static
                    427: get_declaration(dec, dkind)
                    428:        declaration *dec;
                    429:        defkind dkind;
                    430: {
                    431:        token tok;
                    432:
                    433:        get_type(&dec->prefix, &dec->type, dkind);
                    434:        dec->rel = REL_ALIAS;
                    435:        if (streq(dec->type, "void")) {
                    436:                return;
                    437:        }
                    438:
                    439:        check_type_name( dec->type, 0 );
                    440:
                    441:        scan2(TOK_STAR, TOK_IDENT, &tok);
                    442:        if (tok.kind == TOK_STAR) {
                    443:                dec->rel = REL_POINTER;
                    444:                scan(TOK_IDENT, &tok);
                    445:        }
                    446:        dec->name = tok.str;
                    447:        if (peekscan(TOK_LBRACKET, &tok)) {
                    448:                if (dec->rel == REL_POINTER) {
                    449:                        error("no array-of-pointer declarations -- use typedef");
                    450:                }
                    451:                dec->rel = REL_VECTOR;
                    452:                scan_num(&tok);
                    453:                dec->array_max = tok.str;
                    454:                scan(TOK_RBRACKET, &tok);
                    455:        } else if (peekscan(TOK_LANGLE, &tok)) {
                    456:                if (dec->rel == REL_POINTER) {
                    457:                        error("no array-of-pointer declarations -- use typedef");
                    458:                }
                    459:                dec->rel = REL_ARRAY;
                    460:                if (peekscan(TOK_RANGLE, &tok)) {
                    461:                        dec->array_max = "~0";  /* unspecified size, use max */
                    462:                } else {
                    463:                        scan_num(&tok);
                    464:                        dec->array_max = tok.str;
                    465:                        scan(TOK_RANGLE, &tok);
                    466:                }
                    467:        }
                    468:        if (streq(dec->type, "opaque")) {
                    469:                if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
                    470:                        error("array declaration expected");
                    471:                }
                    472:        } else if (streq(dec->type, "string")) {
                    473:                if (dec->rel != REL_ARRAY) {
                    474:                        error("variable-length array declaration expected");
                    475:                }
                    476:        }
                    477: }
                    478:
                    479: static
                    480: get_prog_declaration(dec, dkind, num)
                    481:        declaration *dec;
                    482:        defkind dkind;
                    483:         int num;  /* arg number */
                    484: {
                    485:        token tok;
                    486:        char name[10]; /* argument name */
                    487:
                    488:        if (dkind == DEF_PROGRAM) {
                    489:          peek(&tok);
                    490:          if (tok.kind == TOK_RPAREN) { /* no arguments */
                    491:                dec->rel = REL_ALIAS;
                    492:                dec->type = "void";
                    493:                dec->prefix = NULL;
                    494:                dec->name = NULL;
                    495:                return;
                    496:              }
                    497:        }
                    498:        get_type(&dec->prefix, &dec->type, dkind);
                    499:        dec->rel = REL_ALIAS;
                    500:        if (peekscan(TOK_IDENT, &tok))  /* optional name of argument */
                    501:                strcpy(name, tok.str);
                    502:        else
                    503:                sprintf(name, "%s%d", ARGNAME, num); /* default name of argument */
                    504:
                    505:        dec->name = (char *)strdup(name);
                    506:
                    507:        if (streq(dec->type, "void")) {
                    508:                return;
                    509:        }
                    510:
                    511:        if (streq(dec->type, "opaque")) {
                    512:                error("opaque -- illegal argument type");
                    513:        }
                    514:        if (peekscan(TOK_STAR, &tok)) {
                    515:          if (streq(dec->type, "string")) {
                    516:            error("pointer to string not allowed in program arguments\n");
                    517:          }
                    518:                dec->rel = REL_POINTER;
                    519:                if (peekscan(TOK_IDENT, &tok))  /* optional name of argument */
                    520:                  dec->name = (char *)strdup(tok.str);
                    521:       }
                    522:          if (peekscan(TOK_LANGLE, &tok)) {
                    523:            if (!streq(dec->type, "string")) {
                    524:              error("arrays cannot be declared as arguments to procedures -- use typedef");
                    525:            }
                    526:                dec->rel = REL_ARRAY;
                    527:                if (peekscan(TOK_RANGLE, &tok)) {
                    528:                        dec->array_max = "~0";/* unspecified size, use max */
                    529:                } else {
                    530:                        scan_num(&tok);
                    531:                        dec->array_max = tok.str;
                    532:                        scan(TOK_RANGLE, &tok);
                    533:                }
                    534:        }
                    535:        if (streq(dec->type, "string")) {
                    536:                if (dec->rel != REL_ARRAY) {  /* .x specifies just string as
                    537:                                               * type of argument
                    538:                                               * - make it string<>
                    539:                                               */
                    540:                        dec->rel = REL_ARRAY;
                    541:                        dec->array_max = "~0";/* unspecified size, use max */
                    542:                }
                    543:        }
                    544: }
                    545:
                    546:
                    547:
                    548: static
                    549: get_type(prefixp, typep, dkind)
                    550:        char **prefixp;
                    551:        char **typep;
                    552:        defkind dkind;
                    553: {
                    554:        token tok;
                    555:
                    556:        *prefixp = NULL;
                    557:        get_token(&tok);
                    558:        switch (tok.kind) {
                    559:        case TOK_IDENT:
                    560:                *typep = tok.str;
                    561:                break;
                    562:        case TOK_STRUCT:
                    563:        case TOK_ENUM:
                    564:        case TOK_UNION:
                    565:                *prefixp = tok.str;
                    566:                scan(TOK_IDENT, &tok);
                    567:                *typep = tok.str;
                    568:                break;
                    569:        case TOK_UNSIGNED:
                    570:                unsigned_dec(typep);
                    571:                break;
                    572:        case TOK_SHORT:
                    573:                *typep = "short";
                    574:                (void) peekscan(TOK_INT, &tok);
                    575:                break;
                    576:        case TOK_LONG:
                    577:                *typep = "long";
                    578:                (void) peekscan(TOK_INT, &tok);
                    579:                break;
                    580:        case TOK_VOID:
                    581:                if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
                    582:                        error("voids allowed only inside union and program definitions with one argument");
                    583:                }
                    584:                *typep = tok.str;
                    585:                break;
                    586:        case TOK_STRING:
                    587:        case TOK_OPAQUE:
                    588:        case TOK_CHAR:
                    589:        case TOK_INT:
                    590:        case TOK_FLOAT:
                    591:        case TOK_DOUBLE:
                    592:        case TOK_BOOL:
                    593:                *typep = tok.str;
                    594:                break;
                    595:        default:
                    596:                error("expected type specifier");
                    597:        }
                    598: }
                    599:
                    600: static
                    601: unsigned_dec(typep)
                    602:        char **typep;
                    603: {
                    604:        token tok;
                    605:
                    606:        peek(&tok);
                    607:        switch (tok.kind) {
                    608:        case TOK_CHAR:
                    609:                get_token(&tok);
                    610:                *typep = "u_char";
                    611:                break;
                    612:        case TOK_SHORT:
                    613:                get_token(&tok);
                    614:                *typep = "u_short";
                    615:                (void) peekscan(TOK_INT, &tok);
                    616:                break;
                    617:        case TOK_LONG:
                    618:                get_token(&tok);
                    619:                *typep = "u_long";
                    620:                (void) peekscan(TOK_INT, &tok);
                    621:                break;
                    622:        case TOK_INT:
                    623:                get_token(&tok);
                    624:                *typep = "u_int";
                    625:                break;
                    626:        default:
                    627:                *typep = "u_int";
                    628:                break;
                    629:        }
                    630: }