v13i084: Sun RPC, release 3.9, Part07/15
Rich Salz
rsalz at bbn.com
Thu Mar 3 09:18:32 AEST 1988
Submitted-by: Stephen X. Nahm <sxn at 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 at uunet.uu.net.
More information about the Comp.sources.unix
mailing list