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