1 /* @(#)rpc_parse.c 1.1 87/11/04 3.9 RPCSRC */
3 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4 * unrestricted use provided that this legend is included on all tape
5 * media and as a part of the software program in whole or part. Users
6 * may copy or modify Sun RPC without charge, but are not authorized
7 * to license or distribute it to anyone else except as part of a product or
8 * program developed by the user.
10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14 * Sun RPC is provided with no support and without any obligation on the
15 * part of Sun Microsystems, Inc. to assist in its use, correction,
16 * modification or enhancement.
18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20 * OR ANY PART THEREOF.
22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23 * or profits or other special, indirect and consequential damages, even if
24 * Sun has been advised of the possibility of such damages.
26 * Sun Microsystems, Inc.
28 * Mountain View, California 94043
32 * rpc_parse.c, Parser for the RPC protocol compiler
33 * Copyright (C) 1987 Sun Microsystems, Inc.
35 #include <afsconfig.h>
36 #include <afs/param.h>
51 #include "rpc_parse.h"
54 list *proc_defined[MAX_PACKAGES], *special_defined, *typedef_defined, *uniondef_defined;
55 char *SplitStart = NULL;
56 char *SplitEnd = NULL;
57 char *MasterPrefix = NULL;
58 char *ServerPrefix = "";
59 char *PackagePrefix[MAX_PACKAGES];
60 char *PackageStatIndex[MAX_PACKAGES];
61 int no_of_stat_funcs = 0; /*
62 * current function number in client interface
65 int no_of_stat_funcs_header[MAX_PACKAGES]; /*
66 * Total number of functions in client
69 int no_of_opcodes[MAX_PACKAGES], master_no_of_opcodes = 0;
70 int lowest_opcode[MAX_PACKAGES], master_lowest_opcode = 99999;
71 int highest_opcode[MAX_PACKAGES], master_highest_opcode = 0;
72 int master_opcodenumber = 99999;
73 int opcodesnotallowed[MAX_PACKAGES];
74 int combinepackages = 0;
75 int PackageIndex = -1;
76 int PerProcCounter = 0;
80 * Character arrays to keep list of function names as we process the file
83 char function_list[MAX_PACKAGES]
84 [MAX_FUNCTIONS_PER_PACKAGE]
85 [MAX_FUNCTION_NAME_LEN];
86 int function_list_index;
88 /* static prototypes */
89 static void isdefined(definition *defp);
90 static void def_struct(definition *defp);
91 static void def_program(definition *defp);
92 static void def_enum(definition *defp);
93 static void def_const(definition *defp);
94 static void def_union(definition *defp);
95 static void def_typedef(definition *defp);
96 static void get_declaration(declaration *dec, defkind dkind);
97 static void get_type(char **prefixp, char **typep, defkind dkind);
98 static void unsigned_dec(char **typep);
99 static void def_package(definition *defp);
100 static void def_prefix(definition *defp);
101 static void def_statindex(definition *defp);
102 static void def_startingopcode(definition *defp);
103 static void def_split(definition *defp);
104 static void customize_struct(definition *defp);
105 static char *structname(char *name);
106 static void def_special(declaration *dec, definition *defp);
107 static void check_proc(definition *defp, token *tokp, int noname);
108 static int InvalidConstant(char *name);
109 static int opcodenum_is_defined(int opcode_num);
110 static void analyze_ProcParams(definition *defp, token *tokp);
111 static void generate_code(definition *defp, int proc_split_flag, int multi_flag);
112 static void handle_split_proc(definition *defp, int multi_flag);
113 static void do_split(definition *defp, int direction, int *numofparams, defkind param_kind, int restore_flag);
114 static void hdle_param_tok(definition *defp, declaration *dec, token *tokp, defkind par_kind);
115 static void get1_param_type(definition *defp, declaration *dec, char **param_type);
116 static void get_param_type(definition *defp, declaration *dec, char **param_type, char **typename);
118 static void hndle_param_tail(definition *defp, declaration *dec, token *tokp, char *typename);
120 static void cs_Proc_CodeGeneration(definition *defp, int split_flag, char *procheader);
121 static void cs_ProcName_setup(definition *defp, char *procheader, int split_flag);
122 static void cs_ProcParams_setup(definition *defp, int split_flag);
123 static void cs_ProcMarshallInParams_setup(definition *defp, int split_flag);
124 static void cs_ProcSendPacket_setup(definition *defp, int split_flag);
125 static void cs_ProcUnmarshallOutParams_setup(definition *defp);
126 static void cs_ProcTail_setup(definition *defp, int split_flag);
127 static void ss_Proc_CodeGeneration(definition *defp);
128 static void ss_ProcName_setup(definition *defp);
129 static void ss_ProcParams_setup(definition *defp, int *somefrees);
130 static void ss_ProcSpecial_setup(definition *defp, int *somefrees);
131 static void ss_ProcUnmarshallInParams_setup(definition *defp);
132 static void ss_ProcCallRealProc_setup(definition *defp);
133 static void ss_ProcMarshallOutParams_setup(definition *defp);
134 static void ss_ProcTail_setup(definition *defp, int somefrees);
135 static int opcode_holes_exist(void);
136 static void er_ProcDeclExterns_setup(void);
137 static void er_ProcProcsArray_setup(void);
138 static void er_ProcMainBody_setup(void);
139 static void er_HeadofOldStyleProc_setup(void);
140 static void er_BodyofOldStyleProc_setup(void);
141 static void proc_er_case(definition *defp);
142 static void er_TailofOldStyleProc_setup(void);
147 * return the next definition you see
149 definition *get_definition(void)
154 defp = ALLOC(definition);
155 memset((char *)defp, 0, sizeof(definition));
191 def_special(&dec, defp);
194 case TOK_STARTINGOPCODE:
195 def_startingopcode(defp);
200 customize_struct(defp);
202 case TOK_SPLITPREFIX:
207 if (tok.kind == TOK_LPAREN) {
209 check_proc(defp, &tok, 1);
212 check_proc(defp, &tok, 0);
215 check_proc(defp, &tok, 0);
219 check_proc(defp, &tok, 1);
222 error("definition keyword expected");
224 if (!IsRxgenToken(&tok))
226 scan(TOK_SEMICOLON,&tok);
232 static void isdefined(definition *defp)
234 STOREVAL(&defined, defp);
238 static void def_struct(definition *defp)
245 defp->def_kind = DEF_STRUCT;
247 scan(TOK_IDENT, &tok);
248 defp->def_name = tok.str;
249 scan(TOK_LBRACE, &tok);
250 tailp = &defp->def.st.decls;
252 get_declaration(&dec, DEF_STRUCT);
253 decls = ALLOC(decl_list);
256 tailp = &decls->next;
257 scan(TOK_SEMICOLON, &tok);
259 } while (tok.kind != TOK_RBRACE);
264 static void def_program(definition *defp)
268 version_list **vtailp;
272 defp->def_kind = DEF_PROGRAM;
273 scan(TOK_IDENT, &tok);
274 defp->def_name = tok.str;
275 scan(TOK_LBRACE, &tok);
276 vtailp = &defp->def.pr.versions;
277 scan(TOK_VERSION, &tok);
279 scan(TOK_IDENT, &tok);
280 vlist = ALLOC(version_list);
281 vlist->vers_name = tok.str;
282 scan(TOK_LBRACE, &tok);
283 ptailp = &vlist->procs;
285 plist = ALLOC(proc_list);
286 get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM);
287 if (streq(plist->res_type, "opaque")) {
288 error("illegal result type");
290 scan(TOK_IDENT, &tok);
291 plist->proc_name = tok.str;
292 scan(TOK_LPAREN, &tok);
293 get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM);
294 if (streq(plist->arg_type, "opaque")) {
295 error("illegal argument type");
297 scan(TOK_RPAREN, &tok);
298 scan(TOK_EQUAL, &tok);
300 scan(TOK_SEMICOLON, &tok);
301 plist->proc_num = tok.str;
303 ptailp = &plist->next;
305 } while (tok.kind != TOK_RBRACE);
307 vtailp = &vlist->next;
308 scan(TOK_RBRACE, &tok);
309 scan(TOK_EQUAL, &tok);
311 vlist->vers_num = tok.str;
312 scan(TOK_SEMICOLON, &tok);
313 scan2(TOK_VERSION, TOK_RBRACE, &tok);
314 } while (tok.kind == TOK_VERSION);
315 scan(TOK_EQUAL, &tok);
317 defp->def.pr.prog_num = tok.str;
321 static void def_enum(definition *defp)
325 enumval_list **tailp;
327 defp->def_kind = DEF_ENUM;
328 scan(TOK_IDENT, &tok);
329 defp->def_name = tok.str;
330 scan(TOK_LBRACE, &tok);
331 tailp = &defp->def.en.vals;
333 scan(TOK_IDENT, &tok);
334 elist = ALLOC(enumval_list);
335 elist->name = tok.str;
336 elist->assignment = NULL;
337 scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
338 if (tok.kind == TOK_EQUAL) {
340 elist->assignment = tok.str;
341 scan2(TOK_COMMA, TOK_RBRACE, &tok);
344 tailp = &elist->next;
345 } while (tok.kind != TOK_RBRACE);
349 static void def_const(definition *defp)
353 defp->def_kind = DEF_CONST;
354 scan(TOK_IDENT, &tok);
355 defp->def_name = tok.str;
356 scan(TOK_EQUAL, &tok);
357 scan2(TOK_IDENT, TOK_STRCONST, &tok);
358 defp->def.co = tok.str;
361 static void def_union(definition *defp)
368 defp->def_kind = DEF_UNION;
369 scan(TOK_IDENT, &tok);
370 defp->def_name = tok.str;
371 scan(TOK_SWITCH, &tok);
372 scan(TOK_LPAREN, &tok);
373 get_declaration(&dec, DEF_UNION);
374 defp->def.un.enum_decl = dec;
375 tailp = &defp->def.un.cases;
376 scan(TOK_RPAREN, &tok);
377 scan(TOK_LBRACE, &tok);
378 scan(TOK_CASE, &tok);
379 while (tok.kind == TOK_CASE) {
380 scan(TOK_IDENT, &tok);
381 cases = ALLOC(case_list);
382 cases->case_name = tok.str;
383 scan(TOK_COLON, &tok);
384 get_declaration(&dec, DEF_UNION);
385 cases->case_decl = dec;
387 tailp = &cases->next;
388 scan(TOK_SEMICOLON, &tok);
389 scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
392 if (tok.kind == TOK_DEFAULT) {
393 scan(TOK_COLON, &tok);
394 get_declaration(&dec, DEF_UNION);
395 defp->def.un.default_decl = ALLOC(declaration);
396 *defp->def.un.default_decl = dec;
397 scan(TOK_SEMICOLON, &tok);
398 scan(TOK_RBRACE, &tok);
400 defp->def.un.default_decl = NULL;
405 static void def_typedef(definition *defp)
409 defp->def_kind = DEF_TYPEDEF;
410 get_declaration(&dec, DEF_TYPEDEF);
411 defp->def_name = dec.name;
412 defp->def.ty.old_prefix = dec.prefix;
413 defp->def.ty.old_type = dec.type;
414 defp->def.ty.rel = dec.rel;
415 defp->def.ty.array_max = dec.array_max;
419 static void get_declaration(declaration *dec, defkind dkind)
423 get_type(&dec->prefix, &dec->type, dkind);
424 dec->rel = REL_ALIAS;
425 if (streq(dec->type, "void")) {
428 scan2(TOK_STAR, TOK_IDENT, &tok);
429 if (tok.kind == TOK_STAR) {
430 dec->rel = REL_POINTER;
431 scan(TOK_IDENT, &tok);
434 if (peekscan(TOK_LBRACKET, &tok)) {
435 if (dec->rel == REL_POINTER) {
436 error("no array-of-pointer declarations -- use typedef");
438 dec->rel = REL_VECTOR;
440 dec->array_max = tok.str;
441 scan(TOK_RBRACKET, &tok);
442 } else if (peekscan(TOK_LANGLE, &tok)) {
443 if (dec->rel == REL_POINTER) {
444 error("no array-of-pointer declarations -- use typedef");
446 dec->rel = REL_ARRAY;
447 if (peekscan(TOK_RANGLE, &tok)) {
448 dec->array_max = "~0"; /* unspecified size, use max */
451 dec->array_max = tok.str;
452 scan(TOK_RANGLE, &tok);
455 if (streq(dec->type, "opaque")) {
456 if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
457 error("array declaration expected");
459 } else if (streq(dec->type, "string")) {
460 if (dec->rel != REL_ARRAY) {
461 error(" variable-length array declaration expected");
467 static void get_type(char **prefixp, char **typep, defkind dkind)
481 scan(TOK_IDENT, &tok);
489 (void) peekscan(TOK_INT, &tok);
492 *typep = "afs_int32";
493 (void) peekscan(TOK_INT, &tok);
496 if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
497 error("voids allowed only inside union and program definitions");
512 error("expected type specifier");
517 static void unsigned_dec(char **typep)
530 (void) peekscan(TOK_INT, &tok);
534 *typep = "afs_uint32";
535 (void) peekscan(TOK_INT, &tok);
548 static void def_package(definition *defp)
552 defp->def_kind = DEF_PACKAGE;
553 scan(TOK_IDENT, &tok);
554 defp->def_name = tok.str;
555 no_of_stat_funcs = 0;
556 if (PackageIndex++ >= MAX_PACKAGES)
557 error("Exceeded upper limit of package statements\n");
558 function_list_index = 0;
559 PackagePrefix[PackageIndex] = tok.str;
560 if (MasterPrefix == NULL)
561 MasterPrefix = tok.str;
562 no_of_opcodes[PackageIndex] = highest_opcode[PackageIndex] = opcodesnotallowed[PackageIndex] = 0;
563 lowest_opcode[PackageIndex] = 99999;
564 proc_defined[PackageIndex] = NULL;
565 PackageStatIndex[PackageIndex] = NULL;
568 static void def_prefix(definition *defp)
572 defp->def_kind = DEF_PREFIX;
573 scan(TOK_IDENT, &tok);
574 defp->def_name = tok.str;
575 ServerPrefix = tok.str;
578 static void def_statindex(definition *defp)
583 defp->def_kind = DEF_CONST;
585 if (PackageIndex < 0)
586 error("'statindex' command must follow 'package' command!\n");
587 if (PackageStatIndex[PackageIndex])
588 error("Cannot have more then one 'statindex' per package!\n");
589 if (InvalidConstant(tok.str))
590 error("Index in 'statindex' command must be a constant!");
591 name = alloc(strlen(PackagePrefix[PackageIndex])+strlen("STATINDEX")+1);
592 strcpy(name, PackagePrefix[PackageIndex]);
593 strcat(name, "STATINDEX");
594 defp->def_name = name;
595 defp->def.co = tok.str;
596 PackageStatIndex[PackageIndex] = name;
599 static void def_startingopcode(definition *defp)
603 defp->def_kind = DEF_STARTINGOPCODE;
604 scan(TOK_IDENT, &tok);
605 defp->def_name = tok.str;
606 if (InvalidConstant(defp->def_name))
607 error("Opcode in 'startingopcode' command must be a constant!");
608 lowest_opcode[PackageIndex] = master_lowest_opcode = atoi(tok.str);
609 if (lowest_opcode[PackageIndex] < 0 || lowest_opcode[PackageIndex] > 99999)
610 error("startingopcode number is out of bounds (must be >= 0 < 100000)");
611 master_opcodenumber = lowest_opcode[PackageIndex];
612 opcodesnotallowed[PackageIndex]=1;
615 static void def_split(definition *defp)
619 defp->def_kind = DEF_SPLITPREFIX;
624 scan(TOK_EQUAL, &tok);
625 scan(TOK_IDENT, &tok);
626 SplitStart = tok.str;
629 scan(TOK_EQUAL, &tok);
630 scan(TOK_IDENT, &tok);
636 error("syntax error in the 'splitprefix' line");
638 } while (tok.kind != TOK_SEMICOLON);
639 if (!SplitStart && !SplitEnd)
640 error("At least one param should be passed to 'splitprefix' cmd");
644 static void customize_struct(definition *defp)
648 definition *defp1 = ALLOC(definition);
649 spec_list *specs, **tailp;
651 defp->def_kind = DEF_CUSTOMIZED;
652 defp1->def_kind = DEF_SPECIAL;
653 tailp = &defp1->def.sd.specs;
654 for (listp = defp->def.st.decls; listp; listp = listp->next) {
656 if (streq(dec->type, "string") || (dec->rel == REL_POINTER)) {
657 specs = ALLOC(spec_list);
658 specs->sdef.string_name = dec->name;
659 specs->sdef.string_value = defp->def_name;
661 tailp = &specs->next;
665 STOREVAL(&special_defined, defp1);
668 static char *structname(char *name)
670 char namecontents[150], *pnt, *pnt1;
672 strcpy(namecontents, name);
674 if (!strncmp(pnt, "struct", 6)) pnt += 6;
675 while (isspace(*pnt)) pnt++;
677 while (*pnt != ' ' && *pnt != '\0') pnt++;
683 static void def_special(declaration *dec, definition *defp)
686 spec_list *specs, **tailp;
689 defp->def_kind = DEF_SPECIAL;
690 get_type(&dec->prefix, &dec->type, DEF_SPECIAL);
691 dec->rel = REL_POINTER;
692 scan(TOK_IDENT, &tok);
693 tailp = &defp->def.sd.specs;
695 specs = ALLOC(spec_list);
696 specs->sdef.string_name = tok.str;
697 get_param_type(defp, dec, &specs->sdef.string_value, &typename);
699 tailp = &specs->next;
700 scan2(TOK_COMMA, TOK_SEMICOLON, &tok);
701 if (tok.kind == TOK_SEMICOLON)
704 } while (tok.kind == TOK_IDENT);
706 STOREVAL(&special_defined, defp);
710 proc1_list *Proc_list, **Proc_listp;
712 static void check_proc(definition *defp, token *tokp, int noname)
718 tokp->kind = TOK_PROC;
719 defp->def_kind = DEF_PROC;
721 defp->pc.proc_name = "";
723 defp->pc.proc_name = tokp->str;
725 defp->pc.proc_prefix = alloc(strlen(PackagePrefix[PackageIndex])+1);
726 strcpy(defp->pc.proc_prefix, PackagePrefix[PackageIndex]);
727 scan2(TOK_LPAREN, TOK_IDENT, &tok);
728 defp->pc.proc_serverstub = NULL;
729 if (tok.kind == TOK_IDENT) {
730 defp->pc.proc_serverstub = tok.str;
731 scan(TOK_LPAREN, &tok);
733 analyze_ProcParams(defp, &tok);
734 defp->pc.proc_opcodenum = -1;
735 scan4(TOK_SPLIT, TOK_MULTI, TOK_EQUAL, TOK_SEMICOLON, &tok);
736 if (tok.kind == TOK_MULTI) {
738 scan2(TOK_EQUAL, TOK_SEMICOLON, &tok);
740 if (tok.kind == TOK_SPLIT) {
742 defp->pc.split_flag = 1;
743 scan2(TOK_EQUAL, TOK_SEMICOLON, &tok);
746 defp->pc.split_flag = 0;
748 if (tok.kind == TOK_EQUAL) {
749 if (opcodesnotallowed[PackageIndex])
750 error("Opcode assignment isn't allowed here!");
752 if (InvalidConstant(tok.str))
753 error("Illegal Opcode assignment (Must be a constant opcode!)");
754 if (opcodenum_is_defined(atoi(tok.str)))
755 error("The opcode number is already used by a previous proc");
756 defp->pc.proc_opcodename = tok.str;
757 defp->pc.proc_opcodenum = atoi(tok.str);
758 if (defp->pc.proc_opcodenum < lowest_opcode[PackageIndex])
759 lowest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
760 if (defp->pc.proc_opcodenum < master_lowest_opcode)
761 master_lowest_opcode = defp->pc.proc_opcodenum;
762 if (defp->pc.proc_opcodenum > highest_opcode[PackageIndex])
763 highest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
764 if (defp->pc.proc_opcodenum > master_highest_opcode)
765 master_highest_opcode = defp->pc.proc_opcodenum;
766 scan(TOK_SEMICOLON, &tok);
768 if (master_opcodenumber == 99999) master_opcodenumber = 0;
769 defp->pc.proc_opcodenum = master_opcodenumber++;
770 if (defp->pc.proc_opcodenum < lowest_opcode[PackageIndex])
771 lowest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
772 if (defp->pc.proc_opcodenum > highest_opcode[PackageIndex])
773 highest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
774 if (defp->pc.proc_opcodenum > master_highest_opcode)
775 master_highest_opcode = defp->pc.proc_opcodenum;
776 opcodesnotallowed[PackageIndex] = 1; /* force it */
778 no_of_opcodes[PackageIndex]++, master_no_of_opcodes++;
780 generate_code(defp, 0, 1);
781 if (Cflag || cflag) {
782 generate_code(defp, 1, 1);
784 generate_multi_macros(defp);
786 generate_code(defp, proc_split, 0);
789 if (function_list_index >= MAX_FUNCTIONS_PER_INTERFACE) {
790 error("too many functions in interface, "
791 "increase MAX_FUNCTIONS_PER_INTERFACE");
793 sprintf(function_list[PackageIndex][function_list_index],
796 PackagePrefix[PackageIndex],
799 function_list_index++;
800 no_of_stat_funcs_header[PackageIndex]++;
806 #define LEGALNUMS "0123456789"
807 static int InvalidConstant(char *name)
814 return(slen != strspn(name, map));
817 static int opcodenum_is_defined(int opcode_num)
822 for (listp = proc_defined[PackageIndex]; listp != NULL; listp = listp->next) {
823 defp = (definition *)listp->val;
824 if (opcode_num == defp->pc.proc_opcodenum)
831 static void analyze_ProcParams(definition *defp, token *tokp)
834 decl_list *decls, **tailp;
836 Proc_listp = &defp->pc.plists;
837 tailp = &defp->def.st.decls;
840 Proc_list = ALLOC(proc1_list);
841 memset((char *)Proc_list, 0, sizeof(proc1_list));
842 Proc_list->pl.param_flag = 0;
843 switch (tokp->kind) {
845 hdle_param_tok(defp, &dec, tokp, DEF_INPARAM);
848 hdle_param_tok(defp, &dec, tokp, DEF_OUTPARAM);
851 hdle_param_tok(defp, &dec, tokp, DEF_INOUTPARAM);
857 hdle_param_tok(defp, &dec, tokp, DEF_NULL);
860 *Proc_listp = Proc_list;
861 Proc_listp = &Proc_list->next;
862 decls = ALLOC(decl_list);
863 memset((char *)decls, 0, sizeof(decl_list));
866 tailp = &decls->next;
867 } while (tokp->kind != TOK_RPAREN);
872 static void generate_code(definition *defp, int proc_split_flag, int multi_flag)
875 handle_split_proc(defp, multi_flag);
877 if (Cflag || cflag) {
878 cs_Proc_CodeGeneration(defp, 0, "");
881 ss_Proc_CodeGeneration(defp);
884 STOREVAL(&proc_defined[PackageIndex], defp);
888 static void handle_split_proc(definition *defp, int multi_flag)
890 char *startname = SplitStart, *endname = SplitEnd;
897 if (Cflag || cflag) {
899 do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 0);
901 cs_Proc_CodeGeneration(defp, 1, startname);
903 do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 1);
904 do_split(defp, IN, &numofparams, DEF_INPARAM, 0);
906 cs_Proc_CodeGeneration(defp, (multi_flag ? 3 : 2), endname);
908 do_split(defp, IN, &numofparams, DEF_INPARAM, 1);
912 ss_Proc_CodeGeneration(defp);
916 static void do_split(definition *defp, int direction, int *numofparams, defkind param_kind, int restore_flag)
921 defp->pc.paramtypes[direction] = *numofparams;
922 for (plist = defp->pc.plists; plist; plist = plist->next) {
923 if (plist->component_kind == DEF_NULL && plist->pl.param_kind == param_kind)
924 plist->component_kind = DEF_PARAM;
927 *numofparams = defp->pc.paramtypes[direction];
928 defp->pc.paramtypes[direction] = 0;
929 for (plist = defp->pc.plists; plist; plist = plist->next) {
930 if (plist->component_kind == DEF_PARAM && plist->pl.param_kind == param_kind)
931 plist->component_kind = DEF_NULL;
937 static void hdle_param_tok(definition *defp, declaration *dec, token *tokp, defkind par_kind)
939 static defkind last_param_kind = DEF_NULL;
941 if (par_kind == DEF_NULL)
942 Proc_list->pl.param_kind = last_param_kind;
944 Proc_list->pl.param_kind = par_kind;
945 last_param_kind = Proc_list->pl.param_kind;
946 defp->pc.paramtypes[(int)last_param_kind]++;
947 Proc_list->component_kind = DEF_PARAM;
948 Proc_list->code = alloc(250);
949 Proc_list->scode = alloc(250);
950 get_declaration(dec, DEF_PARAM);
951 Proc_list->pl.param_name = dec->name;
952 get1_param_type(defp, dec, &Proc_list->pl.param_type);
954 scan2(TOK_COMMA, TOK_RPAREN, tokp);
955 if (tokp->kind == TOK_COMMA)
960 static void get1_param_type(definition *defp, declaration *dec, char **param_type)
962 char typecontents[100];
964 if (streq(dec->type,"string")) {
965 *param_type = "char *";
968 strcpy(typecontents, dec->prefix);
969 strcat(typecontents, " ");
970 strcat(typecontents, dec->type);
971 strcat(typecontents, " *");
972 } else if (dec->rel == REL_POINTER) {
973 strcpy(typecontents, dec->type);
974 strcat(typecontents, " *");
976 strcpy(typecontents, dec->type);
977 *param_type = alloc(100);
978 strcpy(*param_type, typecontents);
983 static void get_param_type(definition *defp, declaration *dec, char **param_type, char **typename)
985 char typecontents[100];
987 if (streq(dec->type,"string")) {
988 *typename = "wrapstring";
989 *param_type = "char *";
991 *typename = dec->type;
993 strcpy(typecontents, dec->prefix);
994 strcat(typecontents, " ");
995 strcat(typecontents, dec->type);
996 strcat(typecontents, " *");
997 dec->rel = REL_POINTER;
998 } else if (dec->rel == REL_POINTER) {
999 strcpy(typecontents, dec->type);
1000 strcat(typecontents, " *");
1002 strcpy(typecontents, dec->type);
1003 *param_type = alloc(100);
1004 strcpy(*param_type, typecontents);
1010 static void hndle_param_tail(definition *defp, declaration *dec, token *tokp, char *typename)
1014 if (dec->rel == REL_POINTER)
1015 Proc_list->pl.param_flag |= INDIRECT_PARAM;
1017 Proc_list->pl.param_flag &= ~INDIRECT_PARAM;
1019 if (!(Proc_list->pl.param_flag & INDIRECT_PARAM))
1022 sprintf(Proc_list->code, "xdr_%s(&z_xdrs, %s%s)", typename, amp, Proc_list->pl.param_name);
1023 sprintf(Proc_list->scode, "xdr_%s(z_xdrs, &%s)", typename, Proc_list->pl.param_name);
1024 scan2(TOK_COMMA, TOK_RPAREN, tokp);
1025 if (tokp->kind == TOK_COMMA)
1031 static void cs_Proc_CodeGeneration(definition *defp, int split_flag, char *procheader)
1034 cs_ProcName_setup(defp, procheader, split_flag);
1036 cs_ProcParams_setup(defp, split_flag);
1037 cs_ProcMarshallInParams_setup(defp, split_flag);
1038 if (split_flag != 1) {
1039 cs_ProcSendPacket_setup(defp, split_flag);
1040 cs_ProcUnmarshallOutParams_setup(defp);
1042 cs_ProcTail_setup(defp, split_flag);
1047 static void cs_ProcName_setup(definition *defp, char *procheader, int split_flag)
1053 f_print(fout, "int %s%s%s%s(z_call", procheader, prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1055 f_print(fout, "int %s%s%s%s(z_conn", procheader, prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1058 if ((strlen(procheader) + strlen(prefix) + strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >= MAX_FUNCTION_NAME_LEN) {
1059 error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1062 for (plist = defp->pc.plists; plist; plist = plist->next) {
1063 if (plist->component_kind == DEF_PARAM) {
1064 plist->pl.param_flag &= ~PROCESSED_PARAM;
1065 f_print(fout, ", %s", plist->pl.param_name);
1068 f_print(fout, ")\n");
1073 static void cs_ProcParams_setup(definition *defp, int split_flag)
1075 proc1_list *plist, *plist1;
1078 f_print(fout, "\tregister struct rx_connection *z_conn;\n");
1080 f_print(fout, "\tregister struct rx_call *z_call;\n");
1082 for (plist = defp->pc.plists; plist; plist = plist->next) {
1083 if (plist->component_kind == DEF_PARAM && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1084 if (plist->pl.param_flag & OUT_STRING) {
1085 f_print(fout, "\t%s *%s", plist->pl.param_type, plist->pl.param_name);
1087 f_print(fout, "\t%s %s", plist->pl.param_type, plist->pl.param_name);
1089 plist->pl.param_flag |= PROCESSED_PARAM;
1090 for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1091 if ((plist1->component_kind == DEF_PARAM) && streq(plist->pl.param_type, plist1->pl.param_type) && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1093 char *pntr = strchr(plist1->pl.param_type, '*');
1094 if (pntr) star = "*";
1095 if (plist1->pl.param_flag & OUT_STRING) {
1096 f_print(fout, ", *%s%s", star, plist1->pl.param_name);
1098 f_print(fout, ", %s%s", star, plist1->pl.param_name);
1100 plist1->pl.param_flag |= PROCESSED_PARAM;
1103 f_print(fout, ";\n");
1109 static void cs_ProcMarshallInParams_setup(definition *defp, int split_flag)
1111 int noofparams, i=0;
1114 int noofallparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT] +
1115 defp->pc.paramtypes[OUT];
1117 f_print(fout, "{\n");
1119 f_print(fout, "\tstruct rx_call *z_call = rx_NewCall(z_conn);\n");
1120 if ((!split_flag) || (split_flag == 1)) {
1121 if (opcodesnotallowed[PackageIndex]) {
1122 f_print(fout, "\tstatic int z_op = %d;\n", defp->pc.proc_opcodenum);
1124 f_print(fout, "\tstatic int z_op = %s;\n", defp->pc.proc_opcodename);
1127 f_print(fout, "\tint z_result;\n");
1128 if (!(split_flag > 1) || (noofallparams != 0)) {
1129 f_print(fout, "\tXDR z_xdrs;\n");
1132 * Print out client side stat gathering call
1134 if (xflag && split_flag != 1) {
1135 f_print(fout, "\tstruct clock __QUEUE, __EXEC;\n");
1138 if ((!split_flag) || (split_flag == 1)) {
1139 f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_ENCODE);\n");
1140 f_print(fout, "\n\t/* Marshal the arguments */\n");
1141 f_print(fout, "\tif ((!xdr_int(&z_xdrs, &z_op))");
1142 noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1143 for (plist = defp->pc.plists, dl=defp->def.st.decls; plist; plist = plist->next, dl = dl->next) {
1144 if (plist->component_kind == DEF_PARAM && (plist->pl.param_kind == DEF_INPARAM || plist->pl.param_kind == DEF_INOUTPARAM)) {
1145 f_print(fout, "\n\t || (!%s)", plist->code);
1146 if (++i == noofparams) {
1147 f_print(fout, ") {\n\t\tz_result = RXGEN_CC_MARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1153 f_print(fout, ") {\n\t\tz_result = RXGEN_CC_MARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1160 static void cs_ProcSendPacket_setup(definition *defp, int split_flag)
1162 int noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1164 if (noofoutparams) {
1165 f_print(fout, "\t/* Un-marshal the reply arguments */\n");
1167 f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
1169 f_print(fout, "\tz_xdrs.x_op = XDR_DECODE;\n");
1175 static void cs_ProcUnmarshallOutParams_setup(definition *defp)
1181 noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1183 for (plist = defp->pc.plists, dl=defp->def.st.decls,i = 0; plist; plist = plist->next, dl=dl->next) {
1184 if (plist->component_kind == DEF_PARAM && (plist->pl.param_kind == DEF_OUTPARAM || plist->pl.param_kind == DEF_INOUTPARAM)) {
1186 f_print(fout, "\tif ((!%s)", plist->code);
1188 f_print(fout, "\n\t || (!%s)", plist->code);
1190 if (++i == noofparams) {
1191 f_print(fout, ") {\n\t\tz_result = RXGEN_CC_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1199 static void cs_ProcTail_setup(definition *defp, int split_flag)
1201 f_print(fout, "\tz_result = RXGEN_SUCCESS;\n");
1202 if (defp->can_fail) {
1203 f_print(fout, "fail:\n");
1206 f_print(fout, "\tz_result = rx_EndCall(z_call, z_result);\n");
1208 if (xflag && split_flag != 1) {
1209 f_print(fout, "\tif (rx_enable_stats) {\n");
1210 f_print(fout, "\t clock_GetTime(&__EXEC);\n");
1211 f_print(fout, "\t clock_Sub(&__EXEC, &z_call->startTime);\n");
1212 f_print(fout, "\t __QUEUE = z_call->startTime;\n");
1213 f_print(fout, "\t clock_Sub(&__QUEUE, &z_call->queueTime);\n");
1214 if (PackageStatIndex[PackageIndex]) {
1217 "\t rx_IncrementTimeAndCount(z_conn->peer, %s,\n",
1218 PackageStatIndex[PackageIndex]);
1221 "\t rx_IncrementTimeAndCount(z_call->conn->peer, %s,\n",
1222 PackageStatIndex[PackageIndex]);
1227 "\t rx_IncrementTimeAndCount(z_conn->peer,\n"
1228 "\t\t(((afs_uint32)(ntohs(z_conn->serviceId) << 16)) \n"
1229 "\t\t| ((afs_uint32)ntohs(z_conn->peer->port))),\n");
1232 "\t rx_IncrementTimeAndCount(z_call->conn->peer,\n"
1233 "\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
1234 "\t\t((afs_uint32)ntohs(z_call->conn->peer->port))),\n");
1238 f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
1240 PackagePrefix[PackageIndex]);
1241 f_print(fout, "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 1);\n");
1243 f_print(fout, "\t}\n\n");
1245 f_print(fout, "\treturn z_result;\n}\n\n");
1249 static void ss_Proc_CodeGeneration(definition *defp)
1254 ss_ProcName_setup(defp);
1256 ss_ProcParams_setup(defp, &somefrees);
1257 ss_ProcSpecial_setup(defp, &somefrees);
1258 ss_ProcUnmarshallInParams_setup(defp);
1259 ss_ProcCallRealProc_setup(defp);
1260 ss_ProcMarshallOutParams_setup(defp);
1261 ss_ProcTail_setup(defp, somefrees);
1266 static void ss_ProcName_setup(definition *defp)
1270 if ((strlen(prefix) + strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >= MAX_FUNCTION_NAME_LEN) {
1271 error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1275 f_print(fout, "static afs_int32 _%s%s%s(", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1276 f_print(fout, "struct rx_call *z_call, XDR *z_xdrs)\n{\n");
1277 f_print(fout, "\t" "afs_int32 z_result;\n");
1279 f_print(fout, "\tstruct clock __QUEUE, __EXEC;\n");
1282 for (plist = defp->pc.plists; plist; plist = plist->next)
1283 if (plist->component_kind == DEF_PARAM) {
1284 plist->pl.param_flag &= ~(PROCESSED_PARAM);
1285 plist->pl.string_name = NULL;
1291 static void ss_ProcParams_setup(definition *defp, int *somefrees)
1293 proc1_list *plist, *plist1;
1297 for (plist = defp->pc.plists; plist; plist = plist->next) {
1298 if ((plist->component_kind == DEF_PARAM) && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1299 if (plist->pl.param_flag & INDIRECT_PARAM) {
1300 char pres='\0', *pntr = strchr(plist->pl.param_type, '*');
1301 if (pntr){ --pntr; pres = *pntr; *pntr = (char)0; }
1302 f_print(fout, "\t%s %s", plist->pl.param_type, plist->pl.param_name);
1304 } else if (strchr(plist->pl.param_type, '*') == 0) {
1305 f_print(fout, "\t%s %s", plist->pl.param_type, plist->pl.param_name);
1307 plist->pl.param_flag |= FREETHIS_PARAM;
1309 f_print(fout, "\t%s %s=(%s)0", plist->pl.param_type, plist->pl.param_name, plist->pl.param_type);
1311 plist->pl.param_flag |= PROCESSED_PARAM;
1312 for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1313 if ((plist1->component_kind == DEF_PARAM) && streq(plist->pl.param_type, plist1->pl.param_type) && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1314 if (plist1->pl.param_flag & INDIRECT_PARAM) {
1315 f_print(fout, ", %s", plist1->pl.param_name);
1316 } else if (strchr(plist1->pl.param_type, '*') == 0) {
1317 f_print(fout, ", %s", plist1->pl.param_name);
1319 plist1->pl.param_flag |= FREETHIS_PARAM;
1321 f_print(fout, ", *%s=(%s)0", plist1->pl.param_name, plist1->pl.param_type);
1323 plist1->pl.param_flag |= PROCESSED_PARAM;
1326 f_print(fout, ";\n");
1329 for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1330 defp1 = (definition *)listp->val;
1331 for (plist=defp->pc.plists; plist; plist=plist->next) {
1332 if (plist->component_kind == DEF_PARAM && (plist->pl.param_kind == DEF_OUTPARAM || plist->pl.param_kind == DEF_INOUTPARAM) && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1333 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1334 switch (defp1->pc.rel) {
1343 fprintf(fout, "\n");
1347 static void ss_ProcSpecial_setup(definition *defp, int *somefrees)
1353 for (listp = special_defined; listp != NULL; listp = listp->next) {
1354 defp1 = (definition *)listp->val;
1355 for (plist=defp->pc.plists; plist; plist=plist->next) {
1356 if (plist->component_kind == DEF_PARAM && (plist->pl.param_kind == DEF_INPARAM || plist->pl.param_kind == DEF_INOUTPARAM)) {
1357 spec_list *spec = defp1->def.sd.specs;
1359 strcpy(string, structname(spec->sdef.string_value));
1360 if (streq(string, structname(plist->pl.param_type))) {
1361 plist->pl.string_name = spec->sdef.string_name;
1362 plist->pl.param_flag |= FREETHIS_PARAM;
1364 fprintf(fout, "\n\t%s.%s = 0;", plist->pl.param_name, spec->sdef.string_name);
1370 fprintf(fout, "\n");
1371 for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1372 defp1 = (definition *)listp->val;
1373 for (plist=defp->pc.plists; plist; plist=plist->next) {
1374 if (plist->component_kind == DEF_PARAM ) {
1375 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1376 plist->pl.param_flag |= FREETHIS_PARAM;
1378 switch (defp1->pc.rel) {
1380 f_print(fout, "\n\t%s.%s_val = 0;", plist->pl.param_name, defp1->def_name);
1381 f_print(fout, "\n\t%s.%s_len = 0;", plist->pl.param_name, defp1->def_name);
1382 plist->pl.string_name = alloc(40);
1383 s_print(plist->pl.string_name, "%s_val", defp1->def_name);
1386 f_print(fout, "\n\t%s = 0;", plist->pl.param_name);
1387 plist->pl.string_name = NULL;
1394 f_print(fout, "\n");
1398 static void ss_ProcUnmarshallInParams_setup(definition *defp)
1400 int noofparams, noofoutparams, i;
1403 noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1404 noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1405 for (plist = defp->pc.plists, i=0; plist; plist = plist->next) {
1406 if (plist->component_kind == DEF_PARAM && (plist->pl.param_kind == DEF_INPARAM || plist->pl.param_kind == DEF_INOUTPARAM)) {
1408 f_print(fout, "\n\tif ((!%s)", (plist->scode ? plist->scode : plist->code));
1410 f_print(fout, "\n\t || (!%s)", (plist->scode ? plist->scode : plist->code));
1412 if (++i == noofparams) {
1413 if (!noofoutparams) {
1414 f_print(fout, ") {\n");
1416 f_print(fout, ") {\n");
1418 f_print(fout, "\t\tz_result = RXGEN_SS_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1426 static void ss_ProcCallRealProc_setup(definition *defp)
1431 f_print(fout, "\tz_result = %s%s%s%s(z_call", prefix, ServerPrefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1432 for (plist = defp->pc.plists; plist; plist = plist->next) {
1433 if (plist->component_kind == DEF_PARAM) {
1434 if (plist->pl.param_flag & INDIRECT_PARAM) {
1435 f_print(fout, ", &%s", plist->pl.param_name);
1437 if (plist->pl.param_flag & OUT_STRING) {
1438 f_print(fout, ", &%s", plist->pl.param_name);
1440 f_print(fout, ", %s", plist->pl.param_name);
1445 f_print(fout, ");\n");
1447 f_print(fout, "\tif (z_result)\n\t\treturn z_result;\n");
1452 static void ss_ProcMarshallOutParams_setup(definition *defp)
1457 noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1459 f_print(fout, "\tz_xdrs->x_op = XDR_ENCODE;\n");
1461 for (plist = defp->pc.plists, i=0; plist; plist = plist->next) {
1462 if (plist->component_kind == DEF_PARAM && (plist->pl.param_kind == DEF_OUTPARAM || plist->pl.param_kind == DEF_INOUTPARAM)) {
1464 f_print(fout, "\tif ((!%s)", (plist->scode ? plist->scode : plist->code));
1466 f_print(fout, "\n\t || (!%s)", (plist->scode ? plist->scode : plist->code));
1468 if (++i == noofparams) {
1469 f_print(fout, ")\n\t\tz_result = RXGEN_SS_MARSHAL;\n");
1477 static void ss_ProcTail_setup(definition *defp, int somefrees)
1484 if (defp->can_fail) {
1485 f_print(fout, "fail:\n");
1487 for (plist = defp->pc.plists; plist; plist = plist->next) {
1488 if (plist->component_kind == DEF_PARAM && (plist->pl.param_flag & FREETHIS_PARAM))
1492 f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1493 for (plist = defp->pc.plists; plist; plist = plist->next) {
1494 if (plist->component_kind == DEF_PARAM && (plist->pl.param_flag & FREETHIS_PARAM)) {
1495 char *dot = "", *extens = "";
1496 if (plist->pl.string_name) {
1498 extens = plist->pl.string_name;
1500 f_print(fout, "\tif (!%s) goto fail1;\n", plist->scode);
1503 for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1504 defp1 = (definition *)listp->val;
1505 for (plist=defp->pc.plists; plist; plist=plist->next) {
1506 if (plist->component_kind == DEF_PARAM && (plist->pl.param_kind == DEF_OUTPARAM || plist->pl.param_kind == DEF_INOUTPARAM) && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1507 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1508 switch (defp1->pc.rel) {
1511 if (!somefrees && !firsttime) {
1513 f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1516 f_print(fout, "\tif (!%s) goto fail1;\n", plist->scode);
1523 for (listp = uniondef_defined; listp != NULL; listp = listp->next) {
1524 defp1 = (definition *)listp->val;
1525 for (plist=defp->pc.plists; plist; plist=plist->next) {
1526 if (plist->component_kind == DEF_PARAM && (plist->pl.param_kind == DEF_OUTPARAM || plist->pl.param_kind == DEF_INOUTPARAM) && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1527 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1528 if (plist->pl.param_flag & INDIRECT_PARAM) {
1529 if (!somefrees && !firsttime) {
1531 f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1534 f_print(fout, "\tif (!%s) goto fail1;\n", plist->scode);
1542 f_print(fout, "\tif (rx_enable_stats) {\n");
1543 f_print(fout, "\t clock_GetTime(&__EXEC);\n");
1544 f_print(fout, "\t clock_Sub(&__EXEC, &z_call->startTime);\n");
1545 f_print(fout, "\t __QUEUE = z_call->startTime;\n");
1546 f_print(fout, "\t clock_Sub(&__QUEUE, &z_call->queueTime);\n");
1547 f_print(fout, "\t rx_IncrementTimeAndCount(z_call->conn->peer,");
1548 if (PackageStatIndex[PackageIndex]) {
1549 f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
1552 "\n\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
1553 "\t\t((afs_uint32)ntohs(z_call->conn->service->servicePort))),\n");
1555 f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
1557 PackagePrefix[PackageIndex]);
1558 f_print(fout, "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 0);\n");
1559 f_print(fout, "\t}\n\n");
1562 f_print(fout, "\treturn z_result;\n");
1564 f_print(fout, "fail1:\n");
1567 f_print(fout, "\tif (rx_enable_stats) {\n");
1568 f_print(fout, "\t clock_GetTime(&__EXEC);\n");
1569 f_print(fout, "\t clock_Sub(&__EXEC, &z_call->startTime);\n");
1570 f_print(fout, "\t __QUEUE = z_call->startTime;\n");
1571 f_print(fout, "\t clock_Sub(&__QUEUE, &z_call->queueTime);\n");
1572 f_print(fout, "\t rx_IncrementTimeAndCount(z_call->conn->peer,");
1573 if (PackageStatIndex[PackageIndex]) {
1574 f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
1577 "\n\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
1578 "\t\t((afs_uint32)ntohs(z_call->conn->service->servicePort))),\n");
1580 f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
1582 PackagePrefix[PackageIndex]);
1583 f_print(fout, "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 0);\n");
1584 f_print(fout, "\t}\n\n");
1587 f_print(fout, "\treturn RXGEN_SS_XDRFREE;\n}\n\n");
1589 f_print(fout, "}\n\n");
1594 static int opcode_holes_exist(void)
1598 for (i=lowest_opcode[PackageIndex]; i<highest_opcode[PackageIndex]; i++) {
1599 if (!opcodenum_is_defined(i))
1606 void er_Proc_CodeGeneration(void)
1610 temp = PackageIndex;
1611 if (!combinepackages) PackageIndex = 0;
1612 for (; PackageIndex <= temp; PackageIndex++) {
1613 if (proc_defined[PackageIndex] == NULL) continue;
1614 if (combinepackages || opcode_holes_exist()) {
1615 er_HeadofOldStyleProc_setup();
1616 er_BodyofOldStyleProc_setup();
1617 er_TailofOldStyleProc_setup();
1619 er_ProcDeclExterns_setup();
1620 er_ProcProcsArray_setup();
1621 er_ProcMainBody_setup();
1624 PackageIndex = temp;
1628 static void er_ProcDeclExterns_setup(void)
1633 f_print(fout, "\n");
1634 for (listp = proc_defined[PackageIndex]; listp != NULL; listp = listp->next) {
1635 defp = (definition *)listp->val;
1636 if (defp->pc.proc_serverstub) {
1637 f_print(fout, "afs_int32 %s();\n", defp->pc.proc_serverstub);
1643 static void er_ProcProcsArray_setup(void)
1648 if ((listp = proc_defined[PackageIndex])) {
1649 defp = (definition *)listp->val;
1650 if (defp->pc.proc_serverstub){
1651 f_print(fout, "\nstatic afs_int32 (*StubProcsArray%d[])() = {%s",
1652 PackageIndex, defp->pc.proc_serverstub);
1655 "\nstatic afs_int32 (*StubProcsArray%d[])(struct rx_call *z_call, XDR *z_xdrs) = {_%s%s%s",
1656 PackageIndex, prefix, defp->pc.proc_prefix,
1657 ((definition *)listp->val)->pc.proc_name);
1658 defp = (definition *)listp->val;
1660 listp = listp->next;
1662 for (; listp != NULL; listp = listp->next) {
1663 defp = (definition *)listp->val;
1664 if (defp->pc.proc_serverstub) {
1665 f_print(fout, ",%s", defp->pc.proc_serverstub);
1667 f_print(fout, ", _%s%s%s", prefix, defp->pc.proc_prefix, defp->pc.proc_name);
1670 f_print(fout, "};\n\n");
1674 static void er_ProcMainBody_setup(void)
1676 f_print(fout, "int %s%sExecuteRequest(register struct rx_call *z_call)\n", prefix, PackagePrefix[PackageIndex]);
1677 f_print(fout, "{\n\tint op;\n");
1678 f_print(fout, "\tXDR z_xdrs;\n");
1679 f_print(fout, "\t" "afs_int32 z_result;\n\n");
1680 f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
1681 f_print(fout, "\tif (!xdr_int(&z_xdrs, &op))\n\t\tz_result = RXGEN_DECODE;\n");
1682 f_print(fout, "\telse if (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\tz_result = RXGEN_OPCODE;\n", PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
1683 f_print(fout, "\telse\n\t\tz_result = (*StubProcsArray%d[op - %sLOWEST_OPCODE])(z_call, &z_xdrs);\n", PackageIndex, PackagePrefix[PackageIndex]);
1684 f_print(fout, "\treturn hton_syserr_conv(z_result);\n}\n");
1688 static void er_HeadofOldStyleProc_setup(void)
1690 f_print(fout, "\nint %s%sExecuteRequest (register struct rx_call *z_call)\n",
1691 prefix, (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
1692 f_print(fout, "{\n");
1693 f_print(fout, "\tint op;\n");
1694 f_print(fout, "\tXDR z_xdrs;\n");
1695 f_print(fout, "\t" "afs_int32 z_result;\n\n");
1696 f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
1697 f_print(fout, "\tz_result = RXGEN_DECODE;\n");
1698 f_print(fout, "\tif (!xdr_int(&z_xdrs, &op)) goto fail;\n");
1699 f_print(fout, "\tswitch (op) {\n");
1702 static void er_BodyofOldStyleProc_setup(void)
1706 if (combinepackages) {
1707 int temp = PackageIndex;
1708 for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
1709 for (listp = proc_defined[PackageIndex]; listp != NULL; listp = listp->next)
1710 proc_er_case((definition *)listp->val);
1712 PackageIndex = temp;
1714 for (listp = proc_defined[PackageIndex]; listp != NULL; listp = listp->next)
1715 proc_er_case((definition *)listp->val);
1720 static void proc_er_case(definition *defp)
1722 if (opcodesnotallowed[PackageIndex]) {
1723 f_print(fout, "\t\tcase %d:\n", defp->pc.proc_opcodenum);
1725 f_print(fout, "\t\tcase %s:\n", defp->pc.proc_opcodename);
1727 if (defp->pc.proc_serverstub) {
1728 f_print(fout, "\t\t\tz_result = %s(z_call, &z_xdrs);\n", defp->pc.proc_serverstub);
1730 f_print(fout, "\t\t\tz_result = _%s%s%s(z_call, &z_xdrs);\n", prefix, defp->pc.proc_prefix, defp->pc.proc_name);
1732 f_print(fout, "\t\t\tbreak;\n");
1736 static void er_TailofOldStyleProc_setup(void)
1738 f_print(fout, "\t\tdefault:\n");
1739 f_print(fout, "\t\t\tz_result = RXGEN_OPCODE;\n");
1740 f_print(fout, "\t\t\tbreak;\n\t}\n");
1741 f_print(fout, "fail:\n");
1742 f_print(fout, "\treturn z_result;\n}\n");
1746 void h_opcode_stats(void)
1748 if (combinepackages) {
1749 f_print(fout, "\n/* Opcode-related useful stats for Master package: %s */\n", MasterPrefix);
1750 f_print(fout, "#define %sLOWEST_OPCODE %d\n", MasterPrefix, master_lowest_opcode);
1751 f_print(fout, "#define %sHIGHEST_OPCODE %d\n", MasterPrefix, master_highest_opcode);
1752 f_print(fout, "#define %sNUMBER_OPCODES %d\n\n", MasterPrefix, master_no_of_opcodes);
1754 f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n", MasterPrefix, no_of_stat_funcs_header[0]);
1755 f_print(fout, "AFS_RXGEN_EXPORT\n");
1756 f_print(fout, "extern const char *%sfunction_names[];\n\n", MasterPrefix);
1760 for (i=0; i <= PackageIndex; i++) {
1761 f_print(fout, "\n/* Opcode-related useful stats for package: %s */\n", PackagePrefix[i]);
1762 f_print(fout, "#define %sLOWEST_OPCODE %d\n", PackagePrefix[i], lowest_opcode[i]);
1763 f_print(fout, "#define %sHIGHEST_OPCODE %d\n", PackagePrefix[i], highest_opcode[i]);
1764 f_print(fout, "#define %sNUMBER_OPCODES %d\n\n", PackagePrefix[i], no_of_opcodes[i]);
1766 f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n", PackagePrefix[i], no_of_stat_funcs_header[i]);
1767 f_print(fout, "AFS_RXGEN_EXPORT\n");
1768 f_print(fout, "extern const char *%sfunction_names[];\n\n", PackagePrefix[i]);
1775 void generate_multi_macros(definition *defp)
1777 char *startname = SplitStart, *endname = SplitEnd;
1785 f_print(fout, "\n#include <rx/rx_multi.h>");
1787 f_print(fout, "\n#define multi_%s%s(", PackagePrefix[PackageIndex],defp->pc.proc_name);
1788 for (plist = defp->pc.plists; plist; plist = plist->next) {
1789 if (plist->component_kind == DEF_PARAM) {
1792 f_print(fout, "%s", plist->pl.param_name);
1794 f_print(fout, ", %s", plist->pl.param_name);
1798 f_print(fout, ") \\\n");
1799 if (!startname) startname = "Start";
1800 if (!endname) endname = "End";
1801 f_print(fout, "\tmulti_Body(%s%s%s(multi_call", startname, PackagePrefix[PackageIndex], defp->pc.proc_name);
1802 do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 0);
1803 for (plist = defp->pc.plists; plist; plist = plist->next) {
1804 if (plist->component_kind == DEF_PARAM)
1805 f_print(fout, ", %s", plist->pl.param_name);
1807 do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 1);
1808 f_print(fout, "), %s%s%s(multi_call", endname, PackagePrefix[PackageIndex], defp->pc.proc_name);
1809 do_split(defp, IN, &numofparams, DEF_INPARAM, 0);
1810 for (plist = defp->pc.plists; plist; plist = plist->next) {
1811 if (plist->component_kind == DEF_PARAM) {
1812 f_print(fout, ", %s", plist->pl.param_name);
1815 do_split(defp, IN, &numofparams, DEF_INPARAM, 1);
1816 f_print(fout, "))\n\n");
1820 int IsRxgenToken(token *tokp)
1822 if (tokp->kind == TOK_PACKAGE || tokp->kind == TOK_PREFIX ||
1823 tokp->kind == TOK_SPECIAL || tokp->kind == TOK_STARTINGOPCODE ||
1824 tokp->kind == TOK_SPLITPREFIX || tokp->kind == TOK_PROC ||
1825 tokp->kind == TOK_STATINDEX)
1830 int IsRxgenDefinition(definition *def)
1832 if (def->def_kind == DEF_PACKAGE || def->def_kind == DEF_PREFIX || def->def_kind == DEF_SPECIAL || def->def_kind == DEF_STARTINGOPCODE || def->def_kind == DEF_SPLITPREFIX || def->def_kind == DEF_PROC)