[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     ! 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: }