📄 gen_rpc.awk
字号:
## $Id: gen_rpc.awk,v 11.50 2002/07/02 19:26:57 sue Exp $# Awk script for generating client/server RPC code.## This awk script generates most of the RPC routines for DB client/server# use. It also generates a template for server and client procedures. These# functions must still be edited, but are highly stylized and the initial# template gets you a fair way along the path).## This awk script requires that these variables be set when it is called:## major -- Major version number# minor -- Minor version number# xidsize -- size of GIDs# client_file -- the C source file being created for client code# ctmpl_file -- the C template file being created for client code# sed_file -- the sed file created to alter server proc code# server_file -- the C source file being created for server code# stmpl_file -- the C template file being created for server code# xdr_file -- the XDR message file created## And stdin must be the input file that defines the RPC setup.BEGIN { if (major == "" || minor == "" || xidsize == "" || client_file == "" || ctmpl_file == "" || sed_file == "" || server_file == "" || stmpl_file == "" || xdr_file == "") { print "Usage: gen_rpc.awk requires these variables be set:" print "\tmajor\t-- Major version number" print "\tminor\t-- Minor version number" print "\txidsize\t-- GID size" print "\tclient_file\t-- the client C source file being created" print "\tctmpl_file\t-- the client template file being created" print "\tsed_file\t-- the sed command file being created" print "\tserver_file\t-- the server C source file being created" print "\tstmpl_file\t-- the server template file being created" print "\txdr_file\t-- the XDR message file being created" error = 1; exit } FS="\t\t*" CFILE=client_file printf("/* Do not edit: automatically built by gen_rpc.awk. */\n") \ > CFILE TFILE = ctmpl_file printf("/* Do not edit: automatically built by gen_rpc.awk. */\n") \ > TFILE SFILE = server_file printf("/* Do not edit: automatically built by gen_rpc.awk. */\n") \ > SFILE # Server procedure template and a sed file to massage an existing # template source file to change args. # SEDFILE should be same name as PFILE but .c # PFILE = stmpl_file SEDFILE = sed_file printf("") > SEDFILE printf("/* Do not edit: automatically built by gen_rpc.awk. */\n") \ > PFILE XFILE = xdr_file printf("/* Do not edit: automatically built by gen_rpc.awk. */\n") \ > XFILE nendlist = 1;}END { printf("#endif /* HAVE_RPC */\n") >> CFILE printf("#endif /* HAVE_RPC */\n") >> TFILE printf("program DB_RPC_SERVERPROG {\n") >> XFILE printf("\tversion DB_RPC_SERVERVERS {\n") >> XFILE for (i = 1; i < nendlist; ++i) printf("\t\t%s;\n", endlist[i]) >> XFILE printf("\t} = %d%03d;\n", major, minor) >> XFILE printf("} = 351457;\n") >> XFILE}/^[ ]*BEGIN/ { name = $2; nofunc_code = 0; funcvars = 0; ret_code = 0; if ($3 == "NOFUNC") nofunc_code = 1; if ($3 == "RETCODE") ret_code = 1; nvars = 0; rvars = 0; newvars = 0; db_handle = 0; env_handle = 0; dbc_handle = 0; txn_handle = 0; mp_handle = 0; dbt_handle = 0; xdr_free = 0;}/^[ ]*ARG/ { rpc_type[nvars] = $2; c_type[nvars] = $3; pr_type[nvars] = $3; args[nvars] = $4; func_arg[nvars] = 0; if (rpc_type[nvars] == "LIST") { list_type[nvars] = $5; } else list_type[nvars] = 0; if (c_type[nvars] == "DBT *") dbt_handle = 1; if (c_type[nvars] == "DB_ENV *") { ctp_type[nvars] = "CT_ENV"; env_handle = 1; env_idx = nvars; } if (c_type[nvars] == "DB *") { ctp_type[nvars] = "CT_DB"; if (db_handle != 1) { db_handle = 1; db_idx = nvars; } } if (c_type[nvars] == "DBC *") { ctp_type[nvars] = "CT_CURSOR"; dbc_handle = 1; dbc_idx = nvars; } if (c_type[nvars] == "DB_TXN *") { ctp_type[nvars] = "CT_TXN"; txn_handle = 1; txn_idx = nvars; } if (c_type[nvars] == "DB_MPOOLFILE *") { mp_handle = 1; mp_idx = nvars; } ++nvars;}/^[ ]*FUNCPROT/ { pr_type[nvars] = $2;}/^[ ]*FUNCARG/ { rpc_type[nvars] = "IGNORE"; c_type[nvars] = $2; args[nvars] = sprintf("func%d", funcvars); func_arg[nvars] = 1; ++funcvars; ++nvars;}/^[ ]*RET/ { ret_type[rvars] = $2; retc_type[rvars] = $3; retargs[rvars] = $4; if (ret_type[rvars] == "LIST" || ret_type[rvars] == "DBT") { xdr_free = 1; } if (ret_type[rvars] == "LIST") { retlist_type[rvars] = $5; } else retlist_type[rvars] = 0; ++rvars;}/^[ ]*END/ { # # ===================================================== # File headers, if necessary. # if (first == 0) { printf("#include \"db_config.h\"\n") >> CFILE printf("\n") >> CFILE printf("#ifdef HAVE_RPC\n") >> CFILE printf("#ifndef NO_SYSTEM_INCLUDES\n") >> CFILE printf("#include <sys/types.h>\n\n") >> CFILE printf("#include <rpc/rpc.h>\n") >> CFILE printf("#include <rpc/xdr.h>\n") >> CFILE printf("\n") >> CFILE printf("#include <string.h>\n") >> CFILE printf("#endif\n") >> CFILE printf("\n") >> CFILE printf("#include \"db_int.h\"\n") >> CFILE printf("#include \"dbinc/txn.h\"\n") >> CFILE printf("\n") >> CFILE printf("#include \"dbinc_auto/db_server.h\"\n") >> CFILE printf("#include \"dbinc_auto/rpc_client_ext.h\"\n") >> CFILE printf("\n") >> CFILE printf("#include \"db_config.h\"\n") >> TFILE printf("\n") >> TFILE printf("#ifdef HAVE_RPC\n") >> TFILE printf("#ifndef NO_SYSTEM_INCLUDES\n") >> TFILE printf("#include <sys/types.h>\n") >> TFILE printf("#include <rpc/rpc.h>\n") >> TFILE printf("\n") >> TFILE printf("#include <string.h>\n") >> TFILE printf("#endif\n") >> TFILE printf("#include \"db_int.h\"\n") >> TFILE printf("#include \"dbinc_auto/db_server.h\"\n") >> TFILE printf("#include \"dbinc/txn.h\"\n") >> TFILE printf("\n") >> TFILE printf("#include \"db_config.h\"\n") >> SFILE printf("\n") >> SFILE printf("#ifndef NO_SYSTEM_INCLUDES\n") >> SFILE printf("#include <sys/types.h>\n") >> SFILE printf("\n") >> SFILE printf("#include <rpc/rpc.h>\n") >> SFILE printf("#include <rpc/xdr.h>\n") >> SFILE printf("\n") >> SFILE printf("#include <string.h>\n") >> SFILE printf("#endif\n") >> SFILE printf("\n") >> SFILE printf("#include \"db_int.h\"\n") >> SFILE printf("#include \"dbinc_auto/db_server.h\"\n") >> SFILE printf("#include \"dbinc/db_server_int.h\"\n") >> SFILE printf("#include \"dbinc_auto/rpc_server_ext.h\"\n") >> SFILE printf("\n") >> SFILE printf("#include \"db_config.h\"\n") >> PFILE printf("\n") >> PFILE printf("#ifndef NO_SYSTEM_INCLUDES\n") >> PFILE printf("#include <sys/types.h>\n") >> PFILE printf("\n") >> PFILE printf("#include <rpc/rpc.h>\n") >> PFILE printf("\n") >> PFILE printf("#include <string.h>\n") >> PFILE printf("#endif\n") >> PFILE printf("\n") >> PFILE printf("#include \"db_int.h\"\n") >> PFILE printf("#include \"dbinc_auto/db_server.h\"\n") >> PFILE printf("#include \"dbinc/db_server_int.h\"\n") >> PFILE printf("#include \"dbinc_auto/rpc_server_ext.h\"\n") >> PFILE printf("\n") >> PFILE first = 1; } # # ===================================================== # Generate Client Nofunc code first if necessary # NOTE: This code must be first, because we don't want any # other code other than this function, so before we write # out to the XDR and server files, we just generate this # and move on if this is all we are doing. # if (nofunc_code == 1) { # # First time through, put out the general no server and # illegal functions. # if (first_nofunc == 0) { printf("static int __dbcl_noserver ") >> CFILE printf("__P((DB_ENV *));\n\n") >> CFILE printf("static int\n") >> CFILE printf("__dbcl_noserver(dbenv)\n") >> CFILE printf("\tDB_ENV *dbenv;\n") >> CFILE printf("{\n\t__db_err(dbenv,") >> CFILE printf(" \"No server environment\");\n") >> CFILE printf("\treturn (DB_NOSERVER);\n") >> CFILE printf("}\n\n") >> CFILE printf("static int __dbcl_rpc_illegal ") >> CFILE printf("__P((DB_ENV *, char *));\n\n") >> CFILE printf("static int\n") >> CFILE printf("__dbcl_rpc_illegal(dbenv, name)\n") >> CFILE printf("\tDB_ENV *dbenv;\n\tchar *name;\n") >> CFILE printf("{\n\t__db_err(dbenv,") >> CFILE printf(" \"%%s method meaningless in an RPC") >> CFILE printf(" environment\", name);\n") >> CFILE printf("\treturn (__db_eopnotsup(dbenv));\n") >> CFILE printf("}\n\n") >> CFILE first_nofunc = 1 } # # Spit out PUBLIC prototypes. # pi = 1; p[pi++] = sprintf("int __dbcl_%s __P((", name); p[pi++] = ""; for (i = 0; i < nvars; ++i) { p[pi++] = pr_type[i]; p[pi++] = ", "; } p[pi - 1] = ""; p[pi++] = "));"; p[pi] = ""; proto_format(p, 0, CFILE); # # Spit out function name/args. # printf("int\n") >> CFILE printf("__dbcl_%s(", name) >> CFILE sep = ""; for (i = 0; i < nvars; ++i) { printf("%s%s", sep, args[i]) >> CFILE sep = ", "; } printf(")\n") >> CFILE for (i = 0; i < nvars; ++i) if (func_arg[i] == 0) printf("\t%s %s;\n", c_type[i], args[i]) \ >> CFILE else printf("\t%s;\n", c_type[i]) >> CFILE # # Call error function and return EINVAL # printf("{\n") >> CFILE # # If we don't have a local env, set one. # if (env_handle == 0) { printf("\tDB_ENV *dbenv;\n\n") >> CFILE if (db_handle) printf("\tdbenv = %s->dbenv;\n", \ args[db_idx]) >> CFILE else if (dbc_handle) printf("\tdbenv = %s->dbp->dbenv;\n", \ args[dbc_idx]) >> CFILE else if (txn_handle) printf("\tdbenv = %s->mgrp->dbenv;\n", \ args[txn_idx]) >> CFILE else if (mp_handle) printf("\tdbenv = %s->dbmp->dbenv;\n", \ args[mp_idx]) >> CFILE else printf("\tdbenv = NULL;\n") >> CFILE } # # Quiet the compiler for all variables. # # NOTE: Index 'i' starts at 1, not 0. Our first arg is # the handle we need to get to the env, and we do not want # to COMPQUIET that one. for (i = 1; i < nvars; ++i) { if (rpc_type[i] == "CONST" || rpc_type[i] == "DBT" || rpc_type[i] == "LIST" || rpc_type[i] == "STRING" || rpc_type[i] == "GID") { printf("\tCOMPQUIET(%s, NULL);\n", args[i]) \ >> CFILE } if (rpc_type[i] == "INT" || rpc_type[i] == "IGNORE" || rpc_type[i] == "ID") { printf("\tCOMPQUIET(%s, 0);\n", args[i]) \ >> CFILE } } if (!env_handle) { printf("\treturn (__dbcl_rpc_illegal(dbenv, ") >> CFILE printf("\"%s\"));\n", name) >> CFILE } else printf("\treturn (__dbcl_rpc_illegal(%s, \"%s\"));\n", \ args[env_idx], name) >> CFILE printf("}\n\n") >> CFILE next; } # # ===================================================== # XDR messages. # printf("\n") >> XFILE printf("struct __%s_msg {\n", name) >> XFILE for (i = 0; i < nvars; ++i) { if (rpc_type[i] == "LIST") { if (list_type[i] == "GID") { printf("\topaque %s<>;\n", args[i]) >> XFILE } else { printf("\tunsigned int %s<>;\n", args[i]) >> XFILE } } if (rpc_type[i] == "ID") { printf("\tunsigned int %scl_id;\n", args[i]) >> XFILE } if (rpc_type[i] == "STRING") { printf("\tstring %s<>;\n", args[i]) >> XFILE } if (rpc_type[i] == "GID") { printf("\topaque %s[%d];\n", args[i], xidsize) >> XFILE } if (rpc_type[i] == "INT") { printf("\tunsigned int %s;\n", args[i]) >> XFILE } if (rpc_type[i] == "DBT") { printf("\tunsigned int %sdlen;\n", args[i]) >> XFILE printf("\tunsigned int %sdoff;\n", args[i]) >> XFILE printf("\tunsigned int %sulen;\n", args[i]) >> XFILE printf("\tunsigned int %sflags;\n", args[i]) >> XFILE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -