Home | History | Annotate | Line # | Download | only in rpcgen
rpc_parse.c revision 1.3
      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.3 1993/08/01 18:09:19 mycroft 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