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>
52 #include "rpc_parse.h"
55 list *proc_defined[MAX_PACKAGES], *special_defined, *typedef_defined,
57 char *SplitStart = NULL;
58 char *SplitEnd = NULL;
59 char *MasterPrefix = NULL;
60 char *ServerPrefix = "";
61 char *PackagePrefix[MAX_PACKAGES];
62 char *PackageStatIndex[MAX_PACKAGES];
63 int no_of_stat_funcs = 0; /*
64 * current function number in client interface
67 int no_of_stat_funcs_header[MAX_PACKAGES]; /*
68 * Total number of functions in client
71 int no_of_opcodes[MAX_PACKAGES], master_no_of_opcodes = 0;
72 int lowest_opcode[MAX_PACKAGES], master_lowest_opcode = 99999;
73 int highest_opcode[MAX_PACKAGES], master_highest_opcode = 0;
74 int master_opcodenumber = 99999;
75 int opcodesnotallowed[MAX_PACKAGES];
76 int combinepackages = 0;
77 int PackageIndex = -1;
78 int PerProcCounter = 0;
82 * Character arrays to keep list of function names as we process the file
85 char function_list[MAX_PACKAGES]
86 [MAX_FUNCTIONS_PER_PACKAGE]
87 [MAX_FUNCTION_NAME_LEN];
88 int function_list_index;
90 /* static prototypes */
91 static void isdefined(definition * defp);
92 static void def_struct(definition * defp);
93 static void def_program(definition * defp);
94 static void def_enum(definition * defp);
95 static void def_const(definition * defp);
96 static void def_union(definition * defp);
97 static void def_typedef(definition * defp);
98 static void get_declaration(declaration * dec, defkind dkind);
99 static void get_type(char **prefixp, char **typep, defkind dkind);
100 static void unsigned_dec(char **typep);
101 static void def_package(definition * defp);
102 static void def_prefix(definition * defp);
103 static void def_statindex(definition * defp);
104 static void def_startingopcode(definition * defp);
105 static void def_split(definition * defp);
106 static void customize_struct(definition * defp);
107 static char *structname(char *name);
108 static void def_special(declaration * dec, definition * defp);
109 static void check_proc(definition * defp, token * tokp, int noname);
110 static int InvalidConstant(char *name);
111 static int opcodenum_is_defined(int opcode_num);
112 static void analyze_ProcParams(definition * defp, token * tokp);
113 static void generate_code(definition * defp, int proc_split_flag,
115 static void handle_split_proc(definition * defp, int multi_flag);
116 static void do_split(definition * defp, int direction, int *numofparams,
117 defkind param_kind, int restore_flag);
118 static void hdle_param_tok(definition * defp, declaration * dec, token * tokp,
120 static void get1_param_type(definition * defp, declaration * dec,
122 static void get_param_type(definition * defp, declaration * dec,
123 char **param_type, char **typename);
125 static void hndle_param_tail(definition * defp, declaration * dec,
126 token * tokp, char *typename);
128 static void cs_Proc_CodeGeneration(definition * defp, int split_flag,
130 static void cs_ProcName_setup(definition * defp, char *procheader,
132 static void cs_ProcParams_setup(definition * defp, int split_flag);
133 static void cs_ProcMarshallInParams_setup(definition * defp, int split_flag);
134 static void cs_ProcSendPacket_setup(definition * defp, int split_flag);
135 static void cs_ProcUnmarshallOutParams_setup(definition * defp);
136 static void cs_ProcTail_setup(definition * defp, int split_flag);
137 static void ucs_ProcName_setup(definition * defp, char *procheader,
139 static void ucs_ProcParams_setup(definition * defp, int split_flag);
140 static void ucs_ProcTail_setup(definition * defp, int split_flag);
141 static void ss_Proc_CodeGeneration(definition * defp);
142 static void ss_ProcName_setup(definition * defp);
143 static void ss_ProcParams_setup(definition * defp, int *somefrees);
144 static void ss_ProcSpecial_setup(definition * defp, int *somefrees);
145 static void ss_ProcUnmarshallInParams_setup(definition * defp);
146 static void ss_ProcCallRealProc_setup(definition * defp);
147 static void ss_ProcMarshallOutParams_setup(definition * defp);
148 static void ss_ProcTail_setup(definition * defp, int somefrees);
149 static int opcode_holes_exist(void);
150 static void er_ProcDeclExterns_setup(void);
151 static void er_ProcProcsArray_setup(void);
152 static void er_ProcMainBody_setup(void);
153 static void er_HeadofOldStyleProc_setup(void);
154 static void er_BodyofOldStyleProc_setup(void);
155 static void proc_er_case(definition * defp);
156 static void er_TailofOldStyleProc_setup(void);
161 * return the next definition you see
169 defp = ALLOC(definition);
170 memset((char *)defp, 0, sizeof(definition));
206 def_special(&dec, defp);
209 case TOK_STARTINGOPCODE:
210 def_startingopcode(defp);
215 customize_struct(defp);
217 case TOK_SPLITPREFIX:
222 if (tok.kind == TOK_LPAREN) {
224 check_proc(defp, &tok, 1);
226 check_proc(defp, &tok, 0);
229 check_proc(defp, &tok, 0);
233 check_proc(defp, &tok, 1);
236 error("definition keyword expected");
238 if (!IsRxgenToken(&tok)) {
239 scan(TOK_SEMICOLON, &tok);
247 isdefined(definition * defp)
249 STOREVAL(&defined, defp);
254 def_struct(definition * defp)
261 defp->def_kind = DEF_STRUCT;
263 scan(TOK_IDENT, &tok);
264 defp->def_name = tok.str;
265 scan(TOK_LBRACE, &tok);
266 tailp = &defp->def.st.decls;
268 get_declaration(&dec, DEF_STRUCT);
269 decls = ALLOC(decl_list);
272 tailp = &decls->next;
273 scan(TOK_SEMICOLON, &tok);
275 } while (tok.kind != TOK_RBRACE);
281 def_program(definition * defp)
285 version_list **vtailp;
289 defp->def_kind = DEF_PROGRAM;
290 scan(TOK_IDENT, &tok);
291 defp->def_name = tok.str;
292 scan(TOK_LBRACE, &tok);
293 vtailp = &defp->def.pr.versions;
294 scan(TOK_VERSION, &tok);
296 scan(TOK_IDENT, &tok);
297 vlist = ALLOC(version_list);
298 vlist->vers_name = tok.str;
299 scan(TOK_LBRACE, &tok);
300 ptailp = &vlist->procs;
302 plist = ALLOC(proc_list);
303 get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM);
304 if (streq(plist->res_type, "opaque")) {
305 error("illegal result type");
307 scan(TOK_IDENT, &tok);
308 plist->proc_name = tok.str;
309 scan(TOK_LPAREN, &tok);
310 get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM);
311 if (streq(plist->arg_type, "opaque")) {
312 error("illegal argument type");
314 scan(TOK_RPAREN, &tok);
315 scan(TOK_EQUAL, &tok);
317 scan(TOK_SEMICOLON, &tok);
318 plist->proc_num = tok.str;
320 ptailp = &plist->next;
322 } while (tok.kind != TOK_RBRACE);
324 vtailp = &vlist->next;
325 scan(TOK_RBRACE, &tok);
326 scan(TOK_EQUAL, &tok);
328 vlist->vers_num = tok.str;
329 scan(TOK_SEMICOLON, &tok);
330 scan2(TOK_VERSION, TOK_RBRACE, &tok);
331 } while (tok.kind == TOK_VERSION);
332 scan(TOK_EQUAL, &tok);
334 defp->def.pr.prog_num = tok.str;
339 def_enum(definition * defp)
343 enumval_list **tailp;
345 defp->def_kind = DEF_ENUM;
346 scan(TOK_IDENT, &tok);
347 defp->def_name = tok.str;
348 scan(TOK_LBRACE, &tok);
349 tailp = &defp->def.en.vals;
351 scan(TOK_IDENT, &tok);
352 elist = ALLOC(enumval_list);
353 elist->name = tok.str;
354 elist->assignment = NULL;
355 scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
356 if (tok.kind == TOK_EQUAL) {
358 elist->assignment = tok.str;
359 scan2(TOK_COMMA, TOK_RBRACE, &tok);
362 tailp = &elist->next;
363 } while (tok.kind != TOK_RBRACE);
368 def_const(definition * defp)
372 defp->def_kind = DEF_CONST;
373 scan(TOK_IDENT, &tok);
374 defp->def_name = tok.str;
375 scan(TOK_EQUAL, &tok);
376 scan2(TOK_IDENT, TOK_STRCONST, &tok);
377 defp->def.co = tok.str;
381 def_union(definition * defp)
388 defp->def_kind = DEF_UNION;
389 scan(TOK_IDENT, &tok);
390 defp->def_name = tok.str;
391 scan(TOK_SWITCH, &tok);
392 scan(TOK_LPAREN, &tok);
393 get_declaration(&dec, DEF_UNION);
394 defp->def.un.enum_decl = dec;
395 tailp = &defp->def.un.cases;
396 scan(TOK_RPAREN, &tok);
397 scan(TOK_LBRACE, &tok);
398 scan(TOK_CASE, &tok);
399 while (tok.kind == TOK_CASE) {
400 scan(TOK_IDENT, &tok);
401 cases = ALLOC(case_list);
402 cases->case_name = tok.str;
403 scan(TOK_COLON, &tok);
404 get_declaration(&dec, DEF_UNION);
405 cases->case_decl = dec;
407 tailp = &cases->next;
408 scan(TOK_SEMICOLON, &tok);
409 scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
412 if (tok.kind == TOK_DEFAULT) {
413 scan(TOK_COLON, &tok);
414 get_declaration(&dec, DEF_UNION);
415 defp->def.un.default_decl = ALLOC(declaration);
416 *defp->def.un.default_decl = dec;
417 scan(TOK_SEMICOLON, &tok);
418 scan(TOK_RBRACE, &tok);
420 defp->def.un.default_decl = NULL;
426 def_typedef(definition * defp)
430 defp->def_kind = DEF_TYPEDEF;
431 get_declaration(&dec, DEF_TYPEDEF);
432 defp->def_name = dec.name;
433 defp->def.ty.old_prefix = dec.prefix;
434 defp->def.ty.old_type = dec.type;
435 defp->def.ty.rel = dec.rel;
436 defp->def.ty.array_max = dec.array_max;
441 get_declaration(declaration * dec, defkind dkind)
445 get_type(&dec->prefix, &dec->type, dkind);
446 dec->rel = REL_ALIAS;
447 if (streq(dec->type, "void")) {
450 scan2(TOK_STAR, TOK_IDENT, &tok);
451 if (tok.kind == TOK_STAR) {
452 dec->rel = REL_POINTER;
453 scan(TOK_IDENT, &tok);
456 if (peekscan(TOK_LBRACKET, &tok)) {
457 if (dec->rel == REL_POINTER) {
458 error("no array-of-pointer declarations -- use typedef");
460 dec->rel = REL_VECTOR;
462 dec->array_max = tok.str;
463 scan(TOK_RBRACKET, &tok);
464 } else if (peekscan(TOK_LANGLE, &tok)) {
465 if (dec->rel == REL_POINTER) {
466 error("no array-of-pointer declarations -- use typedef");
468 dec->rel = REL_ARRAY;
469 if (peekscan(TOK_RANGLE, &tok)) {
470 dec->array_max = "~0"; /* unspecified size, use max */
473 dec->array_max = tok.str;
474 scan(TOK_RANGLE, &tok);
477 if (streq(dec->type, "opaque")) {
478 if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
479 error("array declaration expected");
481 } else if (streq(dec->type, "string")) {
482 if (dec->rel != REL_ARRAY) {
483 error(" variable-length array declaration expected");
490 get_type(char **prefixp, char **typep, defkind dkind)
504 scan(TOK_IDENT, &tok);
512 (void)peekscan(TOK_INT, &tok);
515 *typep = "afs_int32";
516 (void)peekscan(TOK_INT, &tok);
519 if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
520 error("voids allowed only inside union and program definitions");
535 error("expected type specifier");
541 unsigned_dec(char **typep)
554 (void)peekscan(TOK_INT, &tok);
558 *typep = "afs_uint32";
559 (void)peekscan(TOK_INT, &tok);
573 def_package(definition * defp)
577 defp->def_kind = DEF_PACKAGE;
578 scan(TOK_IDENT, &tok);
579 defp->def_name = tok.str;
580 no_of_stat_funcs = 0;
581 if (PackageIndex++ >= MAX_PACKAGES)
582 error("Exceeded upper limit of package statements\n");
583 function_list_index = 0;
584 PackagePrefix[PackageIndex] = tok.str;
585 if (MasterPrefix == NULL)
586 MasterPrefix = tok.str;
587 no_of_opcodes[PackageIndex] = highest_opcode[PackageIndex] =
588 opcodesnotallowed[PackageIndex] = 0;
589 lowest_opcode[PackageIndex] = 99999;
590 proc_defined[PackageIndex] = NULL;
591 PackageStatIndex[PackageIndex] = NULL;
595 def_prefix(definition * defp)
599 defp->def_kind = DEF_PREFIX;
600 scan(TOK_IDENT, &tok);
601 defp->def_name = tok.str;
602 ServerPrefix = tok.str;
606 def_statindex(definition * defp)
611 defp->def_kind = DEF_CONST;
613 if (PackageIndex < 0)
614 error("'statindex' command must follow 'package' command!\n");
615 if (PackageStatIndex[PackageIndex])
616 error("Cannot have more then one 'statindex' per package!\n");
617 if (InvalidConstant(tok.str))
618 error("Index in 'statindex' command must be a constant!");
620 alloc(strlen(PackagePrefix[PackageIndex]) + strlen("STATINDEX") + 1);
621 strcpy(name, PackagePrefix[PackageIndex]);
622 strcat(name, "STATINDEX");
623 defp->def_name = name;
624 defp->def.co = tok.str;
625 PackageStatIndex[PackageIndex] = name;
629 def_startingopcode(definition * defp)
633 defp->def_kind = DEF_STARTINGOPCODE;
634 scan(TOK_IDENT, &tok);
635 defp->def_name = tok.str;
636 if (InvalidConstant(defp->def_name))
637 error("Opcode in 'startingopcode' command must be a constant!");
638 lowest_opcode[PackageIndex] = master_lowest_opcode = atoi(tok.str);
639 if (lowest_opcode[PackageIndex] < 0
640 || lowest_opcode[PackageIndex] > 99999)
642 ("startingopcode number is out of bounds (must be >= 0 < 100000)");
643 master_opcodenumber = lowest_opcode[PackageIndex];
644 opcodesnotallowed[PackageIndex] = 1;
648 def_split(definition * defp)
652 defp->def_kind = DEF_SPLITPREFIX;
657 scan(TOK_EQUAL, &tok);
658 scan(TOK_IDENT, &tok);
659 SplitStart = tok.str;
662 scan(TOK_EQUAL, &tok);
663 scan(TOK_IDENT, &tok);
669 error("syntax error in the 'splitprefix' line");
671 } while (tok.kind != TOK_SEMICOLON);
672 if (!SplitStart && !SplitEnd)
673 error("At least one param should be passed to 'splitprefix' cmd");
678 customize_struct(definition * defp)
682 definition *defp1 = ALLOC(definition);
683 spec_list *specs, **tailp;
685 defp->def_kind = DEF_CUSTOMIZED;
686 defp1->def_kind = DEF_SPECIAL;
687 tailp = &defp1->def.sd.specs;
688 for (listp = defp->def.st.decls; listp; listp = listp->next) {
690 if (streq(dec->type, "string") || (dec->rel == REL_POINTER)) {
691 specs = ALLOC(spec_list);
692 specs->sdef.string_name = dec->name;
693 specs->sdef.string_value = defp->def_name;
695 tailp = &specs->next;
699 STOREVAL(&special_defined, defp1);
703 structname(char *name)
705 static char namecontents[150];
708 strcpy(namecontents, name);
710 if (!strncmp(pnt, "struct", 6))
712 while (isspace(*pnt))
715 while (*pnt != ' ' && *pnt != '\0')
723 def_special(declaration * dec, definition * defp)
726 spec_list *specs, **tailp;
729 defp->def_kind = DEF_SPECIAL;
730 get_type(&dec->prefix, &dec->type, DEF_SPECIAL);
731 dec->rel = REL_POINTER;
732 scan(TOK_IDENT, &tok);
733 tailp = &defp->def.sd.specs;
735 specs = ALLOC(spec_list);
736 specs->sdef.string_name = tok.str;
737 get_param_type(defp, dec, &specs->sdef.string_value, &typename);
739 tailp = &specs->next;
740 scan2(TOK_COMMA, TOK_SEMICOLON, &tok);
741 if (tok.kind == TOK_SEMICOLON)
744 } while (tok.kind == TOK_IDENT);
746 STOREVAL(&special_defined, defp);
750 proc1_list *Proc_list, **Proc_listp;
753 check_proc(definition * defp, token * tokp, int noname)
759 if (PackageIndex < 0)
760 error("Procedure must be in a package!\n");
762 tokp->kind = TOK_PROC;
763 defp->def_kind = DEF_PROC;
765 defp->pc.proc_name = "";
767 defp->pc.proc_name = tokp->str;
769 defp->pc.proc_prefix = alloc(strlen(PackagePrefix[PackageIndex]) + 1);
770 strcpy(defp->pc.proc_prefix, PackagePrefix[PackageIndex]);
771 scan2(TOK_LPAREN, TOK_IDENT, &tok);
772 defp->pc.proc_serverstub = NULL;
773 if (tok.kind == TOK_IDENT) {
774 defp->pc.proc_serverstub = tok.str;
775 scan(TOK_LPAREN, &tok);
777 analyze_ProcParams(defp, &tok);
778 defp->pc.proc_opcodenum = -1;
779 scan4(TOK_SPLIT, TOK_MULTI, TOK_EQUAL, TOK_SEMICOLON, &tok);
780 if (tok.kind == TOK_MULTI) {
782 defp->pc.multi_flag = 1;
783 scan2(TOK_EQUAL, TOK_SEMICOLON, &tok);
785 defp->pc.multi_flag = 0;
787 if (tok.kind == TOK_SPLIT) {
789 defp->pc.split_flag = 1;
790 scan2(TOK_EQUAL, TOK_SEMICOLON, &tok);
792 defp->pc.split_flag = 0;
794 if (tok.kind == TOK_EQUAL) {
795 if (opcodesnotallowed[PackageIndex])
796 error("Opcode assignment isn't allowed here!");
798 if (InvalidConstant(tok.str))
799 error("Illegal Opcode assignment (Must be a constant opcode!)");
800 if (opcodenum_is_defined(atoi(tok.str)))
801 error("The opcode number is already used by a previous proc");
802 defp->pc.proc_opcodename = tok.str;
803 defp->pc.proc_opcodenum = atoi(tok.str);
804 if (defp->pc.proc_opcodenum < lowest_opcode[PackageIndex])
805 lowest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
806 if (defp->pc.proc_opcodenum < master_lowest_opcode)
807 master_lowest_opcode = defp->pc.proc_opcodenum;
808 if (defp->pc.proc_opcodenum > highest_opcode[PackageIndex])
809 highest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
810 if (defp->pc.proc_opcodenum > master_highest_opcode)
811 master_highest_opcode = defp->pc.proc_opcodenum;
812 scan(TOK_SEMICOLON, &tok);
814 if (master_opcodenumber == 99999)
815 master_opcodenumber = 0;
816 defp->pc.proc_opcodenum = master_opcodenumber++;
817 if (defp->pc.proc_opcodenum < lowest_opcode[PackageIndex])
818 lowest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
819 if (defp->pc.proc_opcodenum > highest_opcode[PackageIndex])
820 highest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
821 if (defp->pc.proc_opcodenum > master_highest_opcode)
822 master_highest_opcode = defp->pc.proc_opcodenum;
823 opcodesnotallowed[PackageIndex] = 1; /* force it */
825 no_of_opcodes[PackageIndex]++, master_no_of_opcodes++;
827 generate_code(defp, 0, 1);
828 if (Cflag || cflag) {
829 generate_code(defp, 1, 1);
831 generate_multi_macros(defp);
833 generate_code(defp, proc_split, 0);
836 if (function_list_index >= MAX_FUNCTIONS_PER_INTERFACE) {
837 error("too many functions in interface, "
838 "increase MAX_FUNCTIONS_PER_INTERFACE");
840 sprintf(function_list[PackageIndex][function_list_index], "%s%s%s",
841 prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
843 function_list_index++;
844 no_of_stat_funcs_header[PackageIndex]++;
850 #define LEGALNUMS "0123456789"
852 InvalidConstant(char *name)
858 slen = (int)strlen(name);
859 return (slen != strspn(name, map));
863 opcodenum_is_defined(int opcode_num)
868 for (listp = proc_defined[PackageIndex]; listp != NULL;
869 listp = listp->next) {
870 defp = (definition *) listp->val;
871 if (opcode_num == defp->pc.proc_opcodenum)
879 analyze_ProcParams(definition * defp, token * tokp)
882 decl_list *decls, **tailp;
884 Proc_listp = &defp->pc.plists;
885 tailp = &defp->def.st.decls;
888 Proc_list = ALLOC(proc1_list);
889 memset((char *)Proc_list, 0, sizeof(proc1_list));
890 Proc_list->pl.param_flag = 0;
891 switch (tokp->kind) {
893 hdle_param_tok(defp, &dec, tokp, DEF_INPARAM);
896 hdle_param_tok(defp, &dec, tokp, DEF_OUTPARAM);
899 hdle_param_tok(defp, &dec, tokp, DEF_INOUTPARAM);
905 hdle_param_tok(defp, &dec, tokp, DEF_NULL);
908 *Proc_listp = Proc_list;
909 Proc_listp = &Proc_list->next;
910 decls = ALLOC(decl_list);
911 memset((char *)decls, 0, sizeof(decl_list));
912 if (tokp->kind != TOK_RPAREN)
915 tailp = &decls->next;
916 } while (tokp->kind != TOK_RPAREN);
922 generate_code(definition * defp, int proc_split_flag, int multi_flag)
925 handle_split_proc(defp, multi_flag);
927 if (Cflag || cflag) {
928 cs_Proc_CodeGeneration(defp, 0, "");
931 ss_Proc_CodeGeneration(defp);
934 STOREVAL(&proc_defined[PackageIndex], defp);
939 handle_split_proc(definition * defp, int multi_flag)
941 char *startname = SplitStart, *endname = SplitEnd;
948 if (Cflag || cflag) {
950 do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 0);
952 cs_Proc_CodeGeneration(defp, 1, startname);
954 do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 1);
955 do_split(defp, IN, &numofparams, DEF_INPARAM, 0);
957 cs_Proc_CodeGeneration(defp, (multi_flag ? 3 : 2), endname);
959 do_split(defp, IN, &numofparams, DEF_INPARAM, 1);
963 ss_Proc_CodeGeneration(defp);
968 do_split(definition * defp, int direction, int *numofparams,
969 defkind param_kind, int restore_flag)
974 defp->pc.paramtypes[direction] = *numofparams;
975 for (plist = defp->pc.plists; plist; plist = plist->next) {
976 if (plist->component_kind == DEF_NULL
977 && plist->pl.param_kind == param_kind)
978 plist->component_kind = DEF_PARAM;
981 *numofparams = defp->pc.paramtypes[direction];
982 defp->pc.paramtypes[direction] = 0;
983 for (plist = defp->pc.plists; plist; plist = plist->next) {
984 if (plist->component_kind == DEF_PARAM
985 && plist->pl.param_kind == param_kind)
986 plist->component_kind = DEF_NULL;
993 hdle_param_tok(definition * defp, declaration * dec, token * tokp,
996 static defkind last_param_kind = DEF_NULL;
998 if (par_kind == DEF_NULL)
999 Proc_list->pl.param_kind = last_param_kind;
1001 Proc_list->pl.param_kind = par_kind;
1002 last_param_kind = Proc_list->pl.param_kind;
1003 defp->pc.paramtypes[(int)last_param_kind]++;
1004 Proc_list->component_kind = DEF_PARAM;
1005 Proc_list->code = alloc(250);
1006 Proc_list->scode = alloc(250);
1007 get_declaration(dec, DEF_PARAM);
1008 Proc_list->pl.param_name = dec->name;
1009 get1_param_type(defp, dec, &Proc_list->pl.param_type);
1011 scan2(TOK_COMMA, TOK_RPAREN, tokp);
1012 if (tokp->kind == TOK_COMMA)
1018 get1_param_type(definition * defp, declaration * dec, char **param_type)
1020 char typecontents[100];
1022 if (streq(dec->type, "string")) {
1023 *param_type = "char *";
1026 strcpy(typecontents, dec->prefix);
1027 strcat(typecontents, " ");
1028 strcat(typecontents, dec->type);
1029 strcat(typecontents, " *");
1030 } else if (dec->rel == REL_POINTER) {
1031 strcpy(typecontents, dec->type);
1032 strcat(typecontents, " *");
1034 strcpy(typecontents, dec->type);
1035 *param_type = alloc(100);
1036 strcpy(*param_type, typecontents);
1042 get_param_type(definition * defp, declaration * dec, char **param_type,
1045 char typecontents[100];
1047 if (streq(dec->type, "string")) {
1048 *typename = "wrapstring";
1049 *param_type = "char *";
1051 *typename = dec->type;
1053 strcpy(typecontents, dec->prefix);
1054 strcat(typecontents, " ");
1055 strcat(typecontents, dec->type);
1056 strcat(typecontents, " *");
1057 dec->rel = REL_POINTER;
1058 } else if (dec->rel == REL_POINTER) {
1059 strcpy(typecontents, dec->type);
1060 strcat(typecontents, " *");
1062 strcpy(typecontents, dec->type);
1063 *param_type = alloc(100);
1064 strcpy(*param_type, typecontents);
1071 hndle_param_tail(definition * defp, declaration * dec, token * tokp,
1076 if (dec->rel == REL_POINTER)
1077 Proc_list->pl.param_flag |= INDIRECT_PARAM;
1079 Proc_list->pl.param_flag &= ~INDIRECT_PARAM;
1081 if (!(Proc_list->pl.param_flag & INDIRECT_PARAM))
1084 sprintf(Proc_list->code, "xdr_%s(&z_xdrs, %s%s)", typename, amp,
1085 Proc_list->pl.param_name);
1086 sprintf(Proc_list->scode, "xdr_%s(z_xdrs, &%s)", typename,
1087 Proc_list->pl.param_name);
1088 scan2(TOK_COMMA, TOK_RPAREN, tokp);
1089 if (tokp->kind == TOK_COMMA)
1096 cs_Proc_CodeGeneration(definition * defp, int split_flag, char *procheader)
1099 cs_ProcName_setup(defp, procheader, split_flag);
1101 cs_ProcParams_setup(defp, split_flag);
1102 cs_ProcMarshallInParams_setup(defp, split_flag);
1103 if (split_flag != 1) {
1104 cs_ProcSendPacket_setup(defp, split_flag);
1105 cs_ProcUnmarshallOutParams_setup(defp);
1107 cs_ProcTail_setup(defp, split_flag);
1110 if (!kflag && !split_flag && uflag) {
1111 ucs_ProcName_setup(defp, "ubik_", split_flag);
1113 ucs_ProcParams_setup(defp, split_flag);
1114 ucs_ProcTail_setup(defp, split_flag);
1121 cs_ProcName_setup(definition * defp, char *procheader, int split_flag)
1127 f_print(fout, "int %s%s%s%s(z_call", procheader, prefix,
1128 PackagePrefix[PackageIndex], defp->pc.proc_name);
1130 f_print(fout, "int %s%s%s%s(z_conn", procheader, prefix,
1131 PackagePrefix[PackageIndex], defp->pc.proc_name);
1134 if ((strlen(procheader) + strlen(prefix) +
1135 strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >=
1136 MAX_FUNCTION_NAME_LEN) {
1137 error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1140 for (plist = defp->pc.plists; plist; plist = plist->next) {
1141 if (plist->component_kind == DEF_PARAM) {
1142 plist->pl.param_flag &= ~PROCESSED_PARAM;
1143 f_print(fout, ", %s", plist->pl.param_name);
1146 f_print(fout, ")\n");
1152 cs_ProcParams_setup(definition * defp, int split_flag)
1154 proc1_list *plist, *plist1;
1157 f_print(fout, "\tregister struct rx_connection *z_conn;\n");
1159 f_print(fout, "\tregister struct rx_call *z_call;\n");
1161 for (plist = defp->pc.plists; plist; plist = plist->next) {
1162 if (plist->component_kind == DEF_PARAM
1163 && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1164 if (plist->pl.param_flag & OUT_STRING) {
1165 f_print(fout, "\t%s *%s", plist->pl.param_type,
1166 plist->pl.param_name);
1168 f_print(fout, "\t%s %s", plist->pl.param_type,
1169 plist->pl.param_name);
1171 plist->pl.param_flag |= PROCESSED_PARAM;
1172 for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1173 if ((plist1->component_kind == DEF_PARAM)
1174 && streq(plist->pl.param_type, plist1->pl.param_type)
1175 && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1177 char *pntr = strchr(plist1->pl.param_type, '*');
1180 if (plist1->pl.param_flag & OUT_STRING) {
1181 f_print(fout, ", *%s%s", star, plist1->pl.param_name);
1183 f_print(fout, ", %s%s", star, plist1->pl.param_name);
1185 plist1->pl.param_flag |= PROCESSED_PARAM;
1188 f_print(fout, ";\n");
1195 cs_ProcMarshallInParams_setup(definition * defp, int split_flag)
1197 int noofparams, i = 0;
1201 defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT] +
1202 defp->pc.paramtypes[OUT];
1204 f_print(fout, "{\n");
1206 f_print(fout, "\tstruct rx_call *z_call = rx_NewCall(z_conn);\n");
1207 if ((!split_flag) || (split_flag == 1)) {
1208 if (opcodesnotallowed[PackageIndex]) {
1209 f_print(fout, "\tstatic int z_op = %d;\n",
1210 defp->pc.proc_opcodenum);
1212 f_print(fout, "\tstatic int z_op = %s;\n",
1213 defp->pc.proc_opcodename);
1216 f_print(fout, "\tint z_result;\n");
1217 if (!(split_flag > 1) || (noofallparams != 0)) {
1218 f_print(fout, "\tXDR z_xdrs;\n");
1221 * Print out client side stat gathering call
1223 if (xflag && split_flag != 1) {
1224 f_print(fout, "\tstruct clock __QUEUE, __EXEC;\n");
1227 if ((!split_flag) || (split_flag == 1)) {
1228 f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_ENCODE);\n");
1229 f_print(fout, "\n\t/* Marshal the arguments */\n");
1230 f_print(fout, "\tif ((!xdr_int(&z_xdrs, &z_op))");
1231 noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1232 for (plist = defp->pc.plists, dl = defp->def.st.decls; plist;
1233 plist = plist->next, dl = dl->next) {
1234 if (plist->component_kind == DEF_PARAM
1235 && (plist->pl.param_kind == DEF_INPARAM
1236 || plist->pl.param_kind == DEF_INOUTPARAM)) {
1237 f_print(fout, "\n\t || (!%s)", plist->code);
1238 if (++i == noofparams) {
1240 ") {\n\t\tz_result = RXGEN_CC_MARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1247 ") {\n\t\tz_result = RXGEN_CC_MARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1255 cs_ProcSendPacket_setup(definition * defp, int split_flag)
1257 int noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1259 if (noofoutparams) {
1260 f_print(fout, "\t/* Un-marshal the reply arguments */\n");
1262 f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
1264 f_print(fout, "\tz_xdrs.x_op = XDR_DECODE;\n");
1271 cs_ProcUnmarshallOutParams_setup(definition * defp)
1277 noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1279 for (plist = defp->pc.plists, dl = defp->def.st.decls, i = 0; plist;
1280 plist = plist->next, dl = dl->next) {
1281 if (plist->component_kind == DEF_PARAM
1282 && (plist->pl.param_kind == DEF_OUTPARAM
1283 || plist->pl.param_kind == DEF_INOUTPARAM)) {
1285 f_print(fout, "\tif ((!%s)", plist->code);
1287 f_print(fout, "\n\t || (!%s)", plist->code);
1289 if (++i == noofparams) {
1291 ") {\n\t\tz_result = RXGEN_CC_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1300 cs_ProcTail_setup(definition * defp, int split_flag)
1302 f_print(fout, "\tz_result = RXGEN_SUCCESS;\n");
1303 if (defp->can_fail) {
1304 f_print(fout, "fail:\n");
1307 f_print(fout, "\tz_result = rx_EndCall(z_call, z_result);\n");
1309 if (xflag && split_flag != 1) {
1310 f_print(fout, "\tif (rx_enable_stats) {\n");
1311 f_print(fout, "\t clock_GetTime(&__EXEC);\n");
1312 f_print(fout, "\t clock_Sub(&__EXEC, &z_call->startTime);\n");
1313 f_print(fout, "\t __QUEUE = z_call->startTime;\n");
1314 f_print(fout, "\t clock_Sub(&__QUEUE, &z_call->queueTime);\n");
1315 if (PackageStatIndex[PackageIndex]) {
1318 "\t rx_IncrementTimeAndCount(z_conn->peer, %s,\n",
1319 PackageStatIndex[PackageIndex]);
1322 "\t rx_IncrementTimeAndCount(z_call->conn->peer, %s,\n",
1323 PackageStatIndex[PackageIndex]);
1328 "\t rx_IncrementTimeAndCount(z_conn->peer,\n"
1329 "\t\t(((afs_uint32)(ntohs(z_conn->serviceId) << 16)) \n"
1330 "\t\t| ((afs_uint32)ntohs(z_conn->peer->port))),\n");
1333 "\t rx_IncrementTimeAndCount(z_call->conn->peer,\n"
1334 "\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
1335 "\t\t((afs_uint32)ntohs(z_call->conn->peer->port))),\n");
1339 f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
1340 no_of_stat_funcs, PackagePrefix[PackageIndex]);
1342 "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 1);\n");
1344 f_print(fout, "\t}\n\n");
1346 f_print(fout, "\treturn z_result;\n}\n\n");
1351 ss_Proc_CodeGeneration(definition * defp)
1356 ss_ProcName_setup(defp);
1358 ss_ProcParams_setup(defp, &somefrees);
1359 ss_ProcSpecial_setup(defp, &somefrees);
1360 ss_ProcUnmarshallInParams_setup(defp);
1361 ss_ProcCallRealProc_setup(defp);
1362 ss_ProcMarshallOutParams_setup(defp);
1363 ss_ProcTail_setup(defp, somefrees);
1369 ss_ProcName_setup(definition * defp)
1373 if ((strlen(prefix) + strlen(PackagePrefix[PackageIndex]) +
1374 strlen(defp->pc.proc_name)) >= MAX_FUNCTION_NAME_LEN) {
1375 error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1379 f_print(fout, "static afs_int32 _%s%s%s(", prefix,
1380 PackagePrefix[PackageIndex], defp->pc.proc_name);
1381 f_print(fout, "struct rx_call *z_call, XDR *z_xdrs)\n{\n");
1382 f_print(fout, "\t" "afs_int32 z_result;\n");
1384 f_print(fout, "\tstruct clock __QUEUE, __EXEC;\n");
1387 for (plist = defp->pc.plists; plist; plist = plist->next)
1388 if (plist->component_kind == DEF_PARAM) {
1389 plist->pl.param_flag &= ~(PROCESSED_PARAM);
1390 plist->pl.string_name = NULL;
1397 ss_ProcParams_setup(definition * defp, int *somefrees)
1399 proc1_list *plist, *plist1;
1403 for (plist = defp->pc.plists; plist; plist = plist->next) {
1404 if ((plist->component_kind == DEF_PARAM)
1405 && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1406 if (plist->pl.param_flag & INDIRECT_PARAM) {
1407 char pres = '\0', *pntr = strchr(plist->pl.param_type, '*');
1413 f_print(fout, "\t%s %s", plist->pl.param_type,
1414 plist->pl.param_name);
1416 } else if (strchr(plist->pl.param_type, '*') == 0) {
1417 f_print(fout, "\t%s %s", plist->pl.param_type,
1418 plist->pl.param_name);
1420 plist->pl.param_flag |= FREETHIS_PARAM;
1422 f_print(fout, "\t%s %s=(%s)0", plist->pl.param_type,
1423 plist->pl.param_name, plist->pl.param_type);
1425 plist->pl.param_flag |= PROCESSED_PARAM;
1426 for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1427 if ((plist1->component_kind == DEF_PARAM)
1428 && streq(plist->pl.param_type, plist1->pl.param_type)
1429 && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1430 if (plist1->pl.param_flag & INDIRECT_PARAM) {
1431 f_print(fout, ", %s", plist1->pl.param_name);
1432 } else if (strchr(plist1->pl.param_type, '*') == 0) {
1433 f_print(fout, ", %s", plist1->pl.param_name);
1435 plist1->pl.param_flag |= FREETHIS_PARAM;
1437 f_print(fout, ", *%s=(%s)0", plist1->pl.param_name,
1438 plist1->pl.param_type);
1440 plist1->pl.param_flag |= PROCESSED_PARAM;
1443 f_print(fout, ";\n");
1446 for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1447 defp1 = (definition *) listp->val;
1448 for (plist = defp->pc.plists; plist; plist = plist->next) {
1449 if (plist->component_kind == DEF_PARAM
1450 && (plist->pl.param_kind == DEF_OUTPARAM
1451 || plist->pl.param_kind == DEF_INOUTPARAM)
1452 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1453 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1454 switch (defp1->pc.rel) {
1463 fprintf(fout, "\n");
1468 ss_ProcSpecial_setup(definition * defp, int *somefrees)
1474 for (listp = special_defined; listp != NULL; listp = listp->next) {
1475 defp1 = (definition *) listp->val;
1476 for (plist = defp->pc.plists; plist; plist = plist->next) {
1477 if (plist->component_kind == DEF_PARAM
1478 && (plist->pl.param_kind == DEF_INPARAM
1479 || plist->pl.param_kind == DEF_INOUTPARAM)) {
1480 spec_list *spec = defp1->def.sd.specs;
1482 strcpy(string, structname(spec->sdef.string_value));
1483 if (streq(string, structname(plist->pl.param_type))) {
1484 plist->pl.string_name = spec->sdef.string_name;
1485 plist->pl.param_flag |= FREETHIS_PARAM;
1487 fprintf(fout, "\n\t%s.%s = 0;", plist->pl.param_name,
1488 spec->sdef.string_name);
1494 fprintf(fout, "\n");
1495 for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1496 defp1 = (definition *) listp->val;
1497 for (plist = defp->pc.plists; plist; plist = plist->next) {
1498 if (plist->component_kind == DEF_PARAM) {
1499 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1500 plist->pl.param_flag |= FREETHIS_PARAM;
1502 switch (defp1->pc.rel) {
1504 f_print(fout, "\n\t%s.%s_val = 0;",
1505 plist->pl.param_name, defp1->def_name);
1506 f_print(fout, "\n\t%s.%s_len = 0;",
1507 plist->pl.param_name, defp1->def_name);
1508 plist->pl.string_name = alloc(40);
1509 s_print(plist->pl.string_name, "%s_val",
1513 f_print(fout, "\n\t%s = 0;", plist->pl.param_name);
1514 plist->pl.string_name = NULL;
1521 f_print(fout, "\n");
1526 ss_ProcUnmarshallInParams_setup(definition * defp)
1528 int noofparams, noofoutparams, i;
1531 noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1532 noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1533 for (plist = defp->pc.plists, i = 0; plist; plist = plist->next) {
1534 if (plist->component_kind == DEF_PARAM
1535 && (plist->pl.param_kind == DEF_INPARAM
1536 || plist->pl.param_kind == DEF_INOUTPARAM)) {
1538 f_print(fout, "\n\tif ((!%s)",
1539 (plist->scode ? plist->scode : plist->code));
1541 f_print(fout, "\n\t || (!%s)",
1542 (plist->scode ? plist->scode : plist->code));
1544 if (++i == noofparams) {
1545 if (!noofoutparams) {
1546 f_print(fout, ") {\n");
1548 f_print(fout, ") {\n");
1551 "\t\tz_result = RXGEN_SS_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1560 ss_ProcCallRealProc_setup(definition * defp)
1565 f_print(fout, "\tz_result = %s%s%s%s(z_call", prefix, ServerPrefix,
1566 PackagePrefix[PackageIndex], defp->pc.proc_name);
1567 for (plist = defp->pc.plists; plist; plist = plist->next) {
1568 if (plist->component_kind == DEF_PARAM) {
1569 if (plist->pl.param_flag & INDIRECT_PARAM) {
1570 f_print(fout, ", &%s", plist->pl.param_name);
1572 if (plist->pl.param_flag & OUT_STRING) {
1573 f_print(fout, ", &%s", plist->pl.param_name);
1575 f_print(fout, ", %s", plist->pl.param_name);
1580 f_print(fout, ");\n");
1582 f_print(fout, "\tif (z_result)\n\t\treturn z_result;\n");
1588 ss_ProcMarshallOutParams_setup(definition * defp)
1593 noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1595 f_print(fout, "\tz_xdrs->x_op = XDR_ENCODE;\n");
1597 for (plist = defp->pc.plists, i = 0; plist; plist = plist->next) {
1598 if (plist->component_kind == DEF_PARAM
1599 && (plist->pl.param_kind == DEF_OUTPARAM
1600 || plist->pl.param_kind == DEF_INOUTPARAM)) {
1602 f_print(fout, "\tif ((!%s)",
1603 (plist->scode ? plist->scode : plist->code));
1605 f_print(fout, "\n\t || (!%s)",
1606 (plist->scode ? plist->scode : plist->code));
1608 if (++i == noofparams) {
1609 f_print(fout, ")\n\t\tz_result = RXGEN_SS_MARSHAL;\n");
1618 ss_ProcTail_setup(definition * defp, int somefrees)
1625 if (defp->can_fail) {
1626 f_print(fout, "fail:\n");
1628 for (plist = defp->pc.plists; plist; plist = plist->next) {
1629 if (plist->component_kind == DEF_PARAM
1630 && (plist->pl.param_flag & FREETHIS_PARAM))
1634 f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1635 for (plist = defp->pc.plists; plist; plist = plist->next) {
1636 if (plist->component_kind == DEF_PARAM
1637 && (plist->pl.param_flag & FREETHIS_PARAM)) {
1638 char *dot = "", *extens = "";
1639 if (plist->pl.string_name) {
1641 extens = plist->pl.string_name;
1643 f_print(fout, "\tif (!%s) goto fail1;\n", plist->scode);
1646 for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1647 defp1 = (definition *) listp->val;
1648 for (plist = defp->pc.plists; plist; plist = plist->next) {
1649 if (plist->component_kind == DEF_PARAM
1650 && (plist->pl.param_kind == DEF_OUTPARAM
1651 || plist->pl.param_kind == DEF_INOUTPARAM)
1652 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1653 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1654 switch (defp1->pc.rel) {
1657 if (!somefrees && !firsttime) {
1659 f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1662 f_print(fout, "\tif (!%s) goto fail1;\n",
1670 for (listp = uniondef_defined; listp != NULL; listp = listp->next) {
1671 defp1 = (definition *) listp->val;
1672 for (plist = defp->pc.plists; plist; plist = plist->next) {
1673 if (plist->component_kind == DEF_PARAM
1674 && (plist->pl.param_kind == DEF_OUTPARAM
1675 || plist->pl.param_kind == DEF_INOUTPARAM)
1676 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1677 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1678 if (plist->pl.param_flag & INDIRECT_PARAM) {
1679 if (!somefrees && !firsttime) {
1681 f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1684 f_print(fout, "\tif (!%s) goto fail1;\n",
1693 f_print(fout, "\tif (rx_enable_stats) {\n");
1694 f_print(fout, "\t clock_GetTime(&__EXEC);\n");
1695 f_print(fout, "\t clock_Sub(&__EXEC, &z_call->startTime);\n");
1696 f_print(fout, "\t __QUEUE = z_call->startTime;\n");
1697 f_print(fout, "\t clock_Sub(&__QUEUE, &z_call->queueTime);\n");
1698 f_print(fout, "\t rx_IncrementTimeAndCount(z_call->conn->peer,");
1699 if (PackageStatIndex[PackageIndex]) {
1700 f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
1703 "\n\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
1704 "\t\t((afs_uint32)ntohs(z_call->conn->service->servicePort))),\n");
1706 f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
1707 no_of_stat_funcs, PackagePrefix[PackageIndex]);
1708 f_print(fout, "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 0);\n");
1709 f_print(fout, "\t}\n\n");
1712 f_print(fout, "\treturn z_result;\n");
1714 f_print(fout, "fail1:\n");
1717 f_print(fout, "\tif (rx_enable_stats) {\n");
1718 f_print(fout, "\t clock_GetTime(&__EXEC);\n");
1719 f_print(fout, "\t clock_Sub(&__EXEC, &z_call->startTime);\n");
1720 f_print(fout, "\t __QUEUE = z_call->startTime;\n");
1721 f_print(fout, "\t clock_Sub(&__QUEUE, &z_call->queueTime);\n");
1723 "\t rx_IncrementTimeAndCount(z_call->conn->peer,");
1724 if (PackageStatIndex[PackageIndex]) {
1725 f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
1728 "\n\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
1729 "\t\t((afs_uint32)ntohs(z_call->conn->service->servicePort))),\n");
1731 f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
1732 no_of_stat_funcs, PackagePrefix[PackageIndex]);
1734 "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 0);\n");
1735 f_print(fout, "\t}\n\n");
1738 f_print(fout, "\treturn RXGEN_SS_XDRFREE;\n}\n\n");
1740 f_print(fout, "}\n\n");
1746 ucs_ProcName_setup(definition * defp, char *procheader, int split_flag)
1751 f_print(fout, "int %s%s%s%s(aclient, aflags", procheader, prefix,
1752 PackagePrefix[PackageIndex], defp->pc.proc_name);
1754 if ((strlen(procheader) + strlen(prefix) +
1755 strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >=
1756 MAX_FUNCTION_NAME_LEN) {
1757 error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1760 for (plist = defp->pc.plists; plist; plist = plist->next) {
1761 if (plist->component_kind == DEF_PARAM) {
1762 plist->pl.param_flag &= ~PROCESSED_PARAM;
1763 f_print(fout, ", %s", plist->pl.param_name);
1766 f_print(fout, ")\n");
1772 ucs_ProcParams_setup(definition * defp, int split_flag)
1774 proc1_list *plist, *plist1;
1776 f_print(fout, "\tregister struct ubik_client *aclient;\n\tafs_int32 aflags;\n");
1777 for (plist = defp->pc.plists; plist; plist = plist->next) {
1778 if (plist->component_kind == DEF_PARAM
1779 && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1780 if (plist->pl.param_flag & OUT_STRING) {
1781 f_print(fout, "\t%s *%s", plist->pl.param_type,
1782 plist->pl.param_name);
1784 f_print(fout, "\t%s %s", plist->pl.param_type,
1785 plist->pl.param_name);
1787 plist->pl.param_flag |= PROCESSED_PARAM;
1788 for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1789 if ((plist1->component_kind == DEF_PARAM)
1790 && streq(plist->pl.param_type, plist1->pl.param_type)
1791 && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1793 char *pntr = strchr(plist1->pl.param_type, '*');
1796 if (plist1->pl.param_flag & OUT_STRING) {
1797 f_print(fout, ", *%s%s", star, plist1->pl.param_name);
1799 f_print(fout, ", %s%s", star, plist1->pl.param_name);
1801 plist1->pl.param_flag |= PROCESSED_PARAM;
1804 f_print(fout, ";\n");
1810 ucs_ProcTail_setup(definition * defp, int split_flag)
1814 f_print(fout, "{\tafs_int32 rcode, code, newHost, thisHost, i, _ucount;\n");
1815 f_print(fout, "\tint chaseCount, pass, needsync, inlist, j;\n");
1816 f_print(fout, "\tstruct rx_connection *tc;\n");
1817 f_print(fout, "\tstruct rx_peer *rxp;\n");
1818 f_print(fout, "\tshort origLevel;\n\n");
1819 f_print(fout, "\tif (!aclient)\n");
1820 f_print(fout, "\t\treturn UNOENT;\n");
1821 f_print(fout, "\tLOCK_UBIK_CLIENT(aclient);\n\n");
1822 f_print(fout, "\t restart:\n");
1823 f_print(fout, "\torigLevel = aclient->initializationState;\n");
1824 f_print(fout, "\trcode = UNOSERVERS;\n");
1825 f_print(fout, "\tchaseCount = inlist = needsync = 0;\n\n");
1826 #if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
1827 f_print(fout, "\tLOCK_UCLNT_CACHE;\n");
1828 f_print(fout, "\tfor (j = 0; ((j < SYNCCOUNT) && calls_needsync[j]); j++) {\n");
1829 f_print(fout, "\t\tif (calls_needsync[j] == (int *)%s%s%s) {\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1830 f_print(fout, "\t\t\tinlist = needsync = 1;\n");
1831 f_print(fout, "\t\t\tbreak;\n");
1832 f_print(fout, "\t\t}\n");
1833 f_print(fout, "\t}\n");
1834 f_print(fout, "\tUNLOCK_UCLNT_CACHE;\n");
1836 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");
1837 f_print(fout, "\tfor (pass = 0; pass < 2; pass++) { /*p */\n");
1838 f_print(fout, "\t\t/* For each entry in our servers list */\n");
1839 f_print(fout, "\t\tfor (_ucount = 0;; _ucount++) { /*s */\n\n");
1840 f_print(fout, "\t\tif (needsync) {\n");
1841 f_print(fout, "\t\t\t/* Need a sync site. Lets try to quickly find it */\n");
1842 f_print(fout, "\t\t\tif (aclient->syncSite) {\n");
1843 f_print(fout, "\t\t\t\tnewHost = aclient->syncSite; /* already in network order */\n");
1844 f_print(fout, "\t\t\t\taclient->syncSite = 0; /* Will reset if it works */\n");
1845 f_print(fout, "\t\t\t} else if (aclient->conns[3]) {\n");
1846 f_print(fout, "\t\t\t\t/* If there are fewer than four db servers in a cell,\n");
1847 f_print(fout, "\t\t\t\t* there's no point in making the GetSyncSite call.\n");
1848 f_print(fout, "\t\t\t\t* At best, it's a wash. At worst, it results in more\n");
1849 f_print(fout, "\t\t\t\t* RPCs than you would otherwise make.\n");
1850 f_print(fout, "\t\t\t\t*/\n");
1851 f_print(fout, "\t\t\t\ttc = aclient->conns[_ucount];\n");
1852 f_print(fout, "\t\t\t\tif (tc && rx_ConnError(tc)) {\n");
1853 f_print(fout, "\t\t\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
1854 f_print(fout, "\t\t\t\t}\n");
1855 f_print(fout, "\t\t\t\tif (!tc)\n");
1856 f_print(fout, "\t\t\t\t\tbreak;\n");
1857 f_print(fout, "\t\t\t\tcode = VOTE_GetSyncSite(tc, &newHost);\n");
1858 f_print(fout, "\t\t\t\tif (aclient->initializationState != origLevel)\n");
1859 f_print(fout, "\t\t\t\t\tgoto restart; /* somebody did a ubik_ClientInit */\n");
1860 f_print(fout, "\t\t\t\tif (code)\n");
1861 f_print(fout, "\t\t\t\t\tnewHost = 0;\n");
1862 f_print(fout, "\t\t\t\tnewHost = htonl(newHost); /* convert to network order */\n");
1863 f_print(fout, "\t\t\t} else {\n");
1864 f_print(fout, "\t\t\t\tnewHost = 0;\n");
1865 f_print(fout, "\t\t\t}\n");
1866 f_print(fout, "\t\t\tif (newHost) {\n");
1867 f_print(fout, "\t\t\t\t/* position count at the appropriate slot in the client\n");
1868 f_print(fout, "\t\t\t\t* structure and retry. If we can't find in slot, we'll\n");
1869 f_print(fout, "\t\t\t\t* just continue through the whole list \n");
1870 f_print(fout, "\t\t\t\t*/\n");
1871 f_print(fout, "\t\t\t\tfor (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {\n");
1872 f_print(fout, "\t\t\t\t\trxp = rx_PeerOf(aclient->conns[i]);\n");
1873 f_print(fout, "\t\t\t\t\tthisHost = rx_HostOf(rxp);\n");
1874 f_print(fout, "\t\t\t\t\tif (!thisHost)\n");
1875 f_print(fout, "\t\t\t\t\t\tbreak;\n");
1876 f_print(fout, "\t\t\t\t\tif (thisHost == newHost) {\n");
1877 f_print(fout, "\t\t\t\t\t\tif (chaseCount++ > 2)\n");
1878 f_print(fout, "\t\t\t\t\t\t\tbreak; /* avoid loop asking */\n");
1879 f_print(fout, "\t\t\t\t\t\t_ucount = i; /* this index is the sync site */\n");
1880 f_print(fout, "\t\t\t\t\t\tbreak;\n");
1881 f_print(fout, "\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n");
1882 f_print(fout, "\t\t/*needsync */\n");
1883 f_print(fout, "\t\ttc = aclient->conns[_ucount];\n");
1884 f_print(fout, "\t\tif (tc && rx_ConnError(tc)) {\n");
1885 f_print(fout, "\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
1886 f_print(fout, "\t\t}\n");
1887 f_print(fout, "\t\tif (!tc)\n");
1888 f_print(fout, "\t\t\tbreak;\n\n");
1889 f_print(fout, "\t\tif ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {\n");
1890 f_print(fout, "\t\t\tcontinue; /* this guy's down */\n");
1891 f_print(fout, "\t\t}\n");
1893 f_print(fout, "\t\trcode = %s%s%s(tc\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1894 for (plist = defp->pc.plists; plist; plist = plist->next) {
1895 if (plist->component_kind == DEF_PARAM) {
1896 plist->pl.param_flag &= ~PROCESSED_PARAM;
1897 f_print(fout, ", %s", plist->pl.param_name);
1900 f_print(fout, ");\n");
1901 f_print(fout, "\t\tif (aclient->initializationState != origLevel) {\n");
1902 f_print(fout, "\t\t\t/* somebody did a ubik_ClientInit */\n");
1903 f_print(fout, "\t\t\tif (rcode)\n");
1904 f_print(fout, "\t\t\t\tgoto restart; /* call failed */\n");
1905 f_print(fout, "\t\t\telse\n");
1906 f_print(fout, "\t\t\t\tgoto done; /* call suceeded */\n");
1907 f_print(fout, "\t\t}\n");
1908 f_print(fout, "\t\tif (rcode < 0) { /* network errors */\n");
1909 f_print(fout, "\t\t\taclient->states[_ucount] |= CFLastFailed; /* Mark server down */\n");
1910 f_print(fout, "\t\t} else if (rcode == UNOTSYNC) {\n");
1911 f_print(fout, "\t\t\tneedsync = 1;\n");
1912 f_print(fout, "\t\t} else if (rcode != UNOQUORUM) {\n");
1913 f_print(fout, "\t\t\t/* either misc ubik code, or misc appl code, or success. */\n");
1914 f_print(fout, "\t\t\taclient->states[_ucount] &= ~CFLastFailed; /* mark server up*/\n");
1915 f_print(fout, "\t\t\tgoto done; /* all done */\n");
1916 f_print(fout, "\t\t}\n");
1917 f_print(fout, "\t\t} /*s */\n");
1918 f_print(fout, "\t} /*p */\n\n");
1919 f_print(fout, "\tdone:\n");
1920 f_print(fout, "\tif (needsync) {\n");
1921 f_print(fout, "\t\tif (!inlist) { /* Remember proc call that needs sync site */\n");
1922 #if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
1923 f_print(fout, "\t\t\tLOCK_UCLNT_CACHE;\n");
1924 f_print(fout, "\t\t\tcalls_needsync[synccount % SYNCCOUNT] = (int *)%s%s%s;\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1925 f_print(fout, "\t\t\tsynccount++;\n");
1926 f_print(fout, "\t\t\tUNLOCK_UCLNT_CACHE;\n");
1928 f_print(fout, "\t\t\tinlist = 1;\n");
1929 f_print(fout, "\t\t}\n");
1930 f_print(fout, "\t\tif (!rcode) { /* Remember the sync site - cmd successful */\n");
1931 f_print(fout, "\t\t\trxp = rx_PeerOf(aclient->conns[_ucount]);\n");
1932 f_print(fout, "\t\t\taclient->syncSite = rx_HostOf(rxp);\n");
1933 f_print(fout, "\t\t}\n");
1934 f_print(fout, "\t}\n");
1935 f_print(fout, "\tUNLOCK_UBIK_CLIENT(aclient);\n");
1936 f_print(fout, "\treturn rcode;\n}\n\n");
1941 opcode_holes_exist(void)
1945 for (i = lowest_opcode[PackageIndex]; i < highest_opcode[PackageIndex];
1947 if (!opcodenum_is_defined(i))
1955 er_Proc_CodeGeneration(void)
1959 temp = PackageIndex;
1960 if (!combinepackages)
1962 for (; PackageIndex <= temp; PackageIndex++) {
1963 if (proc_defined[PackageIndex] == NULL)
1965 if (combinepackages || opcode_holes_exist()) {
1966 er_HeadofOldStyleProc_setup();
1967 er_BodyofOldStyleProc_setup();
1968 er_TailofOldStyleProc_setup();
1970 er_ProcDeclExterns_setup();
1971 er_ProcProcsArray_setup();
1972 er_ProcMainBody_setup();
1975 PackageIndex = temp;
1980 er_ProcDeclExterns_setup(void)
1985 f_print(fout, "\n");
1986 for (listp = proc_defined[PackageIndex]; listp != NULL;
1987 listp = listp->next) {
1988 defp = (definition *) listp->val;
1989 if (defp->pc.proc_serverstub) {
1990 f_print(fout, "afs_int32 %s();\n", defp->pc.proc_serverstub);
1997 er_ProcProcsArray_setup(void)
2002 if ((listp = proc_defined[PackageIndex])) {
2003 defp = (definition *) listp->val;
2004 if (defp->pc.proc_serverstub) {
2005 f_print(fout, "\nstatic afs_int32 (*StubProcsArray%d[])() = {%s",
2006 PackageIndex, defp->pc.proc_serverstub);
2009 "\nstatic afs_int32 (*StubProcsArray%d[])(struct rx_call *z_call, XDR *z_xdrs) = {_%s%s%s",
2010 PackageIndex, prefix, defp->pc.proc_prefix,
2011 ((definition *) listp->val)->pc.proc_name);
2012 defp = (definition *) listp->val;
2014 listp = listp->next;
2016 for (; listp != NULL; listp = listp->next) {
2017 defp = (definition *) listp->val;
2018 if (defp->pc.proc_serverstub) {
2019 f_print(fout, ",%s", defp->pc.proc_serverstub);
2021 f_print(fout, ", _%s%s%s", prefix, defp->pc.proc_prefix,
2022 defp->pc.proc_name);
2025 f_print(fout, "};\n\n");
2030 er_ProcMainBody_setup(void)
2032 f_print(fout, "int %s%sExecuteRequest(register struct rx_call *z_call)\n",
2033 prefix, PackagePrefix[PackageIndex]);
2034 f_print(fout, "{\n\tint op;\n");
2035 f_print(fout, "\tXDR z_xdrs;\n");
2036 f_print(fout, "\t" "afs_int32 z_result;\n\n");
2037 f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
2039 "\tif (!xdr_int(&z_xdrs, &op))\n\t\tz_result = RXGEN_DECODE;\n");
2041 "\telse if (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\tz_result = RXGEN_OPCODE;\n",
2042 PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2044 "\telse\n\t\tz_result = (*StubProcsArray%d[op - %sLOWEST_OPCODE])(z_call, &z_xdrs);\n",
2045 PackageIndex, PackagePrefix[PackageIndex]);
2046 f_print(fout, "\treturn hton_syserr_conv(z_result);\n}\n");
2051 er_HeadofOldStyleProc_setup(void)
2054 "\nint %s%sExecuteRequest (register struct rx_call *z_call)\n",
2056 (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2057 f_print(fout, "{\n");
2058 f_print(fout, "\tint op;\n");
2059 f_print(fout, "\tXDR z_xdrs;\n");
2060 f_print(fout, "\t" "afs_int32 z_result;\n\n");
2061 f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
2062 f_print(fout, "\tz_result = RXGEN_DECODE;\n");
2063 f_print(fout, "\tif (!xdr_int(&z_xdrs, &op)) goto fail;\n");
2064 f_print(fout, "\tswitch (op) {\n");
2068 er_BodyofOldStyleProc_setup(void)
2072 if (combinepackages) {
2073 int temp = PackageIndex;
2074 for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
2075 for (listp = proc_defined[PackageIndex]; listp != NULL;
2076 listp = listp->next)
2077 proc_er_case((definition *) listp->val);
2079 PackageIndex = temp;
2081 for (listp = proc_defined[PackageIndex]; listp != NULL;
2082 listp = listp->next)
2083 proc_er_case((definition *) listp->val);
2089 proc_er_case(definition * defp)
2091 if (opcodesnotallowed[PackageIndex]) {
2092 f_print(fout, "\t\tcase %d:\n", defp->pc.proc_opcodenum);
2094 f_print(fout, "\t\tcase %s:\n", defp->pc.proc_opcodename);
2096 if (defp->pc.proc_serverstub) {
2097 f_print(fout, "\t\t\tz_result = %s(z_call, &z_xdrs);\n",
2098 defp->pc.proc_serverstub);
2100 f_print(fout, "\t\t\tz_result = _%s%s%s(z_call, &z_xdrs);\n", prefix,
2101 defp->pc.proc_prefix, defp->pc.proc_name);
2103 f_print(fout, "\t\t\tbreak;\n");
2108 er_TailofOldStyleProc_setup(void)
2110 f_print(fout, "\t\tdefault:\n");
2111 f_print(fout, "\t\t\tz_result = RXGEN_OPCODE;\n");
2112 f_print(fout, "\t\t\tbreak;\n\t}\n");
2113 f_print(fout, "fail:\n");
2114 f_print(fout, "\treturn z_result;\n}\n");
2119 h_opcode_stats(void)
2121 if (combinepackages) {
2123 "\n/* Opcode-related useful stats for Master package: %s */\n",
2125 f_print(fout, "#define %sLOWEST_OPCODE %d\n", MasterPrefix,
2126 master_lowest_opcode);
2127 f_print(fout, "#define %sHIGHEST_OPCODE %d\n", MasterPrefix,
2128 master_highest_opcode);
2129 f_print(fout, "#define %sNUMBER_OPCODES %d\n\n", MasterPrefix,
2130 master_no_of_opcodes);
2132 f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n", MasterPrefix,
2133 no_of_stat_funcs_header[0]);
2134 f_print(fout, "AFS_RXGEN_EXPORT\n");
2135 f_print(fout, "extern const char *%sfunction_names[];\n\n",
2140 for (i = 0; i <= PackageIndex; i++) {
2142 "\n/* Opcode-related useful stats for package: %s */\n",
2144 f_print(fout, "#define %sLOWEST_OPCODE %d\n", PackagePrefix[i],
2146 f_print(fout, "#define %sHIGHEST_OPCODE %d\n",
2147 PackagePrefix[i], highest_opcode[i]);
2148 f_print(fout, "#define %sNUMBER_OPCODES %d\n\n",
2149 PackagePrefix[i], no_of_opcodes[i]);
2151 f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n",
2152 PackagePrefix[i], no_of_stat_funcs_header[i]);
2153 f_print(fout, "AFS_RXGEN_EXPORT\n");
2154 f_print(fout, "extern const char *%sfunction_names[];\n\n",
2163 generate_multi_macros(definition * defp)
2165 char *startname = SplitStart, *endname = SplitEnd;
2174 f_print(fout, "\n#include <rx/rx_multi.h>");
2176 f_print(fout, "\n#define multi_%s%s(", PackagePrefix[PackageIndex],
2177 defp->pc.proc_name);
2178 for (plist = defp->pc.plists; plist; plist = plist->next) {
2179 if (plist->component_kind == DEF_PARAM) {
2182 f_print(fout, "%s", plist->pl.param_name);
2184 f_print(fout, ", %s", plist->pl.param_name);
2188 f_print(fout, ") \\\n");
2190 startname = "Start";
2193 f_print(fout, "\tmulti_Body(%s%s%s(multi_call", startname,
2194 PackagePrefix[PackageIndex], defp->pc.proc_name);
2195 do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 0);
2196 for (plist = defp->pc.plists; plist; plist = plist->next) {
2197 if (plist->component_kind == DEF_PARAM)
2198 f_print(fout, ", %s", plist->pl.param_name);
2200 do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 1);
2201 f_print(fout, "), %s%s%s(multi_call", endname,
2202 PackagePrefix[PackageIndex], defp->pc.proc_name);
2203 do_split(defp, IN, &numofparams, DEF_INPARAM, 0);
2204 for (plist = defp->pc.plists; plist; plist = plist->next) {
2205 if (plist->component_kind == DEF_PARAM) {
2206 f_print(fout, ", %s", plist->pl.param_name);
2209 do_split(defp, IN, &numofparams, DEF_INPARAM, 1);
2210 f_print(fout, "))\n\n");
2215 IsRxgenToken(token * tokp)
2217 if (tokp->kind == TOK_PACKAGE || tokp->kind == TOK_PREFIX
2218 || tokp->kind == TOK_SPECIAL || tokp->kind == TOK_STARTINGOPCODE
2219 || tokp->kind == TOK_SPLITPREFIX || tokp->kind == TOK_PROC
2220 || tokp->kind == TOK_STATINDEX)
2226 IsRxgenDefinition(definition * def)
2228 if (def->def_kind == DEF_PACKAGE || def->def_kind == DEF_PREFIX
2229 || def->def_kind == DEF_SPECIAL || def->def_kind == DEF_STARTINGOPCODE
2230 || def->def_kind == DEF_SPLITPREFIX || def->def_kind == DEF_PROC)