rsalz@bbn.com (Rich Salz) (03/03/88)
Submitted-by: Stephen X. Nahm <sxn@Sun.COM> Posting-number: Volume 13, Issue 84 Archive-name: rpc3.9/part07 #! /bin/sh # This is a shell archive. To extract, remove the header and type "sh filename" # echo x - rpcgen echo creating directory rpcgen mkdir rpcgen cd rpcgen echo x - Makefile cat > Makefile <<'Funky_Stuff' # # @(#)Makefile 1.2 87/11/09 3.9 RPCSRC # # Makefile for rpc protocol compiler # Copyright (C) 1987, Sun Microsystems, Inc. # SRCS= rpc_main.c rpc_hout.c rpc_cout.c rpc_parse.c rpc_scan.c rpc_util.c \ rpc_svcout.c rpc_clntout.c HDRS= rpc_util.h rpc_parse.h rpc_scan.h OBJS= rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o rpc_scan.o rpc_util.o \ rpc_svcout.o rpc_clntout.o GOAL=rpcgen CFLAGS = -O DESTDIR= $(GOAL): $(OBJS) $(CC) $(CFLAGS) $(OBJS) -o $@ install: $(GOAL) @echo "Installing the RPC Protocol Compiler" install -s $(GOAL) $(DESTDIR)/usr/bin lint: $(SRCS) $(HDRS) lint $(SRCS) clean: rm -f $(GOAL) $(OBJS) depend: $(SRCS) $(HDRS) @${CC} ${CFLAGS} -M ${SRCS} > makedep @echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep @echo '$$r makedep' >>eddep @echo 'w' >>eddep @cp Makefile makefile.bak @ed - Makefile < eddep @rm eddep makedep makefile.bak depend.42BSD depend.42bsd: cp /dev/null x.c for i in $(SRCS) ; do \ (/bin/grep '^#[ ]*include' x.c $$i | sed \ -e '/\.\.\/h/d' \ -e '/\.\.\/ufs/d' \ -e 's,<\(.*\)>,"/usr/include/\1",' \ -e 's/:[^"]*"\([^"]*\)".*/: \1/' \ -e 's/\.c/\.o/' >>makedep); done echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep echo '$$r makedep' >>eddep echo 'w' >>eddep cp Makefile Makefile.bak ed - Makefile < eddep rm eddep makedep x.c echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile echo '# see make depend above' >> Makefile # DO NOT DELETE THIS LINE Funky_Stuff len=`wc -c < Makefile` if [ $len != 1618 ] ; then echo error: Makefile was $len bytes long, should have been 1618 fi echo x - rpc_clntout.c cat > rpc_clntout.c <<'Funky_Stuff' /* @(#)rpc_clntout.c 1.2 87/11/24 3.9 RPCSRC */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ #ifndef lint static char sccsid[] = "@(#)rpc_clntout.c 1.2 87/06/24 (C) 1987 SMI"; #endif /* * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler * Copyright (C) 1987, Sun Microsytsems, Inc. */ #include <stdio.h> #include <strings.h> #include "rpc_parse.h" #include "rpc_util.h" #define DEFAULT_TIMEOUT 25 /* in seconds */ void write_stubs() { list *l; definition *def; f_print(fout, "\nstatic struct timeval TIMEOUT = { %d, 0 };\n", DEFAULT_TIMEOUT); for (l = defined; l != NULL; l = l->next) { def = (definition *) l->val; if (def->def_kind == DEF_PROGRAM) { write_program(def); } } } static write_program(def) definition *def; { version_list *vp; proc_list *proc; for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) { for (proc = vp->procs; proc != NULL; proc = proc->next) { f_print(fout, "\n"); ptype(proc->res_prefix, proc->res_type, 1); f_print(fout, "*\n"); pvname(proc->proc_name, vp->vers_num); f_print(fout, "(argp, clnt)\n"); f_print(fout, "\t"); ptype(proc->arg_prefix, proc->arg_type, 1); f_print(fout, "*argp;\n"); f_print(fout, "\tCLIENT *clnt;\n"); f_print(fout, "{\n"); printbody(proc); f_print(fout, "}\n\n"); } } } static char * ampr(type) char *type; { if (isvectordef(type, REL_ALIAS)) { return (""); } else { return ("&"); } } static printbody(proc) proc_list *proc; { f_print(fout, "\tstatic "); if (streq(proc->res_type, "void")) { f_print(fout, "char "); } else { ptype(proc->res_prefix, proc->res_type, 0); } f_print(fout, "res;\n"); f_print(fout, "\n"); f_print(fout, "\tbzero(%sres, sizeof(res));\n", ampr(proc->res_type)); f_print(fout, "\tif (clnt_call(clnt, %s, xdr_%s, argp, xdr_%s, %sres, TIMEOUT) != RPC_SUCCESS) {\n", proc->proc_name, stringfix(proc->arg_type), stringfix(proc->res_type), ampr(proc->res_type)); f_print(fout, "\t\treturn (NULL);\n"); f_print(fout, "\t}\n"); if (streq(proc->res_type, "void")) { f_print(fout, "\treturn ((void *)%sres);\n", ampr(proc->res_type)); } else { f_print(fout, "\treturn (%sres);\n", ampr(proc->res_type)); } } Funky_Stuff len=`wc -c < rpc_clntout.c` if [ $len != 3441 ] ; then echo error: rpc_clntout.c was $len bytes long, should have been 3441 fi echo x - rpc_cout.c cat > rpc_cout.c <<'Funky_Stuff' /* @(#)rpc_cout.c 1.1 87/11/04 3.9 RPCSRC */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ #ifndef lint static char sccsid[] = "@(#)rpc_cout.c 1.8 87/06/24 (C) 1987 SMI"; #endif /* * rpc_cout.c, XDR routine outputter for the RPC protocol compiler * Copyright (C) 1987, Sun Microsystems, Inc. */ #include <stdio.h> #include <strings.h> #include "rpc_util.h" #include "rpc_parse.h" /* * Emit the C-routine for the given definition */ void emit(def) definition *def; { if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) { return; } print_header(def); switch (def->def_kind) { case DEF_UNION: emit_union(def); break; case DEF_ENUM: emit_enum(def); break; case DEF_STRUCT: emit_struct(def); break; case DEF_TYPEDEF: emit_typedef(def); break; } print_trailer(); } static findtype(def, type) definition *def; char *type; { if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) { return (0); } else { return (streq(def->def_name, type)); } } static undefined(type) char *type; { definition *def; def = (definition *) FINDVAL(defined, type, findtype); return (def == NULL); } static print_header(def) definition *def; { space(); f_print(fout, "bool_t\n"); f_print(fout, "xdr_%s(xdrs, objp)\n", def->def_name); f_print(fout, "\tXDR *xdrs;\n"); f_print(fout, "\t%s ", def->def_name); if (def->def_kind != DEF_TYPEDEF || !isvectordef(def->def.ty.old_type, def->def.ty.rel)) { f_print(fout, "*"); } f_print(fout, "objp;\n"); f_print(fout, "{\n"); } static print_trailer() { f_print(fout, "\treturn (TRUE);\n"); f_print(fout, "}\n"); space(); } static print_ifopen(indent, name) int indent; char *name; { tabify(fout, indent); f_print(fout, "if (!xdr_%s(xdrs", name); } static print_ifarg(arg) char *arg; { f_print(fout, ", %s", arg); } static print_ifsizeof(prefix, type) char *prefix; char *type; { if (streq(type, "bool")) { f_print(fout, ", sizeof(bool_t), xdr_bool"); } else { f_print(fout, ", sizeof("); if (undefined(type) && prefix) { f_print(fout, "%s ", prefix); } f_print(fout, "%s), xdr_%s", type, type); } } static print_ifclose(indent) int indent; { f_print(fout, ")) {\n"); tabify(fout, indent); f_print(fout, "\treturn (FALSE);\n"); tabify(fout, indent); f_print(fout, "}\n"); } static space() { f_print(fout, "\n\n"); } static print_ifstat(indent, prefix, type, rel, amax, objname, name) int indent; char *prefix; char *type; relation rel; char *amax; char *objname; char *name; { char *alt = NULL; switch (rel) { case REL_POINTER: print_ifopen(indent, "pointer"); print_ifarg("(char **)"); f_print(fout, "%s", objname); print_ifsizeof(prefix, type); break; case REL_VECTOR: if (streq(type, "string")) { alt = "string"; } else if (streq(type, "opaque")) { alt = "opaque"; } if (alt) { print_ifopen(indent, alt); print_ifarg(objname); } else { print_ifopen(indent, "vector"); print_ifarg("(char *)"); f_print(fout, "%s", objname); } print_ifarg(amax); if (!alt) { print_ifsizeof(prefix, type); } break; case REL_ARRAY: if (streq(type, "string")) { alt = "string"; } else if (streq(type, "opaque")) { alt = "bytes"; } if (streq(type, "string")) { print_ifopen(indent, alt); print_ifarg(objname); } else { if (alt) { print_ifopen(indent, alt); } else { print_ifopen(indent, "array"); } print_ifarg("(char **)"); if (*objname == '&') { f_print(fout, "%s.%s_val, (u_int *)%s.%s_len", objname, name, objname, name); } else { f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len", objname, name, objname, name); } } print_ifarg(amax); if (!alt) { print_ifsizeof(prefix, type); } break; case REL_ALIAS: print_ifopen(indent, type); print_ifarg(objname); break; } print_ifclose(indent); } /* ARGSUSED */ static emit_enum(def) definition *def; { print_ifopen(1, "enum"); print_ifarg("(enum_t *)objp"); print_ifclose(1); } static emit_union(def) definition *def; { declaration *dflt; case_list *cl; declaration *cs; char *object; char *format = "&objp->%s_u.%s"; print_stat(&def->def.un.enum_decl); f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name); for (cl = def->def.un.cases; cl != NULL; cl = cl->next) { cs = &cl->case_decl; f_print(fout, "\tcase %s:\n", cl->case_name); if (!streq(cs->type, "void")) { object = alloc(strlen(def->def_name) + strlen(format) + strlen(cs->name) + 1); s_print(object, format, def->def_name, cs->name); print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max, object, cs->name); free(object); } f_print(fout, "\t\tbreak;\n"); } dflt = def->def.un.default_decl; if (dflt != NULL) { if (!streq(dflt->type, "void")) { f_print(fout, "\tdefault:\n"); object = alloc(strlen(def->def_name) + strlen(format) + strlen(dflt->name) + 1); s_print(object, format, def->def_name, dflt->name); print_ifstat(2, dflt->prefix, dflt->type, dflt->rel, dflt->array_max, object, dflt->name); free(object); f_print(fout, "\t\tbreak;\n"); } } else { f_print(fout, "\tdefault:\n"); f_print(fout, "\t\treturn (FALSE);\n"); } f_print(fout, "\t}\n"); } static emit_struct(def) definition *def; { decl_list *dl; for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { print_stat(&dl->decl); } } static emit_typedef(def) definition *def; { char *prefix = def->def.ty.old_prefix; char *type = def->def.ty.old_type; char *amax = def->def.ty.array_max; relation rel = def->def.ty.rel; print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name); } static print_stat(dec) declaration *dec; { char *prefix = dec->prefix; char *type = dec->type; char *amax = dec->array_max; relation rel = dec->rel; char name[256]; if (isvectordef(type, rel)) { s_print(name, "objp->%s", dec->name); } else { s_print(name, "&objp->%s", dec->name); } print_ifstat(1, prefix, type, rel, amax, name, dec->name); } Funky_Stuff len=`wc -c < rpc_cout.c` if [ $len != 7284 ] ; then echo error: rpc_cout.c was $len bytes long, should have been 7284 fi echo x - rpc_hout.c cat > rpc_hout.c <<'Funky_Stuff' /* @(#)rpc_hout.c 1.2 87/11/30 3.9 RPCSRC */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ #ifndef lint static char sccsid[] = "@(#)rpc_hout.c 1.6 87/07/28 (C) 1987 SMI"; #endif /* * rpc_hout.c, Header file outputter for the RPC protocol compiler * Copyright (C) 1987, Sun Microsystems, Inc. */ #include <stdio.h> #include <ctype.h> #include "rpc_util.h" #include "rpc_parse.h" /* * Print the C-version of an xdr definition */ void print_datadef(def) definition *def; { if (def->def_kind != DEF_CONST) { f_print(fout, "\n"); } switch (def->def_kind) { case DEF_STRUCT: pstructdef(def); break; case DEF_UNION: puniondef(def); break; case DEF_ENUM: penumdef(def); break; case DEF_TYPEDEF: ptypedef(def); break; case DEF_PROGRAM: pprogramdef(def); break; case DEF_CONST: pconstdef(def); break; } if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) { f_print(fout, "bool_t xdr_%s();\n", def->def_name); } if (def->def_kind != DEF_CONST) { f_print(fout, "\n"); } } static pconstdef(def) definition *def; { pdefine(def->def_name, def->def.co); } static pstructdef(def) definition *def; { decl_list *l; char *name = def->def_name; f_print(fout, "struct %s {\n", name); for (l = def->def.st.decls; l != NULL; l = l->next) { pdeclaration(name, &l->decl, 1); } f_print(fout, "};\n"); f_print(fout, "typedef struct %s %s;\n", name, name); } static puniondef(def) definition *def; { case_list *l; char *name = def->def_name; declaration *decl; f_print(fout, "struct %s {\n", name); decl = &def->def.un.enum_decl; if (streq(decl->type, "bool")) { f_print(fout, "\tbool_t %s;\n", decl->name); } else { f_print(fout, "\t%s %s;\n", decl->type, decl->name); } f_print(fout, "\tunion {\n"); for (l = def->def.un.cases; l != NULL; l = l->next) { pdeclaration(name, &l->case_decl, 2); } decl = def->def.un.default_decl; if (decl && !streq(decl->type, "void")) { pdeclaration(name, decl, 2); } f_print(fout, "\t} %s_u;\n", name); f_print(fout, "};\n"); f_print(fout, "typedef struct %s %s;\n", name, name); } static pdefine(name, num) char *name; char *num; { f_print(fout, "#define %s %s\n", name, num); } static puldefine(name, num) char *name; char *num; { f_print(fout, "#define %s ((u_long)%s)\n", name, num); } static define_printed(stop, start) proc_list *stop; version_list *start; { version_list *vers; proc_list *proc; for (vers = start; vers != NULL; vers = vers->next) { for (proc = vers->procs; proc != NULL; proc = proc->next) { if (proc == stop) { return (0); } else if (streq(proc->proc_name, stop->proc_name)) { return (1); } } } abort(); /* NOTREACHED */ } static pprogramdef(def) definition *def; { version_list *vers; proc_list *proc; puldefine(def->def_name, def->def.pr.prog_num); for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { puldefine(vers->vers_name, vers->vers_num); for (proc = vers->procs; proc != NULL; proc = proc->next) { if (!define_printed(proc, def->def.pr.versions)) { puldefine(proc->proc_name, proc->proc_num); } pprocdef(proc, vers); } } } pprocdef(proc, vp) proc_list *proc; version_list *vp; { f_print(fout, "extern "); if (proc->res_prefix) { if (streq(proc->res_prefix, "enum")) { f_print(fout, "enum "); } else { f_print(fout, "struct "); } } if (streq(proc->res_type, "bool")) { f_print(fout, "bool_t *"); } else if (streq(proc->res_type, "string")) { f_print(fout, "char **"); } else { f_print(fout, "%s *", fixtype(proc->res_type)); } pvname(proc->proc_name, vp->vers_num); f_print(fout, "();\n"); } static penumdef(def) definition *def; { char *name = def->def_name; enumval_list *l; char *last = NULL; int count = 0; f_print(fout, "enum %s {\n", name); for (l = def->def.en.vals; l != NULL; l = l->next) { f_print(fout, "\t%s", l->name); if (l->assignment) { f_print(fout, " = %s", l->assignment); last = l->assignment; count = 1; } else { if (last == NULL) { f_print(fout, " = %d", count++); } else { f_print(fout, " = %s + %d", last, count++); } } f_print(fout, ",\n"); } f_print(fout, "};\n"); f_print(fout, "typedef enum %s %s;\n", name, name); } static ptypedef(def) definition *def; { char *name = def->def_name; char *old = def->def.ty.old_type; char prefix[8]; /* enough to contain "struct ", including NUL */ relation rel = def->def.ty.rel; if (!streq(name, old)) { if (streq(old, "string")) { old = "char"; rel = REL_POINTER; } else if (streq(old, "opaque")) { old = "char"; } else if (streq(old, "bool")) { old = "bool_t"; } if (undefined2(old, name) && def->def.ty.old_prefix) { s_print(prefix, "%s ", def->def.ty.old_prefix); } else { prefix[0] = 0; } f_print(fout, "typedef "); switch (rel) { case REL_ARRAY: f_print(fout, "struct {\n"); f_print(fout, "\tu_int %s_len;\n", name); f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name); f_print(fout, "} %s", name); break; case REL_POINTER: f_print(fout, "%s%s *%s", prefix, old, name); break; case REL_VECTOR: f_print(fout, "%s%s %s[%s]", prefix, old, name, def->def.ty.array_max); break; case REL_ALIAS: f_print(fout, "%s%s *%s", prefix, old, name); break; } f_print(fout, ";\n"); } } static pdeclaration(name, dec, tab) char *name; declaration *dec; int tab; { char buf[8]; /* enough to hold "struct ", include NUL */ char *prefix; char *type; if (streq(dec->type, "void")) { return; } tabify(fout, tab); if (streq(dec->type, name) && !dec->prefix) { f_print(fout, "struct "); } if (streq(dec->type, "string")) { f_print(fout, "char *%s", dec->name); } else { prefix = ""; if (streq(dec->type, "bool")) { type = "bool_t"; } else if (streq(dec->type, "opaque")) { type = "char"; } else { if (dec->prefix) { s_print(buf, "%s ", dec->prefix); prefix = buf; } type = dec->type; } switch (dec->rel) { case REL_ALIAS: f_print(fout, "%s%s %s", prefix, type, dec->name); break; case REL_VECTOR: f_print(fout, "%s%s %s[%s]", prefix, type, dec->name, dec->array_max); break; case REL_POINTER: f_print(fout, "%s%s *%s", prefix, type, dec->name); break; case REL_ARRAY: f_print(fout, "struct {\n"); tabify(fout, tab); f_print(fout, "\tu_int %s_len;\n", dec->name); tabify(fout, tab); f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name); tabify(fout, tab); f_print(fout, "} %s", dec->name); break; } } f_print(fout, ";\n"); } static undefined2(type, stop) char *type; char *stop; { list *l; definition *def; for (l = defined; l != NULL; l = l->next) { def = (definition *) l->val; if (def->def_kind != DEF_PROGRAM) { if (streq(def->def_name, stop)) { return (1); } else if (streq(def->def_name, type)) { return (0); } } } return (1); } Funky_Stuff len=`wc -c < rpc_hout.c` if [ $len != 8172 ] ; then echo error: rpc_hout.c was $len bytes long, should have been 8172 fi echo x - rpc_main.c cat > rpc_main.c <<'Funky_Stuff' /* @(#)rpc_main.c 1.4 87/11/30 3.9 RPCSRC */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ #ifndef lint static char sccsid[] = "@(#)rpc_main.c 1.7 87/06/24 (C) 1987 SMI"; #endif /* * rpc_main.c, Top level of the RPC protocol compiler. * Copyright (C) 1987, Sun Microsystems, Inc. */ #include <stdio.h> #include <strings.h> #include <sys/file.h> #include "rpc_util.h" #include "rpc_parse.h" #include "rpc_scan.h" #define EXTEND 1 /* alias for TRUE */ struct commandline { int cflag; int hflag; int lflag; int sflag; int mflag; char *infile; char *outfile; }; static char *cmdname; static char CPP[] = "/lib/cpp"; static char CPPFLAGS[] = "-C"; static char *allv[] = { "rpcgen", "-s", "udp", "-s", "tcp", }; static int allc = sizeof(allv)/sizeof(allv[0]); main(argc, argv) int argc; char *argv[]; { struct commandline cmd; if (!parseargs(argc, argv, &cmd)) { f_print(stderr, "usage: %s infile\n", cmdname); f_print(stderr, " %s [-c | -h | -l | -m] [-o outfile] [infile]\n", cmdname); f_print(stderr, " %s [-s udp|tcp]* [-o outfile] [infile]\n", cmdname); exit(1); } if (cmd.cflag) { c_output(cmd.infile, "-DRPC_XDR", !EXTEND, cmd.outfile); } else if (cmd.hflag) { h_output(cmd.infile, "-DRPC_HDR", !EXTEND, cmd.outfile); } else if (cmd.lflag) { l_output(cmd.infile, "-DRPC_CLNT", !EXTEND, cmd.outfile); } else if (cmd.sflag || cmd.mflag) { s_output(argc, argv, cmd.infile, "-DRPC_SVC", !EXTEND, cmd.outfile, cmd.mflag); } else { c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c"); reinitialize(); h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h"); reinitialize(); l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c"); reinitialize(); s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND, "_svc.c", cmd.mflag); } exit(0); } /* * add extension to filename */ static char * extendfile(file, ext) char *file; char *ext; { char *res; char *p; res = alloc(strlen(file) + strlen(ext) + 1); if (res == NULL) { abort(); } p = rindex(file, '.'); if (p == NULL) { p = file + strlen(file); } (void) strcpy(res, file); (void) strcpy(res + (p - file), ext); return (res); } /* * Open output file with given extension */ static open_output(infile, outfile) char *infile; char *outfile; { if (outfile == NULL) { fout = stdout; return; } if (infile != NULL && streq(outfile, infile)) { f_print(stderr, "%s: output would overwrite %s\n", cmdname, infile); crash(); } fout = fopen(outfile, "w"); if (fout == NULL) { f_print(stderr, "%s: unable to open ", cmdname); perror(outfile); crash(); } record_open(outfile); } /* * Open input file with given define for C-preprocessor */ static open_input(infile, define) char *infile; char *define; { int pd[2]; infilename = (infile == NULL) ? "<stdin>" : infile; (void) pipe(pd); switch (fork()) { case 0: (void) close(1); (void) dup2(pd[1], 1); (void) close(pd[0]); execl(CPP, CPP, CPPFLAGS, define, infile, NULL); perror("execl"); exit(1); case -1: perror("fork"); exit(1); } (void) close(pd[1]); fin = fdopen(pd[0], "r"); if (fin == NULL) { f_print(stderr, "%s: ", cmdname); perror(infilename); crash(); } } /* * Compile into an XDR routine output file */ static c_output(infile, define, extend, outfile) char *infile; char *define; int extend; char *outfile; { definition *def; char *include; char *outfilename; long tell; open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); f_print(fout, "#include <rpc/rpc.h>\n"); if (infile && (include = extendfile(infile, ".h"))) { f_print(fout, "#include \"%s\"\n", include); free(include); } tell = ftell(fout); while (def = get_definition()) { emit(def); } if (extend && tell == ftell(fout)) { (void) unlink(outfilename); } } /* * Compile into an XDR header file */ static h_output(infile, define, extend, outfile) char *infile; char *define; int extend; char *outfile; { definition *def; char *outfilename; long tell; open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); tell = ftell(fout); while (def = get_definition()) { print_datadef(def); } if (extend && tell == ftell(fout)) { (void) unlink(outfilename); } } /* * Compile into an RPC service */ static s_output(argc, argv, infile, define, extend, outfile, nomain) int argc; char *argv[]; char *infile; char *define; int extend; char *outfile; int nomain; { char *include; definition *def; int foundprogram; char *outfilename; open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); f_print(fout, "#include <stdio.h>\n"); f_print(fout, "#include <rpc/rpc.h>\n"); if (infile && (include = extendfile(infile, ".h"))) { f_print(fout, "#include \"%s\"\n", include); free(include); } foundprogram = 0; while (def = get_definition()) { foundprogram |= (def->def_kind == DEF_PROGRAM); } if (extend && !foundprogram) { (void) unlink(outfilename); return; } if (nomain) { write_programs((char *)NULL); } else { write_most(); do_registers(argc, argv); write_rest(); write_programs("static"); } } static l_output(infile, define, extend, outfile) char *infile; char *define; int extend; char *outfile; { char *include; definition *def; int foundprogram; char *outfilename; open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); f_print(fout, "#include <rpc/rpc.h>\n"); f_print(fout, "#include <sys/time.h>\n"); if (infile && (include = extendfile(infile, ".h"))) { f_print(fout, "#include \"%s\"\n", include); free(include); } foundprogram = 0; while (def = get_definition()) { foundprogram |= (def->def_kind == DEF_PROGRAM); } if (extend && !foundprogram) { (void) unlink(outfilename); return; } write_stubs(); } /* * Perform registrations for service output */ static do_registers(argc, argv) int argc; char *argv[]; { int i; for (i = 1; i < argc; i++) { if (streq(argv[i], "-s")) { write_register(argv[i + 1]); i++; } } } /* * Parse command line arguments */ static parseargs(argc, argv, cmd) int argc; char *argv[]; struct commandline *cmd; { int i; int j; char c; char flag[(1 << 8 * sizeof(char))]; int nflags; cmdname = argv[0]; cmd->infile = cmd->outfile = NULL; if (argc < 2) { return (0); } flag['c'] = 0; flag['h'] = 0; flag['s'] = 0; flag['o'] = 0; flag['l'] = 0; flag['m'] = 0; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') { if (cmd->infile) { return (0); } cmd->infile = argv[i]; } else { for (j = 1; argv[i][j] != 0; j++) { c = argv[i][j]; switch (c) { case 'c': case 'h': case 'l': case 'm': if (flag[c]) { return (0); } flag[c] = 1; break; case 'o': case 's': if (argv[i][j - 1] != '-' || argv[i][j + 1] != 0) { return (0); } flag[c] = 1; if (++i == argc) { return (0); } if (c == 's') { if (!streq(argv[i], "udp") && !streq(argv[i], "tcp")) { return (0); } } else if (c == 'o') { if (cmd->outfile) { return (0); } cmd->outfile = argv[i]; } goto nextarg; default: return (0); } } nextarg: ; } } cmd->cflag = flag['c']; cmd->hflag = flag['h']; cmd->sflag = flag['s']; cmd->lflag = flag['l']; cmd->mflag = flag['m']; nflags = cmd->cflag + cmd->hflag + cmd->sflag + cmd->lflag + cmd->mflag; if (nflags == 0) { if (cmd->outfile != NULL || cmd->infile == NULL) { return (0); } } else if (nflags > 1) { return (0); } return (1); } Funky_Stuff len=`wc -c < rpc_main.c` if [ $len != 9083 ] ; then echo error: rpc_main.c was $len bytes long, should have been 9083 fi echo x - rpc_parse.c cat > rpc_parse.c <<'Funky_Stuff' /* @(#)rpc_parse.c 1.1 87/11/04 3.9 RPCSRC */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ #ifndef lint static char sccsid[] = "@(#)rpc_parse.c 1.4 87/04/28 (C) 1987 SMI"; #endif /* * rpc_parse.c, Parser for the RPC protocol compiler * Copyright (C) 1987 Sun Microsystems, Inc. */ #include <stdio.h> #include "rpc_util.h" #include "rpc_scan.h" #include "rpc_parse.h" /* * return the next definition you see */ definition * get_definition() { definition *defp; token tok; defp = ALLOC(definition); get_token(&tok); switch (tok.kind) { case TOK_STRUCT: def_struct(defp); break; case TOK_UNION: def_union(defp); break; case TOK_TYPEDEF: def_typedef(defp); break; case TOK_ENUM: def_enum(defp); break; case TOK_PROGRAM: def_program(defp); break; case TOK_CONST: def_const(defp); break; case TOK_EOF: return (NULL); break; default: error("definition keyword expected"); } scan(TOK_SEMICOLON, &tok); isdefined(defp); return (defp); } static isdefined(defp) definition *defp; { STOREVAL(&defined, defp); } static def_struct(defp) definition *defp; { token tok; declaration dec; decl_list *decls; decl_list **tailp; defp->def_kind = DEF_STRUCT; scan(TOK_IDENT, &tok); defp->def_name = tok.str; scan(TOK_LBRACE, &tok); tailp = &defp->def.st.decls; do { get_declaration(&dec, DEF_STRUCT); decls = ALLOC(decl_list); decls->decl = dec; *tailp = decls; tailp = &decls->next; scan(TOK_SEMICOLON, &tok); peek(&tok); } while (tok.kind != TOK_RBRACE); get_token(&tok); *tailp = NULL; } static def_program(defp) definition *defp; { token tok; version_list *vlist; version_list **vtailp; proc_list *plist; proc_list **ptailp; defp->def_kind = DEF_PROGRAM; scan(TOK_IDENT, &tok); defp->def_name = tok.str; scan(TOK_LBRACE, &tok); vtailp = &defp->def.pr.versions; scan(TOK_VERSION, &tok); do { scan(TOK_IDENT, &tok); vlist = ALLOC(version_list); vlist->vers_name = tok.str; scan(TOK_LBRACE, &tok); ptailp = &vlist->procs; do { plist = ALLOC(proc_list); get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM); if (streq(plist->res_type, "opaque")) { error("illegal result type"); } scan(TOK_IDENT, &tok); plist->proc_name = tok.str; scan(TOK_LPAREN, &tok); get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM); if (streq(plist->arg_type, "opaque")) { error("illegal argument type"); } scan(TOK_RPAREN, &tok); scan(TOK_EQUAL, &tok); scan_num(&tok); scan(TOK_SEMICOLON, &tok); plist->proc_num = tok.str; *ptailp = plist; ptailp = &plist->next; peek(&tok); } while (tok.kind != TOK_RBRACE); *vtailp = vlist; vtailp = &vlist->next; scan(TOK_RBRACE, &tok); scan(TOK_EQUAL, &tok); scan_num(&tok); vlist->vers_num = tok.str; scan(TOK_SEMICOLON, &tok); scan2(TOK_VERSION, TOK_RBRACE, &tok); } while (tok.kind == TOK_VERSION); scan(TOK_EQUAL, &tok); scan_num(&tok); defp->def.pr.prog_num = tok.str; *vtailp = NULL; } static def_enum(defp) definition *defp; { token tok; enumval_list *elist; enumval_list **tailp; defp->def_kind = DEF_ENUM; scan(TOK_IDENT, &tok); defp->def_name = tok.str; scan(TOK_LBRACE, &tok); tailp = &defp->def.en.vals; do { scan(TOK_IDENT, &tok); elist = ALLOC(enumval_list); elist->name = tok.str; elist->assignment = NULL; scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok); if (tok.kind == TOK_EQUAL) { scan_num(&tok); elist->assignment = tok.str; scan2(TOK_COMMA, TOK_RBRACE, &tok); } *tailp = elist; tailp = &elist->next; } while (tok.kind != TOK_RBRACE); *tailp = NULL; } static def_const(defp) definition *defp; { token tok; defp->def_kind = DEF_CONST; scan(TOK_IDENT, &tok); defp->def_name = tok.str; scan(TOK_EQUAL, &tok); scan2(TOK_IDENT, TOK_STRCONST, &tok); defp->def.co = tok.str; } static def_union(defp) definition *defp; { token tok; declaration dec; case_list *cases; case_list **tailp; defp->def_kind = DEF_UNION; scan(TOK_IDENT, &tok); defp->def_name = tok.str; scan(TOK_SWITCH, &tok); scan(TOK_LPAREN, &tok); get_declaration(&dec, DEF_UNION); defp->def.un.enum_decl = dec; tailp = &defp->def.un.cases; scan(TOK_RPAREN, &tok); scan(TOK_LBRACE, &tok); scan(TOK_CASE, &tok); while (tok.kind == TOK_CASE) { scan(TOK_IDENT, &tok); cases = ALLOC(case_list); cases->case_name = tok.str; scan(TOK_COLON, &tok); get_declaration(&dec, DEF_UNION); cases->case_decl = dec; *tailp = cases; tailp = &cases->next; scan(TOK_SEMICOLON, &tok); scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); } *tailp = NULL; if (tok.kind == TOK_DEFAULT) { scan(TOK_COLON, &tok); get_declaration(&dec, DEF_UNION); defp->def.un.default_decl = ALLOC(declaration); *defp->def.un.default_decl = dec; scan(TOK_SEMICOLON, &tok); scan(TOK_RBRACE, &tok); } else { defp->def.un.default_decl = NULL; } } static def_typedef(defp) definition *defp; { declaration dec; defp->def_kind = DEF_TYPEDEF; get_declaration(&dec, DEF_TYPEDEF); defp->def_name = dec.name; defp->def.ty.old_prefix = dec.prefix; defp->def.ty.old_type = dec.type; defp->def.ty.rel = dec.rel; defp->def.ty.array_max = dec.array_max; } static get_declaration(dec, dkind) declaration *dec; defkind dkind; { token tok; get_type(&dec->prefix, &dec->type, dkind); dec->rel = REL_ALIAS; if (streq(dec->type, "void")) { return; } scan2(TOK_STAR, TOK_IDENT, &tok); if (tok.kind == TOK_STAR) { dec->rel = REL_POINTER; scan(TOK_IDENT, &tok); } dec->name = tok.str; if (peekscan(TOK_LBRACKET, &tok)) { if (dec->rel == REL_POINTER) { error("no array-of-pointer declarations -- use typedef"); } dec->rel = REL_VECTOR; scan_num(&tok); dec->array_max = tok.str; scan(TOK_RBRACKET, &tok); } else if (peekscan(TOK_LANGLE, &tok)) { if (dec->rel == REL_POINTER) { error("no array-of-pointer declarations -- use typedef"); } dec->rel = REL_ARRAY; if (peekscan(TOK_RANGLE, &tok)) { dec->array_max = "~0"; /* unspecified size, use max */ } else { scan_num(&tok); dec->array_max = tok.str; scan(TOK_RANGLE, &tok); } } if (streq(dec->type, "opaque")) { if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { error("array declaration expected"); } } else if (streq(dec->type, "string")) { if (dec->rel != REL_ARRAY) { error("variable-length array declaration expected"); } } } static get_type(prefixp, typep, dkind) char **prefixp; char **typep; defkind dkind; { token tok; *prefixp = NULL; get_token(&tok); switch (tok.kind) { case TOK_IDENT: *typep = tok.str; break; case TOK_STRUCT: case TOK_ENUM: case TOK_UNION: *prefixp = tok.str; scan(TOK_IDENT, &tok); *typep = tok.str; break; case TOK_UNSIGNED: unsigned_dec(typep); break; case TOK_SHORT: *typep = "short"; (void) peekscan(TOK_INT, &tok); break; case TOK_LONG: *typep = "long"; (void) peekscan(TOK_INT, &tok); break; case TOK_VOID: if (dkind != DEF_UNION && dkind != DEF_PROGRAM) { error("voids allowed only inside union and program definitions"); } *typep = tok.str; break; case TOK_STRING: case TOK_OPAQUE: case TOK_CHAR: case TOK_INT: case TOK_FLOAT: case TOK_DOUBLE: case TOK_BOOL: *typep = tok.str; break; default: error("expected type specifier"); } } static unsigned_dec(typep) char **typep; { token tok; peek(&tok); switch (tok.kind) { case TOK_CHAR: get_token(&tok); *typep = "u_char"; break; case TOK_SHORT: get_token(&tok); *typep = "u_short"; (void) peekscan(TOK_INT, &tok); break; case TOK_LONG: get_token(&tok); *typep = "u_long"; (void) peekscan(TOK_INT, &tok); break; case TOK_INT: get_token(&tok); *typep = "u_int"; break; default: *typep = "u_int"; break; } } Funky_Stuff len=`wc -c < rpc_parse.c` if [ $len != 8998 ] ; then echo error: rpc_parse.c was $len bytes long, should have been 8998 fi echo x - rpc_parse.h cat > rpc_parse.h <<'Funky_Stuff' /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* @(#)rpc_parse.h 1.3 87/03/09 (C) 1987 SMI */ /* * rpc_parse.h, Definitions for the RPCL parser * Copyright (C) 1987, Sun Microsystems, Inc. */ enum defkind { DEF_CONST, DEF_STRUCT, DEF_UNION, DEF_ENUM, DEF_TYPEDEF, DEF_PROGRAM }; typedef enum defkind defkind; typedef char *const_def; enum relation { REL_VECTOR, /* fixed length array */ REL_ARRAY, /* variable length array */ REL_POINTER, /* pointer */ REL_ALIAS, /* simple */ }; typedef enum relation relation; struct typedef_def { char *old_prefix; char *old_type; relation rel; char *array_max; }; typedef struct typedef_def typedef_def; struct enumval_list { char *name; char *assignment; struct enumval_list *next; }; typedef struct enumval_list enumval_list; struct enum_def { enumval_list *vals; }; typedef struct enum_def enum_def; struct declaration { char *prefix; char *type; char *name; relation rel; char *array_max; }; typedef struct declaration declaration; struct decl_list { declaration decl; struct decl_list *next; }; typedef struct decl_list decl_list; struct struct_def { decl_list *decls; }; typedef struct struct_def struct_def; struct case_list { char *case_name; declaration case_decl; struct case_list *next; }; typedef struct case_list case_list; struct union_def { declaration enum_decl; case_list *cases; declaration *default_decl; }; typedef struct union_def union_def; struct proc_list { char *proc_name; char *proc_num; char *arg_type; char *arg_prefix; char *res_type; char *res_prefix; struct proc_list *next; }; typedef struct proc_list proc_list; struct version_list { char *vers_name; char *vers_num; proc_list *procs; struct version_list *next; }; typedef struct version_list version_list; struct program_def { char *prog_num; version_list *versions; }; typedef struct program_def program_def; struct definition { char *def_name; defkind def_kind; union { const_def co; struct_def st; union_def un; enum_def en; typedef_def ty; program_def pr; } def; }; typedef struct definition definition; /* @(#)rpc_parse.h 1.2 87/11/19 3.9 RPCSRC */ definition *get_definition(); Funky_Stuff len=`wc -c < rpc_parse.h` if [ $len != 3419 ] ; then echo error: rpc_parse.h was $len bytes long, should have been 3419 fi echo x - rpc_scan.c cat > rpc_scan.c <<'Funky_Stuff' /* @(#)rpc_scan.c 1.1 87/11/04 3.9 RPCSRC */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ #ifndef lint static char sccsid[] = "@(#)rpc_scan.c 1.6 87/06/24 (C) 1987 SMI"; #endif /* * rpc_scan.c, Scanner for the RPC protocol compiler * Copyright (C) 1987, Sun Microsystems, Inc. */ #include <stdio.h> #include <ctype.h> #include <strings.h> #include "rpc_scan.h" #include "rpc_util.h" #define startcomment(where) (where[0] == '/' && where[1] == '*') #define endcomment(where) (where[-1] == '*' && where[0] == '/') static int pushed = 0; /* is a token pushed */ static token lasttok; /* last token, if pushed */ /* * scan expecting 1 given token */ void scan(expect, tokp) tok_kind expect; token *tokp; { get_token(tokp); if (tokp->kind != expect) { expected1(expect); } } /* * scan expecting 2 given tokens */ void scan2(expect1, expect2, tokp) tok_kind expect1; tok_kind expect2; token *tokp; { get_token(tokp); if (tokp->kind != expect1 && tokp->kind != expect2) { expected2(expect1, expect2); } } /* * scan expecting 3 given token */ void scan3(expect1, expect2, expect3, tokp) tok_kind expect1; tok_kind expect2; tok_kind expect3; token *tokp; { get_token(tokp); if (tokp->kind != expect1 && tokp->kind != expect2 && tokp->kind != expect3) { expected3(expect1, expect2, expect3); } } /* * scan expecting a constant, possibly symbolic */ void scan_num(tokp) token *tokp; { get_token(tokp); switch (tokp->kind) { case TOK_IDENT: break; default: error("constant or identifier expected"); } } /* * Peek at the next token */ void peek(tokp) token *tokp; { get_token(tokp); unget_token(tokp); } /* * Peek at the next token and scan it if it matches what you expect */ int peekscan(expect, tokp) tok_kind expect; token *tokp; { peek(tokp); if (tokp->kind == expect) { get_token(tokp); return (1); } return (0); } /* * Get the next token, printing out any directive that are encountered. */ void get_token(tokp) token *tokp; { int commenting; if (pushed) { pushed = 0; *tokp = lasttok; return; } commenting = 0; for (;;) { if (*where == 0) { for (;;) { if (!fgets(curline, MAXLINESIZE, fin)) { tokp->kind = TOK_EOF; *where = 0; return; } linenum++; if (commenting) { break; } else if (cppline(curline)) { docppline(curline, &linenum, &infilename); } else if (directive(curline)) { printdirective(curline); } else { break; } } where = curline; } else if (isspace(*where)) { while (isspace(*where)) { where++; /* eat */ } } else if (commenting) { where++; if (endcomment(where)) { where++; commenting--; } } else if (startcomment(where)) { where += 2; commenting++; } else { break; } } /* * 'where' is not whitespace, comment or directive Must be a token! */ switch (*where) { case ':': tokp->kind = TOK_COLON; where++; break; case ';': tokp->kind = TOK_SEMICOLON; where++; break; case ',': tokp->kind = TOK_COMMA; where++; break; case '=': tokp->kind = TOK_EQUAL; where++; break; case '*': tokp->kind = TOK_STAR; where++; break; case '[': tokp->kind = TOK_LBRACKET; where++; break; case ']': tokp->kind = TOK_RBRACKET; where++; break; case '{': tokp->kind = TOK_LBRACE; where++; break; case '}': tokp->kind = TOK_RBRACE; where++; break; case '(': tokp->kind = TOK_LPAREN; where++; break; case ')': tokp->kind = TOK_RPAREN; where++; break; case '<': tokp->kind = TOK_LANGLE; where++; break; case '>': tokp->kind = TOK_RANGLE; where++; break; case '"': tokp->kind = TOK_STRCONST; findstrconst(&where, &tokp->str); break; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': tokp->kind = TOK_IDENT; findconst(&where, &tokp->str); break; default: if (!(isalpha(*where) || *where == '_')) { char buf[100]; char *p; s_print(buf, "illegal character in file: "); p = buf + strlen(buf); if (isprint(*where)) { s_print(p, "%c", *where); } else { s_print(p, "%d", *where); } error(buf); } findkind(&where, tokp); break; } } static unget_token(tokp) token *tokp; { lasttok = *tokp; pushed = 1; } static findstrconst(str, val) char **str; char **val; { char *p; int size; p = *str; do { *p++; } while (*p && *p != '"'); if (*p == 0) { error("unterminated string constant"); } p++; size = p - *str; *val = alloc(size + 1); (void) strncpy(*val, *str, size); (*val)[size] = 0; *str = p; } static findconst(str, val) char **str; char **val; { char *p; int size; p = *str; if (*p == '0' && *(p + 1) == 'x') { p++; do { p++; } while (isxdigit(*p)); } else { do { p++; } while (isdigit(*p)); } size = p - *str; *val = alloc(size + 1); (void) strncpy(*val, *str, size); (*val)[size] = 0; *str = p; } static token symbols[] = { {TOK_CONST, "const"}, {TOK_UNION, "union"}, {TOK_SWITCH, "switch"}, {TOK_CASE, "case"}, {TOK_DEFAULT, "default"}, {TOK_STRUCT, "struct"}, {TOK_TYPEDEF, "typedef"}, {TOK_ENUM, "enum"}, {TOK_OPAQUE, "opaque"}, {TOK_BOOL, "bool"}, {TOK_VOID, "void"}, {TOK_CHAR, "char"}, {TOK_INT, "int"}, {TOK_UNSIGNED, "unsigned"}, {TOK_SHORT, "short"}, {TOK_LONG, "long"}, {TOK_FLOAT, "float"}, {TOK_DOUBLE, "double"}, {TOK_STRING, "string"}, {TOK_PROGRAM, "program"}, {TOK_VERSION, "version"}, {TOK_EOF, "??????"}, }; static findkind(mark, tokp) char **mark; token *tokp; { int len; token *s; char *str; str = *mark; for (s = symbols; s->kind != TOK_EOF; s++) { len = strlen(s->str); if (strncmp(str, s->str, len) == 0) { if (!isalnum(str[len]) && str[len] != '_') { tokp->kind = s->kind; tokp->str = s->str; *mark = str + len; return; } } } tokp->kind = TOK_IDENT; for (len = 0; isalnum(str[len]) || str[len] == '_'; len++); tokp->str = alloc(len + 1); (void) strncpy(tokp->str, str, len); tokp->str[len] = 0; *mark = str + len; } static cppline(line) char *line; { return (line == curline && *line == '#'); } static directive(line) char *line; { return (line == curline && *line == '%'); } static printdirective(line) char *line; { f_print(fout, "%s", line + 1); } static docppline(line, lineno, fname) char *line; int *lineno; char **fname; { char *file; int num; char *p; line++; while (isspace(*line)) { line++; } num = atoi(line); while (isdigit(*line)) { line++; } while (isspace(*line)) { line++; } if (*line != '"') { error("preprocessor error"); } line++; p = file = alloc(strlen(line) + 1); while (*line && *line != '"') { *p++ = *line++; } if (*line == 0) { error("preprocessor error"); } *p = 0; if (*file == 0) { *fname = NULL; } else { *fname = file; } *lineno = num - 1; } Funky_Stuff len=`wc -c < rpc_scan.c` if [ $len != 8235 ] ; then echo error: rpc_scan.c was $len bytes long, should have been 8235 fi echo x - rpc_scan.h cat > rpc_scan.h <<'Funky_Stuff' /* @(#)rpc_scan.h 1.1 87/11/04 3.9 RPCSRC */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* @(#)rpc_scan.h 1.3 87/03/09 (C) 1987 SMI */ /* * rpc_scan.h, Definitions for the RPCL scanner * Copyright (C) 1987, Sun Microsystems, Inc. */ /* * kinds of tokens */ enum tok_kind { TOK_IDENT, TOK_STRCONST, TOK_LPAREN, TOK_RPAREN, TOK_LBRACE, TOK_RBRACE, TOK_LBRACKET, TOK_RBRACKET, TOK_LANGLE, TOK_RANGLE, TOK_STAR, TOK_COMMA, TOK_EQUAL, TOK_COLON, TOK_SEMICOLON, TOK_CONST, TOK_STRUCT, TOK_UNION, TOK_SWITCH, TOK_CASE, TOK_DEFAULT, TOK_ENUM, TOK_TYPEDEF, TOK_INT, TOK_SHORT, TOK_LONG, TOK_UNSIGNED, TOK_FLOAT, TOK_DOUBLE, TOK_OPAQUE, TOK_CHAR, TOK_STRING, TOK_BOOL, TOK_VOID, TOK_PROGRAM, TOK_VERSION, TOK_EOF }; typedef enum tok_kind tok_kind; /* * a token */ struct token { tok_kind kind; char *str; }; typedef struct token token; /* * routine interface */ void scanprint(); void scan(); void scan2(); void scan3(); void scan_num(); void peek(); int peekscan(); void get_token(); Funky_Stuff len=`wc -c < rpc_scan.h` if [ $len != 2259 ] ; then echo error: rpc_scan.h was $len bytes long, should have been 2259 fi cd .. echo more files to follow exit -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.