mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-30 06:32:44 +00:00
Import a newer and more functional version of rpcgen.
Obtained from: the Sun TI-RPC 2.3 source distribution
This commit is contained in:
commit
ee4f614e7e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/SUNRPC/; revision=12795
13
usr.bin/rpcgen/Makefile
Normal file
13
usr.bin/rpcgen/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
SRCS= rpc_main.c rpc_clntout.c rpc_cout.c rpc_hout.c rpc_parse.c \
|
||||
rpc_sample.c rpc_scan.c rpc_svcout.c rpc_tblout.c rpc_util.c
|
||||
|
||||
PROG= rpcgen
|
||||
MAN1= rpcgen.1
|
||||
|
||||
#
|
||||
# This is a kludge to work around the fact that this program
|
||||
# uses 'inline' as a variable name.
|
||||
#
|
||||
CFLAGS+=-Dinline=rpcgen_inline
|
||||
|
||||
.include <bsd.prog.mk>
|
331
usr.bin/rpcgen/rpc_clntout.c
Normal file
331
usr.bin/rpcgen/rpc_clntout.c
Normal file
@ -0,0 +1,331 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ident "@(#)rpc_clntout.c 1.15 94/04/25 SMI"
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (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 <string.h>
|
||||
#include <rpc/types.h>
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
extern int pdeclaration __P(( char *, declaration *, int, char * ));
|
||||
void printarglist __P(( proc_list *, char *, char *, char *));
|
||||
static int write_program __P(( definition * ));
|
||||
static int printbody __P(( proc_list * ));
|
||||
|
||||
static char RESULT[] = "clnt_res";
|
||||
|
||||
|
||||
#define DEFAULT_TIMEOUT 25 /* in seconds */
|
||||
|
||||
|
||||
void
|
||||
write_stubs()
|
||||
{
|
||||
list *l;
|
||||
definition *def;
|
||||
|
||||
f_print(fout,
|
||||
"\n/* Default timeout can be changed using clnt_control() */\n");
|
||||
f_print(fout, "static 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");
|
||||
if (mtflag == 0) {
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
f_print(fout, "*\n");
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
printarglist(proc, RESULT, "clnt", "CLIENT *");
|
||||
} else {
|
||||
f_print(fout, "enum clnt_stat \n");
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
printarglist(proc, RESULT, "clnt", "CLIENT *");
|
||||
|
||||
}
|
||||
f_print(fout, "{\n");
|
||||
printbody(proc);
|
||||
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes out declarations of procedure's argument list.
|
||||
* In either ANSI C style, in one of old rpcgen style (pass by reference),
|
||||
* or new rpcgen style (multiple arguments, pass by value);
|
||||
*/
|
||||
|
||||
/* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
|
||||
|
||||
void printarglist(proc, result, addargname, addargtype)
|
||||
proc_list *proc;
|
||||
char *result;
|
||||
char* addargname, * addargtype;
|
||||
{
|
||||
|
||||
decl_list *l;
|
||||
|
||||
if (!newstyle) {
|
||||
/* old style: always pass argument by reference */
|
||||
if (Cflag) { /* C++ style heading */
|
||||
f_print(fout, "(");
|
||||
ptype(proc->args.decls->decl.prefix,
|
||||
proc->args.decls->decl.type, 1);
|
||||
|
||||
if (mtflag) {/* Generate result field */
|
||||
f_print(fout, "*argp, ");
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
f_print(fout, "*%s, %s%s)\n",
|
||||
result, addargtype, addargname);
|
||||
} else
|
||||
f_print(fout, "*argp, %s%s)\n", addargtype, addargname);
|
||||
} else {
|
||||
if (!mtflag)
|
||||
f_print(fout, "(argp, %s)\n", addargname);
|
||||
else
|
||||
f_print(fout, "(argp, %s, %s)\n",
|
||||
result, addargname);
|
||||
f_print(fout, "\t");
|
||||
ptype(proc->args.decls->decl.prefix,
|
||||
proc->args.decls->decl.type, 1);
|
||||
f_print(fout, "*argp;\n");
|
||||
if (mtflag) {
|
||||
f_print(fout, "\t");
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
f_print(fout, "*%s;\n", result);
|
||||
}
|
||||
}
|
||||
} else if (streq(proc->args.decls->decl.type, "void")) {
|
||||
/* newstyle, 0 argument */
|
||||
if (mtflag) {
|
||||
f_print(fout, "(");
|
||||
|
||||
|
||||
if (Cflag) {
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
f_print(fout, "*%s, %s%s)\n",
|
||||
result, addargtype, addargname);
|
||||
}
|
||||
else
|
||||
f_print(fout, "(%s)\n", addargname);
|
||||
|
||||
} else
|
||||
if (Cflag)
|
||||
f_print(fout, "(%s%s)\n", addargtype, addargname);
|
||||
else
|
||||
f_print(fout, "(%s)\n", addargname);
|
||||
} else {
|
||||
/* new style, 1 or multiple arguments */
|
||||
if (!Cflag) {
|
||||
f_print(fout, "(");
|
||||
for (l = proc->args.decls; l != NULL; l = l->next)
|
||||
f_print(fout, "%s, ", l->decl.name);
|
||||
if (mtflag)
|
||||
f_print(fout, "%s, ", result);
|
||||
|
||||
f_print(fout, "%s)\n", addargname);
|
||||
for (l = proc->args.decls; l != NULL; l = l->next) {
|
||||
pdeclaration(proc->args.argname,
|
||||
&l->decl, 1, ";\n");
|
||||
}
|
||||
if (mtflag) {
|
||||
f_print(fout, "\t");
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
f_print(fout, "*%s;\n", result);
|
||||
}
|
||||
|
||||
} else { /* C++ style header */
|
||||
f_print(fout, "(");
|
||||
for (l = proc->args.decls; l != NULL; l = l->next) {
|
||||
pdeclaration(proc->args.argname, &l->decl, 0,
|
||||
", ");
|
||||
}
|
||||
if (mtflag) {
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
f_print(fout, "*%s, ", result);
|
||||
|
||||
}
|
||||
f_print(fout, "%s%s)\n", addargtype, addargname);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Cflag)
|
||||
f_print(fout, "\t%s%s;\n", addargtype, addargname);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char *
|
||||
ampr(type)
|
||||
char *type;
|
||||
{
|
||||
if (isvectordef(type, REL_ALIAS)) {
|
||||
return ("");
|
||||
} else {
|
||||
return ("&");
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
printbody(proc)
|
||||
proc_list *proc;
|
||||
{
|
||||
decl_list *l;
|
||||
bool_t args2 = (proc->arg_num > 1);
|
||||
int i;
|
||||
|
||||
/*
|
||||
* For new style with multiple arguments, need a structure in which
|
||||
* to stuff the arguments.
|
||||
*/
|
||||
|
||||
|
||||
if (newstyle && args2) {
|
||||
f_print(fout, "\t%s", proc->args.argname);
|
||||
f_print(fout, " arg;\n");
|
||||
}
|
||||
if (!mtflag) {
|
||||
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, "%s;\n", RESULT);
|
||||
f_print(fout, "\n");
|
||||
f_print(fout, "\tmemset((char *)%s%s, 0, sizeof (%s));\n",
|
||||
ampr(proc->res_type), RESULT, RESULT);
|
||||
|
||||
}
|
||||
if (newstyle && !args2 &&
|
||||
(streq(proc->args.decls->decl.type, "void"))) {
|
||||
/* newstyle, 0 arguments */
|
||||
|
||||
if (mtflag)
|
||||
f_print(fout, "\t return ");
|
||||
else
|
||||
f_print(fout, "\t if ");
|
||||
|
||||
f_print(fout,
|
||||
"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_void, ",
|
||||
proc->proc_name);
|
||||
f_print(fout,
|
||||
"(caddr_t) NULL,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
|
||||
stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
|
||||
RESULT);
|
||||
|
||||
if (mtflag)
|
||||
f_print(fout, "\n\t\tTIMEOUT));\n}\n");
|
||||
else
|
||||
f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
|
||||
|
||||
} else if (newstyle && args2) {
|
||||
/*
|
||||
* Newstyle, multiple arguments
|
||||
* stuff arguments into structure
|
||||
*/
|
||||
for (l = proc->args.decls; l != NULL; l = l->next) {
|
||||
f_print(fout, "\targ.%s = %s;\n",
|
||||
l->decl.name, l->decl.name);
|
||||
}
|
||||
if (mtflag)
|
||||
f_print(fout, "\treturn ");
|
||||
else
|
||||
f_print(fout, "\tif ");
|
||||
f_print(fout,
|
||||
"(clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s",
|
||||
proc->proc_name,proc->args.argname);
|
||||
f_print(fout,
|
||||
", (caddr_t) &arg,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
|
||||
stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
|
||||
RESULT);
|
||||
if (mtflag)
|
||||
f_print(fout, "\n\t\tTIMEOUT));\n");
|
||||
else
|
||||
f_print(fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
|
||||
} else { /* single argument, new or old style */
|
||||
if (!mtflag)
|
||||
f_print(fout,
|
||||
"\tif (clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\tTIMEOUT) != RPC_SUCCESS) {\n",
|
||||
proc->proc_name,
|
||||
stringfix(proc->args.decls->decl.type),
|
||||
(newstyle ? "&" : ""),
|
||||
(newstyle ? proc->args.decls->decl.name : "argp"),
|
||||
stringfix(proc->res_type), ampr(proc->res_type),
|
||||
RESULT);
|
||||
else
|
||||
|
||||
f_print(fout,
|
||||
"\treturn (clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\tTIMEOUT));\n",
|
||||
proc->proc_name,
|
||||
stringfix(proc->args.decls->decl.type),
|
||||
(newstyle ? "&" : ""),
|
||||
(newstyle ? proc->args.decls->decl.name : "argp"),
|
||||
stringfix(proc->res_type), "",
|
||||
RESULT);
|
||||
}
|
||||
if (!mtflag) {
|
||||
f_print(fout, "\t\treturn (NULL);\n");
|
||||
f_print(fout, "\t}\n");
|
||||
|
||||
if (streq(proc->res_type, "void")) {
|
||||
f_print(fout, "\treturn ((void *)%s%s);\n",
|
||||
ampr(proc->res_type), RESULT);
|
||||
} else {
|
||||
f_print(fout, "\treturn (%s%s);\n",
|
||||
ampr(proc->res_type), RESULT);
|
||||
}
|
||||
}
|
||||
}
|
752
usr.bin/rpcgen/rpc_cout.c
Normal file
752
usr.bin/rpcgen/rpc_cout.c
Normal file
@ -0,0 +1,752 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ident "@(#)rpc_cout.c 1.14 93/07/05 SMI"
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)rpc_cout.c 1.13 89/02/22 (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 <string.h>
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
static int print_header __P(( definition * ));
|
||||
static int print_trailer __P(( void ));
|
||||
static int print_stat __P(( int , declaration * ));
|
||||
static int emit_enum __P(( definition * ));
|
||||
static int emit_program __P(( definition * ));
|
||||
static int emit_union __P(( definition * ));
|
||||
static int emit_struct __P(( definition * ));
|
||||
static int emit_typedef __P(( definition * ));
|
||||
|
||||
/*
|
||||
* Emit the C-routine for the given definition
|
||||
*/
|
||||
void
|
||||
emit(def)
|
||||
definition *def;
|
||||
{
|
||||
if (def->def_kind == DEF_CONST) {
|
||||
return;
|
||||
}
|
||||
if (def->def_kind == DEF_PROGRAM) {
|
||||
emit_program(def);
|
||||
return;
|
||||
}
|
||||
if (def->def_kind == DEF_TYPEDEF) {
|
||||
/*
|
||||
* now we need to handle declarations like
|
||||
* struct typedef foo foo;
|
||||
* since we dont want this to be expanded into 2 calls to xdr_foo
|
||||
*/
|
||||
|
||||
if (strcmp(def->def.ty.old_type, def->def_name) == 0)
|
||||
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_generic_header(procname, pointerp)
|
||||
char* procname;
|
||||
int pointerp;
|
||||
{
|
||||
f_print(fout, "\n");
|
||||
f_print(fout, "bool_t\n");
|
||||
if (Cflag) {
|
||||
f_print(fout, "xdr_%s(", procname);
|
||||
f_print(fout, "register XDR *xdrs, ");
|
||||
f_print(fout, "%s ", procname);
|
||||
if (pointerp)
|
||||
f_print(fout, "*");
|
||||
f_print(fout, "objp)\n{\n\n");
|
||||
} else {
|
||||
f_print(fout, "xdr_%s(xdrs, objp)\n", procname);
|
||||
f_print(fout, "\tregister XDR *xdrs;\n");
|
||||
f_print(fout, "\t%s ", procname);
|
||||
if (pointerp)
|
||||
f_print(fout, "*");
|
||||
f_print(fout, "objp;\n{\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
print_header(def)
|
||||
definition *def;
|
||||
{
|
||||
|
||||
decl_list *dl;
|
||||
bas_type *ptr;
|
||||
int i;
|
||||
|
||||
print_generic_header(def->def_name,
|
||||
def->def_kind != DEF_TYPEDEF ||
|
||||
!isvectordef(def->def.ty.old_type,
|
||||
def->def.ty.rel));
|
||||
/* Now add Inline support */
|
||||
|
||||
if (inline == 0)
|
||||
return;
|
||||
/* May cause lint to complain. but ... */
|
||||
f_print(fout, "\tregister long *buf;\n\n");
|
||||
}
|
||||
|
||||
static
|
||||
print_prog_header(plist)
|
||||
proc_list *plist;
|
||||
{
|
||||
print_generic_header(plist->args.argname, 1);
|
||||
}
|
||||
|
||||
static
|
||||
print_trailer()
|
||||
{
|
||||
f_print(fout, "\treturn (TRUE);\n");
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
|
||||
|
||||
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(indent, prefix, type)
|
||||
int indent;
|
||||
char *prefix;
|
||||
char *type;
|
||||
{
|
||||
if (indent) {
|
||||
f_print(fout, ",\n");
|
||||
tabify(fout, indent);
|
||||
} else {
|
||||
f_print(fout, ", ");
|
||||
}
|
||||
if (streq(type, "bool")) {
|
||||
f_print(fout, "sizeof (bool_t), (xdrproc_t) xdr_bool");
|
||||
} else {
|
||||
f_print(fout, "sizeof (");
|
||||
if (undefined(type) && prefix) {
|
||||
f_print(fout, "%s ", prefix);
|
||||
}
|
||||
f_print(fout, "%s), (xdrproc_t) xdr_%s", type, type);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
print_ifclose(indent)
|
||||
int indent;
|
||||
{
|
||||
f_print(fout, "))\n");
|
||||
tabify(fout, indent);
|
||||
f_print(fout, "\treturn (FALSE);\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(0, 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(indent + 1, 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(indent + 1, 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_program(def)
|
||||
definition *def;
|
||||
{
|
||||
decl_list *dl;
|
||||
version_list *vlist;
|
||||
proc_list *plist;
|
||||
|
||||
for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next)
|
||||
for (plist = vlist->procs; plist != NULL; plist = plist->next) {
|
||||
if (!newstyle || plist->arg_num < 2)
|
||||
continue; /* old style, or single argument */
|
||||
print_prog_header(plist);
|
||||
for (dl = plist->args.decls; dl != NULL;
|
||||
dl = dl->next)
|
||||
print_stat(1, &dl->decl);
|
||||
print_trailer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
emit_union(def)
|
||||
definition *def;
|
||||
{
|
||||
declaration *dflt;
|
||||
case_list *cl;
|
||||
declaration *cs;
|
||||
char *object;
|
||||
char *vecformat = "objp->%s_u.%s";
|
||||
char *format = "&objp->%s_u.%s";
|
||||
|
||||
print_stat(1, &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) {
|
||||
|
||||
f_print(fout, "\tcase %s:\n", cl->case_name);
|
||||
if (cl->contflag == 1) /* a continued case statement */
|
||||
continue;
|
||||
cs = &cl->case_decl;
|
||||
if (!streq(cs->type, "void")) {
|
||||
object = alloc(strlen(def->def_name) + strlen(format) +
|
||||
strlen(cs->name) + 1);
|
||||
if (isvectordef (cs->type, cs->rel)) {
|
||||
s_print(object, vecformat, def->def_name,
|
||||
cs->name);
|
||||
} else {
|
||||
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);
|
||||
if (isvectordef (dflt->type, dflt->rel)) {
|
||||
s_print(object, vecformat, def->def_name,
|
||||
dflt->name);
|
||||
} else {
|
||||
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 void
|
||||
inline_struct(def, flag)
|
||||
definition *def;
|
||||
int flag;
|
||||
{
|
||||
decl_list *dl;
|
||||
int i, size;
|
||||
decl_list *cur, *psav;
|
||||
bas_type *ptr;
|
||||
char *sizestr, *plus;
|
||||
char ptemp[256];
|
||||
int indent = 1;
|
||||
|
||||
if (flag == PUT)
|
||||
f_print(fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n");
|
||||
else
|
||||
f_print(fout, "\t\treturn (TRUE);\n\t} else if (xdrs->x_op == XDR_DECODE) {\n");
|
||||
|
||||
i = 0;
|
||||
size = 0;
|
||||
sizestr = NULL;
|
||||
for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */
|
||||
/* now walk down the list and check for basic types */
|
||||
if ((dl->decl.prefix == NULL) &&
|
||||
((ptr = find_type(dl->decl.type)) != NULL) &&
|
||||
((dl->decl.rel == REL_ALIAS) ||
|
||||
(dl->decl.rel == REL_VECTOR))){
|
||||
if (i == 0)
|
||||
cur = dl;
|
||||
i++;
|
||||
|
||||
if (dl->decl.rel == REL_ALIAS)
|
||||
size += ptr->length;
|
||||
else {
|
||||
/* this code is required to handle arrays */
|
||||
if (sizestr == NULL)
|
||||
plus = "";
|
||||
else
|
||||
plus = " + ";
|
||||
|
||||
if (ptr->length != 1)
|
||||
s_print(ptemp, "%s%s * %d",
|
||||
plus, dl->decl.array_max,
|
||||
ptr->length);
|
||||
else
|
||||
s_print(ptemp, "%s%s", plus,
|
||||
dl->decl.array_max);
|
||||
|
||||
/* now concatenate to sizestr !!!! */
|
||||
if (sizestr == NULL)
|
||||
sizestr = strdup(ptemp);
|
||||
else{
|
||||
sizestr = realloc(sizestr,
|
||||
strlen(sizestr)
|
||||
+strlen(ptemp)+1);
|
||||
if (sizestr == NULL){
|
||||
f_print(stderr,
|
||||
"Fatal error : no memory\n");
|
||||
crash();
|
||||
};
|
||||
sizestr = strcat(sizestr, ptemp);
|
||||
/* build up length of array */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (i > 0)
|
||||
if (sizestr == NULL && size < inline){
|
||||
/*
|
||||
* don't expand into inline code
|
||||
* if size < inline
|
||||
*/
|
||||
while (cur != dl){
|
||||
print_stat(indent + 1, &cur->decl);
|
||||
cur = cur->next;
|
||||
}
|
||||
} else {
|
||||
/* were already looking at a xdr_inlineable structure */
|
||||
tabify(fout, indent + 1);
|
||||
if (sizestr == NULL)
|
||||
f_print(fout, "buf = XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);",
|
||||
size);
|
||||
else
|
||||
if (size == 0)
|
||||
f_print(fout,
|
||||
"buf = XDR_INLINE(xdrs, (%s) * BYTES_PER_XDR_UNIT);",
|
||||
sizestr);
|
||||
else
|
||||
f_print(fout,
|
||||
"buf = XDR_INLINE(xdrs, (%d + (%s)) * BYTES_PER_XDR_UNIT);",
|
||||
size, sizestr);
|
||||
|
||||
f_print(fout, "\n");
|
||||
tabify(fout, indent + 1);
|
||||
f_print(fout,
|
||||
"if (buf == NULL) {\n");
|
||||
|
||||
psav = cur;
|
||||
while (cur != dl){
|
||||
print_stat(indent + 2, &cur->decl);
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
f_print(fout, "\n\t\t} else {\n");
|
||||
|
||||
cur = psav;
|
||||
while (cur != dl){
|
||||
emit_inline(indent + 2, &cur->decl, flag);
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
tabify(fout, indent + 1);
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
size = 0;
|
||||
i = 0;
|
||||
sizestr = NULL;
|
||||
print_stat(indent + 1, &dl->decl);
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 0)
|
||||
if (sizestr == NULL && size < inline){
|
||||
/* don't expand into inline code if size < inline */
|
||||
while (cur != dl){
|
||||
print_stat(indent + 1, &cur->decl);
|
||||
cur = cur->next;
|
||||
}
|
||||
} else {
|
||||
/* were already looking at a xdr_inlineable structure */
|
||||
if (sizestr == NULL)
|
||||
f_print(fout, "\t\tbuf = XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);",
|
||||
size);
|
||||
else
|
||||
if (size == 0)
|
||||
f_print(fout,
|
||||
"\t\tbuf = XDR_INLINE(xdrs, (%s) * BYTES_PER_XDR_UNIT);",
|
||||
sizestr);
|
||||
else
|
||||
f_print(fout,
|
||||
"\t\tbuf = XDR_INLINE(xdrs, (%d + (%s)) * BYTES_PER_XDR_UNIT);",
|
||||
size, sizestr);
|
||||
|
||||
f_print(fout, "\n\t\tif (buf == NULL) {\n");
|
||||
psav = cur;
|
||||
while (cur != NULL){
|
||||
print_stat(indent + 2, &cur->decl);
|
||||
cur = cur->next;
|
||||
}
|
||||
f_print(fout, "\t\t} else {\n");
|
||||
|
||||
cur = psav;
|
||||
while (cur != dl){
|
||||
emit_inline(indent + 2, &cur->decl, flag);
|
||||
cur = cur->next;
|
||||
}
|
||||
f_print(fout, "\t\t}\n");
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
emit_struct(def)
|
||||
definition *def;
|
||||
{
|
||||
decl_list *dl;
|
||||
int i, j, size, flag;
|
||||
bas_type *ptr;
|
||||
int can_inline;
|
||||
|
||||
if (inline == 0) {
|
||||
/* No xdr_inlining at all */
|
||||
for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
|
||||
print_stat(1, &dl->decl);
|
||||
return;
|
||||
}
|
||||
|
||||
for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
|
||||
if (dl->decl.rel == REL_VECTOR){
|
||||
f_print(fout, "\tint i;\n");
|
||||
break;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
can_inline = 0;
|
||||
/*
|
||||
* Make a first pass and see if inling is possible.
|
||||
*/
|
||||
for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
|
||||
if ((dl->decl.prefix == NULL) &&
|
||||
((ptr = find_type(dl->decl.type)) != NULL) &&
|
||||
((dl->decl.rel == REL_ALIAS)||
|
||||
(dl->decl.rel == REL_VECTOR))){
|
||||
if (dl->decl.rel == REL_ALIAS)
|
||||
size += ptr->length;
|
||||
else {
|
||||
can_inline = 1;
|
||||
break; /* can be inlined */
|
||||
}
|
||||
} else {
|
||||
if (size >= inline){
|
||||
can_inline = 1;
|
||||
break; /* can be inlined */
|
||||
}
|
||||
size = 0;
|
||||
}
|
||||
if (size >= inline)
|
||||
can_inline = 1;
|
||||
|
||||
if (can_inline == 0){ /* can not inline, drop back to old mode */
|
||||
for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
|
||||
print_stat(1, &dl->decl);
|
||||
return;
|
||||
}
|
||||
|
||||
flag = PUT;
|
||||
for (j = 0; j < 2; j++){
|
||||
inline_struct(def, flag);
|
||||
if (flag == PUT)
|
||||
flag = GET;
|
||||
}
|
||||
|
||||
f_print(fout, "\t\treturn (TRUE);\n\t}\n\n");
|
||||
|
||||
/* now take care of XDR_FREE case */
|
||||
|
||||
for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
|
||||
print_stat(1, &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(indent, dec)
|
||||
int indent;
|
||||
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(indent, prefix, type, rel, amax, name, dec->name);
|
||||
}
|
||||
|
||||
|
||||
char *upcase ();
|
||||
|
||||
emit_inline(indent, decl, flag)
|
||||
int indent;
|
||||
declaration *decl;
|
||||
int flag;
|
||||
{
|
||||
switch (decl->rel) {
|
||||
case REL_ALIAS :
|
||||
emit_single_in_line(indent, decl, flag, REL_ALIAS);
|
||||
break;
|
||||
case REL_VECTOR :
|
||||
tabify(fout, indent);
|
||||
f_print(fout, "{\n");
|
||||
tabify(fout, indent + 1);
|
||||
f_print(fout, "register %s *genp;\n\n", decl->type);
|
||||
tabify(fout, indent + 1);
|
||||
f_print(fout,
|
||||
"for (i = 0, genp = objp->%s;\n", decl->name);
|
||||
tabify(fout, indent + 2);
|
||||
f_print(fout, "i < %s; i++) {\n", decl->array_max);
|
||||
emit_single_in_line(indent + 2, decl, flag, REL_VECTOR);
|
||||
tabify(fout, indent + 1);
|
||||
f_print(fout, "}\n");
|
||||
tabify(fout, indent);
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
}
|
||||
|
||||
emit_single_in_line(indent, decl, flag, rel)
|
||||
int indent;
|
||||
declaration *decl;
|
||||
int flag;
|
||||
relation rel;
|
||||
{
|
||||
char *upp_case;
|
||||
int freed = 0;
|
||||
|
||||
tabify(fout, indent);
|
||||
if (flag == PUT)
|
||||
f_print(fout, "IXDR_PUT_");
|
||||
else
|
||||
if (rel == REL_ALIAS)
|
||||
f_print(fout, "objp->%s = IXDR_GET_", decl->name);
|
||||
else
|
||||
f_print(fout, "*genp++ = IXDR_GET_");
|
||||
|
||||
upp_case = upcase(decl->type);
|
||||
|
||||
/* hack - XX */
|
||||
if (strcmp(upp_case, "INT") == 0)
|
||||
{
|
||||
free(upp_case);
|
||||
freed = 1;
|
||||
upp_case = "LONG";
|
||||
}
|
||||
|
||||
if (strcmp(upp_case, "U_INT") == 0)
|
||||
{
|
||||
free(upp_case);
|
||||
freed = 1;
|
||||
upp_case = "U_LONG";
|
||||
}
|
||||
if (flag == PUT)
|
||||
if (rel == REL_ALIAS)
|
||||
f_print(fout,
|
||||
"%s(buf, objp->%s);\n", upp_case, decl->name);
|
||||
else
|
||||
f_print(fout, "%s(buf, *genp++);\n", upp_case);
|
||||
|
||||
else
|
||||
f_print(fout, "%s(buf);\n", upp_case);
|
||||
if (!freed)
|
||||
free(upp_case);
|
||||
}
|
||||
|
||||
char *upcase(str)
|
||||
char *str;
|
||||
{
|
||||
char *ptr, *hptr;
|
||||
|
||||
ptr = (char *)malloc(strlen(str)+1);
|
||||
if (ptr == (char *) NULL)
|
||||
{
|
||||
f_print(stderr, "malloc failed\n");
|
||||
exit(1);
|
||||
};
|
||||
|
||||
hptr = ptr;
|
||||
while (*str != '\0')
|
||||
*ptr++ = toupper(*str++);
|
||||
|
||||
*ptr = '\0';
|
||||
return (hptr);
|
||||
}
|
597
usr.bin/rpcgen/rpc_hout.c
Normal file
597
usr.bin/rpcgen/rpc_hout.c
Normal file
@ -0,0 +1,597 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ident "@(#)rpc_hout.c 1.16 94/04/25 SMI"
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (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_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
void storexdrfuncdecl __P(( char *, int ));
|
||||
static int pconstdef __P(( definition * ));
|
||||
static int pstructdef __P(( definition * ));
|
||||
static int puniondef __P(( definition * ));
|
||||
static int pprogramdef __P(( definition * ));
|
||||
static int pstructdef __P(( definition * ));
|
||||
static int penumdef __P(( definition * ));
|
||||
static int ptypedef __P(( definition * ));
|
||||
static int pdefine __P(( char *, char * ));
|
||||
static int undefined2 __P(( char *, char * ));
|
||||
static int parglist __P(( proc_list *, char * ));
|
||||
|
||||
static char RESULT[] = "clnt_res";
|
||||
|
||||
|
||||
/*
|
||||
* Print the C-version of an xdr definition
|
||||
*/
|
||||
void
|
||||
print_datadef(def)
|
||||
definition *def;
|
||||
{
|
||||
|
||||
if (def->def_kind == DEF_PROGRAM) /* handle data only */
|
||||
return;
|
||||
|
||||
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) {
|
||||
storexdrfuncdecl(def->def_name,
|
||||
def->def_kind != DEF_TYPEDEF ||
|
||||
!isvectordef(def->def.ty.old_type,
|
||||
def->def.ty.rel));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
print_funcdef(def)
|
||||
definition *def;
|
||||
{
|
||||
switch (def->def_kind) {
|
||||
case DEF_PROGRAM:
|
||||
f_print(fout, "\n");
|
||||
pprogramdef(def);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* store away enough information to allow the XDR functions to be spat
|
||||
out at the end of the file */
|
||||
|
||||
void
|
||||
storexdrfuncdecl(name, pointerp)
|
||||
char *name;
|
||||
int pointerp;
|
||||
{
|
||||
xdrfunc * xdrptr;
|
||||
|
||||
xdrptr = (xdrfunc *) malloc(sizeof (struct xdrfunc));
|
||||
|
||||
xdrptr->name = name;
|
||||
xdrptr->pointerp = pointerp;
|
||||
xdrptr->next = NULL;
|
||||
|
||||
if (xdrfunc_tail == NULL){
|
||||
xdrfunc_head = xdrptr;
|
||||
xdrfunc_tail = xdrptr;
|
||||
} else {
|
||||
xdrfunc_tail->next = xdrptr;
|
||||
xdrfunc_tail = xdrptr;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
print_xdr_func_def(name, pointerp, i)
|
||||
char* name;
|
||||
int pointerp;
|
||||
int i;
|
||||
{
|
||||
if (i == 2) {
|
||||
f_print(fout, "extern bool_t xdr_%s();\n", name);
|
||||
return;
|
||||
}
|
||||
else
|
||||
f_print(fout, "extern bool_t xdr_%s(XDR *, %s%s);\n", name,
|
||||
name, pointerp ? "*" : "");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
pconstdef(def)
|
||||
definition *def;
|
||||
{
|
||||
pdefine(def->def_name, def->def.co);
|
||||
}
|
||||
|
||||
/* print out the definitions for the arguments of functions in the
|
||||
header file
|
||||
*/
|
||||
static
|
||||
pargdef(def)
|
||||
definition *def;
|
||||
{
|
||||
decl_list *l;
|
||||
version_list *vers;
|
||||
char *name;
|
||||
proc_list *plist;
|
||||
|
||||
|
||||
for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
|
||||
for (plist = vers->procs; plist != NULL;
|
||||
plist = plist->next) {
|
||||
|
||||
if (!newstyle || plist->arg_num < 2) {
|
||||
continue; /* old style or single args */
|
||||
}
|
||||
name = plist->args.argname;
|
||||
f_print(fout, "struct %s {\n", name);
|
||||
for (l = plist->args.decls;
|
||||
l != NULL; l = l->next) {
|
||||
pdeclaration(name, &l->decl, 1,
|
||||
";\n");
|
||||
}
|
||||
f_print(fout, "};\n");
|
||||
f_print(fout, "typedef struct %s %s;\n",
|
||||
name, name);
|
||||
storexdrfuncdecl(name, 1);
|
||||
f_print(fout, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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, ";\n");
|
||||
}
|
||||
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) {
|
||||
if (l->contflag == 0)
|
||||
pdeclaration(name, &l->case_decl, 2, ";\n");
|
||||
}
|
||||
decl = def->def.un.default_decl;
|
||||
if (decl && !streq(decl->type, "void")) {
|
||||
pdeclaration(name, decl, 2, ";\n");
|
||||
}
|
||||
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\t%s %s\n", name, num);
|
||||
}
|
||||
|
||||
static
|
||||
puldefine(name, num)
|
||||
char *name;
|
||||
char *num;
|
||||
{
|
||||
f_print(fout, "#define\t%s ((unsigned 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
|
||||
pfreeprocdef(char * name, char *vers, int mode)
|
||||
{
|
||||
f_print(fout, "extern int ");
|
||||
pvname(name, vers);
|
||||
if (mode == 1)
|
||||
f_print(fout,"_freeresult(SVCXPRT *, xdrproc_t, caddr_t);\n");
|
||||
else
|
||||
f_print(fout,"_freeresult();\n");
|
||||
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
pprogramdef(def)
|
||||
definition *def;
|
||||
{
|
||||
version_list *vers;
|
||||
proc_list *proc;
|
||||
int i;
|
||||
char *ext;
|
||||
|
||||
pargdef(def);
|
||||
|
||||
puldefine(def->def_name, def->def.pr.prog_num);
|
||||
for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
|
||||
if (tblflag) {
|
||||
f_print(fout,
|
||||
"extern struct rpcgen_table %s_%s_table[];\n",
|
||||
locase(def->def_name), vers->vers_num);
|
||||
f_print(fout,
|
||||
"extern %s_%s_nproc;\n",
|
||||
locase(def->def_name), vers->vers_num);
|
||||
}
|
||||
puldefine(vers->vers_name, vers->vers_num);
|
||||
|
||||
/*
|
||||
* Print out 2 definitions, one for ANSI-C, another for
|
||||
* old K & R C
|
||||
*/
|
||||
|
||||
if(!Cflag){
|
||||
ext = "extern ";
|
||||
for (proc = vers->procs; proc != NULL;
|
||||
proc = proc->next) {
|
||||
if (!define_printed(proc,
|
||||
def->def.pr.versions)) {
|
||||
puldefine(proc->proc_name,
|
||||
proc->proc_num);
|
||||
}
|
||||
f_print(fout, "%s", ext);
|
||||
pprocdef(proc, vers, NULL, 0, 2);
|
||||
|
||||
if (mtflag) {
|
||||
f_print(fout, "%s", ext);
|
||||
pprocdef(proc, vers, NULL, 1, 2);
|
||||
}
|
||||
}
|
||||
pfreeprocdef(def->def_name, vers->vers_num, 2);
|
||||
|
||||
} else {
|
||||
for (i = 1; i < 3; i++){
|
||||
if (i == 1){
|
||||
f_print(fout, "\n#if defined(__STDC__) || defined(__cplusplus)\n");
|
||||
ext = "extern ";
|
||||
}else{
|
||||
f_print(fout, "\n#else /* K&R C */\n");
|
||||
ext = "extern ";
|
||||
}
|
||||
|
||||
for (proc = vers->procs; proc != NULL;
|
||||
proc = proc->next) {
|
||||
if (!define_printed(proc,
|
||||
def->def.pr.versions)) {
|
||||
puldefine(proc->proc_name,
|
||||
proc->proc_num);
|
||||
}
|
||||
f_print(fout, "%s", ext);
|
||||
pprocdef(proc, vers, "CLIENT *", 0, i);
|
||||
f_print(fout, "%s", ext);
|
||||
pprocdef(proc, vers, "struct svc_req *", 1, i);
|
||||
}
|
||||
pfreeprocdef(def->def_name, vers->vers_num, i);
|
||||
}
|
||||
f_print(fout, "#endif /* K&R C */\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pprocdef(proc, vp, addargtype, server_p, mode)
|
||||
proc_list *proc;
|
||||
version_list *vp;
|
||||
char* addargtype;
|
||||
int server_p;
|
||||
int mode;
|
||||
{
|
||||
if (mtflag) {/* Print MT style stubs */
|
||||
if (server_p)
|
||||
f_print(fout, "bool_t ");
|
||||
else
|
||||
f_print(fout, "enum clnt_stat ");
|
||||
} else {
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
f_print(fout, "* ");
|
||||
}
|
||||
if (server_p)
|
||||
pvname_svc(proc->proc_name, vp->vers_num);
|
||||
else
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
|
||||
/*
|
||||
* mode 1 = ANSI-C, mode 2 = K&R C
|
||||
*/
|
||||
if ( mode == 1)
|
||||
parglist(proc, addargtype);
|
||||
else
|
||||
f_print(fout, "();\n");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* print out argument list of procedure */
|
||||
static
|
||||
parglist(proc, addargtype)
|
||||
proc_list *proc;
|
||||
char* addargtype;
|
||||
{
|
||||
decl_list *dl;
|
||||
|
||||
f_print(fout, "(");
|
||||
if (proc->arg_num < 2 && newstyle &&
|
||||
streq(proc->args.decls->decl.type, "void")) {
|
||||
/* 0 argument in new style: do nothing*/
|
||||
}
|
||||
else {
|
||||
for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
|
||||
ptype(dl->decl.prefix, dl->decl.type, 1);
|
||||
if (!newstyle)
|
||||
f_print(fout, "*");
|
||||
/* old style passes by reference */
|
||||
f_print(fout, ", ");
|
||||
}
|
||||
}
|
||||
|
||||
if (mtflag) {
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
f_print(fout, "*, ");
|
||||
}
|
||||
|
||||
f_print(fout, "%s);\n", addargtype);
|
||||
|
||||
}
|
||||
|
||||
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++);
|
||||
}
|
||||
}
|
||||
if (l->next)
|
||||
f_print(fout, ",\n");
|
||||
else
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
pdeclaration(name, dec, tab, separator)
|
||||
char *name;
|
||||
declaration *dec;
|
||||
int tab;
|
||||
char *separator;
|
||||
{
|
||||
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, separator);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
1381
usr.bin/rpcgen/rpc_main.c
Normal file
1381
usr.bin/rpcgen/rpc_main.c
Normal file
File diff suppressed because it is too large
Load Diff
655
usr.bin/rpcgen/rpc_parse.c
Normal file
655
usr.bin/rpcgen/rpc_parse.c
Normal file
@ -0,0 +1,655 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ident "@(#)rpc_parse.c 1.12 93/07/05 SMI"
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_parse.c, Parser for the RPC protocol compiler
|
||||
* Copyright (C) 1987 Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rpc/types.h"
|
||||
#include "rpc_scan.h"
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
#define ARGNAME "arg"
|
||||
|
||||
extern char *make_argname __P(( char *, char * ));
|
||||
static int isdefined __P(( definition * ));
|
||||
static int def_struct __P(( definition * ));
|
||||
static int def_program __P(( definition * ));
|
||||
static int def_enum __P(( definition * ));
|
||||
static int def_const __P(( definition * ));
|
||||
static int def_union __P(( definition * ));
|
||||
static int def_typedef __P(( definition * ));
|
||||
static int get_declaration __P(( declaration *, defkind ));
|
||||
static int get_prog_declaration __P(( declaration *, defkind, int ));
|
||||
static int get_type __P(( char **, char **, defkind ));
|
||||
static int unsigned_dec __P(( char ** ));
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
extern char *strdup();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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);
|
||||
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;
|
||||
declaration dec;
|
||||
decl_list *decls;
|
||||
decl_list **tailp;
|
||||
version_list *vlist;
|
||||
version_list **vtailp;
|
||||
proc_list *plist;
|
||||
proc_list **ptailp;
|
||||
int num_args;
|
||||
bool_t isvoid = FALSE; /* whether first argument is void */
|
||||
defp->def_kind = DEF_PROGRAM;
|
||||
scan(TOK_IDENT, &tok);
|
||||
defp->def_name = tok.str;
|
||||
scan(TOK_LBRACE, &tok);
|
||||
vtailp = &defp->def.pr.versions;
|
||||
tailp = &defp->def.st.decls;
|
||||
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 {
|
||||
/* get result type */
|
||||
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 args - first one */
|
||||
num_args = 1;
|
||||
isvoid = FALSE;
|
||||
/*
|
||||
* type of DEF_PROGRAM in the first
|
||||
* get_prog_declaration and DEF_STURCT in the next
|
||||
* allows void as argument if it is the only argument
|
||||
*/
|
||||
get_prog_declaration(&dec, DEF_PROGRAM, num_args);
|
||||
if (streq(dec.type, "void"))
|
||||
isvoid = TRUE;
|
||||
decls = ALLOC(decl_list);
|
||||
plist->args.decls = decls;
|
||||
decls->decl = dec;
|
||||
tailp = &decls->next;
|
||||
/* get args */
|
||||
while (peekscan(TOK_COMMA, &tok)) {
|
||||
num_args++;
|
||||
get_prog_declaration(&dec, DEF_STRUCT,
|
||||
num_args);
|
||||
decls = ALLOC(decl_list);
|
||||
decls->decl = dec;
|
||||
*tailp = decls;
|
||||
if (streq(dec.type, "void"))
|
||||
isvoid = TRUE;
|
||||
tailp = &decls->next;
|
||||
}
|
||||
/* multiple arguments are only allowed in newstyle */
|
||||
if (!newstyle && num_args > 1) {
|
||||
error("only one argument is allowed");
|
||||
}
|
||||
if (isvoid && num_args > 1) {
|
||||
error("illegal use of void in program definition");
|
||||
}
|
||||
*tailp = NULL;
|
||||
scan(TOK_RPAREN, &tok);
|
||||
scan(TOK_EQUAL, &tok);
|
||||
scan_num(&tok);
|
||||
scan(TOK_SEMICOLON, &tok);
|
||||
plist->proc_num = tok.str;
|
||||
plist->arg_num = num_args;
|
||||
*ptailp = plist;
|
||||
ptailp = &plist->next;
|
||||
peek(&tok);
|
||||
} while (tok.kind != TOK_RBRACE);
|
||||
*ptailp = NULL;
|
||||
*vtailp = vlist;
|
||||
vtailp = &vlist->next;
|
||||
scan(TOK_RBRACE, &tok);
|
||||
scan(TOK_EQUAL, &tok);
|
||||
scan_num(&tok);
|
||||
vlist->vers_num = tok.str;
|
||||
/* make the argument structure name for each arg */
|
||||
for (plist = vlist->procs; plist != NULL;
|
||||
plist = plist->next) {
|
||||
plist->args.argname = make_argname(plist->proc_name,
|
||||
vlist->vers_num);
|
||||
/* free the memory ?? */
|
||||
}
|
||||
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, *tcase;
|
||||
case_list **tailp;
|
||||
int flag;
|
||||
|
||||
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) {
|
||||
scan2(TOK_IDENT, TOK_CHARCONST, &tok);
|
||||
cases = ALLOC(case_list);
|
||||
cases->case_name = tok.str;
|
||||
scan(TOK_COLON, &tok);
|
||||
/* now peek at next token */
|
||||
flag = 0;
|
||||
if (peekscan(TOK_CASE, &tok)){
|
||||
do {
|
||||
scan2(TOK_IDENT, TOK_CHARCONST, &tok);
|
||||
cases->contflag = 1;
|
||||
/* continued case statement */
|
||||
*tailp = cases;
|
||||
tailp = &cases->next;
|
||||
cases = ALLOC(case_list);
|
||||
cases->case_name = tok.str;
|
||||
scan(TOK_COLON, &tok);
|
||||
} while (peekscan(TOK_CASE, &tok));
|
||||
}
|
||||
else
|
||||
if (flag)
|
||||
{
|
||||
|
||||
*tailp = cases;
|
||||
tailp = &cases->next;
|
||||
cases = ALLOC(case_list);
|
||||
};
|
||||
|
||||
get_declaration(&dec, DEF_UNION);
|
||||
cases->case_decl = dec;
|
||||
cases->contflag = 0; /* no continued case statement */
|
||||
*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 char* reserved_words[] =
|
||||
{
|
||||
"array",
|
||||
"bytes",
|
||||
"destroy",
|
||||
"free",
|
||||
"getpos",
|
||||
"inline",
|
||||
"pointer",
|
||||
"reference",
|
||||
"setpos",
|
||||
"sizeof",
|
||||
"union",
|
||||
"vector",
|
||||
NULL
|
||||
};
|
||||
|
||||
static char* reserved_types[] =
|
||||
{
|
||||
"opaque",
|
||||
"string",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* check that the given name is not one that would eventually result in
|
||||
* xdr routines that would conflict with internal XDR routines.
|
||||
*/
|
||||
static check_type_name(name, new_type)
|
||||
int new_type;
|
||||
char* name;
|
||||
{
|
||||
int i;
|
||||
char tmp[100];
|
||||
|
||||
for (i = 0; reserved_words[i] != NULL; i++) {
|
||||
if (strcmp(name, reserved_words[i]) == 0) {
|
||||
sprintf(tmp,
|
||||
"illegal (reserved) name :\'%s\' in type definition",
|
||||
name);
|
||||
error(tmp);
|
||||
}
|
||||
}
|
||||
if (new_type) {
|
||||
for (i = 0; reserved_types[i] != NULL; i++) {
|
||||
if (strcmp(name, reserved_types[i]) == 0) {
|
||||
sprintf(tmp,
|
||||
"illegal (reserved) name :\'%s\' in type definition",
|
||||
name);
|
||||
error(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
def_typedef(defp)
|
||||
definition *defp;
|
||||
{
|
||||
declaration dec;
|
||||
|
||||
defp->def_kind = DEF_TYPEDEF;
|
||||
get_declaration(&dec, DEF_TYPEDEF);
|
||||
defp->def_name = dec.name;
|
||||
check_type_name(dec.name, 1);
|
||||
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;
|
||||
}
|
||||
|
||||
check_type_name(dec->type, 0);
|
||||
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_prog_declaration(dec, dkind, num)
|
||||
declaration *dec;
|
||||
defkind dkind;
|
||||
int num; /* arg number */
|
||||
{
|
||||
token tok;
|
||||
char name[10]; /* argument name */
|
||||
|
||||
if (dkind == DEF_PROGRAM) {
|
||||
peek(&tok);
|
||||
if (tok.kind == TOK_RPAREN) { /* no arguments */
|
||||
dec->rel = REL_ALIAS;
|
||||
dec->type = "void";
|
||||
dec->prefix = NULL;
|
||||
dec->name = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
get_type(&dec->prefix, &dec->type, dkind);
|
||||
dec->rel = REL_ALIAS;
|
||||
if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
|
||||
strcpy(name, tok.str);
|
||||
else
|
||||
sprintf(name, "%s%d", ARGNAME, num);
|
||||
/* default name of argument */
|
||||
|
||||
dec->name = (char *) strdup(name);
|
||||
if (streq(dec->type, "void")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (streq(dec->type, "opaque")) {
|
||||
error("opaque -- illegal argument type");
|
||||
}
|
||||
if (peekscan(TOK_STAR, &tok)) {
|
||||
if (streq(dec->type, "string")) {
|
||||
error("pointer to string not allowed in program arguments\n");
|
||||
}
|
||||
dec->rel = REL_POINTER;
|
||||
if (peekscan(TOK_IDENT, &tok))
|
||||
/* optional name of argument */
|
||||
dec->name = strdup(tok.str);
|
||||
}
|
||||
if (peekscan(TOK_LANGLE, &tok)) {
|
||||
if (!streq(dec->type, "string")) {
|
||||
error("arrays cannot be declared as arguments to procedures -- 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, "string")) {
|
||||
if (dec->rel != REL_ARRAY) {
|
||||
/*
|
||||
* .x specifies just string as
|
||||
* type of argument
|
||||
* - make it string<>
|
||||
*/
|
||||
dec->rel = REL_ARRAY;
|
||||
dec->array_max = "~0"; /* unspecified size, use max */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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_HYPER:
|
||||
*typep = "longlong_t";
|
||||
(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 with one argument");
|
||||
}
|
||||
*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:
|
||||
case TOK_QUAD:
|
||||
*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_HYPER:
|
||||
get_token(&tok);
|
||||
*typep = "ulonglong_t";
|
||||
(void) peekscan(TOK_INT, &tok);
|
||||
break;
|
||||
case TOK_INT:
|
||||
get_token(&tok);
|
||||
*typep = "u_int";
|
||||
break;
|
||||
default:
|
||||
*typep = "u_int";
|
||||
break;
|
||||
}
|
||||
}
|
197
usr.bin/rpcgen/rpc_parse.h
Normal file
197
usr.bin/rpcgen/rpc_parse.h
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
#pragma ident "@(#)rpc_parse.h 1.10 94/05/15 SMI"
|
||||
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/* @(#)rpc_parse.h 1.3 90/08/29 (C) 1987 SMI */
|
||||
|
||||
/*
|
||||
* rpc_parse.h, Definitions for the RPCL parser
|
||||
*/
|
||||
|
||||
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;
|
||||
int contflag;
|
||||
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 arg_list {
|
||||
char *argname; /* name of struct for arg*/
|
||||
decl_list *decls;
|
||||
};
|
||||
|
||||
typedef struct arg_list arg_list;
|
||||
|
||||
struct proc_list {
|
||||
char *proc_name;
|
||||
char *proc_num;
|
||||
arg_list args;
|
||||
int arg_num;
|
||||
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;
|
||||
|
||||
definition *get_definition();
|
||||
|
||||
|
||||
struct bas_type
|
||||
{
|
||||
char *name;
|
||||
int length;
|
||||
struct bas_type *next;
|
||||
};
|
||||
|
||||
typedef struct bas_type bas_type;
|
311
usr.bin/rpcgen/rpc_sample.c
Normal file
311
usr.bin/rpcgen/rpc_sample.c
Normal file
@ -0,0 +1,311 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#pragma ident "@(#)rpc_sample.c 1.9 94/04/25 SMI"
|
||||
|
||||
/*
|
||||
* rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler
|
||||
* Copyright (C) 1987, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
|
||||
static char RQSTP[] = "rqstp";
|
||||
|
||||
extern void printarglist __P(( proc_list *, char *, char *, char *));
|
||||
static int write_sample_client __P(( char *, version_list * ));
|
||||
static int write_sample_server __P(( definition * ));
|
||||
static int return_type __P(( proc_list * ));
|
||||
|
||||
void
|
||||
write_sample_svc(def)
|
||||
definition *def;
|
||||
{
|
||||
|
||||
if (def->def_kind != DEF_PROGRAM)
|
||||
return;
|
||||
write_sample_server(def);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
write_sample_clnt(def)
|
||||
definition *def;
|
||||
{
|
||||
version_list *vp;
|
||||
int count = 0;
|
||||
|
||||
if (def->def_kind != DEF_PROGRAM)
|
||||
return(0);
|
||||
/* generate sample code for each version */
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
write_sample_client(def->def_name, vp);
|
||||
++count;
|
||||
}
|
||||
return(count);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
write_sample_client(program_name, vp)
|
||||
char *program_name;
|
||||
version_list *vp;
|
||||
{
|
||||
proc_list *proc;
|
||||
int i;
|
||||
decl_list *l;
|
||||
|
||||
f_print(fout, "\n\nvoid\n");
|
||||
pvname(program_name, vp->vers_num);
|
||||
if(Cflag)
|
||||
f_print(fout,"(char *host)\n{\n");
|
||||
else
|
||||
f_print(fout, "(host)\n\tchar *host;\n{\n");
|
||||
f_print(fout, "\tCLIENT *clnt;\n");
|
||||
|
||||
i = 0;
|
||||
for (proc = vp->procs; proc != NULL; proc = proc->next) {
|
||||
f_print(fout, "\t");
|
||||
if (mtflag) {
|
||||
f_print(fout, "enum clnt_stat retval_%d;\n\t", ++i);
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
f_print(fout, "result_%d;\n", i);
|
||||
} else {
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
f_print(fout, " *result_%d;\n",++i);
|
||||
}
|
||||
/* print out declarations for arguments */
|
||||
if(proc->arg_num < 2 && !newstyle) {
|
||||
f_print(fout, "\t");
|
||||
if(!streq(proc->args.decls->decl.type, "void"))
|
||||
ptype(proc->args.decls->decl.prefix,
|
||||
proc->args.decls->decl.type, 1);
|
||||
else
|
||||
f_print(fout, "char * "); /* cannot have "void" type */
|
||||
f_print(fout, " ");
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_arg;\n");
|
||||
} else if (!streq(proc->args.decls->decl.type, "void")) {
|
||||
for (l = proc->args.decls; l != NULL; l = l->next) {
|
||||
f_print(fout, "\t");
|
||||
ptype(l->decl.prefix, l->decl.type, 1);
|
||||
if (strcmp(l->decl.type,"string") == 1)
|
||||
f_print(fout, " ");
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_%s;\n", l->decl.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* generate creation of client handle */
|
||||
f_print(fout, "\n#ifndef\tDEBUG\n");
|
||||
f_print(fout, "\tclnt = clnt_create(host, %s, %s, \"%s\");\n",
|
||||
program_name, vp->vers_name, tirpcflag? "netpath" : "udp");
|
||||
f_print(fout, "\tif (clnt == (CLIENT *) NULL) {\n");
|
||||
f_print(fout, "\t\tclnt_pcreateerror(host);\n");
|
||||
f_print(fout, "\t\texit(1);\n\t}\n");
|
||||
f_print(fout, "#endif\t/* DEBUG */\n\n");
|
||||
|
||||
/* generate calls to procedures */
|
||||
i = 0;
|
||||
for (proc = vp->procs; proc != NULL; proc = proc->next) {
|
||||
if (mtflag)
|
||||
f_print(fout, "\tretval_%d = ",++i);
|
||||
else
|
||||
f_print(fout, "\tresult_%d = ",++i);
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
if (proc->arg_num < 2 && !newstyle) {
|
||||
f_print(fout, "(");
|
||||
if(streq(proc->args.decls->decl.type, "void"))
|
||||
/* cast to void * */
|
||||
f_print(fout, "(void *)");
|
||||
f_print(fout, "&");
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
if (mtflag)
|
||||
f_print(fout, "_arg, &result_%d, clnt);\n",
|
||||
i);
|
||||
else
|
||||
f_print(fout, "_arg, clnt);\n");
|
||||
|
||||
} else if (streq(proc->args.decls->decl.type, "void")) {
|
||||
if (mtflag)
|
||||
f_print(fout, "(&result_%d, clnt);\n", i);
|
||||
else
|
||||
f_print(fout, "(clnt);\n");
|
||||
}
|
||||
else {
|
||||
f_print(fout, "(");
|
||||
for (l = proc->args.decls; l != NULL; l = l->next) {
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
f_print(fout, "_%s, ", l->decl.name);
|
||||
}
|
||||
if (mtflag)
|
||||
f_print(fout, "&result_%d, ", i);
|
||||
|
||||
f_print(fout, "clnt);\n");
|
||||
}
|
||||
if (mtflag) {
|
||||
f_print(fout, "\tif (retval_%d != RPC_SUCCESS) {\n", i);
|
||||
|
||||
} else {
|
||||
f_print(fout, "\tif (result_%d == (", i);
|
||||
ptype(proc->res_prefix, proc->res_type, 1);
|
||||
f_print(fout, "*) NULL) {\n");
|
||||
}
|
||||
f_print(fout, "\t\tclnt_perror(clnt, \"call failed\");\n");
|
||||
f_print(fout, "\t}\n");
|
||||
}
|
||||
|
||||
f_print(fout, "#ifndef\tDEBUG\n");
|
||||
f_print(fout, "\tclnt_destroy(clnt);\n");
|
||||
f_print(fout, "#endif\t /* DEBUG */\n");
|
||||
f_print(fout, "}\n");
|
||||
}
|
||||
|
||||
static
|
||||
write_sample_server(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");
|
||||
if (!mtflag) {
|
||||
return_type(proc);
|
||||
f_print(fout, "*\n");
|
||||
} else
|
||||
f_print(fout, "bool_t\n");
|
||||
if (Cflag || mtflag)
|
||||
pvname_svc(proc->proc_name, vp->vers_num);
|
||||
else
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
printarglist(proc, "result", RQSTP, "struct svc_req *");
|
||||
|
||||
f_print(fout, "{\n");
|
||||
if (!mtflag) {
|
||||
f_print(fout, "\tstatic ");
|
||||
if(!streq(proc->res_type, "void"))
|
||||
return_type(proc);
|
||||
else
|
||||
f_print(fout, "char *");
|
||||
/* cannot have void type */
|
||||
f_print(fout, " result;\n", proc->res_type);
|
||||
}
|
||||
else
|
||||
f_print(fout, "\tbool_t retval;\n");
|
||||
f_print(fout,
|
||||
"\n\t/*\n\t * insert server code here\n\t */\n\n");
|
||||
|
||||
if (!mtflag)
|
||||
if(!streq(proc->res_type, "void"))
|
||||
f_print(fout, "\treturn (&result);\n}\n");
|
||||
else /* cast back to void * */
|
||||
f_print(fout, "\treturn((void *) &result);\n}\n");
|
||||
else
|
||||
f_print(fout, "\treturn (retval);\n}\n");
|
||||
}
|
||||
/* put in sample freeing routine */
|
||||
if (mtflag) {
|
||||
f_print(fout, "\nint\n");
|
||||
pvname(def->def_name, vp->vers_num);
|
||||
if (Cflag)
|
||||
f_print(fout,"_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)\n");
|
||||
else {
|
||||
f_print(fout,"_freeresult(transp, xdr_result, result)\n");
|
||||
f_print(fout,"\tSVCXPRT *transp;\n");
|
||||
f_print(fout,"\txdrproc_t xdr_result;\n");
|
||||
f_print(fout,"\tcaddr_t result;\n");
|
||||
}
|
||||
f_print(fout, "{\n");
|
||||
f_print(fout, "\t(void) xdr_free(xdr_result, result);\n");
|
||||
f_print(fout,
|
||||
"\n\t/*\n\t * Insert additional freeing code here, if needed\n\t */\n");
|
||||
f_print(fout, "\n}\n");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
return_type(plist)
|
||||
proc_list *plist;
|
||||
{
|
||||
ptype(plist->res_prefix, plist->res_type, 1);
|
||||
}
|
||||
|
||||
add_sample_msg()
|
||||
{
|
||||
f_print(fout, "/*\n");
|
||||
f_print(fout, " * This is sample code generated by rpcgen.\n");
|
||||
f_print(fout, " * These are only templates and you can use them\n");
|
||||
f_print(fout, " * as a guideline for developing your own functions.\n");
|
||||
f_print(fout, " */\n\n");
|
||||
}
|
||||
|
||||
void
|
||||
write_sample_clnt_main()
|
||||
{
|
||||
list *l;
|
||||
definition *def;
|
||||
version_list *vp;
|
||||
|
||||
f_print(fout, "\n\n");
|
||||
if(Cflag)
|
||||
f_print(fout,"main(int argc, char *argv[])\n{\n");
|
||||
else
|
||||
f_print(fout, "main(argc, argv)\n\tint argc;\n\tchar *argv[];\n{\n");
|
||||
|
||||
f_print(fout, "\tchar *host;");
|
||||
f_print(fout, "\n\n\tif (argc < 2) {");
|
||||
f_print(fout, "\n\t\tprintf(\"usage: %%s server_host\\n\", argv[0]);\n");
|
||||
f_print(fout, "\t\texit(1);\n\t}");
|
||||
f_print(fout, "\n\thost = argv[1];\n");
|
||||
|
||||
for (l = defined; l != NULL; l = l->next) {
|
||||
def = l->val;
|
||||
if (def->def_kind != DEF_PROGRAM) {
|
||||
continue;
|
||||
}
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
f_print(fout, "\t");
|
||||
pvname(def->def_name, vp->vers_num);
|
||||
f_print(fout, "(host);\n");
|
||||
}
|
||||
}
|
||||
f_print(fout, "}\n");
|
||||
}
|
517
usr.bin/rpcgen/rpc_scan.c
Normal file
517
usr.bin/rpcgen/rpc_scan.c
Normal file
@ -0,0 +1,517 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ident "@(#)rpc_scan.c 1.13 93/07/05 SMI"
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_scan.c, Scanner for the RPC protocol compiler
|
||||
* Copyright (C) 1987, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "rpc_scan.h"
|
||||
#include "rpc_parse.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 */
|
||||
|
||||
static int unget_token __P(( token * ));
|
||||
static int findstrconst __P(( char **, char **));
|
||||
static int findchrconst __P(( char **, char **));
|
||||
static int findconst __P(( char **, char **));
|
||||
static int findkind __P(( char **, token * ));
|
||||
static int cppline __P(( char * ));
|
||||
static int directive __P(( char * ));
|
||||
static int printdirective __P(( char * ));
|
||||
static int docppline __P(( char *, int *, char ** ));
|
||||
|
||||
/*
|
||||
* 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 any of the 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 any of the 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;
|
||||
int stat = 0;
|
||||
|
||||
|
||||
if (pushed) {
|
||||
pushed = 0;
|
||||
*tokp = lasttok;
|
||||
return;
|
||||
}
|
||||
commenting = 0;
|
||||
for (;;) {
|
||||
if (*where == 0) {
|
||||
for (;;) {
|
||||
if (!fgets(curline, MAXLINESIZE, fin)) {
|
||||
tokp->kind = TOK_EOF;
|
||||
/* now check if cpp returned non NULL value */
|
||||
waitpid(childpid, &stat, WUNTRACED);
|
||||
if (stat > 0) {
|
||||
/* Set return value from rpcgen */
|
||||
nonfatalerrors = stat >> 8;
|
||||
}
|
||||
*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) {
|
||||
for (where++; *where; where++) {
|
||||
if (endcomment(where)) {
|
||||
where++;
|
||||
commenting--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} 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 '\'':
|
||||
tokp->kind = TOK_CHARCONST;
|
||||
findchrconst(&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
|
||||
findchrconst(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;
|
||||
if (size != 3) {
|
||||
error("empty char string");
|
||||
}
|
||||
*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_HYPER, "hyper"},
|
||||
{TOK_FLOAT, "float"},
|
||||
{TOK_DOUBLE, "double"},
|
||||
{TOK_QUAD, "quadruple"},
|
||||
{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;
|
||||
}
|
133
usr.bin/rpcgen/rpc_scan.h
Normal file
133
usr.bin/rpcgen/rpc_scan.h
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
#pragma ident "@(#)rpc_scan.h 1.11 94/05/15 SMI"
|
||||
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
|
||||
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/* @(#)rpc_scan.h 1.3 90/08/29 (C) 1987 SMI */
|
||||
|
||||
/*
|
||||
* rpc_scan.h, Definitions for the RPCL scanner
|
||||
*/
|
||||
|
||||
/*
|
||||
* kinds of tokens
|
||||
*/
|
||||
enum tok_kind {
|
||||
TOK_IDENT,
|
||||
TOK_CHARCONST,
|
||||
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_HYPER,
|
||||
TOK_UNSIGNED,
|
||||
TOK_FLOAT,
|
||||
TOK_DOUBLE,
|
||||
TOK_QUAD,
|
||||
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 scan();
|
||||
void scan2();
|
||||
void scan3();
|
||||
void scan_num();
|
||||
void peek();
|
||||
int peekscan();
|
||||
void get_token();
|
1082
usr.bin/rpcgen/rpc_svcout.c
Normal file
1082
usr.bin/rpcgen/rpc_svcout.c
Normal file
File diff suppressed because it is too large
Load Diff
171
usr.bin/rpcgen/rpc_tblout.c
Normal file
171
usr.bin/rpcgen/rpc_tblout.c
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ident "@(#)rpc_tblout.c 1.11 93/07/05 SMI"
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)rpc_tblout.c 1.4 89/02/22 (C) 1988 SMI";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_tblout.c, Dispatch table outputter for the RPC protocol compiler
|
||||
* Copyright (C) 1989, Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
#define TABSIZE 8
|
||||
#define TABCOUNT 5
|
||||
#define TABSTOP (TABSIZE*TABCOUNT)
|
||||
|
||||
static char tabstr[TABCOUNT+1] = "\t\t\t\t\t";
|
||||
|
||||
static char tbl_hdr[] = "struct rpcgen_table %s_table[] = {\n";
|
||||
static char tbl_end[] = "};\n";
|
||||
|
||||
static char null_entry[] = "\n\t(char *(*)())0,\n\
|
||||
\t(xdrproc_t) xdr_void,\t\t\t0,\n\
|
||||
\t(xdrproc_t) xdr_void,\t\t\t0,\n";
|
||||
|
||||
|
||||
static char tbl_nproc[] = "int %s_nproc =\n\tsizeof(%s_table)/sizeof(%s_table[0]);\n\n";
|
||||
|
||||
static int write_table __P(( definition * ));
|
||||
static int printit __P(( char *, char * ));
|
||||
|
||||
void
|
||||
write_tables()
|
||||
{
|
||||
list *l;
|
||||
definition *def;
|
||||
|
||||
f_print(fout, "\n");
|
||||
for (l = defined; l != NULL; l = l->next) {
|
||||
def = (definition *) l->val;
|
||||
if (def->def_kind == DEF_PROGRAM) {
|
||||
write_table(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
write_table(def)
|
||||
definition *def;
|
||||
{
|
||||
version_list *vp;
|
||||
proc_list *proc;
|
||||
int current;
|
||||
int expected;
|
||||
char progvers[100];
|
||||
int warning;
|
||||
|
||||
for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
|
||||
warning = 0;
|
||||
s_print(progvers, "%s_%s",
|
||||
locase(def->def_name), vp->vers_num);
|
||||
/* print the table header */
|
||||
f_print(fout, tbl_hdr, progvers);
|
||||
|
||||
if (nullproc(vp->procs)) {
|
||||
expected = 0;
|
||||
} else {
|
||||
expected = 1;
|
||||
f_print(fout, null_entry);
|
||||
}
|
||||
for (proc = vp->procs; proc != NULL; proc = proc->next) {
|
||||
current = atoi(proc->proc_num);
|
||||
if (current != expected++) {
|
||||
f_print(fout,
|
||||
"\n/*\n * WARNING: table out of order\n */\n");
|
||||
if (warning == 0) {
|
||||
f_print(stderr,
|
||||
"WARNING %s table is out of order\n",
|
||||
progvers);
|
||||
warning = 1;
|
||||
nonfatalerrors = 1;
|
||||
}
|
||||
expected = current + 1;
|
||||
}
|
||||
f_print(fout, "\n\t(char *(*)())RPCGEN_ACTION(");
|
||||
|
||||
/* routine to invoke */
|
||||
if( Cflag && !newstyle )
|
||||
pvname_svc(proc->proc_name, vp->vers_num);
|
||||
else {
|
||||
if( newstyle )
|
||||
f_print( fout, "_"); /* calls internal func */
|
||||
pvname(proc->proc_name, vp->vers_num);
|
||||
}
|
||||
f_print(fout, "),\n");
|
||||
|
||||
/* argument info */
|
||||
if( proc->arg_num > 1 )
|
||||
printit((char*) NULL, proc->args.argname );
|
||||
else
|
||||
/* do we have to do something special for newstyle */
|
||||
printit( proc->args.decls->decl.prefix,
|
||||
proc->args.decls->decl.type );
|
||||
/* result info */
|
||||
printit(proc->res_prefix, proc->res_type);
|
||||
}
|
||||
|
||||
/* print the table trailer */
|
||||
f_print(fout, tbl_end);
|
||||
f_print(fout, tbl_nproc, progvers, progvers, progvers);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
printit(prefix, type)
|
||||
char *prefix;
|
||||
char *type;
|
||||
{
|
||||
int len;
|
||||
int tabs;
|
||||
|
||||
|
||||
len = fprintf(fout, "\txdr_%s,", stringfix(type));
|
||||
/* account for leading tab expansion */
|
||||
len += TABSIZE - 1;
|
||||
/* round up to tabs required */
|
||||
tabs = (TABSTOP - len + TABSIZE - 1)/TABSIZE;
|
||||
f_print(fout, "%s", &tabstr[TABCOUNT-tabs]);
|
||||
|
||||
if (streq(type, "void")) {
|
||||
f_print(fout, "0");
|
||||
} else {
|
||||
f_print(fout, "sizeof ( ");
|
||||
/* XXX: should "follow" be 1 ??? */
|
||||
ptype(prefix, type, 0);
|
||||
f_print(fout, ")");
|
||||
}
|
||||
f_print(fout, ",\n");
|
||||
}
|
508
usr.bin/rpcgen/rpc_util.c
Normal file
508
usr.bin/rpcgen/rpc_util.c
Normal file
@ -0,0 +1,508 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ident "@(#)rpc_util.c 1.14 93/07/05 SMI"
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpc_util.c, Utility routines for the RPC protocol compiler
|
||||
* Copyright (C) 1989, Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "rpc_scan.h"
|
||||
#include "rpc_parse.h"
|
||||
#include "rpc_util.h"
|
||||
|
||||
#define ARGEXT "argument"
|
||||
|
||||
char curline[MAXLINESIZE]; /* current read line */
|
||||
char *where = curline; /* current point in line */
|
||||
int linenum = 0; /* current line number */
|
||||
|
||||
char *infilename; /* input filename */
|
||||
|
||||
#define NFILES 7
|
||||
char *outfiles[NFILES]; /* output file names */
|
||||
int nfiles;
|
||||
|
||||
FILE *fout; /* file pointer of current output */
|
||||
FILE *fin; /* file pointer of current input */
|
||||
|
||||
list *defined; /* list of defined things */
|
||||
|
||||
static int printwhere __P(( void ));
|
||||
|
||||
/*
|
||||
* Reinitialize the world
|
||||
*/
|
||||
reinitialize()
|
||||
{
|
||||
memset(curline, 0, MAXLINESIZE);
|
||||
where = curline;
|
||||
linenum = 0;
|
||||
defined = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* string equality
|
||||
*/
|
||||
streq(a, b)
|
||||
char *a;
|
||||
char *b;
|
||||
{
|
||||
return (strcmp(a, b) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* find a value in a list
|
||||
*/
|
||||
definition *
|
||||
findval(lst, val, cmp)
|
||||
list *lst;
|
||||
char *val;
|
||||
int (*cmp) ();
|
||||
|
||||
{
|
||||
for (; lst != NULL; lst = lst->next) {
|
||||
if ((*cmp) (lst->val, val)) {
|
||||
return (lst->val);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* store a value in a list
|
||||
*/
|
||||
void
|
||||
storeval(lstp, val)
|
||||
list **lstp;
|
||||
definition *val;
|
||||
{
|
||||
list **l;
|
||||
list *lst;
|
||||
|
||||
for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
|
||||
lst = ALLOC(list);
|
||||
lst->val = val;
|
||||
lst->next = NULL;
|
||||
*l = lst;
|
||||
}
|
||||
|
||||
static
|
||||
findit(def, type)
|
||||
definition *def;
|
||||
char *type;
|
||||
{
|
||||
return (streq(def->def_name, type));
|
||||
}
|
||||
|
||||
static char *
|
||||
fixit(type, orig)
|
||||
char *type;
|
||||
char *orig;
|
||||
{
|
||||
definition *def;
|
||||
|
||||
def = (definition *) FINDVAL(defined, type, findit);
|
||||
if (def == NULL || def->def_kind != DEF_TYPEDEF) {
|
||||
return (orig);
|
||||
}
|
||||
switch (def->def.ty.rel) {
|
||||
case REL_VECTOR:
|
||||
if (streq(def->def.ty.old_type, "opaque"))
|
||||
return ("char");
|
||||
else
|
||||
return (def->def.ty.old_type);
|
||||
|
||||
case REL_ALIAS:
|
||||
return (fixit(def->def.ty.old_type, orig));
|
||||
default:
|
||||
return (orig);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
fixtype(type)
|
||||
char *type;
|
||||
{
|
||||
return (fixit(type, type));
|
||||
}
|
||||
|
||||
char *
|
||||
stringfix(type)
|
||||
char *type;
|
||||
{
|
||||
if (streq(type, "string")) {
|
||||
return ("wrapstring");
|
||||
} else {
|
||||
return (type);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ptype(prefix, type, follow)
|
||||
char *prefix;
|
||||
char *type;
|
||||
int follow;
|
||||
{
|
||||
if (prefix != NULL) {
|
||||
if (streq(prefix, "enum")) {
|
||||
f_print(fout, "enum ");
|
||||
} else {
|
||||
f_print(fout, "struct ");
|
||||
}
|
||||
}
|
||||
if (streq(type, "bool")) {
|
||||
f_print(fout, "bool_t ");
|
||||
} else if (streq(type, "string")) {
|
||||
f_print(fout, "char *");
|
||||
} else {
|
||||
f_print(fout, "%s ", follow ? fixtype(type) : type);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
typedefed(def, type)
|
||||
definition *def;
|
||||
char *type;
|
||||
{
|
||||
if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
|
||||
return (0);
|
||||
} else {
|
||||
return (streq(def->def_name, type));
|
||||
}
|
||||
}
|
||||
|
||||
isvectordef(type, rel)
|
||||
char *type;
|
||||
relation rel;
|
||||
{
|
||||
definition *def;
|
||||
|
||||
for (;;) {
|
||||
switch (rel) {
|
||||
case REL_VECTOR:
|
||||
return (!streq(type, "string"));
|
||||
case REL_ARRAY:
|
||||
return (0);
|
||||
case REL_POINTER:
|
||||
return (0);
|
||||
case REL_ALIAS:
|
||||
def = (definition *) FINDVAL(defined, type, typedefed);
|
||||
if (def == NULL) {
|
||||
return (0);
|
||||
}
|
||||
type = def->def.ty.old_type;
|
||||
rel = def->def.ty.rel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
locase(str)
|
||||
char *str;
|
||||
{
|
||||
char c;
|
||||
static char buf[100];
|
||||
char *p = buf;
|
||||
|
||||
while (c = *str++) {
|
||||
*p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
|
||||
}
|
||||
*p = 0;
|
||||
return (buf);
|
||||
}
|
||||
|
||||
void
|
||||
pvname_svc(pname, vnum)
|
||||
char *pname;
|
||||
char *vnum;
|
||||
{
|
||||
f_print(fout, "%s_%s_svc", locase(pname), vnum);
|
||||
}
|
||||
|
||||
void
|
||||
pvname(pname, vnum)
|
||||
char *pname;
|
||||
char *vnum;
|
||||
{
|
||||
f_print(fout, "%s_%s", locase(pname), vnum);
|
||||
}
|
||||
|
||||
/*
|
||||
* print a useful (?) error message, and then die
|
||||
*/
|
||||
void
|
||||
error(msg)
|
||||
char *msg;
|
||||
{
|
||||
printwhere();
|
||||
f_print(stderr, "%s, line %d: ", infilename, linenum);
|
||||
f_print(stderr, "%s\n", msg);
|
||||
crash();
|
||||
}
|
||||
|
||||
/*
|
||||
* Something went wrong, unlink any files that we may have created and then
|
||||
* die.
|
||||
*/
|
||||
crash()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nfiles; i++) {
|
||||
(void) unlink(outfiles[i]);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
record_open(file)
|
||||
char *file;
|
||||
{
|
||||
if (nfiles < NFILES) {
|
||||
outfiles[nfiles++] = file;
|
||||
} else {
|
||||
f_print(stderr, "too many files!\n");
|
||||
crash();
|
||||
}
|
||||
}
|
||||
|
||||
static char expectbuf[100];
|
||||
static char *toktostr();
|
||||
|
||||
/*
|
||||
* error, token encountered was not the expected one
|
||||
*/
|
||||
void
|
||||
expected1(exp1)
|
||||
tok_kind exp1;
|
||||
{
|
||||
s_print(expectbuf, "expected '%s'",
|
||||
toktostr(exp1));
|
||||
error(expectbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* error, token encountered was not one of two expected ones
|
||||
*/
|
||||
void
|
||||
expected2(exp1, exp2)
|
||||
tok_kind exp1, exp2;
|
||||
{
|
||||
s_print(expectbuf, "expected '%s' or '%s'",
|
||||
toktostr(exp1),
|
||||
toktostr(exp2));
|
||||
error(expectbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* error, token encountered was not one of 3 expected ones
|
||||
*/
|
||||
void
|
||||
expected3(exp1, exp2, exp3)
|
||||
tok_kind exp1, exp2, exp3;
|
||||
{
|
||||
s_print(expectbuf, "expected '%s', '%s' or '%s'",
|
||||
toktostr(exp1),
|
||||
toktostr(exp2),
|
||||
toktostr(exp3));
|
||||
error(expectbuf);
|
||||
}
|
||||
|
||||
void
|
||||
tabify(f, tab)
|
||||
FILE *f;
|
||||
int tab;
|
||||
{
|
||||
while (tab--) {
|
||||
(void) fputc('\t', f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static token tokstrings[] = {
|
||||
{TOK_IDENT, "identifier"},
|
||||
{TOK_CONST, "const"},
|
||||
{TOK_RPAREN, ")"},
|
||||
{TOK_LPAREN, "("},
|
||||
{TOK_RBRACE, "}"},
|
||||
{TOK_LBRACE, "{"},
|
||||
{TOK_LBRACKET, "["},
|
||||
{TOK_RBRACKET, "]"},
|
||||
{TOK_STAR, "*"},
|
||||
{TOK_COMMA, ","},
|
||||
{TOK_EQUAL, "="},
|
||||
{TOK_COLON, ":"},
|
||||
{TOK_SEMICOLON, ";"},
|
||||
{TOK_UNION, "union"},
|
||||
{TOK_STRUCT, "struct"},
|
||||
{TOK_SWITCH, "switch"},
|
||||
{TOK_CASE, "case"},
|
||||
{TOK_DEFAULT, "default"},
|
||||
{TOK_ENUM, "enum"},
|
||||
{TOK_TYPEDEF, "typedef"},
|
||||
{TOK_INT, "int"},
|
||||
{TOK_SHORT, "short"},
|
||||
{TOK_LONG, "long"},
|
||||
{TOK_UNSIGNED, "unsigned"},
|
||||
{TOK_DOUBLE, "double"},
|
||||
{TOK_FLOAT, "float"},
|
||||
{TOK_CHAR, "char"},
|
||||
{TOK_STRING, "string"},
|
||||
{TOK_OPAQUE, "opaque"},
|
||||
{TOK_BOOL, "bool"},
|
||||
{TOK_VOID, "void"},
|
||||
{TOK_PROGRAM, "program"},
|
||||
{TOK_VERSION, "version"},
|
||||
{TOK_EOF, "??????"}
|
||||
};
|
||||
|
||||
static char *
|
||||
toktostr(kind)
|
||||
tok_kind kind;
|
||||
{
|
||||
token *sp;
|
||||
|
||||
for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
|
||||
return (sp->str);
|
||||
}
|
||||
|
||||
static
|
||||
printbuf()
|
||||
{
|
||||
char c;
|
||||
int i;
|
||||
int cnt;
|
||||
|
||||
# define TABSIZE 4
|
||||
|
||||
for (i = 0; c = curline[i]; i++) {
|
||||
if (c == '\t') {
|
||||
cnt = 8 - (i % TABSIZE);
|
||||
c = ' ';
|
||||
} else {
|
||||
cnt = 1;
|
||||
}
|
||||
while (cnt--) {
|
||||
(void) fputc(c, stderr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
printwhere()
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
int cnt;
|
||||
|
||||
printbuf();
|
||||
for (i = 0; i < where - curline; i++) {
|
||||
c = curline[i];
|
||||
if (c == '\t') {
|
||||
cnt = 8 - (i % TABSIZE);
|
||||
} else {
|
||||
cnt = 1;
|
||||
}
|
||||
while (cnt--) {
|
||||
(void) fputc('^', stderr);
|
||||
}
|
||||
}
|
||||
(void) fputc('\n', stderr);
|
||||
}
|
||||
|
||||
char *
|
||||
make_argname(pname, vname)
|
||||
char *pname;
|
||||
char *vname;
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3);
|
||||
if (!name) {
|
||||
fprintf(stderr, "failed in malloc");
|
||||
exit(1);
|
||||
}
|
||||
sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
|
||||
return (name);
|
||||
}
|
||||
|
||||
bas_type *typ_list_h;
|
||||
bas_type *typ_list_t;
|
||||
|
||||
add_type(len, type)
|
||||
int len;
|
||||
char *type;
|
||||
{
|
||||
bas_type *ptr;
|
||||
|
||||
if ((ptr = (bas_type *) malloc(sizeof (bas_type))) ==
|
||||
(bas_type *)NULL) {
|
||||
fprintf(stderr, "failed in malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ptr->name = type;
|
||||
ptr->length = len;
|
||||
ptr->next = NULL;
|
||||
if (typ_list_t == NULL)
|
||||
{
|
||||
|
||||
typ_list_t = ptr;
|
||||
typ_list_h = ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
typ_list_t->next = ptr;
|
||||
typ_list_t = ptr;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
bas_type *find_type(type)
|
||||
char *type;
|
||||
{
|
||||
bas_type * ptr;
|
||||
|
||||
ptr = typ_list_h;
|
||||
while (ptr != NULL)
|
||||
{
|
||||
if (strcmp(ptr->name, type) == 0)
|
||||
return (ptr);
|
||||
else
|
||||
ptr = ptr->next;
|
||||
};
|
||||
return (NULL);
|
||||
}
|
209
usr.bin/rpcgen/rpc_util.h
Normal file
209
usr.bin/rpcgen/rpc_util.h
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
#pragma ident "@(#)rpc_util.h 1.16 94/05/15 SMI"
|
||||
|
||||
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||||
/* All Rights Reserved */
|
||||
|
||||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||||
/* The copyright notice above does not evidence any */
|
||||
/* actual or intended publication of such source code. */
|
||||
|
||||
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* PROPRIETARY NOTICE (Combined)
|
||||
*
|
||||
* This source code is unpublished proprietary information
|
||||
* constituting, or derived under license from AT&T's UNIX(r) System V.
|
||||
* In addition, portions of such source code were derived from Berkeley
|
||||
* 4.3 BSD under license from the Regents of the University of
|
||||
* California.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright Notice
|
||||
*
|
||||
* Notice of copyright on this source code product does not indicate
|
||||
* publication.
|
||||
*
|
||||
* (c) 1986,1987,1988.1989 Sun Microsystems, Inc
|
||||
* (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/* @(#)rpc_util.h 1.5 90/08/29 (C) 1987 SMI */
|
||||
|
||||
/*
|
||||
* rpc_util.h, Useful definitions for the RPC protocol compiler
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define alloc(size) malloc((unsigned)(size))
|
||||
#define ALLOC(object) (object *) malloc(sizeof(object))
|
||||
|
||||
#define s_print (void) sprintf
|
||||
#define f_print (void) fprintf
|
||||
|
||||
struct list {
|
||||
definition *val;
|
||||
struct list *next;
|
||||
};
|
||||
typedef struct list list;
|
||||
|
||||
struct xdrfunc {
|
||||
char *name;
|
||||
int pointerp;
|
||||
struct xdrfunc *next;
|
||||
};
|
||||
typedef struct xdrfunc xdrfunc;
|
||||
|
||||
struct commandline {
|
||||
int cflag; /* xdr C routines */
|
||||
int hflag; /* header file */
|
||||
int lflag; /* client side stubs */
|
||||
int mflag; /* server side stubs */
|
||||
int nflag; /* netid flag */
|
||||
int sflag; /* server stubs for the given transport */
|
||||
int tflag; /* dispatch Table file */
|
||||
int Ssflag; /* produce server sample code */
|
||||
int Scflag; /* produce client sample code */
|
||||
int makefileflag; /* Generate a template Makefile */
|
||||
char *infile; /* input module name */
|
||||
char *outfile; /* output module name */
|
||||
};
|
||||
|
||||
#define PUT 1
|
||||
#define GET 2
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
#define MAXLINESIZE 1024
|
||||
extern char curline[MAXLINESIZE];
|
||||
extern char *where;
|
||||
extern int linenum;
|
||||
|
||||
extern char *infilename;
|
||||
extern FILE *fout;
|
||||
extern FILE *fin;
|
||||
|
||||
extern list *defined;
|
||||
|
||||
|
||||
extern bas_type *typ_list_h;
|
||||
extern bas_type *typ_list_t;
|
||||
extern xdrfunc *xdrfunc_head, *xdrfunc_tail;
|
||||
|
||||
/*
|
||||
* All the option flags
|
||||
*/
|
||||
extern int inetdflag;
|
||||
extern int pmflag;
|
||||
extern int tblflag;
|
||||
extern int logflag;
|
||||
extern int newstyle;
|
||||
extern int Cflag; /* ANSI-C/C++ flag */
|
||||
extern int CCflag; /* C++ flag */
|
||||
extern int tirpcflag; /* flag for generating tirpc code */
|
||||
extern int inline; /* if this is 0, then do not generate inline code */
|
||||
extern int mtflag;
|
||||
|
||||
/*
|
||||
* Other flags related with inetd jumpstart.
|
||||
*/
|
||||
extern int indefinitewait;
|
||||
extern int exitnow;
|
||||
extern int timerflag;
|
||||
|
||||
extern int nonfatalerrors;
|
||||
|
||||
extern pid_t childpid;
|
||||
|
||||
/*
|
||||
* rpc_util routines
|
||||
*/
|
||||
void storeval();
|
||||
|
||||
#define STOREVAL(list,item) \
|
||||
storeval(list,item)
|
||||
|
||||
definition *findval();
|
||||
|
||||
#define FINDVAL(list,item,finder) \
|
||||
findval(list, item, finder)
|
||||
|
||||
char *fixtype();
|
||||
char *stringfix();
|
||||
char *locase();
|
||||
void pvname_svc();
|
||||
void pvname();
|
||||
void ptype();
|
||||
int isvectordef();
|
||||
int streq();
|
||||
void error();
|
||||
void expected1();
|
||||
void expected2();
|
||||
void expected3();
|
||||
void tabify();
|
||||
void record_open();
|
||||
bas_type *find_type();
|
||||
/*
|
||||
* rpc_cout routines
|
||||
*/
|
||||
void cprint();
|
||||
void emit();
|
||||
|
||||
/*
|
||||
* rpc_hout routines
|
||||
*/
|
||||
void print_datadef();
|
||||
void print_funcdef();
|
||||
void print_xdr_func_def();
|
||||
|
||||
/*
|
||||
* rpc_svcout routines
|
||||
*/
|
||||
void write_most();
|
||||
void write_register();
|
||||
void write_rest();
|
||||
void write_programs();
|
||||
void write_svc_aux();
|
||||
void write_inetd_register();
|
||||
void write_netid_register();
|
||||
void write_nettype_register();
|
||||
/*
|
||||
* rpc_clntout routines
|
||||
*/
|
||||
void write_stubs();
|
||||
|
||||
/*
|
||||
* rpc_tblout routines
|
||||
*/
|
||||
void write_tables();
|
554
usr.bin/rpcgen/rpcgen.1
Normal file
554
usr.bin/rpcgen/rpcgen.1
Normal file
@ -0,0 +1,554 @@
|
||||
.\" @(#)rpcgen.1 1.35 93/06/02 SMI
|
||||
'\"macro stdmacro
|
||||
.\" Copyright 1985-1993 Sun Microsystems, Inc.
|
||||
.nr X
|
||||
.TH rpcgen 1 "28 Mar 1993"
|
||||
.SH NAME
|
||||
rpcgen \- an RPC protocol compiler
|
||||
.SH SYNOPSIS
|
||||
.BI rpcgen " infile"
|
||||
.LP
|
||||
.B rpcgen
|
||||
[
|
||||
.B \-a
|
||||
] [
|
||||
.B \-b
|
||||
] [
|
||||
.B \-C
|
||||
] [
|
||||
.BI \-D name
|
||||
[ =
|
||||
.I value
|
||||
] ]
|
||||
.if n .ti +5n
|
||||
[
|
||||
.BI \-i " size"
|
||||
]
|
||||
[
|
||||
.B \-I
|
||||
[
|
||||
.BI \-K " seconds"
|
||||
] ]
|
||||
[
|
||||
.B \-L
|
||||
] [
|
||||
.B \-M
|
||||
]
|
||||
.if n .ti +5n
|
||||
.if t .ti +5n
|
||||
[
|
||||
.B \-N
|
||||
]
|
||||
[
|
||||
.B \-T
|
||||
] [
|
||||
.BI \-Y " pathname"
|
||||
]
|
||||
.I infile
|
||||
.LP
|
||||
.B rpcgen
|
||||
[
|
||||
.B \-c
|
||||
|
|
||||
.B \-h
|
||||
|
|
||||
.B \-l
|
||||
|
|
||||
.B \-m
|
||||
|
|
||||
.B \-t
|
||||
|
|
||||
.B \-Sc
|
||||
|
|
||||
.B \-Ss
|
||||
|
|
||||
.B \-Sm
|
||||
]
|
||||
.if n .ti +5n
|
||||
[
|
||||
.BI \-o " outfile"
|
||||
] [
|
||||
.I infile
|
||||
]
|
||||
.LP
|
||||
.B rpcgen
|
||||
[
|
||||
.BI \-s " nettype"
|
||||
] [
|
||||
.BI \-o " outfile"
|
||||
] [
|
||||
.I infile
|
||||
]
|
||||
.LP
|
||||
.B rpcgen
|
||||
[
|
||||
.BI \-n " netid"
|
||||
] [
|
||||
.BI \-o " outfile"
|
||||
] [
|
||||
.I infile
|
||||
]
|
||||
.\" .SH AVAILABILITY
|
||||
.\" .LP
|
||||
.\" SUNWcsu
|
||||
.SH DESCRIPTION
|
||||
.IX "rpcgen" "" "\fLrpcgen\fP \(em RPC protocol compiler"
|
||||
.IX "RPC" "protocol compiler" "" "protocol compiler \(em \fLrpcgen\fP"
|
||||
.IX "RPC Language" "RPC protocol compiler" "" "RPC protocol compiler \(em \fLrpcgen\fP"
|
||||
.IX "compilers" "RPC protocol compiler" "" "RPC protocol compiler \(em \fLrpcgen\fP"
|
||||
.IX "programming tools" "RPC protocol compiler" "" "RPC protocol compiler \(em \fLrpcgen\fP"
|
||||
.LP
|
||||
\f3rpcgen\f1
|
||||
is a tool that generates C code to implement an RPC protocol.
|
||||
The input to
|
||||
\f3rpcgen\f1
|
||||
is a language similar to C known as
|
||||
RPC Language (Remote Procedure Call Language).
|
||||
.LP
|
||||
\f3rpcgen\f1
|
||||
is normally used as in the first synopsis where
|
||||
it takes an input file and generates three output files.
|
||||
If the
|
||||
\f2infile\f1
|
||||
is named
|
||||
\f3proto.x\f1,
|
||||
then
|
||||
\f3rpcgen\f1
|
||||
generates a header in
|
||||
\f3proto.h\f1,
|
||||
XDR routines in
|
||||
\f3proto_xdr.c\f1,
|
||||
server-side stubs in
|
||||
\f3proto_svc.c\f1,
|
||||
and client-side stubs in
|
||||
\f3proto_clnt.c\f1.
|
||||
With the
|
||||
\f3\-T\f1
|
||||
option,
|
||||
it also generates the RPC dispatch table in
|
||||
\f3proto_tbl.i\f1.
|
||||
.LP
|
||||
.B rpcgen
|
||||
can also generate sample client and server files
|
||||
that can be customized to suit a particular application. The
|
||||
\f3\-Sc\f1,
|
||||
\f3\-Ss\f1
|
||||
and
|
||||
\f3\-Sm\f1
|
||||
options generate sample client, server and makefile, respectively.
|
||||
The
|
||||
\f3\-a\f1
|
||||
option generates all files, including sample files. If the infile
|
||||
is \f3proto.x\f1, then the client side sample file is written to
|
||||
\f3proto_client.c\f1, the server side sample file to \f3proto_server.c\f1
|
||||
and the sample makefile to \f3makefile.proto\f1.
|
||||
.LP
|
||||
The server created can be started both by the port monitors
|
||||
(for example, \f3inetd\f1 or \f3listen\f1)
|
||||
or by itself.
|
||||
When it is started by a port monitor,
|
||||
it creates servers only for the transport for which
|
||||
the file descriptor \f30\fP was passed.
|
||||
The name of the transport must be specified
|
||||
by setting up the environment variable
|
||||
\f3PM_TRANSPORT\f1.
|
||||
When the server generated by
|
||||
\f3rpcgen\f1
|
||||
is executed,
|
||||
it creates server handles for all the transports
|
||||
specified in
|
||||
\f3NETPATH\f1
|
||||
environment variable,
|
||||
or if it is unset,
|
||||
it creates server handles for all the visible transports from
|
||||
\f3/etc/netconfig\f1
|
||||
file.
|
||||
Note:
|
||||
the transports are chosen at run time and not at compile time.
|
||||
When the server is self-started,
|
||||
it backgrounds itself by default.
|
||||
A special define symbol
|
||||
\f3RPC_SVC_FG\f1
|
||||
can be used to run the server process in foreground.
|
||||
.LP
|
||||
The second synopsis provides special features which allow
|
||||
for the creation of more sophisticated RPC servers.
|
||||
These features include support for user provided
|
||||
\f3#defines\f1
|
||||
and RPC dispatch tables.
|
||||
The entries in the RPC dispatch table contain:
|
||||
.RS
|
||||
.PD 0
|
||||
.TP 3
|
||||
\(bu
|
||||
pointers to the service routine corresponding to that procedure,
|
||||
.TP
|
||||
\(bu
|
||||
a pointer to the input and output arguments
|
||||
.TP
|
||||
\(bu
|
||||
the size of these routines
|
||||
.PD
|
||||
.RE
|
||||
A server can use the dispatch table to check authorization
|
||||
and then to execute the service routine;
|
||||
a client library may use it to deal with the details of storage
|
||||
management and XDR data conversion.
|
||||
.LP
|
||||
The other three synopses shown above are used when
|
||||
one does not want to generate all the output files,
|
||||
but only a particular one.
|
||||
See the
|
||||
.SM EXAMPLES
|
||||
section below for examples of
|
||||
.B rpcgen
|
||||
usage.
|
||||
When
|
||||
\f3rpcgen\f1
|
||||
is executed with the
|
||||
\f3\-s\f1
|
||||
option,
|
||||
it creates servers for that particular class of transports.
|
||||
When
|
||||
executed with the
|
||||
\f3\-n\f1
|
||||
option,
|
||||
it creates a server for the transport specified by
|
||||
\f2netid\f1.
|
||||
If
|
||||
\f2infile\f1
|
||||
is not specified,
|
||||
\f3rpcgen\f1
|
||||
accepts the standard input.
|
||||
.LP
|
||||
The C preprocessor,
|
||||
\f3cc \-E\f1
|
||||
is run on the input file before it is actually interpreted by
|
||||
\f3rpcgen\f1.
|
||||
For each type of output file,
|
||||
\f3rpcgen\f1
|
||||
defines a special preprocessor symbol for use by the
|
||||
\f3rpcgen\f1
|
||||
programmer:
|
||||
.LP
|
||||
.PD 0
|
||||
.RS
|
||||
.TP 12
|
||||
\f3RPC_HDR\f1
|
||||
defined when compiling into headers
|
||||
.TP
|
||||
\f3RPC_XDR\f1
|
||||
defined when compiling into XDR routines
|
||||
.TP
|
||||
\f3RPC_SVC\f1
|
||||
defined when compiling into server-side stubs
|
||||
.TP
|
||||
\f3RPC_CLNT\f1
|
||||
defined when compiling into client-side stubs
|
||||
.TP
|
||||
\f3RPC_TBL\f1
|
||||
defined when compiling into RPC dispatch tables
|
||||
.RE
|
||||
.PD
|
||||
.LP
|
||||
Any line beginning with
|
||||
``\f3%\f1''
|
||||
is passed directly into the output file,
|
||||
uninterpreted by
|
||||
\f3rpcgen\f1.
|
||||
To specify the path name of the C preprocessor use \f3\-Y\f1 flag.
|
||||
.LP
|
||||
For every data type referred to in
|
||||
\f2infile\f1,
|
||||
\f3rpcgen\f1
|
||||
assumes that there exists a
|
||||
routine with the string
|
||||
\f3xdr_\f1
|
||||
prepended to the name of the data type.
|
||||
If this routine does not exist in the RPC/XDR
|
||||
library, it must be provided.
|
||||
Providing an undefined data type
|
||||
allows customization of XDR routines.
|
||||
.br
|
||||
.ne 10
|
||||
.SH OPTIONS
|
||||
.TP 15
|
||||
\f3\-a\f1
|
||||
Generate all files, including sample files.
|
||||
.TP
|
||||
\f3\-b\f1
|
||||
Backward compatibility mode.
|
||||
Generate transport specific RPC code for older versions
|
||||
of the operating system.
|
||||
.IP
|
||||
Note: in FreeBSD, this compatibility flag is turned on by
|
||||
default since FreeBSD supports only the older ONC RPC library.
|
||||
.TP
|
||||
\f3\-c\f1
|
||||
Compile into XDR routines.
|
||||
.TP
|
||||
\f3\-C\f1
|
||||
Generate header and stub files which can be used with
|
||||
.SM ANSI C
|
||||
compilers. Headers generated with this flag can also be
|
||||
used with C++ programs.
|
||||
.TP
|
||||
\f3\-D\f2name\f3[=\f2value\f3]\f1
|
||||
Define a symbol
|
||||
\f2name\f1.
|
||||
Equivalent to the
|
||||
\f3#define\f1
|
||||
directive in the source.
|
||||
If no
|
||||
\f2value\f1
|
||||
is given,
|
||||
\f2value\f1
|
||||
is defined as \f31\f1.
|
||||
This option may be specified more than once.
|
||||
.TP
|
||||
\f3\-h\f1
|
||||
Compile into
|
||||
\f3C\f1
|
||||
data-definitions (a header).
|
||||
\f3\-T\f1
|
||||
option can be used in conjunction to produce a
|
||||
header which supports RPC dispatch tables.
|
||||
.TP
|
||||
\f3\-i \f2size\f1
|
||||
Size at which to start generating inline code.
|
||||
This option is useful for optimization. The default size is 5.
|
||||
.IP
|
||||
Note: in order to provide backwards compatibility with the older
|
||||
.B rpcgen
|
||||
on the FreeBSD platform, the default is actually 0 (which means
|
||||
that inline code generation is disabled by default). You must specify
|
||||
a non-zero value explicitly to override this default.
|
||||
.TP
|
||||
\f3\-I\f1
|
||||
Compile support for
|
||||
.BR inetd (1M)
|
||||
in the server side stubs.
|
||||
Such servers can be self-started or can be started by \f3inetd\f1.
|
||||
When the server is self-started, it backgrounds itself by default.
|
||||
A special define symbol \f3RPC_SVC_FG\f1 can be used to run the
|
||||
server process in foreground, or the user may simply compile without
|
||||
the \f3\-I\f1 option.
|
||||
.br
|
||||
.ne 5
|
||||
.IP
|
||||
If there are no pending client requests, the
|
||||
\f3inetd\f1 servers exit after 120 seconds (default).
|
||||
The default can be changed with the
|
||||
.B \-K
|
||||
option.
|
||||
All the error messages for \f3inetd\f1 servers
|
||||
are always logged with
|
||||
.BR syslog (3).
|
||||
.\" .IP
|
||||
.\" Note:
|
||||
.\" this option is supported for backward compatibility only.
|
||||
.\" By default,
|
||||
.\" .B rpcgen
|
||||
.\" generates servers that can be invoked through portmonitors.
|
||||
.TP
|
||||
.BI \-K " seconds"
|
||||
By default, services created using \f3rpcgen\fP and invoked through
|
||||
port monitors wait \f3120\fP seconds
|
||||
after servicing a request before exiting.
|
||||
That interval can be changed using the \f3\-K\fP flag.
|
||||
To create a server that exits immediately upon servicing a request,
|
||||
use
|
||||
.BR "\-K\ 0".
|
||||
To create a server that never exits, the appropriate argument is
|
||||
\f3\-K \-1\fP.
|
||||
.IP
|
||||
When monitoring for a server,
|
||||
some portmonitors, like
|
||||
.BR listen (1M),
|
||||
.I always
|
||||
spawn a new process in response to a service request.
|
||||
If it is known that a server will be used with such a monitor, the
|
||||
server should exit immediately on completion.
|
||||
For such servers, \f3rpcgen\fP should be used with \f3\-K 0\fP.
|
||||
.TP
|
||||
\f3\-l\f1
|
||||
Compile into client-side stubs.
|
||||
.TP
|
||||
.B \-L
|
||||
When the servers are started in foreground, use
|
||||
.BR syslog (3)
|
||||
to log the server errors instead of printing them on the standard
|
||||
error.
|
||||
.TP
|
||||
\f3\-m\f1
|
||||
Compile into server-side stubs,
|
||||
but do not generate a \(lqmain\(rq routine.
|
||||
This option is useful for doing callback-routines
|
||||
and for users who need to write their own
|
||||
\(lqmain\(rq routine to do initialization.
|
||||
.TP
|
||||
\f3\-M\f1
|
||||
Generate multithread-safe stubs for passing arguments and results between
|
||||
rpcgen generated code and user written code. This option is useful
|
||||
for users who want to use threads in their code. However, the
|
||||
.BR rpc_svc_calls (3N)
|
||||
functions are not yet MT-safe, which means that rpcgen generated server-side
|
||||
code will not be MT-safe.
|
||||
.TP
|
||||
.B \-N
|
||||
This option allows procedures to have multiple arguments.
|
||||
It also uses the style of parameter passing that closely resembles C.
|
||||
So, when passing an argument to a remote procedure, you do not have to
|
||||
pass a pointer to the argument, but can pass the argument itself.
|
||||
This behavior is different from the old style of
|
||||
.B rpcgen
|
||||
generated code.
|
||||
To maintain backward compatibility,
|
||||
this option is not the default.
|
||||
.TP
|
||||
\f3\-n \f2netid\f1
|
||||
Compile into server-side stubs for the transport
|
||||
specified by
|
||||
\f2netid\f1.
|
||||
There should be an entry for
|
||||
\f2netid\f1
|
||||
in the
|
||||
netconfig database.
|
||||
This option may be specified more than once,
|
||||
so as to compile a server that serves multiple transports.
|
||||
.TP
|
||||
\f3\-o \f2outfile\f1
|
||||
Specify the name of the output file.
|
||||
If none is specified,
|
||||
standard output is used
|
||||
(\f3\-c\f1,
|
||||
\f3\-h\f1,
|
||||
\f3\-l\f1,
|
||||
\f3\-m\f1,
|
||||
\f3\-n\f1,
|
||||
\f3\-s\f1,
|
||||
\f3\-Sc\f1,
|
||||
\f3\-Sm\f1,
|
||||
\f3\-Ss\f1,
|
||||
and
|
||||
\f3\-t\f1
|
||||
modes only).
|
||||
.TP
|
||||
\f3\-s \f2nettype\f1
|
||||
Compile into server-side stubs for all the
|
||||
transports belonging to the class
|
||||
\f2nettype\f1.
|
||||
The supported classes are
|
||||
\f3netpath\f1,
|
||||
\f3visible\f1,
|
||||
\f3circuit_n\f1,
|
||||
\f3circuit_v\f1,
|
||||
\f3datagram_n\f1,
|
||||
\f3datagram_v\f1,
|
||||
\f3tcp\f1,
|
||||
and
|
||||
\f3udp\f1
|
||||
(see
|
||||
.BR rpc (3N)
|
||||
for the meanings associated with these classes).
|
||||
This option may be specified more than once.
|
||||
Note:
|
||||
the transports are chosen at run time and not at compile time.
|
||||
.TP
|
||||
\f3\-Sc\f1
|
||||
Generate sample client code that uses remote procedure calls.
|
||||
.br
|
||||
.ne 5
|
||||
.TP
|
||||
\f3\-Sm\f1
|
||||
Generate a sample Makefile which can be used for compiling the
|
||||
application.
|
||||
.TP
|
||||
\f3\-Ss\f1
|
||||
Generate sample server code that uses remote procedure calls.
|
||||
.TP
|
||||
\f3\-t\f1
|
||||
Compile into RPC dispatch table.
|
||||
.TP
|
||||
\f3\-T\f1
|
||||
Generate the code to support RPC dispatch tables.
|
||||
.IP
|
||||
The options
|
||||
\f3\-c\f1,
|
||||
\f3\-h\f1,
|
||||
\f3\-l\f1,
|
||||
\f3\-m\f1,
|
||||
\f3\-s\f1,
|
||||
\f3\-Sc\f1,
|
||||
\f3\-Sm\f1,
|
||||
\f3\-Ss\f1,
|
||||
and
|
||||
\f3\-t\f1
|
||||
are used exclusively to generate a particular type of file,
|
||||
while the options
|
||||
\f3\-D\f1
|
||||
and
|
||||
\f3\-T\f1
|
||||
are global and can be used with the other options.
|
||||
.TP
|
||||
\f3\-Y\f2 pathname\f1
|
||||
Give the name of the directory where
|
||||
.B rpcgen
|
||||
will start looking for the C-preprocessor.
|
||||
.br
|
||||
.ne 5
|
||||
.SH EXAMPLES
|
||||
The following example:
|
||||
.LP
|
||||
.RS
|
||||
.B example% rpcgen \-T prot.x
|
||||
.RE
|
||||
.LP
|
||||
generates all the five files:
|
||||
.BR prot.h ,
|
||||
.BR prot_clnt.c ,
|
||||
.BR prot_svc.c ,
|
||||
.B prot_xdr.c
|
||||
and
|
||||
.BR prot_tbl.i .
|
||||
.LP
|
||||
The following example sends the C data-definitions (header)
|
||||
to the standard output.
|
||||
.LP
|
||||
.RS
|
||||
.B example% rpcgen \-h prot.x
|
||||
.RE
|
||||
.LP
|
||||
To send the test version of the
|
||||
.BR -DTEST ,
|
||||
server side stubs for
|
||||
all the transport belonging to the class
|
||||
.B datagram_n
|
||||
to standard output, use:
|
||||
.LP
|
||||
.RS
|
||||
.B example% rpcgen \-s datagram_n \-DTEST prot.x
|
||||
.RE
|
||||
.LP
|
||||
To create the server side stubs for the transport indicated
|
||||
by
|
||||
\f2netid\f1
|
||||
\f3tcp\f1,
|
||||
use:
|
||||
.LP
|
||||
.RS
|
||||
.B example% rpcgen \-n tcp \-o prot_svc.c prot.x
|
||||
.RE
|
||||
.SH "SEE ALSO"
|
||||
.BR cc (1B),
|
||||
.BR inetd (1M),
|
||||
.BR listen (1M),
|
||||
.BR syslog (3),
|
||||
.BR rpc (3N),
|
||||
.\" .BR rpc_svc_calls (3N)
|
||||
.LP
|
||||
The
|
||||
.B rpcgen
|
||||
chapter in the
|
||||
.TZ NETP
|
||||
manual.
|
Loading…
Reference in New Issue
Block a user