1 /* @(#)rpc_parse.c 2.1 88/08/01 4.0 RPCSRC */ 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. 9 * 10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13 * 14 * Sun RPC is provided with no support and without any obligation on the 15 * part of Sun Microsystems, Inc. to assist in its use, correction, 16 * modification or enhancement. 17 * 18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20 * OR ANY PART THEREOF. 21 * 22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23 * or profits or other special, indirect and consequential damages, even if 24 * Sun has been advised of the possibility of such damages. 25 * 26 * Sun Microsystems, Inc. 27 * 2550 Garcia Avenue 28 * Mountain View, California 94043 29 */ 30 #ifndef lint 31 /*static char sccsid[] = "from: @(#)rpc_parse.c 1.4 87/04/28 (C) 1987 SMI";*/ 32 static char rcsid[] = "$Id: rpc_parse.c,v 1.1 1993/09/13 23:20:16 jtc Exp $"; 33 #endif 34 35 /* 36 * rpc_parse.c, Parser for the RPC protocol compiler 37 * Copyright (C) 1987 Sun Microsystems, Inc. 38 */ 39 #include <stdio.h> 40 #include "rpc_util.h" 41 #include "rpc_scan.h" 42 #include "rpc_parse.h" 43 44 static int isdefined(), def_struct(), def_program(), def_enum(), def_const(), 45 def_union(), def_typedef(), get_declaration(), get_type(), 46 unsigned_dec(); 47 /* 48 * return the next definition you see 49 */ 50 definition * 51 get_definition() 52 { 53 definition *defp; 54 token tok; 55 56 defp = ALLOC(definition); 57 get_token(&tok); 58 switch (tok.kind) { 59 case TOK_STRUCT: 60 def_struct(defp); 61 break; 62 case TOK_UNION: 63 def_union(defp); 64 break; 65 case TOK_TYPEDEF: 66 def_typedef(defp); 67 break; 68 case TOK_ENUM: 69 def_enum(defp); 70 break; 71 case TOK_PROGRAM: 72 def_program(defp); 73 break; 74 case TOK_CONST: 75 def_const(defp); 76 break; 77 case TOK_EOF: 78 return (NULL); 79 break; 80 default: 81 error("definition keyword expected"); 82 } 83 scan(TOK_SEMICOLON, &tok); 84 isdefined(defp); 85 return (defp); 86 } 87 88 static 89 isdefined(defp) 90 definition *defp; 91 { 92 STOREVAL(&defined, defp); 93 } 94 95 96 static 97 def_struct(defp) 98 definition *defp; 99 { 100 token tok; 101 declaration dec; 102 decl_list *decls; 103 decl_list **tailp; 104 105 defp->def_kind = DEF_STRUCT; 106 107 scan(TOK_IDENT, &tok); 108 defp->def_name = tok.str; 109 scan(TOK_LBRACE, &tok); 110 tailp = &defp->def.st.decls; 111 do { 112 get_declaration(&dec, DEF_STRUCT); 113 decls = ALLOC(decl_list); 114 decls->decl = dec; 115 *tailp = decls; 116 tailp = &decls->next; 117 scan(TOK_SEMICOLON, &tok); 118 peek(&tok); 119 } while (tok.kind != TOK_RBRACE); 120 get_token(&tok); 121 *tailp = NULL; 122 } 123 124 static 125 def_program(defp) 126 definition *defp; 127 { 128 token tok; 129 version_list *vlist; 130 version_list **vtailp; 131 proc_list *plist; 132 proc_list **ptailp; 133 134 defp->def_kind = DEF_PROGRAM; 135 scan(TOK_IDENT, &tok); 136 defp->def_name = tok.str; 137 scan(TOK_LBRACE, &tok); 138 vtailp = &defp->def.pr.versions; 139 scan(TOK_VERSION, &tok); 140 do { 141 scan(TOK_IDENT, &tok); 142 vlist = ALLOC(version_list); 143 vlist->vers_name = tok.str; 144 scan(TOK_LBRACE, &tok); 145 ptailp = &vlist->procs; 146 do { 147 plist = ALLOC(proc_list); 148 get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM); 149 if (streq(plist->res_type, "opaque")) { 150 error("illegal result type"); 151 } 152 scan(TOK_IDENT, &tok); 153 plist->proc_name = tok.str; 154 scan(TOK_LPAREN, &tok); 155 get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM); 156 if (streq(plist->arg_type, "opaque")) { 157 error("illegal argument type"); 158 } 159 scan(TOK_RPAREN, &tok); 160 scan(TOK_EQUAL, &tok); 161 scan_num(&tok); 162 scan(TOK_SEMICOLON, &tok); 163 plist->proc_num = tok.str; 164 *ptailp = plist; 165 ptailp = &plist->next; 166 peek(&tok); 167 } while (tok.kind != TOK_RBRACE); 168 *vtailp = vlist; 169 vtailp = &vlist->next; 170 scan(TOK_RBRACE, &tok); 171 scan(TOK_EQUAL, &tok); 172 scan_num(&tok); 173 vlist->vers_num = tok.str; 174 scan(TOK_SEMICOLON, &tok); 175 scan2(TOK_VERSION, TOK_RBRACE, &tok); 176 } while (tok.kind == TOK_VERSION); 177 scan(TOK_EQUAL, &tok); 178 scan_num(&tok); 179 defp->def.pr.prog_num = tok.str; 180 *vtailp = NULL; 181 } 182 183 static 184 def_enum(defp) 185 definition *defp; 186 { 187 token tok; 188 enumval_list *elist; 189 enumval_list **tailp; 190 191 defp->def_kind = DEF_ENUM; 192 scan(TOK_IDENT, &tok); 193 defp->def_name = tok.str; 194 scan(TOK_LBRACE, &tok); 195 tailp = &defp->def.en.vals; 196 do { 197 scan(TOK_IDENT, &tok); 198 elist = ALLOC(enumval_list); 199 elist->name = tok.str; 200 elist->assignment = NULL; 201 scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok); 202 if (tok.kind == TOK_EQUAL) { 203 scan_num(&tok); 204 elist->assignment = tok.str; 205 scan2(TOK_COMMA, TOK_RBRACE, &tok); 206 } 207 *tailp = elist; 208 tailp = &elist->next; 209 } while (tok.kind != TOK_RBRACE); 210 *tailp = NULL; 211 } 212 213 static 214 def_const(defp) 215 definition *defp; 216 { 217 token tok; 218 219 defp->def_kind = DEF_CONST; 220 scan(TOK_IDENT, &tok); 221 defp->def_name = tok.str; 222 scan(TOK_EQUAL, &tok); 223 scan2(TOK_IDENT, TOK_STRCONST, &tok); 224 defp->def.co = tok.str; 225 } 226 227 static 228 def_union(defp) 229 definition *defp; 230 { 231 token tok; 232 declaration dec; 233 case_list *cases; 234 case_list **tailp; 235 236 defp->def_kind = DEF_UNION; 237 scan(TOK_IDENT, &tok); 238 defp->def_name = tok.str; 239 scan(TOK_SWITCH, &tok); 240 scan(TOK_LPAREN, &tok); 241 get_declaration(&dec, DEF_UNION); 242 defp->def.un.enum_decl = dec; 243 tailp = &defp->def.un.cases; 244 scan(TOK_RPAREN, &tok); 245 scan(TOK_LBRACE, &tok); 246 scan(TOK_CASE, &tok); 247 while (tok.kind == TOK_CASE) { 248 scan(TOK_IDENT, &tok); 249 cases = ALLOC(case_list); 250 cases->case_name = tok.str; 251 scan(TOK_COLON, &tok); 252 get_declaration(&dec, DEF_UNION); 253 cases->case_decl = dec; 254 *tailp = cases; 255 tailp = &cases->next; 256 scan(TOK_SEMICOLON, &tok); 257 scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); 258 } 259 *tailp = NULL; 260 if (tok.kind == TOK_DEFAULT) { 261 scan(TOK_COLON, &tok); 262 get_declaration(&dec, DEF_UNION); 263 defp->def.un.default_decl = ALLOC(declaration); 264 *defp->def.un.default_decl = dec; 265 scan(TOK_SEMICOLON, &tok); 266 scan(TOK_RBRACE, &tok); 267 } else { 268 defp->def.un.default_decl = NULL; 269 } 270 } 271 272 273 static 274 def_typedef(defp) 275 definition *defp; 276 { 277 declaration dec; 278 279 defp->def_kind = DEF_TYPEDEF; 280 get_declaration(&dec, DEF_TYPEDEF); 281 defp->def_name = dec.name; 282 defp->def.ty.old_prefix = dec.prefix; 283 defp->def.ty.old_type = dec.type; 284 defp->def.ty.rel = dec.rel; 285 defp->def.ty.array_max = dec.array_max; 286 } 287 288 289 static 290 get_declaration(dec, dkind) 291 declaration *dec; 292 defkind dkind; 293 { 294 token tok; 295 296 get_type(&dec->prefix, &dec->type, dkind); 297 dec->rel = REL_ALIAS; 298 if (streq(dec->type, "void")) { 299 return; 300 } 301 scan2(TOK_STAR, TOK_IDENT, &tok); 302 if (tok.kind == TOK_STAR) { 303 dec->rel = REL_POINTER; 304 scan(TOK_IDENT, &tok); 305 } 306 dec->name = tok.str; 307 if (peekscan(TOK_LBRACKET, &tok)) { 308 if (dec->rel == REL_POINTER) { 309 error("no array-of-pointer declarations -- use typedef"); 310 } 311 dec->rel = REL_VECTOR; 312 scan_num(&tok); 313 dec->array_max = tok.str; 314 scan(TOK_RBRACKET, &tok); 315 } else if (peekscan(TOK_LANGLE, &tok)) { 316 if (dec->rel == REL_POINTER) { 317 error("no array-of-pointer declarations -- use typedef"); 318 } 319 dec->rel = REL_ARRAY; 320 if (peekscan(TOK_RANGLE, &tok)) { 321 dec->array_max = "~0"; /* unspecified size, use max */ 322 } else { 323 scan_num(&tok); 324 dec->array_max = tok.str; 325 scan(TOK_RANGLE, &tok); 326 } 327 } 328 if (streq(dec->type, "opaque")) { 329 if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { 330 error("array declaration expected"); 331 } 332 } else if (streq(dec->type, "string")) { 333 if (dec->rel != REL_ARRAY) { 334 error("variable-length array declaration expected"); 335 } 336 } 337 } 338 339 340 static 341 get_type(prefixp, typep, dkind) 342 char **prefixp; 343 char **typep; 344 defkind dkind; 345 { 346 token tok; 347 348 *prefixp = NULL; 349 get_token(&tok); 350 switch (tok.kind) { 351 case TOK_IDENT: 352 *typep = tok.str; 353 break; 354 case TOK_STRUCT: 355 case TOK_ENUM: 356 case TOK_UNION: 357 *prefixp = tok.str; 358 scan(TOK_IDENT, &tok); 359 *typep = tok.str; 360 break; 361 case TOK_UNSIGNED: 362 unsigned_dec(typep); 363 break; 364 case TOK_SHORT: 365 *typep = "short"; 366 (void) peekscan(TOK_INT, &tok); 367 break; 368 case TOK_LONG: 369 *typep = "long"; 370 (void) peekscan(TOK_INT, &tok); 371 break; 372 case TOK_VOID: 373 if (dkind != DEF_UNION && dkind != DEF_PROGRAM) { 374 error("voids allowed only inside union and program definitions"); 375 } 376 *typep = tok.str; 377 break; 378 case TOK_STRING: 379 case TOK_OPAQUE: 380 case TOK_CHAR: 381 case TOK_INT: 382 case TOK_FLOAT: 383 case TOK_DOUBLE: 384 case TOK_BOOL: 385 *typep = tok.str; 386 break; 387 default: 388 error("expected type specifier"); 389 } 390 } 391 392 393 static 394 unsigned_dec(typep) 395 char **typep; 396 { 397 token tok; 398 399 peek(&tok); 400 switch (tok.kind) { 401 case TOK_CHAR: 402 get_token(&tok); 403 *typep = "u_char"; 404 break; 405 case TOK_SHORT: 406 get_token(&tok); 407 *typep = "u_short"; 408 (void) peekscan(TOK_INT, &tok); 409 break; 410 case TOK_LONG: 411 get_token(&tok); 412 *typep = "u_long"; 413 (void) peekscan(TOK_INT, &tok); 414 break; 415 case TOK_INT: 416 get_token(&tok); 417 *typep = "u_int"; 418 break; 419 default: 420 *typep = "u_int"; 421 break; 422 } 423 } 424