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

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