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.2 1995/05/15 00:03:32 ache 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 *ptailp = NULL; 169 *vtailp = vlist; 170 vtailp = &vlist->next; 171 scan(TOK_RBRACE, &tok); 172 scan(TOK_EQUAL, &tok); 173 scan_num(&tok); 174 vlist->vers_num = tok.str; 175 scan(TOK_SEMICOLON, &tok); 176 scan2(TOK_VERSION, TOK_RBRACE, &tok); 177 } while (tok.kind == TOK_VERSION); 178 scan(TOK_EQUAL, &tok); 179 scan_num(&tok); 180 defp->def.pr.prog_num = tok.str; 181 *vtailp = NULL; 182 } 183 184 static 185 def_enum(defp) 186 definition *defp; 187 { 188 token tok; 189 enumval_list *elist; 190 enumval_list **tailp; 191 192 defp->def_kind = DEF_ENUM; 193 scan(TOK_IDENT, &tok); 194 defp->def_name = tok.str; 195 scan(TOK_LBRACE, &tok); 196 tailp = &defp->def.en.vals; 197 do { 198 scan(TOK_IDENT, &tok); 199 elist = ALLOC(enumval_list); 200 elist->name = tok.str; 201 elist->assignment = NULL; 202 scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok); 203 if (tok.kind == TOK_EQUAL) { 204 scan_num(&tok); 205 elist->assignment = tok.str; 206 scan2(TOK_COMMA, TOK_RBRACE, &tok); 207 } 208 *tailp = elist; 209 tailp = &elist->next; 210 } while (tok.kind != TOK_RBRACE); 211 *tailp = NULL; 212 } 213 214 static 215 def_const(defp) 216 definition *defp; 217 { 218 token tok; 219 220 defp->def_kind = DEF_CONST; 221 scan(TOK_IDENT, &tok); 222 defp->def_name = tok.str; 223 scan(TOK_EQUAL, &tok); 224 scan2(TOK_IDENT, TOK_STRCONST, &tok); 225 defp->def.co = tok.str; 226 } 227 228 static 229 def_union(defp) 230 definition *defp; 231 { 232 token tok; 233 declaration dec; 234 case_list *cases; 235 case_list **tailp; 236 237 defp->def_kind = DEF_UNION; 238 scan(TOK_IDENT, &tok); 239 defp->def_name = tok.str; 240 scan(TOK_SWITCH, &tok); 241 scan(TOK_LPAREN, &tok); 242 get_declaration(&dec, DEF_UNION); 243 defp->def.un.enum_decl = dec; 244 tailp = &defp->def.un.cases; 245 scan(TOK_RPAREN, &tok); 246 scan(TOK_LBRACE, &tok); 247 scan(TOK_CASE, &tok); 248 while (tok.kind == TOK_CASE) { 249 scan(TOK_IDENT, &tok); 250 cases = ALLOC(case_list); 251 cases->case_name = tok.str; 252 scan(TOK_COLON, &tok); 253 get_declaration(&dec, DEF_UNION); 254 cases->case_decl = dec; 255 *tailp = cases; 256 tailp = &cases->next; 257 scan(TOK_SEMICOLON, &tok); 258 scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); 259 } 260 *tailp = NULL; 261 if (tok.kind == TOK_DEFAULT) { 262 scan(TOK_COLON, &tok); 263 get_declaration(&dec, DEF_UNION); 264 defp->def.un.default_decl = ALLOC(declaration); 265 *defp->def.un.default_decl = dec; 266 scan(TOK_SEMICOLON, &tok); 267 scan(TOK_RBRACE, &tok); 268 } else { 269 defp->def.un.default_decl = NULL; 270 } 271 } 272 273 274 static 275 def_typedef(defp) 276 definition *defp; 277 { 278 declaration dec; 279 280 defp->def_kind = DEF_TYPEDEF; 281 get_declaration(&dec, DEF_TYPEDEF); 282 defp->def_name = dec.name; 283 defp->def.ty.old_prefix = dec.prefix; 284 defp->def.ty.old_type = dec.type; 285 defp->def.ty.rel = dec.rel; 286 defp->def.ty.array_max = dec.array_max; 287 } 288 289 290 static 291 get_declaration(dec, dkind) 292 declaration *dec; 293 defkind dkind; 294 { 295 token tok; 296 297 get_type(&dec->prefix, &dec->type, dkind); 298 dec->rel = REL_ALIAS; 299 if (streq(dec->type, "void")) { 300 return; 301 } 302 scan2(TOK_STAR, TOK_IDENT, &tok); 303 if (tok.kind == TOK_STAR) { 304 dec->rel = REL_POINTER; 305 scan(TOK_IDENT, &tok); 306 } 307 dec->name = tok.str; 308 if (peekscan(TOK_LBRACKET, &tok)) { 309 if (dec->rel == REL_POINTER) { 310 error("no array-of-pointer declarations -- use typedef"); 311 } 312 dec->rel = REL_VECTOR; 313 scan_num(&tok); 314 dec->array_max = tok.str; 315 scan(TOK_RBRACKET, &tok); 316 } else if (peekscan(TOK_LANGLE, &tok)) { 317 if (dec->rel == REL_POINTER) { 318 error("no array-of-pointer declarations -- use typedef"); 319 } 320 dec->rel = REL_ARRAY; 321 if (peekscan(TOK_RANGLE, &tok)) { 322 dec->array_max = "~0"; /* unspecified size, use max */ 323 } else { 324 scan_num(&tok); 325 dec->array_max = tok.str; 326 scan(TOK_RANGLE, &tok); 327 } 328 } 329 if (streq(dec->type, "opaque")) { 330 if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { 331 error("array declaration expected"); 332 } 333 } else if (streq(dec->type, "string")) { 334 if (dec->rel != REL_ARRAY) { 335 error("variable-length array declaration expected"); 336 } 337 } 338 } 339 340 341 static 342 get_type(prefixp, typep, dkind) 343 char **prefixp; 344 char **typep; 345 defkind dkind; 346 { 347 token tok; 348 349 *prefixp = NULL; 350 get_token(&tok); 351 switch (tok.kind) { 352 case TOK_IDENT: 353 *typep = tok.str; 354 break; 355 case TOK_STRUCT: 356 case TOK_ENUM: 357 case TOK_UNION: 358 *prefixp = tok.str; 359 scan(TOK_IDENT, &tok); 360 *typep = tok.str; 361 break; 362 case TOK_UNSIGNED: 363 unsigned_dec(typep); 364 break; 365 case TOK_SHORT: 366 *typep = "short"; 367 (void) peekscan(TOK_INT, &tok); 368 break; 369 case TOK_LONG: 370 *typep = "long"; 371 (void) peekscan(TOK_INT, &tok); 372 break; 373 case TOK_VOID: 374 if (dkind != DEF_UNION && dkind != DEF_PROGRAM) { 375 error("voids allowed only inside union and program definitions"); 376 } 377 *typep = tok.str; 378 break; 379 case TOK_STRING: 380 case TOK_OPAQUE: 381 case TOK_CHAR: 382 case TOK_INT: 383 case TOK_FLOAT: 384 case TOK_DOUBLE: 385 case TOK_BOOL: 386 *typep = tok.str; 387 break; 388 default: 389 error("expected type specifier"); 390 } 391 } 392 393 394 static 395 unsigned_dec(typep) 396 char **typep; 397 { 398 token tok; 399 400 peek(&tok); 401 switch (tok.kind) { 402 case TOK_CHAR: 403 get_token(&tok); 404 *typep = "u_char"; 405 break; 406 case TOK_SHORT: 407 get_token(&tok); 408 *typep = "u_short"; 409 (void) peekscan(TOK_INT, &tok); 410 break; 411 case TOK_LONG: 412 get_token(&tok); 413 *typep = "u_long"; 414 (void) peekscan(TOK_INT, &tok); 415 break; 416 case TOK_INT: 417 get_token(&tok); 418 *typep = "u_int"; 419 break; 420 default: 421 *typep = "u_int"; 422 break; 423 } 424 } 425