/* static prototypes */
static void isdefined(definition * defp);
static void def_struct(definition * defp);
-static void def_program(definition * defp);
static void def_enum(definition * defp);
static void def_const(definition * defp);
static void def_union(definition * defp);
char **param_type);
static void get_param_type(definition * defp, declaration * dec,
char **param_type, char **typename);
-#ifdef undef
-static void hndle_param_tail(definition * defp, declaration * dec,
- token * tokp, char *typename);
-#endif
static void cs_Proc_CodeGeneration(definition * defp, int split_flag,
char *procheader);
static void cs_ProcName_setup(definition * defp, char *procheader,
static void cs_ProcSendPacket_setup(definition * defp, int split_flag);
static void cs_ProcUnmarshallOutParams_setup(definition * defp);
static void cs_ProcTail_setup(definition * defp, int split_flag);
+static void ucs_ProcCallback_setup(definition * defp, char *cbheader);
static void ucs_ProcName_setup(definition * defp, char *procheader,
int split_flag);
static void ucs_ProcParams_setup(definition * defp, int split_flag);
-static void ucs_ProcTail_setup(definition * defp, int split_flag);
+static void ucs_ProcTail_setup(definition * defp, char *cbheader,
+ int split_flag);
static void ss_Proc_CodeGeneration(definition * defp);
static void ss_ProcName_setup(definition * defp);
static void ss_ProcParams_setup(definition * defp);
case TOK_ENUM:
def_enum(defp);
break;
- case TOK_PROGRAM:
- def_program(defp);
- break;
case TOK_CONST:
def_const(defp);
break;
}
static void
-def_program(definition * defp)
-{
- token tok;
- version_list *vlist;
- version_list **vtailp;
- proc_list *plist;
- proc_list **ptailp;
-
- defp->def_kind = DEF_PROGRAM;
- scan(TOK_IDENT, &tok);
- defp->def_name = tok.str;
- scan(TOK_LBRACE, &tok);
- vtailp = &defp->def.pr.versions;
- scan(TOK_VERSION, &tok);
- do {
- scan(TOK_IDENT, &tok);
- vlist = ALLOC(version_list);
- vlist->vers_name = tok.str;
- scan(TOK_LBRACE, &tok);
- ptailp = &vlist->procs;
- do {
- plist = ALLOC(proc_list);
- get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM);
- if (streq(plist->res_type, "opaque")) {
- error("illegal result type");
- }
- scan(TOK_IDENT, &tok);
- plist->proc_name = tok.str;
- scan(TOK_LPAREN, &tok);
- get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM);
- if (streq(plist->arg_type, "opaque")) {
- error("illegal argument type");
- }
- scan(TOK_RPAREN, &tok);
- scan(TOK_EQUAL, &tok);
- scan_num(&tok);
- scan(TOK_SEMICOLON, &tok);
- plist->proc_num = tok.str;
- *ptailp = plist;
- ptailp = &plist->next;
- peek(&tok);
- } while (tok.kind != TOK_RBRACE);
- *vtailp = vlist;
- vtailp = &vlist->next;
- scan(TOK_RBRACE, &tok);
- scan(TOK_EQUAL, &tok);
- scan_num(&tok);
- vlist->vers_num = tok.str;
- scan(TOK_SEMICOLON, &tok);
- scan2(TOK_VERSION, TOK_RBRACE, &tok);
- } while (tok.kind == TOK_VERSION);
- scan(TOK_EQUAL, &tok);
- scan_num(&tok);
- defp->def.pr.prog_num = tok.str;
- *vtailp = NULL;
-}
-
-static void
def_enum(definition * defp)
{
token tok;
}
dec->rel = REL_ARRAY;
if (peekscan(TOK_RANGLE, &tok)) {
- dec->array_max = "~0"; /* unspecified size, use max */
+ if ((dkind == DEF_INPARAM) || (dkind == DEF_INOUTPARAM)) {
+ error("input arrays must specify a max size");
+ }
+ dec->array_max = "~0u"; /* unspecified size, use max */
} else {
scan_num(&tok);
dec->array_max = tok.str;
(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");
+ if (dkind != DEF_UNION) {
+ error("voids allowed only inside union definitions");
}
*typep = tok.str;
break;
scan(TOK_IDENT, &tok);
defp->def_name = tok.str;
no_of_stat_funcs = 0;
- if (PackageIndex++ >= MAX_PACKAGES)
+
+ PackageIndex++;
+ if (PackageIndex >= MAX_PACKAGES)
error("Exceeded upper limit of package statements\n");
+
function_list_index = 0;
PackagePrefix[PackageIndex] = tok.str;
if (MasterPrefix == NULL)
Proc_listp = &Proc_list->next;
decls = ALLOC(decl_list);
memset(decls, 0, sizeof(decl_list));
- if (tokp->kind != TOK_RPAREN)
- decls->decl = dec;
+ if (tokp->kind != TOK_RPAREN)
+ decls->decl = dec;
*tailp = decls;
tailp = &decls->next;
} while (tokp->kind != TOK_RPAREN);
Proc_list->component_kind = DEF_PARAM;
Proc_list->code = alloc(250);
Proc_list->scode = alloc(250);
- get_declaration(dec, DEF_PARAM);
+ get_declaration(dec, par_kind);
Proc_list->pl.param_name = dec->name;
get1_param_type(defp, dec, &Proc_list->pl.param_type);
print_param(dec);
}
-#ifdef undef
-static void
-hndle_param_tail(definition * defp, declaration * dec, token * tokp,
- char *typename)
-{
- char *amp;
-
- if (dec->rel == REL_POINTER)
- Proc_list->pl.param_flag |= INDIRECT_PARAM;
- else
- Proc_list->pl.param_flag &= ~INDIRECT_PARAM;
- amp = "";
- if (!(Proc_list->pl.param_flag & INDIRECT_PARAM))
- amp = "&";
-
- sprintf(Proc_list->code, "xdr_%s(&z_xdrs, %s%s)", typename, amp,
- Proc_list->pl.param_name);
- sprintf(Proc_list->scode, "xdr_%s(z_xdrs, &%s)", typename,
- Proc_list->pl.param_name);
- scan2(TOK_COMMA, TOK_RPAREN, tokp);
- if (tokp->kind == TOK_COMMA)
- peek(tokp);
-}
-#endif
-
-
static void
cs_Proc_CodeGeneration(definition * defp, int split_flag, char *procheader)
{
}
if (!kflag && !split_flag && uflag) {
+ if (!cflag) {
+ ucs_ProcCallback_setup(defp, "ubik_call_");
+ }
ucs_ProcName_setup(defp, "ubik_", split_flag);
if (!cflag) {
ucs_ProcParams_setup(defp, split_flag);
- ucs_ProcTail_setup(defp, split_flag);
+ ucs_ProcTail_setup(defp, "ubik_call_", split_flag);
}
}
}
static void
ss_Proc_CodeGeneration(definition * defp)
{
- defp->can_fail = 0;
+ extern char zflag;
+
+ if (zflag)
+ defp->can_fail = 0;
+ else
+ defp->can_fail = 1;
ss_ProcName_setup(defp);
if (!cflag) {
ss_ProcParams_setup(defp);
if (streq(string, structname(plist->pl.param_type))) {
plist->pl.string_name = spec->sdef.string_name;
plist->pl.param_flag |= FREETHIS_PARAM;
- fprintf(fout, "\n\t%s.%s = 0;", plist->pl.param_name,
- spec->sdef.string_name);
}
}
}
case REL_ARRAY:
plist->pl.string_name = alloc(40);
if (brief_flag) {
- f_print(fout, "\n\t%s.val = 0;",
- plist->pl.param_name);
- f_print(fout, "\n\t%s.len = 0;",
- plist->pl.param_name);
s_print(plist->pl.string_name, "val");
} else {
- f_print(fout, "\n\t%s.%s_val = 0;",
- plist->pl.param_name, defp1->def_name);
- f_print(fout, "\n\t%s.%s_len = 0;",
- plist->pl.param_name, defp1->def_name);
s_print(plist->pl.string_name, "%s_val",
defp1->def_name);
}
break;
case REL_POINTER:
- f_print(fout, "\n\t%s = 0;", plist->pl.param_name);
plist->pl.string_name = NULL;
break;
default:
if (plist->component_kind == DEF_PARAM) {
if (streq(defp1->def_name, structname(plist->pl.param_type))) {
plist->pl.param_flag |= FREETHIS_PARAM;
- fprintf(fout, "\n\tmemset(&%s, 0, sizeof(%s));",
- plist->pl.param_name, defp1->def_name);
}
}
}
}
+ for (plist = defp->pc.plists; plist; plist = plist->next) {
+ if (plist->component_kind == DEF_PARAM) {
+ fprintf(fout, "\n\tmemset(&%s, 0, sizeof(%s));",
+ plist->pl.param_name,
+ plist->pl.param_name);
+ }
+ }
+
f_print(fout, "\n");
}
f_print(fout, ");\n");
if (zflag) {
f_print(fout, "\tif (z_result)\n\t\treturn z_result;\n");
+ } else {
+ f_print(fout, "\tif (z_result)\n\t\tgoto fail;\n");
}
}
f_print(fout, "}\n\n");
}
+static void
+ucs_ProcCallback_setup(definition * defp, char *cbheader)
+{
+ proc1_list *plist;
+ int any_params = 0;
+
+ for (plist = defp->pc.plists; plist; plist = plist->next) {
+ if (plist->component_kind == DEF_PARAM) {
+ any_params = 1;
+ break;
+ }
+ }
+
+ if (any_params) {
+ f_print(fout, "struct args_%s%s%s {\n", prefix,
+ PackagePrefix[PackageIndex], defp->pc.proc_name);
+
+ for (plist = defp->pc.plists; plist; plist = plist->next) {
+ if (plist->component_kind == DEF_PARAM) {
+ f_print(fout, "\t");
+ if (plist->pl.param_kind == DEF_INPARAM &&
+ strcmp(plist->pl.param_type, "char *") == 0) {
+ f_print(fout, "const ");
+ }
+ if ((plist->pl.param_flag & OUT_STRING) != 0) {
+ f_print(fout, "%s *%s", plist->pl.param_type,
+ plist->pl.param_name);
+ } else {
+ f_print(fout, "%s %s", plist->pl.param_type,
+ plist->pl.param_name);
+ }
+ f_print(fout, ";\n");
+ }
+ }
+
+ f_print(fout, "};\n");
+ }
+
+ f_print(fout, "static int\n"
+ "%s%s%s%s(struct ubik_callrock_info *info, void *z_rock)\n"
+ "{\n",
+ cbheader, prefix, PackagePrefix[PackageIndex],
+ defp->pc.proc_name);
+
+ if (any_params) {
+ f_print(fout, "\tstruct args_%s%s%s *z_args = z_rock;\n", prefix,
+ PackagePrefix[PackageIndex], defp->pc.proc_name);
+ }
+
+ f_print(fout, "\treturn %s%s%s(info->conn", prefix, PackagePrefix[PackageIndex],
+ defp->pc.proc_name);
+
+ for (plist = defp->pc.plists; plist; plist = plist->next) {
+ if (plist->component_kind == DEF_PARAM) {
+ f_print(fout, ",\n\t\t\tz_args->%s", plist->pl.param_name);
+ }
+ }
+
+ f_print(fout, ");\n"
+ "}\n");
+
+}
static void
ucs_ProcName_setup(definition * defp, char *procheader, int split_flag)
}
static void
-ucs_ProcTail_setup(definition * defp, int split_flag)
+ucs_ProcTail_setup(definition * defp, char *cbheader, int split_flag)
{
proc1_list *plist;
+ int any_params = 0;
+
+ f_print(fout, "{\n");
- f_print(fout, "{\tafs_int32 rcode, code, newHost, thisHost, i, _ucount;\n");
- f_print(fout, "\tint chaseCount, pass, needsync;\n");
-#if 0 /* goes with block below */
- f_print(fout, "\tint j, inlist;\n");
-#endif
- f_print(fout, "\tstruct rx_connection *tc;\n");
- f_print(fout, "\tstruct rx_peer *rxp;\n");
- f_print(fout, "\tshort origLevel;\n\n");
- f_print(fout, "\tif (!aclient)\n");
- f_print(fout, "\t\treturn UNOENT;\n");
- f_print(fout, "\tLOCK_UBIK_CLIENT(aclient);\n\n");
- f_print(fout, "\t restart:\n");
- f_print(fout, "\torigLevel = aclient->initializationState;\n");
- f_print(fout, "\trcode = UNOSERVERS;\n");
- f_print(fout, "\tchaseCount = needsync = 0;\n\n");
-#if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
- f_print(fout, "\tinlist = 0;\n");
- f_print(fout, "\tLOCK_UCLNT_CACHE;\n");
- f_print(fout, "\tfor (j = 0; ((j < SYNCCOUNT) && calls_needsync[j]); j++) {\n");
- f_print(fout, "\t\tif (calls_needsync[j] == (int *)%s%s%s) {\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
- f_print(fout, "\t\t\tinlist = needsync = 1;\n");
- f_print(fout, "\t\t\tbreak;\n");
- f_print(fout, "\t\t}\n");
- f_print(fout, "\t}\n");
- f_print(fout, "\tUNLOCK_UCLNT_CACHE;\n");
-#endif
- f_print(fout, "\t/* \n\t* First pass, we try all servers that are up.\n\t* Second pass, we try all servers.\n\t*/\n");
- f_print(fout, "\tfor (pass = 0; pass < 2; pass++) { /*p */\n");
- f_print(fout, "\t\t/* For each entry in our servers list */\n");
- f_print(fout, "\t\tfor (_ucount = 0;; _ucount++) { /*s */\n\n");
- f_print(fout, "\t\tif (needsync) {\n");
- f_print(fout, "\t\t\t/* Need a sync site. Lets try to quickly find it */\n");
- f_print(fout, "\t\t\tif (aclient->syncSite) {\n");
- f_print(fout, "\t\t\t\tnewHost = aclient->syncSite; /* already in network order */\n");
- f_print(fout, "\t\t\t\taclient->syncSite = 0; /* Will reset if it works */\n");
- f_print(fout, "\t\t\t} else if (aclient->conns[3]) {\n");
- f_print(fout, "\t\t\t\t/* If there are fewer than four db servers in a cell,\n");
- f_print(fout, "\t\t\t\t* there's no point in making the GetSyncSite call.\n");
- f_print(fout, "\t\t\t\t* At best, it's a wash. At worst, it results in more\n");
- f_print(fout, "\t\t\t\t* RPCs than you would otherwise make.\n");
- f_print(fout, "\t\t\t\t*/\n");
- f_print(fout, "\t\t\t\ttc = aclient->conns[_ucount];\n");
- f_print(fout, "\t\t\t\tif (tc && rx_ConnError(tc)) {\n");
- f_print(fout, "\t\t\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
- f_print(fout, "\t\t\t\t}\n");
- f_print(fout, "\t\t\t\tif (!tc)\n");
- f_print(fout, "\t\t\t\t\tbreak;\n");
- f_print(fout, "\t\t\t\tcode = VOTE_GetSyncSite(tc, &newHost);\n");
- f_print(fout, "\t\t\t\tif (aclient->initializationState != origLevel)\n");
- f_print(fout, "\t\t\t\t\tgoto restart; /* somebody did a ubik_ClientInit */\n");
- f_print(fout, "\t\t\t\tif (code)\n");
- f_print(fout, "\t\t\t\t\tnewHost = 0;\n");
- f_print(fout, "\t\t\t\tnewHost = htonl(newHost); /* convert to network order */\n");
- f_print(fout, "\t\t\t} else {\n");
- f_print(fout, "\t\t\t\tnewHost = 0;\n");
- f_print(fout, "\t\t\t}\n");
- f_print(fout, "\t\t\tif (newHost) {\n");
- f_print(fout, "\t\t\t\t/* position count at the appropriate slot in the client\n");
- f_print(fout, "\t\t\t\t* structure and retry. If we can't find in slot, we'll\n");
- f_print(fout, "\t\t\t\t* just continue through the whole list \n");
- f_print(fout, "\t\t\t\t*/\n");
- f_print(fout, "\t\t\t\tfor (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {\n");
- f_print(fout, "\t\t\t\t\trxp = rx_PeerOf(aclient->conns[i]);\n");
- f_print(fout, "\t\t\t\t\tthisHost = rx_HostOf(rxp);\n");
- f_print(fout, "\t\t\t\t\tif (!thisHost)\n");
- f_print(fout, "\t\t\t\t\t\tbreak;\n");
- f_print(fout, "\t\t\t\t\tif (thisHost == newHost) {\n");
- f_print(fout, "\t\t\t\t\t\tif (chaseCount++ > 2)\n");
- f_print(fout, "\t\t\t\t\t\t\tbreak; /* avoid loop asking */\n");
- f_print(fout, "\t\t\t\t\t\t_ucount = i; /* this index is the sync site */\n");
- f_print(fout, "\t\t\t\t\t\tbreak;\n");
- f_print(fout, "\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n");
- f_print(fout, "\t\t/*needsync */\n");
- f_print(fout, "\t\ttc = aclient->conns[_ucount];\n");
- f_print(fout, "\t\tif (tc && rx_ConnError(tc)) {\n");
- f_print(fout, "\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
- f_print(fout, "\t\t}\n");
- f_print(fout, "\t\tif (!tc)\n");
- f_print(fout, "\t\t\tbreak;\n\n");
- f_print(fout, "\t\tif ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {\n");
- f_print(fout, "\t\t\tcontinue; /* this guy's down */\n");
- f_print(fout, "\t\t}\n");
-
- f_print(fout, "\t\trcode = %s%s%s(tc\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
for (plist = defp->pc.plists; plist; plist = plist->next) {
if (plist->component_kind == DEF_PARAM) {
- plist->pl.param_flag &= ~PROCESSED_PARAM;
- f_print(fout, ", %s", plist->pl.param_name);
+ any_params = 1;
+ break;
}
}
- f_print(fout, ");\n");
- f_print(fout, "\t\tif (aclient->initializationState != origLevel) {\n");
- f_print(fout, "\t\t\t/* somebody did a ubik_ClientInit */\n");
- f_print(fout, "\t\t\tif (rcode)\n");
- f_print(fout, "\t\t\t\tgoto restart; /* call failed */\n");
- f_print(fout, "\t\t\telse\n");
- f_print(fout, "\t\t\t\tgoto done; /* call suceeded */\n");
- f_print(fout, "\t\t}\n");
- f_print(fout, "\t\tif (rcode < 0) { /* network errors */\n");
- f_print(fout, "\t\t\taclient->states[_ucount] |= CFLastFailed; /* Mark server down */\n");
- f_print(fout, "\t\t} else if (rcode == UNOTSYNC) {\n");
- f_print(fout, "\t\t\tneedsync = 1;\n");
- f_print(fout, "\t\t} else if (rcode != UNOQUORUM) {\n");
- f_print(fout, "\t\t\t/* either misc ubik code, or misc appl code, or success. */\n");
- f_print(fout, "\t\t\taclient->states[_ucount] &= ~CFLastFailed; /* mark server up*/\n");
- f_print(fout, "\t\t\tgoto done; /* all done */\n");
- f_print(fout, "\t\t}\n");
- f_print(fout, "\t\t} /*s */\n");
- f_print(fout, "\t} /*p */\n\n");
- f_print(fout, "\tdone:\n");
- f_print(fout, "\tif (needsync) {\n");
-
-#if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
- f_print(fout, "\t\tif (!inlist) { /* Remember proc call that needs sync site */\n");
- f_print(fout, "\t\t\tLOCK_UCLNT_CACHE;\n");
- f_print(fout, "\t\t\tcalls_needsync[synccount % SYNCCOUNT] = (int *)%s%s%s;\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
- f_print(fout, "\t\t\tsynccount++;\n");
- f_print(fout, "\t\t\tUNLOCK_UCLNT_CACHE;\n");
- f_print(fout, "\t\t\tinlist = 1;\n");
- f_print(fout, "\t\t}\n");
-#endif
- f_print(fout, "\t\tif (!rcode) { /* Remember the sync site - cmd successful */\n");
- f_print(fout, "\t\t\trxp = rx_PeerOf(aclient->conns[_ucount]);\n");
- f_print(fout, "\t\t\taclient->syncSite = rx_HostOf(rxp);\n");
- f_print(fout, "\t\t}\n");
- f_print(fout, "\t}\n");
- f_print(fout, "\tUNLOCK_UBIK_CLIENT(aclient);\n");
- f_print(fout, "\treturn rcode;\n}\n\n");
+
+ if (any_params) {
+ f_print(fout, "\tstruct args_%s%s%s args;\n", prefix,
+ PackagePrefix[PackageIndex], defp->pc.proc_name);
+ f_print(fout, "\tmemset(&args, 0, sizeof(args));\n\n");
+
+ for (plist = defp->pc.plists; plist; plist = plist->next) {
+ if (plist->component_kind == DEF_PARAM) {
+ plist->pl.param_flag &= ~PROCESSED_PARAM;
+ f_print(fout, "\targs.%s = %s;\n", plist->pl.param_name,
+ plist->pl.param_name);
+ }
+ }
+
+ f_print(fout, "\n\treturn ubik_CallRock(aclient, aflags, %s%s%s%s, &args);\n",
+ cbheader, prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
+ } else {
+ f_print(fout, "\treturn ubik_CallRock(aclient, aflags, %s%s%s%s, NULL);\n",
+ cbheader, prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
+ }
+
+ f_print(fout, "}\n\n");
}
"\nstatic afs_int32 (*StubProcsArray%d[])(struct rx_call *z_call, XDR *z_xdrs) = {_%s%s%s",
PackageIndex, prefix, defp->pc.proc_prefix,
((definition *) listp->val)->pc.proc_name);
- defp = (definition *) listp->val;
}
}
listp = listp->next;