1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 28*7c478bd9Sstevel@tonic-gate /* 29*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 30*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 31*7c478bd9Sstevel@tonic-gate * All Rights Reserved 32*7c478bd9Sstevel@tonic-gate * 33*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 34*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 35*7c478bd9Sstevel@tonic-gate * contributors. 36*7c478bd9Sstevel@tonic-gate */ 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate /* 41*7c478bd9Sstevel@tonic-gate * rpc_parse.c, Parser for the RPC protocol compiler 42*7c478bd9Sstevel@tonic-gate */ 43*7c478bd9Sstevel@tonic-gate #include <stdio.h> 44*7c478bd9Sstevel@tonic-gate #include <string.h> 45*7c478bd9Sstevel@tonic-gate #include "rpc/types.h" 46*7c478bd9Sstevel@tonic-gate #include "rpc_scan.h" 47*7c478bd9Sstevel@tonic-gate #include "rpc_parse.h" 48*7c478bd9Sstevel@tonic-gate #include "rpc_util.h" 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate #define ARGNAME "arg" 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate extern char *make_argname(); 53*7c478bd9Sstevel@tonic-gate extern char *strdup(); 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate /* 56*7c478bd9Sstevel@tonic-gate * return the next definition you see 57*7c478bd9Sstevel@tonic-gate */ 58*7c478bd9Sstevel@tonic-gate definition * 59*7c478bd9Sstevel@tonic-gate get_definition() 60*7c478bd9Sstevel@tonic-gate { 61*7c478bd9Sstevel@tonic-gate definition *defp; 62*7c478bd9Sstevel@tonic-gate token tok; 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate defp = ALLOC(definition); 65*7c478bd9Sstevel@tonic-gate get_token(&tok); 66*7c478bd9Sstevel@tonic-gate switch (tok.kind) { 67*7c478bd9Sstevel@tonic-gate case TOK_STRUCT: 68*7c478bd9Sstevel@tonic-gate def_struct(defp); 69*7c478bd9Sstevel@tonic-gate break; 70*7c478bd9Sstevel@tonic-gate case TOK_UNION: 71*7c478bd9Sstevel@tonic-gate def_union(defp); 72*7c478bd9Sstevel@tonic-gate break; 73*7c478bd9Sstevel@tonic-gate case TOK_TYPEDEF: 74*7c478bd9Sstevel@tonic-gate def_typedef(defp); 75*7c478bd9Sstevel@tonic-gate break; 76*7c478bd9Sstevel@tonic-gate case TOK_ENUM: 77*7c478bd9Sstevel@tonic-gate def_enum(defp); 78*7c478bd9Sstevel@tonic-gate break; 79*7c478bd9Sstevel@tonic-gate case TOK_PROGRAM: 80*7c478bd9Sstevel@tonic-gate def_program(defp); 81*7c478bd9Sstevel@tonic-gate break; 82*7c478bd9Sstevel@tonic-gate case TOK_CONST: 83*7c478bd9Sstevel@tonic-gate def_const(defp); 84*7c478bd9Sstevel@tonic-gate break; 85*7c478bd9Sstevel@tonic-gate case TOK_EOF: 86*7c478bd9Sstevel@tonic-gate return (NULL); 87*7c478bd9Sstevel@tonic-gate default: 88*7c478bd9Sstevel@tonic-gate error("definition keyword expected"); 89*7c478bd9Sstevel@tonic-gate } 90*7c478bd9Sstevel@tonic-gate scan(TOK_SEMICOLON, &tok); 91*7c478bd9Sstevel@tonic-gate isdefined(defp); 92*7c478bd9Sstevel@tonic-gate return (defp); 93*7c478bd9Sstevel@tonic-gate } 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate static 96*7c478bd9Sstevel@tonic-gate isdefined(defp) 97*7c478bd9Sstevel@tonic-gate definition *defp; 98*7c478bd9Sstevel@tonic-gate { 99*7c478bd9Sstevel@tonic-gate STOREVAL(&defined, defp); 100*7c478bd9Sstevel@tonic-gate } 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate /* 103*7c478bd9Sstevel@tonic-gate * We treat s == NULL the same as *s == '\0' 104*7c478bd9Sstevel@tonic-gate */ 105*7c478bd9Sstevel@tonic-gate streqn(const char *s1, const char *s2) 106*7c478bd9Sstevel@tonic-gate { 107*7c478bd9Sstevel@tonic-gate if (s1 == NULL) 108*7c478bd9Sstevel@tonic-gate s1 = ""; 109*7c478bd9Sstevel@tonic-gate if (s2 == NULL) 110*7c478bd9Sstevel@tonic-gate s2 = ""; 111*7c478bd9Sstevel@tonic-gate if (s1 == s2) 112*7c478bd9Sstevel@tonic-gate return (1); 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate return (strcmp(s1, s2) == 0); 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate static int 118*7c478bd9Sstevel@tonic-gate cmptype(definition *defp, char *type) 119*7c478bd9Sstevel@tonic-gate { 120*7c478bd9Sstevel@tonic-gate /* We only want typedef definitions */ 121*7c478bd9Sstevel@tonic-gate if (streq(defp->def_name, type) && defp->def_kind == DEF_TYPEDEF) 122*7c478bd9Sstevel@tonic-gate return (1); 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate return (0); 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate static int 128*7c478bd9Sstevel@tonic-gate check_self_reference(const char *name, const declaration *decp, int first) 129*7c478bd9Sstevel@tonic-gate { 130*7c478bd9Sstevel@tonic-gate /* 131*7c478bd9Sstevel@tonic-gate * Now check for the following special case if first is true: 132*7c478bd9Sstevel@tonic-gate * 133*7c478bd9Sstevel@tonic-gate * struct foo { 134*7c478bd9Sstevel@tonic-gate * ... 135*7c478bd9Sstevel@tonic-gate * foo *next; 136*7c478bd9Sstevel@tonic-gate * }; 137*7c478bd9Sstevel@tonic-gate * 138*7c478bd9Sstevel@tonic-gate * 139*7c478bd9Sstevel@tonic-gate * In the above cases foo has not yet been entered in the type list, 140*7c478bd9Sstevel@tonic-gate * defined. So there is no typedef entry. The prefix in that case 141*7c478bd9Sstevel@tonic-gate * could be empty. 142*7c478bd9Sstevel@tonic-gate */ 143*7c478bd9Sstevel@tonic-gate if (decp->rel == REL_POINTER && 144*7c478bd9Sstevel@tonic-gate (streqn(decp->prefix, "struct") || 145*7c478bd9Sstevel@tonic-gate (first && streqn(decp->prefix, ""))) && 146*7c478bd9Sstevel@tonic-gate streqn(name, decp->type)) 147*7c478bd9Sstevel@tonic-gate return (1); 148*7c478bd9Sstevel@tonic-gate return (0); 149*7c478bd9Sstevel@tonic-gate } 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate static int 152*7c478bd9Sstevel@tonic-gate is_self_reference(definition *defp, declaration *decp) 153*7c478bd9Sstevel@tonic-gate { 154*7c478bd9Sstevel@tonic-gate declaration current; 155*7c478bd9Sstevel@tonic-gate definition *dp; 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate if (check_self_reference(defp->def_name, decp, 1)) 158*7c478bd9Sstevel@tonic-gate return (1); 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate /* 161*7c478bd9Sstevel@tonic-gate * Check for valid declaration: 162*7c478bd9Sstevel@tonic-gate * Only prefixes allowed are none and struct. 163*7c478bd9Sstevel@tonic-gate * Only relations allowed are pointer or alias. 164*7c478bd9Sstevel@tonic-gate */ 165*7c478bd9Sstevel@tonic-gate if (!streqn(decp->prefix, "struct") && !streqn(decp->prefix, "")) 166*7c478bd9Sstevel@tonic-gate return (0); 167*7c478bd9Sstevel@tonic-gate if (decp->rel != REL_POINTER && decp->rel != REL_ALIAS) 168*7c478bd9Sstevel@tonic-gate return (0); 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate current.rel = decp->rel; 171*7c478bd9Sstevel@tonic-gate current.prefix = decp->prefix; 172*7c478bd9Sstevel@tonic-gate current.type = decp->type; 173*7c478bd9Sstevel@tonic-gate current.name = decp->name; 174*7c478bd9Sstevel@tonic-gate decp = ¤t; 175*7c478bd9Sstevel@tonic-gate while (!check_self_reference(defp->def_name, decp, 0)) { 176*7c478bd9Sstevel@tonic-gate dp = FINDVAL(defined, decp->type, cmptype); 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate /* 179*7c478bd9Sstevel@tonic-gate * Check if we found a definition. 180*7c478bd9Sstevel@tonic-gate */ 181*7c478bd9Sstevel@tonic-gate if (dp == NULL) 182*7c478bd9Sstevel@tonic-gate return (0); 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate /* 185*7c478bd9Sstevel@tonic-gate * Check for valid prefix. We eventually need to see one 186*7c478bd9Sstevel@tonic-gate * and only one struct. 187*7c478bd9Sstevel@tonic-gate */ 188*7c478bd9Sstevel@tonic-gate if (streqn(decp->prefix, "")) { 189*7c478bd9Sstevel@tonic-gate /* 190*7c478bd9Sstevel@tonic-gate * If the current declaration prefix in empty 191*7c478bd9Sstevel@tonic-gate * then the definition found must have an empty 192*7c478bd9Sstevel@tonic-gate * prefix or a struct prefix 193*7c478bd9Sstevel@tonic-gate */ 194*7c478bd9Sstevel@tonic-gate if (!streqn(dp->def.ty.old_prefix, "") && 195*7c478bd9Sstevel@tonic-gate !streqn(dp->def.ty.old_prefix, "struct")) 196*7c478bd9Sstevel@tonic-gate return (0); 197*7c478bd9Sstevel@tonic-gate } else if (streqn(decp->prefix, "struct") && 198*7c478bd9Sstevel@tonic-gate !streqn(dp->def.ty.old_prefix, "")) 199*7c478bd9Sstevel@tonic-gate /* 200*7c478bd9Sstevel@tonic-gate * if the current prefix is struct tne new prefix 201*7c478bd9Sstevel@tonic-gate * must be empty 202*7c478bd9Sstevel@tonic-gate */ 203*7c478bd9Sstevel@tonic-gate return (0); 204*7c478bd9Sstevel@tonic-gate else if (!streqn(decp->prefix, "struct")) 205*7c478bd9Sstevel@tonic-gate /* Should never get here */ 206*7c478bd9Sstevel@tonic-gate return (0); 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate /* 209*7c478bd9Sstevel@tonic-gate * Check for valid relation. We need to see one and 210*7c478bd9Sstevel@tonic-gate * only one REL_POINTER. The only valid relation types 211*7c478bd9Sstevel@tonic-gate * are REL_POINTER and REL_ALIAS. 212*7c478bd9Sstevel@tonic-gate */ 213*7c478bd9Sstevel@tonic-gate if (decp->rel == REL_POINTER && dp->def.ty.rel != REL_ALIAS) 214*7c478bd9Sstevel@tonic-gate return (0); 215*7c478bd9Sstevel@tonic-gate else if (decp->rel == REL_ALIAS && 216*7c478bd9Sstevel@tonic-gate (dp->def.ty.rel != REL_ALIAS && 217*7c478bd9Sstevel@tonic-gate dp->def.ty.rel != REL_POINTER)) 218*7c478bd9Sstevel@tonic-gate return (0); 219*7c478bd9Sstevel@tonic-gate else if (decp->rel != REL_ALIAS && decp->rel != REL_POINTER) 220*7c478bd9Sstevel@tonic-gate /* Should never get here */ 221*7c478bd9Sstevel@tonic-gate return (0); 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate /* Set up the current declaration */ 224*7c478bd9Sstevel@tonic-gate if (streqn(decp->prefix, "")) 225*7c478bd9Sstevel@tonic-gate decp->prefix = dp->def.ty.old_prefix; 226*7c478bd9Sstevel@tonic-gate decp->type = dp->def.ty.old_type; 227*7c478bd9Sstevel@tonic-gate if (decp->rel == REL_ALIAS) 228*7c478bd9Sstevel@tonic-gate decp->rel = dp->def.ty.rel; 229*7c478bd9Sstevel@tonic-gate } 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate /* We have a self reference type */ 232*7c478bd9Sstevel@tonic-gate return (1); 233*7c478bd9Sstevel@tonic-gate } 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate static 236*7c478bd9Sstevel@tonic-gate def_struct(defp) 237*7c478bd9Sstevel@tonic-gate definition *defp; 238*7c478bd9Sstevel@tonic-gate { 239*7c478bd9Sstevel@tonic-gate token tok; 240*7c478bd9Sstevel@tonic-gate declaration dec; 241*7c478bd9Sstevel@tonic-gate decl_list *decls; 242*7c478bd9Sstevel@tonic-gate decl_list **tailp, *endp; 243*7c478bd9Sstevel@tonic-gate 244*7c478bd9Sstevel@tonic-gate defp->def_kind = DEF_STRUCT; 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate scan(TOK_IDENT, &tok); 247*7c478bd9Sstevel@tonic-gate defp->def_name = tok.str; 248*7c478bd9Sstevel@tonic-gate scan(TOK_LBRACE, &tok); 249*7c478bd9Sstevel@tonic-gate tailp = &defp->def.st.decls; 250*7c478bd9Sstevel@tonic-gate defp->def.st.tail = NULL; 251*7c478bd9Sstevel@tonic-gate do { 252*7c478bd9Sstevel@tonic-gate get_declaration(&dec, DEF_STRUCT); 253*7c478bd9Sstevel@tonic-gate decls = ALLOC(decl_list); 254*7c478bd9Sstevel@tonic-gate decls->decl = dec; 255*7c478bd9Sstevel@tonic-gate /* 256*7c478bd9Sstevel@tonic-gate * Keep a referenct to the last declaration to check for 257*7c478bd9Sstevel@tonic-gate * tail recurrsion. 258*7c478bd9Sstevel@tonic-gate */ 259*7c478bd9Sstevel@tonic-gate endp = *tailp = decls; 260*7c478bd9Sstevel@tonic-gate tailp = &decls->next; 261*7c478bd9Sstevel@tonic-gate scan(TOK_SEMICOLON, &tok); 262*7c478bd9Sstevel@tonic-gate peek(&tok); 263*7c478bd9Sstevel@tonic-gate } while (tok.kind != TOK_RBRACE); 264*7c478bd9Sstevel@tonic-gate *tailp = NULL; 265*7c478bd9Sstevel@tonic-gate /* 266*7c478bd9Sstevel@tonic-gate * Check for tail recurse. If the last declaration refers to this 267*7c478bd9Sstevel@tonic-gate * structure then mark this stucture to convert the tail recursion 268*7c478bd9Sstevel@tonic-gate * to itteration. 269*7c478bd9Sstevel@tonic-gate */ 270*7c478bd9Sstevel@tonic-gate defp->def.st.self_pointer = is_self_reference(defp, &endp->decl); 271*7c478bd9Sstevel@tonic-gate get_token(&tok); 272*7c478bd9Sstevel@tonic-gate defp->def.st.tail = endp; 273*7c478bd9Sstevel@tonic-gate } 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate static 276*7c478bd9Sstevel@tonic-gate def_program(defp) 277*7c478bd9Sstevel@tonic-gate definition *defp; 278*7c478bd9Sstevel@tonic-gate { 279*7c478bd9Sstevel@tonic-gate token tok; 280*7c478bd9Sstevel@tonic-gate declaration dec; 281*7c478bd9Sstevel@tonic-gate decl_list *decls; 282*7c478bd9Sstevel@tonic-gate decl_list **tailp; 283*7c478bd9Sstevel@tonic-gate version_list *vlist; 284*7c478bd9Sstevel@tonic-gate version_list **vtailp; 285*7c478bd9Sstevel@tonic-gate proc_list *plist; 286*7c478bd9Sstevel@tonic-gate proc_list **ptailp; 287*7c478bd9Sstevel@tonic-gate int num_args; 288*7c478bd9Sstevel@tonic-gate bool_t isvoid = FALSE; /* whether first argument is void */ 289*7c478bd9Sstevel@tonic-gate defp->def_kind = DEF_PROGRAM; 290*7c478bd9Sstevel@tonic-gate scan(TOK_IDENT, &tok); 291*7c478bd9Sstevel@tonic-gate defp->def_name = tok.str; 292*7c478bd9Sstevel@tonic-gate scan(TOK_LBRACE, &tok); 293*7c478bd9Sstevel@tonic-gate vtailp = &defp->def.pr.versions; 294*7c478bd9Sstevel@tonic-gate tailp = &defp->def.st.decls; 295*7c478bd9Sstevel@tonic-gate scan(TOK_VERSION, &tok); 296*7c478bd9Sstevel@tonic-gate do { 297*7c478bd9Sstevel@tonic-gate scan(TOK_IDENT, &tok); 298*7c478bd9Sstevel@tonic-gate vlist = ALLOC(version_list); 299*7c478bd9Sstevel@tonic-gate vlist->vers_name = tok.str; 300*7c478bd9Sstevel@tonic-gate scan(TOK_LBRACE, &tok); 301*7c478bd9Sstevel@tonic-gate ptailp = &vlist->procs; 302*7c478bd9Sstevel@tonic-gate do { 303*7c478bd9Sstevel@tonic-gate /* get result type */ 304*7c478bd9Sstevel@tonic-gate plist = ALLOC(proc_list); 305*7c478bd9Sstevel@tonic-gate get_type(&plist->res_prefix, &plist->res_type, 306*7c478bd9Sstevel@tonic-gate DEF_RESULT); 307*7c478bd9Sstevel@tonic-gate if (streq(plist->res_type, "opaque")) { 308*7c478bd9Sstevel@tonic-gate error("illegal result type"); 309*7c478bd9Sstevel@tonic-gate } 310*7c478bd9Sstevel@tonic-gate scan(TOK_IDENT, &tok); 311*7c478bd9Sstevel@tonic-gate plist->proc_name = tok.str; 312*7c478bd9Sstevel@tonic-gate scan(TOK_LPAREN, &tok); 313*7c478bd9Sstevel@tonic-gate /* get args - first one */ 314*7c478bd9Sstevel@tonic-gate num_args = 1; 315*7c478bd9Sstevel@tonic-gate isvoid = FALSE; 316*7c478bd9Sstevel@tonic-gate /* 317*7c478bd9Sstevel@tonic-gate * type of DEF_PROGRAM in the first 318*7c478bd9Sstevel@tonic-gate * get_prog_declaration and DEF_STURCT in the next 319*7c478bd9Sstevel@tonic-gate * allows void as argument if it is the only argument 320*7c478bd9Sstevel@tonic-gate */ 321*7c478bd9Sstevel@tonic-gate get_prog_declaration(&dec, DEF_PROGRAM, num_args); 322*7c478bd9Sstevel@tonic-gate if (streq(dec.type, "void")) 323*7c478bd9Sstevel@tonic-gate isvoid = TRUE; 324*7c478bd9Sstevel@tonic-gate decls = ALLOC(decl_list); 325*7c478bd9Sstevel@tonic-gate plist->args.decls = decls; 326*7c478bd9Sstevel@tonic-gate decls->decl = dec; 327*7c478bd9Sstevel@tonic-gate tailp = &decls->next; 328*7c478bd9Sstevel@tonic-gate /* get args */ 329*7c478bd9Sstevel@tonic-gate while (peekscan(TOK_COMMA, &tok)) { 330*7c478bd9Sstevel@tonic-gate num_args++; 331*7c478bd9Sstevel@tonic-gate get_prog_declaration(&dec, DEF_STRUCT, 332*7c478bd9Sstevel@tonic-gate num_args); 333*7c478bd9Sstevel@tonic-gate decls = ALLOC(decl_list); 334*7c478bd9Sstevel@tonic-gate decls->decl = dec; 335*7c478bd9Sstevel@tonic-gate *tailp = decls; 336*7c478bd9Sstevel@tonic-gate if (streq(dec.type, "void")) 337*7c478bd9Sstevel@tonic-gate isvoid = TRUE; 338*7c478bd9Sstevel@tonic-gate tailp = &decls->next; 339*7c478bd9Sstevel@tonic-gate } 340*7c478bd9Sstevel@tonic-gate /* multiple arguments are only allowed in newstyle */ 341*7c478bd9Sstevel@tonic-gate if (!newstyle && num_args > 1) { 342*7c478bd9Sstevel@tonic-gate error("only one argument is allowed"); 343*7c478bd9Sstevel@tonic-gate } 344*7c478bd9Sstevel@tonic-gate if (isvoid && num_args > 1) { 345*7c478bd9Sstevel@tonic-gate error("illegal use of void " 346*7c478bd9Sstevel@tonic-gate "in program definition"); 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate *tailp = NULL; 349*7c478bd9Sstevel@tonic-gate scan(TOK_RPAREN, &tok); 350*7c478bd9Sstevel@tonic-gate scan(TOK_EQUAL, &tok); 351*7c478bd9Sstevel@tonic-gate scan_num(&tok); 352*7c478bd9Sstevel@tonic-gate scan(TOK_SEMICOLON, &tok); 353*7c478bd9Sstevel@tonic-gate plist->proc_num = tok.str; 354*7c478bd9Sstevel@tonic-gate plist->arg_num = num_args; 355*7c478bd9Sstevel@tonic-gate *ptailp = plist; 356*7c478bd9Sstevel@tonic-gate ptailp = &plist->next; 357*7c478bd9Sstevel@tonic-gate peek(&tok); 358*7c478bd9Sstevel@tonic-gate } while (tok.kind != TOK_RBRACE); 359*7c478bd9Sstevel@tonic-gate *ptailp = NULL; 360*7c478bd9Sstevel@tonic-gate *vtailp = vlist; 361*7c478bd9Sstevel@tonic-gate vtailp = &vlist->next; 362*7c478bd9Sstevel@tonic-gate scan(TOK_RBRACE, &tok); 363*7c478bd9Sstevel@tonic-gate scan(TOK_EQUAL, &tok); 364*7c478bd9Sstevel@tonic-gate scan_num(&tok); 365*7c478bd9Sstevel@tonic-gate vlist->vers_num = tok.str; 366*7c478bd9Sstevel@tonic-gate /* make the argument structure name for each arg */ 367*7c478bd9Sstevel@tonic-gate for (plist = vlist->procs; plist != NULL; 368*7c478bd9Sstevel@tonic-gate plist = plist->next) { 369*7c478bd9Sstevel@tonic-gate plist->args.argname = make_argname(plist->proc_name, 370*7c478bd9Sstevel@tonic-gate vlist->vers_num); 371*7c478bd9Sstevel@tonic-gate /* free the memory ?? */ 372*7c478bd9Sstevel@tonic-gate } 373*7c478bd9Sstevel@tonic-gate scan(TOK_SEMICOLON, &tok); 374*7c478bd9Sstevel@tonic-gate scan2(TOK_VERSION, TOK_RBRACE, &tok); 375*7c478bd9Sstevel@tonic-gate } while (tok.kind == TOK_VERSION); 376*7c478bd9Sstevel@tonic-gate scan(TOK_EQUAL, &tok); 377*7c478bd9Sstevel@tonic-gate scan_num(&tok); 378*7c478bd9Sstevel@tonic-gate defp->def.pr.prog_num = tok.str; 379*7c478bd9Sstevel@tonic-gate *vtailp = NULL; 380*7c478bd9Sstevel@tonic-gate } 381*7c478bd9Sstevel@tonic-gate 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate static 384*7c478bd9Sstevel@tonic-gate def_enum(defp) 385*7c478bd9Sstevel@tonic-gate definition *defp; 386*7c478bd9Sstevel@tonic-gate { 387*7c478bd9Sstevel@tonic-gate token tok; 388*7c478bd9Sstevel@tonic-gate enumval_list *elist; 389*7c478bd9Sstevel@tonic-gate enumval_list **tailp; 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate defp->def_kind = DEF_ENUM; 392*7c478bd9Sstevel@tonic-gate scan(TOK_IDENT, &tok); 393*7c478bd9Sstevel@tonic-gate defp->def_name = tok.str; 394*7c478bd9Sstevel@tonic-gate scan(TOK_LBRACE, &tok); 395*7c478bd9Sstevel@tonic-gate tailp = &defp->def.en.vals; 396*7c478bd9Sstevel@tonic-gate do { 397*7c478bd9Sstevel@tonic-gate scan(TOK_IDENT, &tok); 398*7c478bd9Sstevel@tonic-gate elist = ALLOC(enumval_list); 399*7c478bd9Sstevel@tonic-gate elist->name = tok.str; 400*7c478bd9Sstevel@tonic-gate elist->assignment = NULL; 401*7c478bd9Sstevel@tonic-gate scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok); 402*7c478bd9Sstevel@tonic-gate if (tok.kind == TOK_EQUAL) { 403*7c478bd9Sstevel@tonic-gate scan_num(&tok); 404*7c478bd9Sstevel@tonic-gate elist->assignment = tok.str; 405*7c478bd9Sstevel@tonic-gate scan2(TOK_COMMA, TOK_RBRACE, &tok); 406*7c478bd9Sstevel@tonic-gate } 407*7c478bd9Sstevel@tonic-gate *tailp = elist; 408*7c478bd9Sstevel@tonic-gate tailp = &elist->next; 409*7c478bd9Sstevel@tonic-gate } while (tok.kind != TOK_RBRACE); 410*7c478bd9Sstevel@tonic-gate *tailp = NULL; 411*7c478bd9Sstevel@tonic-gate } 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate static 414*7c478bd9Sstevel@tonic-gate def_const(defp) 415*7c478bd9Sstevel@tonic-gate definition *defp; 416*7c478bd9Sstevel@tonic-gate { 417*7c478bd9Sstevel@tonic-gate token tok; 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate defp->def_kind = DEF_CONST; 420*7c478bd9Sstevel@tonic-gate scan(TOK_IDENT, &tok); 421*7c478bd9Sstevel@tonic-gate defp->def_name = tok.str; 422*7c478bd9Sstevel@tonic-gate scan(TOK_EQUAL, &tok); 423*7c478bd9Sstevel@tonic-gate scan2(TOK_IDENT, TOK_STRCONST, &tok); 424*7c478bd9Sstevel@tonic-gate defp->def.co = tok.str; 425*7c478bd9Sstevel@tonic-gate } 426*7c478bd9Sstevel@tonic-gate 427*7c478bd9Sstevel@tonic-gate static 428*7c478bd9Sstevel@tonic-gate def_union(defp) 429*7c478bd9Sstevel@tonic-gate definition *defp; 430*7c478bd9Sstevel@tonic-gate { 431*7c478bd9Sstevel@tonic-gate token tok; 432*7c478bd9Sstevel@tonic-gate declaration dec; 433*7c478bd9Sstevel@tonic-gate case_list *cases, *tcase; 434*7c478bd9Sstevel@tonic-gate case_list **tailp; 435*7c478bd9Sstevel@tonic-gate int flag; 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate defp->def_kind = DEF_UNION; 438*7c478bd9Sstevel@tonic-gate scan(TOK_IDENT, &tok); 439*7c478bd9Sstevel@tonic-gate defp->def_name = tok.str; 440*7c478bd9Sstevel@tonic-gate scan(TOK_SWITCH, &tok); 441*7c478bd9Sstevel@tonic-gate scan(TOK_LPAREN, &tok); 442*7c478bd9Sstevel@tonic-gate get_declaration(&dec, DEF_UNION); 443*7c478bd9Sstevel@tonic-gate defp->def.un.enum_decl = dec; 444*7c478bd9Sstevel@tonic-gate tailp = &defp->def.un.cases; 445*7c478bd9Sstevel@tonic-gate scan(TOK_RPAREN, &tok); 446*7c478bd9Sstevel@tonic-gate scan(TOK_LBRACE, &tok); 447*7c478bd9Sstevel@tonic-gate scan(TOK_CASE, &tok); 448*7c478bd9Sstevel@tonic-gate while (tok.kind == TOK_CASE) { 449*7c478bd9Sstevel@tonic-gate scan2(TOK_IDENT, TOK_CHARCONST, &tok); 450*7c478bd9Sstevel@tonic-gate cases = ALLOC(case_list); 451*7c478bd9Sstevel@tonic-gate cases->case_name = tok.str; 452*7c478bd9Sstevel@tonic-gate scan(TOK_COLON, &tok); 453*7c478bd9Sstevel@tonic-gate /* now peek at next token */ 454*7c478bd9Sstevel@tonic-gate flag = 0; 455*7c478bd9Sstevel@tonic-gate if (peekscan(TOK_CASE, &tok)) { 456*7c478bd9Sstevel@tonic-gate do { 457*7c478bd9Sstevel@tonic-gate scan2(TOK_IDENT, TOK_CHARCONST, &tok); 458*7c478bd9Sstevel@tonic-gate cases->contflag = 1; 459*7c478bd9Sstevel@tonic-gate /* continued case statement */ 460*7c478bd9Sstevel@tonic-gate *tailp = cases; 461*7c478bd9Sstevel@tonic-gate tailp = &cases->next; 462*7c478bd9Sstevel@tonic-gate cases = ALLOC(case_list); 463*7c478bd9Sstevel@tonic-gate cases->case_name = tok.str; 464*7c478bd9Sstevel@tonic-gate scan(TOK_COLON, &tok); 465*7c478bd9Sstevel@tonic-gate } while (peekscan(TOK_CASE, &tok)); 466*7c478bd9Sstevel@tonic-gate } 467*7c478bd9Sstevel@tonic-gate else 468*7c478bd9Sstevel@tonic-gate if (flag) 469*7c478bd9Sstevel@tonic-gate { 470*7c478bd9Sstevel@tonic-gate 471*7c478bd9Sstevel@tonic-gate *tailp = cases; 472*7c478bd9Sstevel@tonic-gate tailp = &cases->next; 473*7c478bd9Sstevel@tonic-gate cases = ALLOC(case_list); 474*7c478bd9Sstevel@tonic-gate }; 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate get_declaration(&dec, DEF_UNION); 477*7c478bd9Sstevel@tonic-gate cases->case_decl = dec; 478*7c478bd9Sstevel@tonic-gate cases->contflag = 0; /* no continued case statement */ 479*7c478bd9Sstevel@tonic-gate *tailp = cases; 480*7c478bd9Sstevel@tonic-gate tailp = &cases->next; 481*7c478bd9Sstevel@tonic-gate scan(TOK_SEMICOLON, &tok); 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); 484*7c478bd9Sstevel@tonic-gate } 485*7c478bd9Sstevel@tonic-gate *tailp = NULL; 486*7c478bd9Sstevel@tonic-gate if (tok.kind == TOK_DEFAULT) { 487*7c478bd9Sstevel@tonic-gate scan(TOK_COLON, &tok); 488*7c478bd9Sstevel@tonic-gate get_declaration(&dec, DEF_UNION); 489*7c478bd9Sstevel@tonic-gate defp->def.un.default_decl = ALLOC(declaration); 490*7c478bd9Sstevel@tonic-gate *defp->def.un.default_decl = dec; 491*7c478bd9Sstevel@tonic-gate scan(TOK_SEMICOLON, &tok); 492*7c478bd9Sstevel@tonic-gate scan(TOK_RBRACE, &tok); 493*7c478bd9Sstevel@tonic-gate } else { 494*7c478bd9Sstevel@tonic-gate defp->def.un.default_decl = NULL; 495*7c478bd9Sstevel@tonic-gate } 496*7c478bd9Sstevel@tonic-gate } 497*7c478bd9Sstevel@tonic-gate 498*7c478bd9Sstevel@tonic-gate static char *reserved_words[] = 499*7c478bd9Sstevel@tonic-gate { 500*7c478bd9Sstevel@tonic-gate "array", 501*7c478bd9Sstevel@tonic-gate "bytes", 502*7c478bd9Sstevel@tonic-gate "destroy", 503*7c478bd9Sstevel@tonic-gate "free", 504*7c478bd9Sstevel@tonic-gate "getpos", 505*7c478bd9Sstevel@tonic-gate "inline", 506*7c478bd9Sstevel@tonic-gate "pointer", 507*7c478bd9Sstevel@tonic-gate "reference", 508*7c478bd9Sstevel@tonic-gate "setpos", 509*7c478bd9Sstevel@tonic-gate "sizeof", 510*7c478bd9Sstevel@tonic-gate "union", 511*7c478bd9Sstevel@tonic-gate "vector", 512*7c478bd9Sstevel@tonic-gate NULL 513*7c478bd9Sstevel@tonic-gate }; 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate static char *reserved_types[] = 516*7c478bd9Sstevel@tonic-gate { 517*7c478bd9Sstevel@tonic-gate "opaque", 518*7c478bd9Sstevel@tonic-gate "string", 519*7c478bd9Sstevel@tonic-gate NULL 520*7c478bd9Sstevel@tonic-gate }; 521*7c478bd9Sstevel@tonic-gate 522*7c478bd9Sstevel@tonic-gate /* 523*7c478bd9Sstevel@tonic-gate * check that the given name is not one that would eventually result in 524*7c478bd9Sstevel@tonic-gate * xdr routines that would conflict with internal XDR routines. 525*7c478bd9Sstevel@tonic-gate */ 526*7c478bd9Sstevel@tonic-gate static check_type_name(name, new_type) 527*7c478bd9Sstevel@tonic-gate int new_type; 528*7c478bd9Sstevel@tonic-gate char *name; 529*7c478bd9Sstevel@tonic-gate { 530*7c478bd9Sstevel@tonic-gate int i; 531*7c478bd9Sstevel@tonic-gate char tmp[100]; 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate for (i = 0; reserved_words[i] != NULL; i++) { 534*7c478bd9Sstevel@tonic-gate if (strcmp(name, reserved_words[i]) == 0) { 535*7c478bd9Sstevel@tonic-gate snprintf(tmp, sizeof (tmp), 536*7c478bd9Sstevel@tonic-gate "illegal (reserved) name :\'%s\' " 537*7c478bd9Sstevel@tonic-gate "in type definition", 538*7c478bd9Sstevel@tonic-gate name); 539*7c478bd9Sstevel@tonic-gate error(tmp); 540*7c478bd9Sstevel@tonic-gate } 541*7c478bd9Sstevel@tonic-gate } 542*7c478bd9Sstevel@tonic-gate if (new_type) { 543*7c478bd9Sstevel@tonic-gate for (i = 0; reserved_types[i] != NULL; i++) { 544*7c478bd9Sstevel@tonic-gate if (strcmp(name, reserved_types[i]) == 0) { 545*7c478bd9Sstevel@tonic-gate snprintf(tmp, sizeof (tmp), 546*7c478bd9Sstevel@tonic-gate "illegal (reserved) name :\'%s\' " 547*7c478bd9Sstevel@tonic-gate "in type definition", 548*7c478bd9Sstevel@tonic-gate name); 549*7c478bd9Sstevel@tonic-gate error(tmp); 550*7c478bd9Sstevel@tonic-gate } 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate } 553*7c478bd9Sstevel@tonic-gate } 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate static 558*7c478bd9Sstevel@tonic-gate def_typedef(defp) 559*7c478bd9Sstevel@tonic-gate definition *defp; 560*7c478bd9Sstevel@tonic-gate { 561*7c478bd9Sstevel@tonic-gate declaration dec; 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate defp->def_kind = DEF_TYPEDEF; 564*7c478bd9Sstevel@tonic-gate get_declaration(&dec, DEF_TYPEDEF); 565*7c478bd9Sstevel@tonic-gate defp->def_name = dec.name; 566*7c478bd9Sstevel@tonic-gate check_type_name(dec.name, 1); 567*7c478bd9Sstevel@tonic-gate defp->def.ty.old_prefix = dec.prefix; 568*7c478bd9Sstevel@tonic-gate defp->def.ty.old_type = dec.type; 569*7c478bd9Sstevel@tonic-gate defp->def.ty.rel = dec.rel; 570*7c478bd9Sstevel@tonic-gate defp->def.ty.array_max = dec.array_max; 571*7c478bd9Sstevel@tonic-gate } 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate static 574*7c478bd9Sstevel@tonic-gate get_declaration(dec, dkind) 575*7c478bd9Sstevel@tonic-gate declaration *dec; 576*7c478bd9Sstevel@tonic-gate defkind dkind; 577*7c478bd9Sstevel@tonic-gate { 578*7c478bd9Sstevel@tonic-gate token tok; 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate get_type(&dec->prefix, &dec->type, dkind); 581*7c478bd9Sstevel@tonic-gate dec->rel = REL_ALIAS; 582*7c478bd9Sstevel@tonic-gate if (streq(dec->type, "void")) { 583*7c478bd9Sstevel@tonic-gate return; 584*7c478bd9Sstevel@tonic-gate } 585*7c478bd9Sstevel@tonic-gate 586*7c478bd9Sstevel@tonic-gate check_type_name(dec->type, 0); 587*7c478bd9Sstevel@tonic-gate scan2(TOK_STAR, TOK_IDENT, &tok); 588*7c478bd9Sstevel@tonic-gate if (tok.kind == TOK_STAR) { 589*7c478bd9Sstevel@tonic-gate dec->rel = REL_POINTER; 590*7c478bd9Sstevel@tonic-gate scan(TOK_IDENT, &tok); 591*7c478bd9Sstevel@tonic-gate } 592*7c478bd9Sstevel@tonic-gate dec->name = tok.str; 593*7c478bd9Sstevel@tonic-gate if (peekscan(TOK_LBRACKET, &tok)) { 594*7c478bd9Sstevel@tonic-gate if (dec->rel == REL_POINTER) { 595*7c478bd9Sstevel@tonic-gate error("no array-of-pointer declarations " 596*7c478bd9Sstevel@tonic-gate "-- use typedef"); 597*7c478bd9Sstevel@tonic-gate } 598*7c478bd9Sstevel@tonic-gate dec->rel = REL_VECTOR; 599*7c478bd9Sstevel@tonic-gate scan_num(&tok); 600*7c478bd9Sstevel@tonic-gate dec->array_max = tok.str; 601*7c478bd9Sstevel@tonic-gate scan(TOK_RBRACKET, &tok); 602*7c478bd9Sstevel@tonic-gate } else if (peekscan(TOK_LANGLE, &tok)) { 603*7c478bd9Sstevel@tonic-gate if (dec->rel == REL_POINTER) { 604*7c478bd9Sstevel@tonic-gate error("no array-of-pointer declarations " 605*7c478bd9Sstevel@tonic-gate "-- use typedef"); 606*7c478bd9Sstevel@tonic-gate } 607*7c478bd9Sstevel@tonic-gate dec->rel = REL_ARRAY; 608*7c478bd9Sstevel@tonic-gate if (peekscan(TOK_RANGLE, &tok)) { 609*7c478bd9Sstevel@tonic-gate dec->array_max = "~0"; /* unspecified size, use max */ 610*7c478bd9Sstevel@tonic-gate } else { 611*7c478bd9Sstevel@tonic-gate scan_num(&tok); 612*7c478bd9Sstevel@tonic-gate dec->array_max = tok.str; 613*7c478bd9Sstevel@tonic-gate scan(TOK_RANGLE, &tok); 614*7c478bd9Sstevel@tonic-gate } 615*7c478bd9Sstevel@tonic-gate } 616*7c478bd9Sstevel@tonic-gate if (streq(dec->type, "opaque")) { 617*7c478bd9Sstevel@tonic-gate if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { 618*7c478bd9Sstevel@tonic-gate error("array declaration expected"); 619*7c478bd9Sstevel@tonic-gate } 620*7c478bd9Sstevel@tonic-gate } else if (streq(dec->type, "string")) { 621*7c478bd9Sstevel@tonic-gate if (dec->rel != REL_ARRAY) { 622*7c478bd9Sstevel@tonic-gate error("variable-length array declaration expected"); 623*7c478bd9Sstevel@tonic-gate } 624*7c478bd9Sstevel@tonic-gate } 625*7c478bd9Sstevel@tonic-gate } 626*7c478bd9Sstevel@tonic-gate 627*7c478bd9Sstevel@tonic-gate 628*7c478bd9Sstevel@tonic-gate static 629*7c478bd9Sstevel@tonic-gate get_prog_declaration(dec, dkind, num) 630*7c478bd9Sstevel@tonic-gate declaration *dec; 631*7c478bd9Sstevel@tonic-gate defkind dkind; 632*7c478bd9Sstevel@tonic-gate int num; /* arg number */ 633*7c478bd9Sstevel@tonic-gate { 634*7c478bd9Sstevel@tonic-gate token tok; 635*7c478bd9Sstevel@tonic-gate char name[sizeof (ARGNAME) + 10]; 636*7c478bd9Sstevel@tonic-gate 637*7c478bd9Sstevel@tonic-gate if (dkind == DEF_PROGRAM) { 638*7c478bd9Sstevel@tonic-gate peek(&tok); 639*7c478bd9Sstevel@tonic-gate if (tok.kind == TOK_RPAREN) { /* no arguments */ 640*7c478bd9Sstevel@tonic-gate dec->rel = REL_ALIAS; 641*7c478bd9Sstevel@tonic-gate dec->type = "void"; 642*7c478bd9Sstevel@tonic-gate dec->prefix = NULL; 643*7c478bd9Sstevel@tonic-gate dec->name = NULL; 644*7c478bd9Sstevel@tonic-gate return; 645*7c478bd9Sstevel@tonic-gate } 646*7c478bd9Sstevel@tonic-gate } 647*7c478bd9Sstevel@tonic-gate get_type(&dec->prefix, &dec->type, dkind); 648*7c478bd9Sstevel@tonic-gate dec->rel = REL_ALIAS; 649*7c478bd9Sstevel@tonic-gate if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */ 650*7c478bd9Sstevel@tonic-gate dec->name = strdup(tok.str); 651*7c478bd9Sstevel@tonic-gate else { 652*7c478bd9Sstevel@tonic-gate /* default name of argument */ 653*7c478bd9Sstevel@tonic-gate snprintf(name, sizeof (name), "%s%d", ARGNAME, num); 654*7c478bd9Sstevel@tonic-gate dec->name = strdup(name); 655*7c478bd9Sstevel@tonic-gate } 656*7c478bd9Sstevel@tonic-gate if (dec->name == NULL) 657*7c478bd9Sstevel@tonic-gate error("internal error -- out of memory"); 658*7c478bd9Sstevel@tonic-gate 659*7c478bd9Sstevel@tonic-gate if (streq(dec->type, "void")) { 660*7c478bd9Sstevel@tonic-gate return; 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate if (streq(dec->type, "opaque")) { 664*7c478bd9Sstevel@tonic-gate error("opaque -- illegal argument type"); 665*7c478bd9Sstevel@tonic-gate } 666*7c478bd9Sstevel@tonic-gate if (peekscan(TOK_STAR, &tok)) { 667*7c478bd9Sstevel@tonic-gate if (streq(dec->type, "string")) { 668*7c478bd9Sstevel@tonic-gate error("pointer to string not allowed " 669*7c478bd9Sstevel@tonic-gate "in program arguments\n"); 670*7c478bd9Sstevel@tonic-gate } 671*7c478bd9Sstevel@tonic-gate dec->rel = REL_POINTER; 672*7c478bd9Sstevel@tonic-gate if (peekscan(TOK_IDENT, &tok)) 673*7c478bd9Sstevel@tonic-gate /* optional name of argument */ 674*7c478bd9Sstevel@tonic-gate dec->name = strdup(tok.str); 675*7c478bd9Sstevel@tonic-gate } 676*7c478bd9Sstevel@tonic-gate if (peekscan(TOK_LANGLE, &tok)) { 677*7c478bd9Sstevel@tonic-gate if (!streq(dec->type, "string")) { 678*7c478bd9Sstevel@tonic-gate error("arrays cannot be declared as arguments " 679*7c478bd9Sstevel@tonic-gate "to procedures -- use typedef"); 680*7c478bd9Sstevel@tonic-gate } 681*7c478bd9Sstevel@tonic-gate dec->rel = REL_ARRAY; 682*7c478bd9Sstevel@tonic-gate if (peekscan(TOK_RANGLE, &tok)) { 683*7c478bd9Sstevel@tonic-gate dec->array_max = "~0"; 684*7c478bd9Sstevel@tonic-gate /* unspecified size, use max */ 685*7c478bd9Sstevel@tonic-gate } else { 686*7c478bd9Sstevel@tonic-gate scan_num(&tok); 687*7c478bd9Sstevel@tonic-gate dec->array_max = tok.str; 688*7c478bd9Sstevel@tonic-gate scan(TOK_RANGLE, &tok); 689*7c478bd9Sstevel@tonic-gate } 690*7c478bd9Sstevel@tonic-gate } 691*7c478bd9Sstevel@tonic-gate if (streq(dec->type, "string")) { 692*7c478bd9Sstevel@tonic-gate if (dec->rel != REL_ARRAY) { 693*7c478bd9Sstevel@tonic-gate /* 694*7c478bd9Sstevel@tonic-gate * .x specifies just string as 695*7c478bd9Sstevel@tonic-gate * type of argument 696*7c478bd9Sstevel@tonic-gate * - make it string<> 697*7c478bd9Sstevel@tonic-gate */ 698*7c478bd9Sstevel@tonic-gate dec->rel = REL_ARRAY; 699*7c478bd9Sstevel@tonic-gate dec->array_max = "~0"; /* unspecified size, use max */ 700*7c478bd9Sstevel@tonic-gate } 701*7c478bd9Sstevel@tonic-gate } 702*7c478bd9Sstevel@tonic-gate } 703*7c478bd9Sstevel@tonic-gate 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate 706*7c478bd9Sstevel@tonic-gate static 707*7c478bd9Sstevel@tonic-gate get_type(prefixp, typep, dkind) 708*7c478bd9Sstevel@tonic-gate char **prefixp; 709*7c478bd9Sstevel@tonic-gate char **typep; 710*7c478bd9Sstevel@tonic-gate defkind dkind; 711*7c478bd9Sstevel@tonic-gate { 712*7c478bd9Sstevel@tonic-gate token tok; 713*7c478bd9Sstevel@tonic-gate 714*7c478bd9Sstevel@tonic-gate *prefixp = NULL; 715*7c478bd9Sstevel@tonic-gate get_token(&tok); 716*7c478bd9Sstevel@tonic-gate switch (tok.kind) { 717*7c478bd9Sstevel@tonic-gate case TOK_IDENT: 718*7c478bd9Sstevel@tonic-gate *typep = tok.str; 719*7c478bd9Sstevel@tonic-gate break; 720*7c478bd9Sstevel@tonic-gate case TOK_STRUCT: 721*7c478bd9Sstevel@tonic-gate case TOK_ENUM: 722*7c478bd9Sstevel@tonic-gate case TOK_UNION: 723*7c478bd9Sstevel@tonic-gate *prefixp = tok.str; 724*7c478bd9Sstevel@tonic-gate scan(TOK_IDENT, &tok); 725*7c478bd9Sstevel@tonic-gate *typep = tok.str; 726*7c478bd9Sstevel@tonic-gate break; 727*7c478bd9Sstevel@tonic-gate case TOK_UNSIGNED: 728*7c478bd9Sstevel@tonic-gate unsigned_dec(typep); 729*7c478bd9Sstevel@tonic-gate break; 730*7c478bd9Sstevel@tonic-gate case TOK_SHORT: 731*7c478bd9Sstevel@tonic-gate *typep = "short"; 732*7c478bd9Sstevel@tonic-gate (void) peekscan(TOK_INT, &tok); 733*7c478bd9Sstevel@tonic-gate break; 734*7c478bd9Sstevel@tonic-gate case TOK_LONG: 735*7c478bd9Sstevel@tonic-gate *typep = "long"; 736*7c478bd9Sstevel@tonic-gate (void) peekscan(TOK_INT, &tok); 737*7c478bd9Sstevel@tonic-gate break; 738*7c478bd9Sstevel@tonic-gate case TOK_HYPER: 739*7c478bd9Sstevel@tonic-gate *typep = "longlong_t"; 740*7c478bd9Sstevel@tonic-gate (void) peekscan(TOK_INT, &tok); 741*7c478bd9Sstevel@tonic-gate break; 742*7c478bd9Sstevel@tonic-gate 743*7c478bd9Sstevel@tonic-gate case TOK_VOID: 744*7c478bd9Sstevel@tonic-gate if (dkind != DEF_UNION && dkind != DEF_PROGRAM && 745*7c478bd9Sstevel@tonic-gate dkind != DEF_RESULT) { 746*7c478bd9Sstevel@tonic-gate error("voids allowed only inside union and " 747*7c478bd9Sstevel@tonic-gate "program definitions with one argument"); 748*7c478bd9Sstevel@tonic-gate } 749*7c478bd9Sstevel@tonic-gate *typep = tok.str; 750*7c478bd9Sstevel@tonic-gate break; 751*7c478bd9Sstevel@tonic-gate case TOK_ONEWAY: 752*7c478bd9Sstevel@tonic-gate if (dkind != DEF_RESULT) { 753*7c478bd9Sstevel@tonic-gate error("oneways allowed only inside result definitions"); 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate *typep = tok.str; 756*7c478bd9Sstevel@tonic-gate break; 757*7c478bd9Sstevel@tonic-gate case TOK_STRING: 758*7c478bd9Sstevel@tonic-gate case TOK_OPAQUE: 759*7c478bd9Sstevel@tonic-gate case TOK_CHAR: 760*7c478bd9Sstevel@tonic-gate case TOK_INT: 761*7c478bd9Sstevel@tonic-gate case TOK_FLOAT: 762*7c478bd9Sstevel@tonic-gate case TOK_DOUBLE: 763*7c478bd9Sstevel@tonic-gate case TOK_BOOL: 764*7c478bd9Sstevel@tonic-gate case TOK_QUAD: 765*7c478bd9Sstevel@tonic-gate *typep = tok.str; 766*7c478bd9Sstevel@tonic-gate break; 767*7c478bd9Sstevel@tonic-gate default: 768*7c478bd9Sstevel@tonic-gate error("expected type specifier"); 769*7c478bd9Sstevel@tonic-gate } 770*7c478bd9Sstevel@tonic-gate } 771*7c478bd9Sstevel@tonic-gate 772*7c478bd9Sstevel@tonic-gate static 773*7c478bd9Sstevel@tonic-gate unsigned_dec(typep) 774*7c478bd9Sstevel@tonic-gate char **typep; 775*7c478bd9Sstevel@tonic-gate { 776*7c478bd9Sstevel@tonic-gate token tok; 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate peek(&tok); 779*7c478bd9Sstevel@tonic-gate switch (tok.kind) { 780*7c478bd9Sstevel@tonic-gate case TOK_CHAR: 781*7c478bd9Sstevel@tonic-gate get_token(&tok); 782*7c478bd9Sstevel@tonic-gate *typep = "u_char"; 783*7c478bd9Sstevel@tonic-gate break; 784*7c478bd9Sstevel@tonic-gate case TOK_SHORT: 785*7c478bd9Sstevel@tonic-gate get_token(&tok); 786*7c478bd9Sstevel@tonic-gate *typep = "u_short"; 787*7c478bd9Sstevel@tonic-gate (void) peekscan(TOK_INT, &tok); 788*7c478bd9Sstevel@tonic-gate break; 789*7c478bd9Sstevel@tonic-gate case TOK_LONG: 790*7c478bd9Sstevel@tonic-gate get_token(&tok); 791*7c478bd9Sstevel@tonic-gate *typep = "u_long"; 792*7c478bd9Sstevel@tonic-gate (void) peekscan(TOK_INT, &tok); 793*7c478bd9Sstevel@tonic-gate break; 794*7c478bd9Sstevel@tonic-gate case TOK_HYPER: 795*7c478bd9Sstevel@tonic-gate get_token(&tok); 796*7c478bd9Sstevel@tonic-gate *typep = "u_longlong_t"; 797*7c478bd9Sstevel@tonic-gate (void) peekscan(TOK_INT, &tok); 798*7c478bd9Sstevel@tonic-gate break; 799*7c478bd9Sstevel@tonic-gate case TOK_INT: 800*7c478bd9Sstevel@tonic-gate get_token(&tok); 801*7c478bd9Sstevel@tonic-gate *typep = "u_int"; 802*7c478bd9Sstevel@tonic-gate break; 803*7c478bd9Sstevel@tonic-gate default: 804*7c478bd9Sstevel@tonic-gate *typep = "u_int"; 805*7c478bd9Sstevel@tonic-gate break; 806*7c478bd9Sstevel@tonic-gate } 807*7c478bd9Sstevel@tonic-gate } 808