rxgen: per-opcode stats
[openafs.git] / src / rxgen / rpc_parse.c
1 /* @(#)rpc_parse.c      1.1 87/11/04 3.9 RPCSRC */
2 /*
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.
9  *
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.
13  *
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.
17  *
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.
21  *
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.
25  *
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  */
30
31 /*
32  * rpc_parse.c, Parser for the RPC protocol compiler
33  * Copyright (C) 1987 Sun Microsystems, Inc.
34  */
35 #include <afsconfig.h>
36 #include <afs/param.h>
37
38 #include <roken.h>
39
40 #include <ctype.h>
41
42 #include "rpc_scan.h"
43 #include "rpc_parse.h"
44 #include "rpc_util.h"
45
46 list *proc_defined[MAX_PACKAGES], *special_defined, *typedef_defined,
47     *uniondef_defined, *complex_defined;
48 char *SplitStart = NULL;
49 char *SplitEnd = NULL;
50 char *MasterPrefix = NULL;
51 char *ServerPrefix = "";
52 char *PackagePrefix[MAX_PACKAGES];
53 char *PackageStatIndex[MAX_PACKAGES];
54 int no_of_stat_funcs = 0;       /*
55                                  * current function number in client interface
56                                  * starts at 0
57                                  */
58 int no_of_stat_funcs_header[MAX_PACKAGES];      /*
59                                                  * Total number of functions in client
60                                                  * interface
61                                                  */
62 int no_of_opcodes[MAX_PACKAGES], master_no_of_opcodes = 0;
63 int lowest_opcode[MAX_PACKAGES], master_lowest_opcode = 99999;
64 int highest_opcode[MAX_PACKAGES], master_highest_opcode = 0;
65 int master_opcodenumber = 99999;
66 int opcodesnotallowed[MAX_PACKAGES];
67 int combinepackages = 0;
68 int PackageIndex = -1;
69 int PerProcCounter = 0;
70 int Multi_Init = 0;
71 int StatIndex = -1;
72
73 /*
74  * Character arrays to keep list of function names as we process the file
75  */
76
77 char function_list[MAX_PACKAGES]
78     [MAX_FUNCTIONS_PER_PACKAGE]
79     [MAX_FUNCTION_NAME_LEN];
80 int function_list_index;
81
82 /* static prototypes */
83 static void isdefined(definition * defp);
84 static void def_struct(definition * defp);
85 static void def_program(definition * defp);
86 static void def_enum(definition * defp);
87 static void def_const(definition * defp);
88 static void def_union(definition * defp);
89 static void def_typedef(definition * defp);
90 static void get_declaration(declaration * dec, defkind dkind);
91 static void get_type(char **prefixp, char **typep, defkind dkind);
92 static void unsigned_dec(char **typep);
93 static void def_package(definition * defp);
94 static void def_prefix(definition * defp);
95 static void def_statindex(definition * defp);
96 static void def_startingopcode(definition * defp);
97 static void def_split(definition * defp);
98 static void customize_struct(definition * defp);
99 static char *structname(char *name);
100 static void def_special(declaration * dec, definition * defp);
101 static void check_proc(definition * defp, token * tokp, int noname);
102 static int InvalidConstant(char *name);
103 static int opcodenum_is_defined(int opcode_num);
104 static void analyze_ProcParams(definition * defp, token * tokp);
105 static void generate_code(definition * defp, int proc_split_flag,
106                           int multi_flag);
107 static void handle_split_proc(definition * defp, int multi_flag);
108 static void do_split(definition * defp, int direction, int *numofparams,
109                      defkind param_kind, int restore_flag);
110 static void hdle_param_tok(definition * defp, declaration * dec, token * tokp,
111                            defkind par_kind);
112 static void get1_param_type(definition * defp, declaration * dec,
113                             char **param_type);
114 static void get_param_type(definition * defp, declaration * dec,
115                            char **param_type, char **typename);
116 #ifdef undef
117 static void hndle_param_tail(definition * defp, declaration * dec,
118                              token * tokp, char *typename);
119 #endif
120 static void cs_Proc_CodeGeneration(definition * defp, int split_flag,
121                                    char *procheader);
122 static void cs_ProcName_setup(definition * defp, char *procheader,
123                               int split_flag);
124 static void cs_ProcParams_setup(definition * defp, int split_flag);
125 static void cs_ProcMarshallInParams_setup(definition * defp, int split_flag);
126 static void cs_ProcSendPacket_setup(definition * defp, int split_flag);
127 static void cs_ProcUnmarshallOutParams_setup(definition * defp);
128 static void cs_ProcTail_setup(definition * defp, int split_flag);
129 static void ucs_ProcName_setup(definition * defp, char *procheader,
130                               int split_flag);
131 static void ucs_ProcParams_setup(definition * defp, int split_flag);
132 static void ucs_ProcTail_setup(definition * defp, int split_flag);
133 static void ss_Proc_CodeGeneration(definition * defp);
134 static void ss_ProcName_setup(definition * defp);
135 static void ss_ProcParams_setup(definition * defp);
136 static void ss_ProcSpecial_setup(definition * defp);
137 static void ss_ProcUnmarshallInParams_setup(definition * defp);
138 static void ss_ProcCallRealProc_setup(definition * defp);
139 static void ss_ProcMarshallOutParams_setup(definition * defp);
140 static void ss_ProcTail_setup(definition * defp);
141 static int opcode_holes_exist(void);
142 static void er_ProcDeclExterns_setup(void);
143 static void er_ProcProcsArray_setup(void);
144 static void er_ProcMainBody_setup(void);
145 static void er_HeadofOldStyleProc_setup(void);
146 static void er_HeadofOldStyleProc_setup2(void);
147 static void er_BodyofOldStyleProc_setup(void);
148 static void er_BodyofOldStyleProc_setup2(void);
149 static void proc_er_case(definition * defp);
150 static void er_TailofOldStyleProc_setup(void);
151 static void er_TailofOldStyleProc_setup2(void);
152
153
154
155 /*
156  * return the next definition you see
157  */
158 definition *
159 get_definition(void)
160 {
161     definition *defp;
162     token tok;
163
164     defp = ALLOC(definition);
165     memset(defp, 0, sizeof(definition));
166     get_token(&tok);
167     switch (tok.kind) {
168     case TOK_STRUCT:
169         def_struct(defp);
170         break;
171     case TOK_UNION:
172         def_union(defp);
173         break;
174     case TOK_TYPEDEF:
175         def_typedef(defp);
176         break;
177     case TOK_ENUM:
178         def_enum(defp);
179         break;
180     case TOK_PROGRAM:
181         def_program(defp);
182         break;
183     case TOK_CONST:
184         def_const(defp);
185         break;
186     case TOK_EOF:
187         return (NULL);
188     case TOK_PACKAGE:
189         def_package(defp);
190         break;
191     case TOK_PREFIX:
192         def_prefix(defp);
193         break;
194     case TOK_STATINDEX:
195         def_statindex(defp);
196         break;
197     case TOK_SPECIAL:
198         {
199             declaration dec;
200             def_special(&dec, defp);
201             break;
202         }
203     case TOK_STARTINGOPCODE:
204         def_startingopcode(defp);
205         break;
206     case TOK_CUSTOMIZED:
207         get_token(&tok);
208         def_struct(defp);
209         customize_struct(defp);
210         break;
211     case TOK_SPLITPREFIX:
212         def_split(defp);
213         break;
214     case TOK_PROC:
215         get_token(&tok);
216         if (tok.kind == TOK_LPAREN) {
217             unget_token(&tok);
218             check_proc(defp, &tok, 1);
219         } else
220             check_proc(defp, &tok, 0);
221         break;
222     case TOK_IDENT:
223         check_proc(defp, &tok, 0);
224         break;
225     case TOK_LPAREN:
226         unget_token(&tok);
227         check_proc(defp, &tok, 1);
228         break;
229     default:
230         error("definition keyword expected");
231     }
232     if (!IsRxgenToken(&tok)) {
233         scan(TOK_SEMICOLON, &tok);
234         isdefined(defp);
235     } else
236         pushed = 0;
237     return (defp);
238 }
239
240 static void
241 isdefined(definition * defp)
242 {
243     STOREVAL(&defined, defp);
244 }
245
246
247 static void
248 def_struct(definition * defp)
249 {
250     token tok;
251     declaration dec;
252     decl_list *decls;
253     decl_list **tailp;
254     int special = 0;
255
256     defp->def_kind = DEF_STRUCT;
257
258     scan(TOK_IDENT, &tok);
259     defp->def_name = tok.str;
260     scan(TOK_LBRACE, &tok);
261     tailp = &defp->def.st.decls;
262     do {
263         get_declaration(&dec, DEF_STRUCT);
264         /* If a structure contains an array, then we're going
265          * to need to be clever about freeing it */
266         if (dec.rel == REL_ARRAY) {
267            special = 1;
268         }
269         decls = ALLOC(decl_list);
270         decls->decl = dec;
271         *tailp = decls;
272         tailp = &decls->next;
273         scan(TOK_SEMICOLON, &tok);
274         peek(&tok);
275     } while (tok.kind != TOK_RBRACE);
276     get_token(&tok);
277     *tailp = NULL;
278
279     if (special)
280         STOREVAL(&complex_defined, defp);
281 }
282
283 static void
284 def_program(definition * defp)
285 {
286     token tok;
287     version_list *vlist;
288     version_list **vtailp;
289     proc_list *plist;
290     proc_list **ptailp;
291
292     defp->def_kind = DEF_PROGRAM;
293     scan(TOK_IDENT, &tok);
294     defp->def_name = tok.str;
295     scan(TOK_LBRACE, &tok);
296     vtailp = &defp->def.pr.versions;
297     scan(TOK_VERSION, &tok);
298     do {
299         scan(TOK_IDENT, &tok);
300         vlist = ALLOC(version_list);
301         vlist->vers_name = tok.str;
302         scan(TOK_LBRACE, &tok);
303         ptailp = &vlist->procs;
304         do {
305             plist = ALLOC(proc_list);
306             get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM);
307             if (streq(plist->res_type, "opaque")) {
308                 error("illegal result type");
309             }
310             scan(TOK_IDENT, &tok);
311             plist->proc_name = tok.str;
312             scan(TOK_LPAREN, &tok);
313             get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM);
314             if (streq(plist->arg_type, "opaque")) {
315                 error("illegal argument type");
316             }
317             scan(TOK_RPAREN, &tok);
318             scan(TOK_EQUAL, &tok);
319             scan_num(&tok);
320             scan(TOK_SEMICOLON, &tok);
321             plist->proc_num = tok.str;
322             *ptailp = plist;
323             ptailp = &plist->next;
324             peek(&tok);
325         } while (tok.kind != TOK_RBRACE);
326         *vtailp = vlist;
327         vtailp = &vlist->next;
328         scan(TOK_RBRACE, &tok);
329         scan(TOK_EQUAL, &tok);
330         scan_num(&tok);
331         vlist->vers_num = tok.str;
332         scan(TOK_SEMICOLON, &tok);
333         scan2(TOK_VERSION, TOK_RBRACE, &tok);
334     } while (tok.kind == TOK_VERSION);
335     scan(TOK_EQUAL, &tok);
336     scan_num(&tok);
337     defp->def.pr.prog_num = tok.str;
338     *vtailp = NULL;
339 }
340
341 static void
342 def_enum(definition * defp)
343 {
344     token tok;
345     enumval_list *elist;
346     enumval_list **tailp;
347
348     defp->def_kind = DEF_ENUM;
349     scan(TOK_IDENT, &tok);
350     defp->def_name = tok.str;
351     scan(TOK_LBRACE, &tok);
352     tailp = &defp->def.en.vals;
353     do {
354         scan(TOK_IDENT, &tok);
355         elist = ALLOC(enumval_list);
356         elist->name = tok.str;
357         elist->assignment = NULL;
358         scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
359         if (tok.kind == TOK_EQUAL) {
360             scan_num(&tok);
361             elist->assignment = tok.str;
362             scan2(TOK_COMMA, TOK_RBRACE, &tok);
363         }
364         *tailp = elist;
365         tailp = &elist->next;
366     } while (tok.kind != TOK_RBRACE);
367     *tailp = NULL;
368 }
369
370 static void
371 def_const(definition * defp)
372 {
373     token tok;
374
375     defp->def_kind = DEF_CONST;
376     scan(TOK_IDENT, &tok);
377     defp->def_name = tok.str;
378     scan(TOK_EQUAL, &tok);
379     scan2(TOK_IDENT, TOK_STRCONST, &tok);
380     defp->def.co = tok.str;
381 }
382
383 static void
384 def_union(definition * defp)
385 {
386     token tok;
387     declaration dec;
388     case_list *cases;
389     case_list **tailp;
390
391     defp->def_kind = DEF_UNION;
392     scan(TOK_IDENT, &tok);
393     defp->def_name = tok.str;
394     scan(TOK_SWITCH, &tok);
395     scan(TOK_LPAREN, &tok);
396     get_declaration(&dec, DEF_UNION);
397     defp->def.un.enum_decl = dec;
398     tailp = &defp->def.un.cases;
399     scan(TOK_RPAREN, &tok);
400     scan(TOK_LBRACE, &tok);
401     scan(TOK_CASE, &tok);
402     while (tok.kind == TOK_CASE) {
403         scan(TOK_IDENT, &tok);
404         cases = ALLOC(case_list);
405         cases->case_name = tok.str;
406         scan(TOK_COLON, &tok);
407         get_declaration(&dec, DEF_UNION);
408         cases->case_decl = dec;
409         *tailp = cases;
410         tailp = &cases->next;
411         scan(TOK_SEMICOLON, &tok);
412         scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
413     }
414     *tailp = NULL;
415     if (tok.kind == TOK_DEFAULT) {
416         scan(TOK_COLON, &tok);
417         get_declaration(&dec, DEF_UNION);
418         defp->def.un.default_decl = ALLOC(declaration);
419         *defp->def.un.default_decl = dec;
420         scan(TOK_SEMICOLON, &tok);
421         scan(TOK_RBRACE, &tok);
422     } else {
423         defp->def.un.default_decl = NULL;
424     }
425 }
426
427
428 static void
429 def_typedef(definition * defp)
430 {
431     declaration dec;
432
433     defp->def_kind = DEF_TYPEDEF;
434     get_declaration(&dec, DEF_TYPEDEF);
435     defp->def_name = dec.name;
436     defp->def.ty.old_prefix = dec.prefix;
437     defp->def.ty.old_type = dec.type;
438     defp->def.ty.rel = dec.rel;
439     defp->def.ty.array_max = dec.array_max;
440 }
441
442
443 static void
444 get_declaration(declaration * dec, defkind dkind)
445 {
446     token tok;
447
448     get_type(&dec->prefix, &dec->type, dkind);
449     dec->rel = REL_ALIAS;
450     if (streq(dec->type, "void")) {
451         return;
452     }
453     scan2(TOK_STAR, TOK_IDENT, &tok);
454     if (tok.kind == TOK_STAR) {
455         dec->rel = REL_POINTER;
456         scan(TOK_IDENT, &tok);
457     }
458     dec->name = tok.str;
459     if (peekscan(TOK_LBRACKET, &tok)) {
460         if (dec->rel == REL_POINTER) {
461             error("no array-of-pointer declarations -- use typedef");
462         }
463         dec->rel = REL_VECTOR;
464         scan_num(&tok);
465         dec->array_max = tok.str;
466         scan(TOK_RBRACKET, &tok);
467     } else if (peekscan(TOK_LANGLE, &tok)) {
468         if (dec->rel == REL_POINTER) {
469             error("no array-of-pointer declarations -- use typedef");
470         }
471         dec->rel = REL_ARRAY;
472         if (peekscan(TOK_RANGLE, &tok)) {
473             dec->array_max = "~0";      /* unspecified size, use max */
474         } else {
475             scan_num(&tok);
476             dec->array_max = tok.str;
477             scan(TOK_RANGLE, &tok);
478         }
479     }
480     if (streq(dec->type, "opaque")) {
481         if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
482             error("array declaration expected");
483         }
484     } else if (streq(dec->type, "string")) {
485         if (dec->rel != REL_ARRAY) {
486             error(" variable-length array declaration expected");
487         }
488     }
489 }
490
491
492 static void
493 get_type(char **prefixp, char **typep, defkind dkind)
494 {
495     token tok;
496
497     *prefixp = NULL;
498     get_token(&tok);
499     switch (tok.kind) {
500     case TOK_IDENT:
501         *typep = tok.str;
502         break;
503     case TOK_STRUCT:
504     case TOK_ENUM:
505     case TOK_UNION:
506         *prefixp = tok.str;
507         scan(TOK_IDENT, &tok);
508         *typep = tok.str;
509         break;
510     case TOK_UNSIGNED:
511         unsigned_dec(typep);
512         break;
513     case TOK_SHORT:
514         *typep = "short";
515         (void)peekscan(TOK_INT, &tok);
516         break;
517     case TOK_INT32:
518         *typep = "afs_int32";
519         (void)peekscan(TOK_INT, &tok);
520         break;
521     case TOK_VOID:
522         if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
523             error("voids allowed only inside union and program definitions");
524         }
525         *typep = tok.str;
526         break;
527     case TOK_STRING:
528     case TOK_OPAQUE:
529     case TOK_CHAR:
530     case TOK_INT:
531     case TOK_FLOAT:
532     case TOK_DOUBLE:
533     case TOK_BOOL:
534     case TOK_AFSUUID:
535         *typep = tok.str;
536         break;
537     default:
538         error("expected type specifier");
539     }
540 }
541
542
543 static void
544 unsigned_dec(char **typep)
545 {
546     token tok;
547
548     peek(&tok);
549     switch (tok.kind) {
550     case TOK_CHAR:
551         get_token(&tok);
552         *typep = "u_char";
553         break;
554     case TOK_SHORT:
555         get_token(&tok);
556         *typep = "u_short";
557         (void)peekscan(TOK_INT, &tok);
558         break;
559     case TOK_INT32:
560         get_token(&tok);
561         *typep = "afs_uint32";
562         (void)peekscan(TOK_INT, &tok);
563         break;
564     case TOK_INT:
565         get_token(&tok);
566         *typep = "u_int";
567         break;
568     default:
569         *typep = "u_int";
570         break;
571     }
572 }
573
574
575 static void
576 def_package(definition * defp)
577 {
578     token tok;
579
580     defp->def_kind = DEF_PACKAGE;
581     scan(TOK_IDENT, &tok);
582     defp->def_name = tok.str;
583     no_of_stat_funcs = 0;
584     if (PackageIndex++ >= MAX_PACKAGES)
585         error("Exceeded upper limit of package statements\n");
586     function_list_index = 0;
587     PackagePrefix[PackageIndex] = tok.str;
588     if (MasterPrefix == NULL)
589         MasterPrefix = tok.str;
590     no_of_opcodes[PackageIndex] = highest_opcode[PackageIndex] =
591         opcodesnotallowed[PackageIndex] = 0;
592     lowest_opcode[PackageIndex] = 99999;
593     proc_defined[PackageIndex] = NULL;
594     PackageStatIndex[PackageIndex] = NULL;
595 }
596
597 static void
598 def_prefix(definition * defp)
599 {
600     token tok;
601
602     defp->def_kind = DEF_PREFIX;
603     scan(TOK_IDENT, &tok);
604     defp->def_name = tok.str;
605     ServerPrefix = tok.str;
606 }
607
608 static void
609 def_statindex(definition * defp)
610 {
611     token tok;
612     char *name;
613
614     defp->def_kind = DEF_CONST;
615     scan_num(&tok);
616     if (PackageIndex < 0)
617         error("'statindex' command must follow 'package' command!\n");
618     if (PackageStatIndex[PackageIndex])
619         error("Cannot have more then one 'statindex' per package!\n");
620     if (InvalidConstant(tok.str))
621         error("Index in 'statindex' command must be a constant!");
622     name =
623         alloc(strlen(PackagePrefix[PackageIndex]) + strlen("STATINDEX") + 1);
624     strcpy(name, PackagePrefix[PackageIndex]);
625     strcat(name, "STATINDEX");
626     defp->def_name = name;
627     defp->def.co = tok.str;
628     PackageStatIndex[PackageIndex] = name;
629     StatIndex = atoi(tok.str);
630 }
631
632 static void
633 def_startingopcode(definition * defp)
634 {
635     token tok;
636
637     defp->def_kind = DEF_STARTINGOPCODE;
638     scan(TOK_IDENT, &tok);
639     defp->def_name = tok.str;
640     if (InvalidConstant(defp->def_name))
641         error("Opcode in 'startingopcode' command must be a constant!");
642     lowest_opcode[PackageIndex] = master_lowest_opcode = atoi(tok.str);
643     if (lowest_opcode[PackageIndex] < 0
644         || lowest_opcode[PackageIndex] > 99999)
645         error
646             ("startingopcode number is out of bounds (must be >= 0 < 100000)");
647     master_opcodenumber = lowest_opcode[PackageIndex];
648     opcodesnotallowed[PackageIndex] = 1;
649 }
650
651 static void
652 def_split(definition * defp)
653 {
654     token tok;
655
656     defp->def_kind = DEF_SPLITPREFIX;
657     do {
658         get_token(&tok);
659         switch (tok.kind) {
660         case TOK_IN:
661             scan(TOK_EQUAL, &tok);
662             scan(TOK_IDENT, &tok);
663             SplitStart = tok.str;
664             break;
665         case TOK_OUT:
666             scan(TOK_EQUAL, &tok);
667             scan(TOK_IDENT, &tok);
668             SplitEnd = tok.str;
669             break;
670         case TOK_SEMICOLON:
671             break;
672         default:
673             error("syntax error in the 'splitprefix' line");
674         }
675     } while (tok.kind != TOK_SEMICOLON);
676     if (!SplitStart && !SplitEnd)
677         error("At least one param should be passed to 'splitprefix' cmd");
678 }
679
680
681 static void
682 customize_struct(definition * defp)
683 {
684     decl_list *listp;
685     declaration *dec;
686     definition *defp1 = ALLOC(definition);
687     spec_list *specs, **tailp;
688
689     defp->def_kind = DEF_CUSTOMIZED;
690     defp1->def_kind = DEF_SPECIAL;
691     tailp = &defp1->def.sd.specs;
692     for (listp = defp->def.st.decls; listp; listp = listp->next) {
693         dec = &listp->decl;
694         if (streq(dec->type, "string") || (dec->rel == REL_POINTER)) {
695             specs = ALLOC(spec_list);
696             specs->sdef.string_name = dec->name;
697             specs->sdef.string_value = defp->def_name;
698             *tailp = specs;
699             tailp = &specs->next;
700         }
701     }
702     tailp = NULL;
703     STOREVAL(&special_defined, defp1);
704 }
705
706 static char *
707 structname(char *name)
708 {
709     static char namecontents[150];
710     char *pnt, *pnt1;
711
712     strcpy(namecontents, name);
713     pnt = namecontents;
714     if (!strncmp(pnt, "struct", 6))
715         pnt += 6;
716     while (isspace(*pnt))
717         pnt++;
718     pnt1 = pnt;
719     while (*pnt != ' ' && *pnt != '\0')
720         pnt++;
721     *pnt = '\0';
722     return pnt1;
723 }
724
725
726 static void
727 def_special(declaration * dec, definition * defp)
728 {
729     char *typename;
730     spec_list *specs, **tailp;
731     token tok;
732
733     defp->def_kind = DEF_SPECIAL;
734     get_type(&dec->prefix, &dec->type, DEF_SPECIAL);
735     dec->rel = REL_POINTER;
736     scan(TOK_IDENT, &tok);
737     tailp = &defp->def.sd.specs;
738     do {
739         specs = ALLOC(spec_list);
740         specs->sdef.string_name = tok.str;
741         get_param_type(defp, dec, &specs->sdef.string_value, &typename);
742         *tailp = specs;
743         tailp = &specs->next;
744         scan2(TOK_COMMA, TOK_SEMICOLON, &tok);
745         if (tok.kind == TOK_SEMICOLON)
746             break;
747         get_token(&tok);
748     } while (tok.kind == TOK_IDENT);
749     tailp = NULL;
750     STOREVAL(&special_defined, defp);
751 }
752
753
754 proc1_list *Proc_list, **Proc_listp;
755
756 static void
757 check_proc(definition * defp, token * tokp, int noname)
758 {
759     token tok;
760     int proc_split = 0;
761     int proc_multi = 0;
762
763     if (PackageIndex < 0)
764         error("Procedure must be in a package!\n");
765
766     tokp->kind = TOK_PROC;
767     defp->def_kind = DEF_PROC;
768     if (noname)
769         defp->pc.proc_name = "";
770     else
771         defp->pc.proc_name = tokp->str;
772     PerProcCounter = 0;
773     defp->pc.proc_prefix = alloc(strlen(PackagePrefix[PackageIndex]) + 1);
774     strcpy(defp->pc.proc_prefix, PackagePrefix[PackageIndex]);
775     scan2(TOK_LPAREN, TOK_IDENT, &tok);
776     defp->pc.proc_serverstub = NULL;
777     if (tok.kind == TOK_IDENT) {
778         defp->pc.proc_serverstub = tok.str;
779         scan(TOK_LPAREN, &tok);
780     }
781     analyze_ProcParams(defp, &tok);
782     defp->pc.proc_opcodenum = -1;
783     scan4(TOK_SPLIT, TOK_MULTI, TOK_EQUAL, TOK_SEMICOLON, &tok);
784     if (tok.kind == TOK_MULTI) {
785         proc_multi = 1;
786         defp->pc.multi_flag = 1;
787         scan2(TOK_EQUAL, TOK_SEMICOLON, &tok);
788     } else {
789         defp->pc.multi_flag = 0;
790     }
791     if (tok.kind == TOK_SPLIT) {
792         proc_split = 1;
793         defp->pc.split_flag = 1;
794         scan2(TOK_EQUAL, TOK_SEMICOLON, &tok);
795     } else {
796         defp->pc.split_flag = 0;
797     }
798     if (tok.kind == TOK_EQUAL) {
799         if (opcodesnotallowed[PackageIndex])
800             error("Opcode assignment isn't allowed here!");
801         scan_num(&tok);
802         if (InvalidConstant(tok.str))
803             error("Illegal Opcode assignment (Must be a constant opcode!)");
804         if (opcodenum_is_defined(atoi(tok.str)))
805             error("The opcode number is already used by a previous proc");
806         defp->pc.proc_opcodename = tok.str;
807         defp->pc.proc_opcodenum = atoi(tok.str);
808         if (defp->pc.proc_opcodenum < lowest_opcode[PackageIndex])
809             lowest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
810         if (defp->pc.proc_opcodenum < master_lowest_opcode)
811             master_lowest_opcode = defp->pc.proc_opcodenum;
812         if (defp->pc.proc_opcodenum > highest_opcode[PackageIndex])
813             highest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
814         if (defp->pc.proc_opcodenum > master_highest_opcode)
815             master_highest_opcode = defp->pc.proc_opcodenum;
816         scan(TOK_SEMICOLON, &tok);
817     } else {
818         if (master_opcodenumber == 99999)
819             master_opcodenumber = 0;
820         defp->pc.proc_opcodenum = master_opcodenumber++;
821         if (defp->pc.proc_opcodenum < lowest_opcode[PackageIndex])
822             lowest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
823         if (defp->pc.proc_opcodenum > highest_opcode[PackageIndex])
824             highest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
825         if (defp->pc.proc_opcodenum > master_highest_opcode)
826             master_highest_opcode = defp->pc.proc_opcodenum;
827         opcodesnotallowed[PackageIndex] = 1;    /* force it */
828     }
829     no_of_opcodes[PackageIndex]++, master_no_of_opcodes++;
830     if (proc_multi) {
831         generate_code(defp, 0, 1);
832         if (Cflag || cflag) {
833             generate_code(defp, 1, 1);
834         }
835         generate_multi_macros(defp);
836     } else {
837         generate_code(defp, proc_split, 0);
838     }
839
840     if (function_list_index >= MAX_FUNCTIONS_PER_INTERFACE) {
841         error("too many functions in interface, "
842               "increase MAX_FUNCTIONS_PER_INTERFACE");
843     }
844     sprintf(function_list[PackageIndex][function_list_index], "%s%s%s",
845             prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
846
847     function_list_index++;
848     defp->statindex = no_of_stat_funcs;
849     no_of_stat_funcs_header[PackageIndex]++;
850     no_of_stat_funcs++;
851     *Proc_listp = NULL;
852 }
853
854
855 #define LEGALNUMS "0123456789"
856 static int
857 InvalidConstant(char *name)
858 {
859     char *map;
860     int slen;
861
862     map = LEGALNUMS;
863     slen = (int)strlen(name);
864     return (slen != strspn(name, map));
865 }
866
867 static int
868 opcodenum_is_defined(int opcode_num)
869 {
870     list *listp;
871     definition *defp;
872
873     for (listp = proc_defined[PackageIndex]; listp != NULL;
874          listp = listp->next) {
875         defp = (definition *) listp->val;
876         if (opcode_num == defp->pc.proc_opcodenum)
877             return 1;
878     }
879     return 0;
880 }
881
882
883 static void
884 analyze_ProcParams(definition * defp, token * tokp)
885 {
886     declaration dec;
887     decl_list *decls, **tailp;
888
889     Proc_listp = &defp->pc.plists;
890     tailp = &defp->def.st.decls;
891     do {
892         get_token(tokp);
893         Proc_list = ALLOC(proc1_list);
894         memset(Proc_list, 0, sizeof(proc1_list));
895         Proc_list->pl.param_flag = 0;
896         switch (tokp->kind) {
897         case TOK_IN:
898             hdle_param_tok(defp, &dec, tokp, DEF_INPARAM);
899             break;
900         case TOK_OUT:
901             hdle_param_tok(defp, &dec, tokp, DEF_OUTPARAM);
902             break;
903         case TOK_INOUT:
904             hdle_param_tok(defp, &dec, tokp, DEF_INOUTPARAM);
905             break;
906         case TOK_RPAREN:
907             break;
908         default:
909             unget_token(tokp);
910             hdle_param_tok(defp, &dec, tokp, DEF_NULL);
911             break;
912         }
913         *Proc_listp = Proc_list;
914         Proc_listp = &Proc_list->next;
915         decls = ALLOC(decl_list);
916         memset(decls, 0, sizeof(decl_list));
917     if (tokp->kind != TOK_RPAREN)
918         decls->decl = dec;
919         *tailp = decls;
920         tailp = &decls->next;
921     } while (tokp->kind != TOK_RPAREN);
922     *tailp = NULL;
923 }
924
925
926 static void
927 generate_code(definition * defp, int proc_split_flag, int multi_flag)
928 {
929     if (proc_split_flag)
930         handle_split_proc(defp, multi_flag);
931     else {
932         if (Cflag || cflag) {
933             cs_Proc_CodeGeneration(defp, 0, "");
934         }
935         if (Sflag || cflag)
936             ss_Proc_CodeGeneration(defp);
937     }
938     if (Sflag || (cflag && xflag && !proc_split_flag) || hflag)
939         STOREVAL(&proc_defined[PackageIndex], defp);
940 }
941
942
943 static void
944 handle_split_proc(definition * defp, int multi_flag)
945 {
946     char *startname = SplitStart, *endname = SplitEnd;
947     int numofparams = 0;
948
949     if (!startname)
950         startname = "Start";
951     if (!endname)
952         endname = "End";
953     if (Cflag || cflag) {
954         if (!cflag) {
955             do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 0);
956         }
957         cs_Proc_CodeGeneration(defp, 1, startname);
958         if (!cflag) {
959             do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 1);
960             do_split(defp, IN, &numofparams, DEF_INPARAM, 0);
961         }
962         cs_Proc_CodeGeneration(defp, (multi_flag ? 3 : 2), endname);
963         if (!cflag) {
964             do_split(defp, IN, &numofparams, DEF_INPARAM, 1);
965         }
966     }
967     if (Sflag || cflag)
968         ss_Proc_CodeGeneration(defp);
969 }
970
971
972 static void
973 do_split(definition * defp, int direction, int *numofparams,
974          defkind param_kind, int restore_flag)
975 {
976     proc1_list *plist;
977
978     if (restore_flag) {
979         defp->pc.paramtypes[direction] = *numofparams;
980         for (plist = defp->pc.plists; plist; plist = plist->next) {
981             if (plist->component_kind == DEF_NULL
982                 && plist->pl.param_kind == param_kind)
983                 plist->component_kind = DEF_PARAM;
984         }
985     } else {
986         *numofparams = defp->pc.paramtypes[direction];
987         defp->pc.paramtypes[direction] = 0;
988         for (plist = defp->pc.plists; plist; plist = plist->next) {
989             if (plist->component_kind == DEF_PARAM
990                 && plist->pl.param_kind == param_kind)
991                 plist->component_kind = DEF_NULL;
992         }
993     }
994 }
995
996
997 static void
998 hdle_param_tok(definition * defp, declaration * dec, token * tokp,
999                defkind par_kind)
1000 {
1001     static defkind last_param_kind = DEF_NULL;
1002
1003     if (par_kind == DEF_NULL)
1004         Proc_list->pl.param_kind = last_param_kind;
1005     else
1006         Proc_list->pl.param_kind = par_kind;
1007     last_param_kind = Proc_list->pl.param_kind;
1008     defp->pc.paramtypes[(int)last_param_kind]++;
1009     Proc_list->component_kind = DEF_PARAM;
1010     Proc_list->code = alloc(250);
1011     Proc_list->scode = alloc(250);
1012     get_declaration(dec, DEF_PARAM);
1013     Proc_list->pl.param_name = dec->name;
1014     get1_param_type(defp, dec, &Proc_list->pl.param_type);
1015     print_param(dec);
1016     scan2(TOK_COMMA, TOK_RPAREN, tokp);
1017     if (tokp->kind == TOK_COMMA)
1018         peek(tokp);
1019 }
1020
1021
1022 static void
1023 get1_param_type(definition * defp, declaration * dec, char **param_type)
1024 {
1025     char typecontents[100];
1026
1027     if (streq(dec->type, "string")) {
1028         *param_type = "char *";
1029     } else {
1030         if (dec->prefix) {
1031             strcpy(typecontents, dec->prefix);
1032             strcat(typecontents, " ");
1033             strcat(typecontents, dec->type);
1034             strcat(typecontents, " *");
1035         } else if (dec->rel == REL_POINTER) {
1036             strcpy(typecontents, dec->type);
1037             strcat(typecontents, " *");
1038         } else
1039             strcpy(typecontents, dec->type);
1040         *param_type = alloc(100);
1041         strcpy(*param_type, typecontents);
1042     }
1043 }
1044
1045
1046 static void
1047 get_param_type(definition * defp, declaration * dec, char **param_type,
1048                char **typename)
1049 {
1050     char typecontents[100];
1051
1052     if (streq(dec->type, "string")) {
1053         *typename = "wrapstring";
1054         *param_type = "char *";
1055     } else {
1056         *typename = dec->type;
1057         if (dec->prefix) {
1058             strcpy(typecontents, dec->prefix);
1059             strcat(typecontents, " ");
1060             strcat(typecontents, dec->type);
1061             strcat(typecontents, " *");
1062             dec->rel = REL_POINTER;
1063         } else if (dec->rel == REL_POINTER) {
1064             strcpy(typecontents, dec->type);
1065             strcat(typecontents, " *");
1066         } else
1067             strcpy(typecontents, dec->type);
1068         *param_type = alloc(100);
1069         strcpy(*param_type, typecontents);
1070     }
1071 }
1072
1073
1074 #ifdef undef
1075 static void
1076 hndle_param_tail(definition * defp, declaration * dec, token * tokp,
1077                  char *typename)
1078 {
1079     char *amp;
1080
1081     if (dec->rel == REL_POINTER)
1082         Proc_list->pl.param_flag |= INDIRECT_PARAM;
1083     else
1084         Proc_list->pl.param_flag &= ~INDIRECT_PARAM;
1085     amp = "";
1086     if (!(Proc_list->pl.param_flag & INDIRECT_PARAM))
1087         amp = "&";
1088
1089     sprintf(Proc_list->code, "xdr_%s(&z_xdrs, %s%s)", typename, amp,
1090             Proc_list->pl.param_name);
1091     sprintf(Proc_list->scode, "xdr_%s(z_xdrs, &%s)", typename,
1092             Proc_list->pl.param_name);
1093     scan2(TOK_COMMA, TOK_RPAREN, tokp);
1094     if (tokp->kind == TOK_COMMA)
1095         peek(tokp);
1096 }
1097 #endif
1098
1099
1100 static void
1101 cs_Proc_CodeGeneration(definition * defp, int split_flag, char *procheader)
1102 {
1103     defp->can_fail = 0;
1104     cs_ProcName_setup(defp, procheader, split_flag);
1105     if (!cflag) {
1106         cs_ProcParams_setup(defp, split_flag);
1107         cs_ProcMarshallInParams_setup(defp, split_flag);
1108         if (split_flag != 1) {
1109             cs_ProcSendPacket_setup(defp, split_flag);
1110             cs_ProcUnmarshallOutParams_setup(defp);
1111         }
1112         cs_ProcTail_setup(defp, split_flag);
1113     }
1114
1115     if (!kflag && !split_flag && uflag) {
1116         ucs_ProcName_setup(defp, "ubik_", split_flag);
1117         if (!cflag) {
1118             ucs_ProcParams_setup(defp, split_flag);
1119             ucs_ProcTail_setup(defp, split_flag);
1120         }
1121     }
1122 }
1123
1124 static void
1125 cs_ProcName_setup(definition * defp, char *procheader, int split_flag)
1126 {
1127     proc1_list *plist;
1128     char *first_arg;
1129
1130     if (ansic_flag) {
1131         if (split_flag) {
1132             first_arg = "struct rx_call *z_call";
1133         } else {
1134             first_arg = "struct rx_connection *z_conn";
1135         }
1136     } else {
1137         if (split_flag) {
1138             first_arg = "z_call";
1139         } else {
1140             first_arg = "z_conn";
1141         }
1142     }
1143
1144     if (!cflag) {
1145         f_print(fout, "int %s%s%s%s(%s", procheader, prefix,
1146                 PackagePrefix[PackageIndex], defp->pc.proc_name, first_arg);
1147     }
1148     if ((strlen(procheader) + strlen(prefix) +
1149          strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >=
1150         MAX_FUNCTION_NAME_LEN) {
1151         error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1152     }
1153     if (!cflag) {
1154         for (plist = defp->pc.plists; plist; plist = plist->next) {
1155             if (plist->component_kind == DEF_PARAM) {
1156                 f_print(fout, ",");
1157                 if (ansic_flag) {
1158                     if (plist->pl.param_kind == DEF_INPARAM &&
1159                         strcmp(plist->pl.param_type, "char *") == 0) {
1160                         f_print(fout, "const ");
1161                     }
1162                     if (plist->pl.param_flag & OUT_STRING) {
1163                         f_print(fout, "%s *%s", plist->pl.param_type,
1164                                 plist->pl.param_name);
1165                     } else {
1166                         f_print(fout, "%s %s", plist->pl.param_type,
1167                                 plist->pl.param_name);
1168                     }
1169                 } else {
1170                     f_print(fout, " %s", plist->pl.param_name);
1171                     plist->pl.param_flag &= ~PROCESSED_PARAM;
1172                 }
1173             }
1174         }
1175         f_print(fout, ")\n");
1176     }
1177 }
1178
1179 static void
1180 cs_ProcParams_setup(definition * defp, int split_flag)
1181 {
1182     proc1_list *plist, *plist1;
1183
1184     if (ansic_flag)
1185         return;
1186
1187     if (!split_flag)
1188         f_print(fout, "\tstruct rx_connection *z_conn;\n");
1189     if (split_flag) {
1190         f_print(fout, "\tstruct rx_call *z_call;\n");
1191     }
1192     for (plist = defp->pc.plists; plist; plist = plist->next) {
1193         if (plist->component_kind == DEF_PARAM
1194             && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1195             if (plist->pl.param_flag & OUT_STRING) {
1196                 f_print(fout, "\t%s *%s", plist->pl.param_type,
1197                         plist->pl.param_name);
1198             } else {
1199                 f_print(fout, "\t%s %s", plist->pl.param_type,
1200                         plist->pl.param_name);
1201             }
1202             plist->pl.param_flag |= PROCESSED_PARAM;
1203             for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1204                 if ((plist1->component_kind == DEF_PARAM)
1205                     && streq(plist->pl.param_type, plist1->pl.param_type)
1206                     && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1207                     char *star = "";
1208                     char *pntr = strchr(plist1->pl.param_type, '*');
1209                     if (pntr)
1210                         star = "*";
1211                     if (plist1->pl.param_flag & OUT_STRING) {
1212                         f_print(fout, ", *%s%s", star, plist1->pl.param_name);
1213                     } else {
1214                         f_print(fout, ", %s%s", star, plist1->pl.param_name);
1215                     }
1216                     plist1->pl.param_flag |= PROCESSED_PARAM;
1217                 }
1218             }
1219             f_print(fout, ";\n");
1220         }
1221     }
1222 }
1223
1224
1225 static void
1226 cs_ProcMarshallInParams_setup(definition * defp, int split_flag)
1227 {
1228     int noofparams, i = 0;
1229     proc1_list *plist;
1230     decl_list *dl;
1231     int noofallparams =
1232         defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT] +
1233         defp->pc.paramtypes[OUT];
1234
1235     f_print(fout, "{\n");
1236     if (!split_flag)
1237         f_print(fout, "\tstruct rx_call *z_call = rx_NewCall(z_conn);\n");
1238     if ((!split_flag) || (split_flag == 1)) {
1239         if (opcodesnotallowed[PackageIndex]) {
1240             f_print(fout, "\tstatic int z_op = %d;\n",
1241                     defp->pc.proc_opcodenum);
1242         } else {
1243             f_print(fout, "\tstatic int z_op = %s;\n",
1244                     defp->pc.proc_opcodename);
1245         }
1246     }
1247     f_print(fout, "\tint z_result;\n");
1248     if (!(split_flag > 1) || (noofallparams != 0)) {
1249         f_print(fout, "\tXDR z_xdrs;\n");
1250     }
1251
1252     if ((!split_flag) || (split_flag == 1)) {
1253         f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_ENCODE);\n");
1254         f_print(fout, "\n\t/* Marshal the arguments */\n");
1255         f_print(fout, "\tif ((!xdr_int(&z_xdrs, &z_op))");
1256         noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1257         for (plist = defp->pc.plists, dl = defp->def.st.decls; plist;
1258              plist = plist->next, dl = dl->next) {
1259             if (plist->component_kind == DEF_PARAM
1260                 && (plist->pl.param_kind == DEF_INPARAM
1261                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1262                 f_print(fout, "\n\t     || (!%s)", plist->code);
1263                 if (++i == noofparams) {
1264                     f_print(fout,
1265                             ") {\n\t\tz_result = RXGEN_CC_MARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1266                     defp->can_fail = 1;
1267                 }
1268             }
1269         }
1270         if (!i) {
1271             f_print(fout,
1272                     ") {\n\t\tz_result = RXGEN_CC_MARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1273             defp->can_fail = 1;
1274         }
1275     }
1276 }
1277
1278
1279 static void
1280 cs_ProcSendPacket_setup(definition * defp, int split_flag)
1281 {
1282     int noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1283
1284     if (noofoutparams) {
1285         f_print(fout, "\t/* Un-marshal the reply arguments */\n");
1286         if (split_flag) {
1287             f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
1288         } else {
1289             f_print(fout, "\tz_xdrs.x_op = XDR_DECODE;\n");
1290         }
1291     }
1292 }
1293
1294
1295 static void
1296 cs_ProcUnmarshallOutParams_setup(definition * defp)
1297 {
1298     int noofparams, i;
1299     proc1_list *plist;
1300     decl_list *dl;
1301
1302     noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1303     if (noofparams)
1304         for (plist = defp->pc.plists, dl = defp->def.st.decls, i = 0; plist;
1305              plist = plist->next, dl = dl->next) {
1306             if (plist->component_kind == DEF_PARAM
1307                 && (plist->pl.param_kind == DEF_OUTPARAM
1308                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1309                 if (!i) {
1310                     f_print(fout, "\tif ((!%s)", plist->code);
1311                 } else {
1312                     f_print(fout, "\n\t     || (!%s)", plist->code);
1313                 }
1314                 if (++i == noofparams) {
1315                     f_print(fout,
1316                             ") {\n\t\tz_result = RXGEN_CC_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1317                     defp->can_fail = 1;
1318                 }
1319             }
1320         }
1321 }
1322
1323
1324 static void
1325 cs_ProcTail_setup(definition * defp, int split_flag)
1326 {
1327     f_print(fout, "\tz_result = RXGEN_SUCCESS;\n");
1328     if (defp->can_fail) {
1329         f_print(fout, "fail:\n");
1330     }
1331     if (!split_flag) {
1332         f_print(fout, "\tz_result = rx_EndCall(z_call, z_result);\n");
1333     }
1334     if (xflag && split_flag != 1) {
1335         f_print(fout, "\tif (rx_enable_stats) {\n");
1336         if (PackageStatIndex[PackageIndex]) {
1337             f_print(fout,
1338                     "\t    rx_RecordCallStatistics(z_call, %s,\n",
1339                     PackageStatIndex[PackageIndex]);
1340         } else {
1341             f_print(fout,
1342                     "\t    rx_RecordCallStatistics(z_call, \n"
1343                     "\t\t(((afs_uint32)(ntohs(rx_ServiceIdOf(rx_ConnectionOf(z_call))) << 16)) |\n"
1344                     "\t\t((afs_uint32)ntohs(rx_PortOf(rx_PeerOf(rx_ConnectionOf(z_call)))))),\n");
1345         }
1346         f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, 1);\n",
1347                 no_of_stat_funcs, PackagePrefix[PackageIndex]);
1348         f_print(fout, "\t}\n\n");
1349     }
1350     f_print(fout, "\treturn z_result;\n}\n\n");
1351 }
1352
1353
1354 static void
1355 ss_Proc_CodeGeneration(definition * defp)
1356 {
1357     defp->can_fail = 0;
1358     ss_ProcName_setup(defp);
1359     if (!cflag) {
1360         ss_ProcParams_setup(defp);
1361         ss_ProcSpecial_setup(defp);
1362         ss_ProcUnmarshallInParams_setup(defp);
1363         ss_ProcCallRealProc_setup(defp);
1364         ss_ProcMarshallOutParams_setup(defp);
1365         ss_ProcTail_setup(defp);
1366     }
1367 }
1368
1369
1370 static void
1371 ss_ProcName_setup(definition * defp)
1372 {
1373     proc1_list *plist;
1374
1375     if ((strlen(prefix) + strlen(PackagePrefix[PackageIndex]) +
1376          strlen(defp->pc.proc_name)) >= MAX_FUNCTION_NAME_LEN) {
1377         error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1378     }
1379
1380     if (!cflag) {
1381         f_print(fout, "static afs_int32 _%s%s%s(", prefix,
1382                 PackagePrefix[PackageIndex], defp->pc.proc_name);
1383         f_print(fout, "struct rx_call *z_call, XDR *z_xdrs)\n{\n");
1384         f_print(fout, "\t" "afs_int32 z_result;\n");
1385
1386         for (plist = defp->pc.plists; plist; plist = plist->next)
1387             if (plist->component_kind == DEF_PARAM) {
1388                 plist->pl.param_flag &= ~(PROCESSED_PARAM);
1389                 plist->pl.string_name = NULL;
1390             }
1391     }
1392 }
1393
1394
1395 static void
1396 ss_ProcParams_setup(definition * defp)
1397 {
1398     proc1_list *plist, *plist1;
1399     list *listp;
1400     definition *defp1;
1401
1402     for (plist = defp->pc.plists; plist; plist = plist->next) {
1403         if ((plist->component_kind == DEF_PARAM)
1404             && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1405             if (plist->pl.param_flag & INDIRECT_PARAM) {
1406                 char pres = '\0', *pntr = strchr(plist->pl.param_type, '*');
1407                 if (pntr) {
1408                     --pntr;
1409                     pres = *pntr;
1410                     *pntr = (char)0;
1411                 }
1412                 f_print(fout, "\t%s %s", plist->pl.param_type,
1413                         plist->pl.param_name);
1414                 *pntr = pres;
1415             } else if (strchr(plist->pl.param_type, '*') == 0) {
1416                 f_print(fout, "\t%s %s", plist->pl.param_type,
1417                         plist->pl.param_name);
1418             } else {
1419                 plist->pl.param_flag |= FREETHIS_PARAM;
1420                 f_print(fout, "\t%s %s=(%s)0", plist->pl.param_type,
1421                         plist->pl.param_name, plist->pl.param_type);
1422             }
1423             plist->pl.param_flag |= PROCESSED_PARAM;
1424             for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1425                 if ((plist1->component_kind == DEF_PARAM)
1426                     && streq(plist->pl.param_type, plist1->pl.param_type)
1427                     && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1428                     if (plist1->pl.param_flag & INDIRECT_PARAM) {
1429                         f_print(fout, ", %s", plist1->pl.param_name);
1430                     } else if (strchr(plist1->pl.param_type, '*') == 0) {
1431                         f_print(fout, ", %s", plist1->pl.param_name);
1432                     } else {
1433                         plist1->pl.param_flag |= FREETHIS_PARAM;
1434                         f_print(fout, ", *%s=(%s)0", plist1->pl.param_name,
1435                                 plist1->pl.param_type);
1436                     }
1437                     plist1->pl.param_flag |= PROCESSED_PARAM;
1438                 }
1439             }
1440             f_print(fout, ";\n");
1441         }
1442     }
1443     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1444         defp1 = (definition *) listp->val;
1445         for (plist = defp->pc.plists; plist; plist = plist->next) {
1446             if (plist->component_kind == DEF_PARAM
1447                 && (plist->pl.param_kind == DEF_OUTPARAM
1448                     || plist->pl.param_kind == DEF_INOUTPARAM)
1449                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1450                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1451                     switch (defp1->pc.rel) {
1452                     case REL_ARRAY:
1453                     case REL_POINTER:
1454                     default:
1455                         break;
1456                     }
1457                 }
1458             }
1459         }
1460     }
1461     fprintf(fout, "\n");
1462 }
1463
1464
1465 static void
1466 ss_ProcSpecial_setup(definition * defp)
1467 {
1468     proc1_list *plist;
1469     definition *defp1;
1470     list *listp;
1471
1472     for (listp = special_defined; listp != NULL; listp = listp->next) {
1473         defp1 = (definition *) listp->val;
1474
1475         for (plist = defp->pc.plists; plist; plist = plist->next) {
1476             if (plist->component_kind == DEF_PARAM
1477                 && (plist->pl.param_kind == DEF_INPARAM
1478                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1479                 spec_list *spec = defp1->def.sd.specs;
1480                 char string[40];
1481                 strcpy(string, structname(spec->sdef.string_value));
1482                 if (streq(string, structname(plist->pl.param_type))) {
1483                     plist->pl.string_name = spec->sdef.string_name;
1484                     plist->pl.param_flag |= FREETHIS_PARAM;
1485                     fprintf(fout, "\n\t%s.%s = 0;", plist->pl.param_name,
1486                             spec->sdef.string_name);
1487                 }
1488             }
1489         }
1490     }
1491     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1492         defp1 = (definition *) listp->val;
1493         for (plist = defp->pc.plists; plist; plist = plist->next) {
1494             if (plist->component_kind == DEF_PARAM) {
1495                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1496                     plist->pl.param_flag |= FREETHIS_PARAM;
1497                     switch (defp1->pc.rel) {
1498                     case REL_ARRAY:
1499                         plist->pl.string_name = alloc(40);
1500                         if (brief_flag) {
1501                             f_print(fout, "\n\t%s.val = 0;",
1502                                     plist->pl.param_name);
1503                             f_print(fout, "\n\t%s.len = 0;",
1504                                     plist->pl.param_name);
1505                             s_print(plist->pl.string_name, "val");
1506                         } else {
1507                             f_print(fout, "\n\t%s.%s_val = 0;",
1508                                     plist->pl.param_name, defp1->def_name);
1509                             f_print(fout, "\n\t%s.%s_len = 0;",
1510                                     plist->pl.param_name, defp1->def_name);
1511                             s_print(plist->pl.string_name, "%s_val",
1512                                     defp1->def_name);
1513                         }
1514                         break;
1515                     case REL_POINTER:
1516                         f_print(fout, "\n\t%s = 0;", plist->pl.param_name);
1517                         plist->pl.string_name = NULL;
1518                         break;
1519                     default:
1520                         break;
1521                     }
1522                 }
1523             }
1524         }
1525     }
1526     for (listp = complex_defined; listp != NULL; listp = listp->next) {
1527         defp1 = (definition *) listp->val;
1528         for (plist = defp->pc.plists; plist; plist = plist->next) {
1529             if (plist->component_kind == DEF_PARAM) {
1530                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1531                     plist->pl.param_flag |= FREETHIS_PARAM;
1532                     fprintf(fout, "\n\tmemset(&%s, 0, sizeof(%s));",
1533                                  plist->pl.param_name, defp1->def_name);
1534                 }
1535             }
1536         }
1537     }
1538
1539     f_print(fout, "\n");
1540 }
1541
1542
1543 static void
1544 ss_ProcUnmarshallInParams_setup(definition * defp)
1545 {
1546     int noofparams, noofoutparams, i;
1547     proc1_list *plist;
1548
1549     noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1550     noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1551     for (plist = defp->pc.plists, i = 0; plist; plist = plist->next) {
1552         if (plist->component_kind == DEF_PARAM
1553             && (plist->pl.param_kind == DEF_INPARAM
1554                 || plist->pl.param_kind == DEF_INOUTPARAM)) {
1555             if (!i) {
1556                 f_print(fout, "\n\tif ((!%s)",
1557                         (plist->scode ? plist->scode : plist->code));
1558             } else {
1559                 f_print(fout, "\n\t     || (!%s)",
1560                         (plist->scode ? plist->scode : plist->code));
1561             }
1562             if (++i == noofparams) {
1563                 if (!noofoutparams) {
1564                     f_print(fout, ") {\n");
1565                 } else {
1566                     f_print(fout, ") {\n");
1567                 }
1568                 f_print(fout,
1569                         "\t\tz_result = RXGEN_SS_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1570                 defp->can_fail = 1;
1571             }
1572         }
1573     }
1574 }
1575
1576
1577 static void
1578 ss_ProcCallRealProc_setup(definition * defp)
1579 {
1580     extern char zflag;
1581     proc1_list *plist;
1582
1583     f_print(fout, "\tz_result = %s%s%s%s(z_call", prefix, ServerPrefix,
1584             PackagePrefix[PackageIndex], defp->pc.proc_name);
1585     for (plist = defp->pc.plists; plist; plist = plist->next) {
1586         if (plist->component_kind == DEF_PARAM) {
1587             if (plist->pl.param_flag & INDIRECT_PARAM) {
1588                 f_print(fout, ", &%s", plist->pl.param_name);
1589             } else {
1590                 if (plist->pl.param_flag & OUT_STRING) {
1591                     f_print(fout, ", &%s", plist->pl.param_name);
1592                 } else {
1593                     f_print(fout, ", %s", plist->pl.param_name);
1594                 }
1595             }
1596         }
1597     }
1598     f_print(fout, ");\n");
1599     if (zflag) {
1600         f_print(fout, "\tif (z_result)\n\t\treturn z_result;\n");
1601     }
1602 }
1603
1604
1605 static void
1606 ss_ProcMarshallOutParams_setup(definition * defp)
1607 {
1608     proc1_list *plist;
1609     int noofparams, i;
1610
1611     noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1612     if (noofparams)
1613         f_print(fout, "\tz_xdrs->x_op = XDR_ENCODE;\n");
1614     if (noofparams) {
1615         for (plist = defp->pc.plists, i = 0; plist; plist = plist->next) {
1616             if (plist->component_kind == DEF_PARAM
1617                 && (plist->pl.param_kind == DEF_OUTPARAM
1618                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1619                 if (!i) {
1620                     f_print(fout, "\tif ((!%s)",
1621                             (plist->scode ? plist->scode : plist->code));
1622                 } else {
1623                     f_print(fout, "\n\t     || (!%s)",
1624                             (plist->scode ? plist->scode : plist->code));
1625                 }
1626                 if (++i == noofparams) {
1627                     f_print(fout, ")\n\t\tz_result = RXGEN_SS_MARSHAL;\n");
1628                 }
1629             }
1630         }
1631     }
1632 }
1633
1634 static void
1635 ss_ProcTail_frees(char *xdrfunc, int *somefrees) {
1636     if (!*somefrees) {
1637         f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1638         f_print(fout, "\tif ((!%s)", xdrfunc);
1639         *somefrees = 1;
1640     } else {
1641         f_print(fout, "\n\t    || (!%s)", xdrfunc);
1642     }
1643 }
1644
1645
1646 static void
1647 ss_ProcTail_setup(definition * defp)
1648 {
1649     proc1_list *plist;
1650     definition *defp1;
1651     list *listp;
1652     int somefrees = 0;
1653
1654     if (defp->can_fail) {
1655         f_print(fout, "fail:\n");
1656     }
1657
1658     for (plist = defp->pc.plists; plist; plist = plist->next) {
1659         if (plist->component_kind == DEF_PARAM
1660                 && (plist->pl.param_flag & FREETHIS_PARAM))
1661             ss_ProcTail_frees(plist->scode, &somefrees);
1662     }
1663
1664     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1665         defp1 = (definition *) listp->val;
1666         for (plist = defp->pc.plists; plist; plist = plist->next) {
1667             if (plist->component_kind == DEF_PARAM
1668                 && (plist->pl.param_kind == DEF_OUTPARAM
1669                     || plist->pl.param_kind == DEF_INOUTPARAM)
1670                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1671                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1672                     switch (defp1->pc.rel) {
1673                     case REL_ARRAY:
1674                     case REL_POINTER:
1675                         ss_ProcTail_frees(plist->scode, &somefrees);
1676                         break;
1677                     default:
1678                         break;
1679                     }
1680                 }
1681             }
1682         }
1683     }
1684
1685     for (listp = uniondef_defined; listp != NULL; listp = listp->next) {
1686         defp1 = (definition *) listp->val;
1687         for (plist = defp->pc.plists; plist; plist = plist->next) {
1688             if (plist->component_kind == DEF_PARAM
1689                 && (plist->pl.param_kind == DEF_OUTPARAM
1690                     || plist->pl.param_kind == DEF_INOUTPARAM)
1691                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1692                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1693                     if (plist->pl.param_flag & INDIRECT_PARAM) {
1694                         ss_ProcTail_frees(plist->scode, &somefrees);
1695                     }
1696                 }
1697             }
1698         }
1699     }
1700
1701     if (somefrees) {
1702         f_print(fout, ")\n");
1703         f_print(fout, "\t\tz_result = RXGEN_SS_XDRFREE;\n\n");
1704     }
1705
1706     if (xflag) {
1707         f_print(fout, "\tif (rx_enable_stats) {\n");
1708         f_print(fout, "\t    rx_RecordCallStatistics(z_call,");
1709         if (PackageStatIndex[PackageIndex]) {
1710             f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
1711         } else {
1712             f_print(fout,
1713                     "\n\t\t(((afs_uint32)(ntohs(rx_ServiceIdOf(rx_ConnectionOf(z_call))) << 16)) |\n"
1714                     "\t\t((afs_uint32)ntohs(rx_ServiceOf(rx_ConnectionOf(z_call))->servicePort))),\n");
1715         }
1716         f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, 0);\n",
1717                 no_of_stat_funcs, PackagePrefix[PackageIndex]);
1718         f_print(fout, "\t}\n\n");
1719     }
1720
1721     f_print(fout, "\treturn z_result;\n");
1722     f_print(fout, "}\n\n");
1723 }
1724
1725
1726 static void
1727 ucs_ProcName_setup(definition * defp, char *procheader, int split_flag)
1728 {
1729     proc1_list *plist;
1730
1731     if (!cflag) {
1732         if (ansic_flag) {
1733             f_print(fout, "int %s%s%s%s(struct ubik_client *aclient, afs_int32 aflags",
1734                           procheader, prefix, PackagePrefix[PackageIndex],
1735                           defp->pc.proc_name);
1736         } else {
1737             f_print(fout, "int %s%s%s%s(aclient, aflags", procheader, prefix,
1738                           PackagePrefix[PackageIndex], defp->pc.proc_name);
1739         }
1740     }
1741     if ((strlen(procheader) + strlen(prefix) +
1742          strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >=
1743         MAX_FUNCTION_NAME_LEN) {
1744         error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1745     }
1746     if (!cflag) {
1747         for (plist = defp->pc.plists; plist; plist = plist->next) {
1748             if (plist->component_kind == DEF_PARAM) {
1749                 f_print(fout, ",");
1750                 if (ansic_flag) {
1751                     if (plist->pl.param_kind == DEF_INPARAM &&
1752                         strcmp(plist->pl.param_type, "char *") == 0) {
1753                         f_print(fout, "const ");
1754                     }
1755                     if (plist->pl.param_flag & OUT_STRING) {
1756                         f_print(fout, "%s *%s", plist->pl.param_type,
1757                                 plist->pl.param_name);
1758                     } else {
1759                         f_print(fout, "%s %s", plist->pl.param_type,
1760                                 plist->pl.param_name);
1761                     }
1762                 } else {
1763                     plist->pl.param_flag &= ~PROCESSED_PARAM;
1764                     f_print(fout, " %s", plist->pl.param_name);
1765                 }
1766             }
1767         }
1768         f_print(fout, ")\n");
1769     }
1770 }
1771
1772
1773 static void
1774 ucs_ProcParams_setup(definition * defp, int split_flag)
1775 {
1776     proc1_list *plist, *plist1;
1777
1778     if (ansic_flag)
1779         return;
1780
1781     f_print(fout, "\tstruct ubik_client *aclient;\n\tafs_int32 aflags;\n");
1782     for (plist = defp->pc.plists; plist; plist = plist->next) {
1783         if (plist->component_kind == DEF_PARAM
1784             && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1785             if (plist->pl.param_flag & OUT_STRING) {
1786                 f_print(fout, "\t%s *%s", plist->pl.param_type,
1787                         plist->pl.param_name);
1788             } else {
1789                 f_print(fout, "\t%s %s", plist->pl.param_type,
1790                         plist->pl.param_name);
1791             }
1792             plist->pl.param_flag |= PROCESSED_PARAM;
1793             for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1794                 if ((plist1->component_kind == DEF_PARAM)
1795                     && streq(plist->pl.param_type, plist1->pl.param_type)
1796                     && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1797                     char *star = "";
1798                     char *pntr = strchr(plist1->pl.param_type, '*');
1799                     if (pntr)
1800                         star = "*";
1801                     if (plist1->pl.param_flag & OUT_STRING) {
1802                         f_print(fout, ", *%s%s", star, plist1->pl.param_name);
1803                     } else {
1804                         f_print(fout, ", %s%s", star, plist1->pl.param_name);
1805                     }
1806                     plist1->pl.param_flag |= PROCESSED_PARAM;
1807                 }
1808             }
1809             f_print(fout, ";\n");
1810         }
1811     }
1812 }
1813
1814 static void
1815 ucs_ProcTail_setup(definition * defp, int split_flag)
1816 {
1817     proc1_list *plist;
1818
1819     f_print(fout, "{\tafs_int32 rcode, code, newHost, thisHost, i, _ucount;\n");
1820     f_print(fout, "\tint chaseCount, pass, needsync;\n");
1821 #if 0 /* goes with block below */
1822     f_print(fout, "\tint j, inlist;\n");
1823 #endif
1824     f_print(fout, "\tstruct rx_connection *tc;\n");
1825     f_print(fout, "\tstruct rx_peer *rxp;\n");
1826     f_print(fout, "\tshort origLevel;\n\n");
1827     f_print(fout, "\tif (!aclient)\n");
1828     f_print(fout, "\t\treturn UNOENT;\n");
1829     f_print(fout, "\tLOCK_UBIK_CLIENT(aclient);\n\n");
1830     f_print(fout, "\t restart:\n");
1831     f_print(fout, "\torigLevel = aclient->initializationState;\n");
1832     f_print(fout, "\trcode = UNOSERVERS;\n");
1833     f_print(fout, "\tchaseCount = needsync = 0;\n\n");
1834 #if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
1835     f_print(fout, "\tinlist = 0;\n");
1836     f_print(fout, "\tLOCK_UCLNT_CACHE;\n");
1837     f_print(fout, "\tfor (j = 0; ((j < SYNCCOUNT) && calls_needsync[j]); j++) {\n");
1838     f_print(fout, "\t\tif (calls_needsync[j] == (int *)%s%s%s) {\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1839     f_print(fout, "\t\t\tinlist = needsync = 1;\n");
1840     f_print(fout, "\t\t\tbreak;\n");
1841     f_print(fout, "\t\t}\n");
1842     f_print(fout, "\t}\n");
1843     f_print(fout, "\tUNLOCK_UCLNT_CACHE;\n");
1844 #endif
1845     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");
1846     f_print(fout, "\tfor (pass = 0; pass < 2; pass++) {  /*p */\n");
1847     f_print(fout, "\t\t/* For each entry in our servers list */\n");
1848     f_print(fout, "\t\tfor (_ucount = 0;; _ucount++) {     /*s */\n\n");
1849     f_print(fout, "\t\tif (needsync) {\n");
1850     f_print(fout, "\t\t\t/* Need a sync site. Lets try to quickly find it */\n");
1851     f_print(fout, "\t\t\tif (aclient->syncSite) {\n");
1852     f_print(fout, "\t\t\t\tnewHost = aclient->syncSite;        /* already in network order */\n");
1853     f_print(fout, "\t\t\t\taclient->syncSite = 0;      /* Will reset if it works */\n");
1854     f_print(fout, "\t\t\t} else if (aclient->conns[3]) {\n");
1855     f_print(fout, "\t\t\t\t/* If there are fewer than four db servers in a cell,\n");
1856     f_print(fout, "\t\t\t\t* there's no point in making the GetSyncSite call.\n");
1857     f_print(fout, "\t\t\t\t* At best, it's a wash. At worst, it results in more\n");
1858     f_print(fout, "\t\t\t\t* RPCs than you would otherwise make.\n");
1859     f_print(fout, "\t\t\t\t*/\n");
1860     f_print(fout, "\t\t\t\ttc = aclient->conns[_ucount];\n");
1861     f_print(fout, "\t\t\t\tif (tc && rx_ConnError(tc)) {\n");
1862     f_print(fout, "\t\t\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
1863     f_print(fout, "\t\t\t\t}\n");
1864     f_print(fout, "\t\t\t\tif (!tc)\n");
1865     f_print(fout, "\t\t\t\t\tbreak;\n");
1866     f_print(fout, "\t\t\t\tcode = VOTE_GetSyncSite(tc, &newHost);\n");
1867     f_print(fout, "\t\t\t\tif (aclient->initializationState != origLevel)\n");
1868     f_print(fout, "\t\t\t\t\tgoto restart;   /* somebody did a ubik_ClientInit */\n");
1869     f_print(fout, "\t\t\t\tif (code)\n");
1870     f_print(fout, "\t\t\t\t\tnewHost = 0;\n");
1871     f_print(fout, "\t\t\t\tnewHost = htonl(newHost);   /* convert to network order */\n");
1872     f_print(fout, "\t\t\t} else {\n");
1873     f_print(fout, "\t\t\t\tnewHost = 0;\n");
1874     f_print(fout, "\t\t\t}\n");
1875     f_print(fout, "\t\t\tif (newHost) {\n");
1876     f_print(fout, "\t\t\t\t/* position count at the appropriate slot in the client\n");
1877     f_print(fout, "\t\t\t\t* structure and retry. If we can't find in slot, we'll\n");
1878     f_print(fout, "\t\t\t\t* just continue through the whole list \n");
1879     f_print(fout, "\t\t\t\t*/\n");
1880     f_print(fout, "\t\t\t\tfor (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {\n");
1881     f_print(fout, "\t\t\t\t\trxp = rx_PeerOf(aclient->conns[i]);\n");
1882     f_print(fout, "\t\t\t\t\tthisHost = rx_HostOf(rxp);\n");
1883     f_print(fout, "\t\t\t\t\tif (!thisHost)\n");
1884     f_print(fout, "\t\t\t\t\t\tbreak;\n");
1885     f_print(fout, "\t\t\t\t\tif (thisHost == newHost) {\n");
1886     f_print(fout, "\t\t\t\t\t\tif (chaseCount++ > 2)\n");
1887     f_print(fout, "\t\t\t\t\t\t\tbreak;  /* avoid loop asking */\n");
1888     f_print(fout, "\t\t\t\t\t\t_ucount = i;  /* this index is the sync site */\n");
1889     f_print(fout, "\t\t\t\t\t\tbreak;\n");
1890     f_print(fout, "\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n");
1891     f_print(fout, "\t\t/*needsync */\n");
1892     f_print(fout, "\t\ttc = aclient->conns[_ucount];\n");
1893     f_print(fout, "\t\tif (tc && rx_ConnError(tc)) {\n");
1894     f_print(fout, "\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
1895     f_print(fout, "\t\t}\n");
1896     f_print(fout, "\t\tif (!tc)\n");
1897     f_print(fout, "\t\t\tbreak;\n\n");
1898     f_print(fout, "\t\tif ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {\n");
1899     f_print(fout, "\t\t\tcontinue;       /* this guy's down */\n");
1900     f_print(fout, "\t\t}\n");
1901
1902     f_print(fout, "\t\trcode = %s%s%s(tc\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1903     for (plist = defp->pc.plists; plist; plist = plist->next) {
1904         if (plist->component_kind == DEF_PARAM) {
1905             plist->pl.param_flag &= ~PROCESSED_PARAM;
1906             f_print(fout, ", %s", plist->pl.param_name);
1907         }
1908     }
1909     f_print(fout, ");\n");
1910     f_print(fout, "\t\tif (aclient->initializationState != origLevel) {\n");
1911     f_print(fout, "\t\t\t/* somebody did a ubik_ClientInit */\n");
1912     f_print(fout, "\t\t\tif (rcode)\n");
1913     f_print(fout, "\t\t\t\tgoto restart;       /* call failed */\n");
1914     f_print(fout, "\t\t\telse\n");
1915     f_print(fout, "\t\t\t\tgoto done;  /* call suceeded */\n");
1916     f_print(fout, "\t\t}\n");
1917     f_print(fout, "\t\tif (rcode < 0) {    /* network errors */\n");
1918     f_print(fout, "\t\t\taclient->states[_ucount] |= CFLastFailed; /* Mark server down */\n");
1919     f_print(fout, "\t\t} else if (rcode == UNOTSYNC) {\n");
1920     f_print(fout, "\t\t\tneedsync = 1;\n");
1921     f_print(fout, "\t\t} else if (rcode != UNOQUORUM) {\n");
1922     f_print(fout, "\t\t\t/* either misc ubik code, or misc appl code, or success. */\n");
1923     f_print(fout, "\t\t\taclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/\n");
1924     f_print(fout, "\t\t\tgoto done;      /* all done */\n");
1925     f_print(fout, "\t\t}\n");
1926     f_print(fout, "\t\t}                       /*s */\n");
1927     f_print(fout, "\t}                           /*p */\n\n");
1928     f_print(fout, "\tdone:\n");
1929     f_print(fout, "\tif (needsync) {\n");
1930
1931 #if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
1932     f_print(fout, "\t\tif (!inlist) {          /* Remember proc call that needs sync site */\n");
1933     f_print(fout, "\t\t\tLOCK_UCLNT_CACHE;\n");
1934     f_print(fout, "\t\t\tcalls_needsync[synccount % SYNCCOUNT] = (int *)%s%s%s;\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1935     f_print(fout, "\t\t\tsynccount++;\n");
1936     f_print(fout, "\t\t\tUNLOCK_UCLNT_CACHE;\n");
1937     f_print(fout, "\t\t\tinlist = 1;\n");
1938     f_print(fout, "\t\t}\n");
1939 #endif
1940     f_print(fout, "\t\tif (!rcode) {           /* Remember the sync site - cmd successful */\n");
1941     f_print(fout, "\t\t\trxp = rx_PeerOf(aclient->conns[_ucount]);\n");
1942     f_print(fout, "\t\t\taclient->syncSite = rx_HostOf(rxp);\n");
1943     f_print(fout, "\t\t}\n");
1944     f_print(fout, "\t}\n");
1945     f_print(fout, "\tUNLOCK_UBIK_CLIENT(aclient);\n");
1946     f_print(fout, "\treturn rcode;\n}\n\n");
1947 }
1948
1949
1950 static int
1951 opcode_holes_exist(void)
1952 {
1953     int i;
1954
1955     for (i = lowest_opcode[PackageIndex]; i < highest_opcode[PackageIndex];
1956          i++) {
1957         if (!opcodenum_is_defined(i))
1958             return 1;
1959     }
1960     return 0;
1961 }
1962
1963
1964 void
1965 er_Proc_CodeGeneration(void)
1966 {
1967     int temp;
1968
1969     temp = PackageIndex;
1970     if (!combinepackages)
1971         PackageIndex = 0;
1972     for (; PackageIndex <= temp; PackageIndex++) {
1973         if (proc_defined[PackageIndex] == NULL)
1974             continue;
1975         if (combinepackages || opcode_holes_exist()) {
1976             er_HeadofOldStyleProc_setup();
1977             er_BodyofOldStyleProc_setup();
1978             er_TailofOldStyleProc_setup();
1979             er_HeadofOldStyleProc_setup2();
1980             er_BodyofOldStyleProc_setup2();
1981             er_TailofOldStyleProc_setup2();
1982         } else {
1983             er_ProcDeclExterns_setup();
1984             er_ProcProcsArray_setup();
1985             er_ProcMainBody_setup();
1986         }
1987     }
1988     PackageIndex = temp;
1989 }
1990
1991
1992 static void
1993 er_ProcDeclExterns_setup(void)
1994 {
1995     list *listp;
1996     definition *defp;
1997
1998     if ( !Sflag )
1999         return;
2000
2001     f_print(fout, "\n");
2002     for (listp = proc_defined[PackageIndex]; listp != NULL;
2003          listp = listp->next) {
2004         defp = (definition *) listp->val;
2005         if (defp->pc.proc_serverstub) {
2006             f_print(fout, "afs_int32 %s();\n", defp->pc.proc_serverstub);
2007         }
2008     }
2009 }
2010
2011
2012 static void
2013 er_ProcProcsArray_setup(void)
2014 {
2015     list *listp;
2016     definition *defp;
2017
2018     if ((listp = proc_defined[PackageIndex])) {
2019         defp = (definition *) listp->val;
2020         if ( cflag )  {
2021             f_print(fout, "\nstatic char *opnames%d[] = {\"%s%s\"",
2022                         PackageIndex, defp->pc.proc_prefix, defp->pc.proc_name);
2023         }
2024         else {
2025             if (defp->pc.proc_serverstub) {
2026                 f_print(fout, "\nstatic afs_int32 (*StubProcsArray%d[])() = {%s",
2027                         PackageIndex, defp->pc.proc_serverstub);
2028             } else {
2029                 f_print(fout,
2030                         "\nstatic afs_int32 (*StubProcsArray%d[])(struct rx_call *z_call, XDR *z_xdrs) = {_%s%s%s",
2031                         PackageIndex, prefix, defp->pc.proc_prefix,
2032                         ((definition *) listp->val)->pc.proc_name);
2033                 defp = (definition *) listp->val;
2034             }
2035         }
2036         listp = listp->next;
2037     }
2038     for (; listp != NULL; listp = listp->next) {
2039         defp = (definition *) listp->val;
2040         if ( cflag ) {
2041             f_print(fout, ", \"%s%s\"",defp->pc.proc_prefix,defp->pc.proc_name);
2042         }
2043         else {
2044             if (defp->pc.proc_serverstub) {
2045                 f_print(fout, ",%s", defp->pc.proc_serverstub);
2046             } else {
2047                 f_print(fout, ", _%s%s%s", prefix, defp->pc.proc_prefix,
2048                         defp->pc.proc_name);
2049             }
2050         }
2051     }
2052     f_print(fout, "};\n\n");
2053 }
2054
2055
2056 static void
2057 er_ProcMainBody_setup(void)
2058 {
2059     if ( cflag ) {
2060         f_print(fout, "char *%sTranslateOpCode(int op)\n{\n",
2061                 PackagePrefix[PackageIndex]);
2062         f_print(fout, "\tif (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\treturn NULL;\n",
2063                 PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2064         f_print(fout, "\treturn opnames%d[op - %sLOWEST_OPCODE];\n}\n",
2065                 PackageIndex, PackagePrefix[PackageIndex]);
2066         f_print(fout, "struct %sstats *%sOpCodeStats(int op)\n{\n",
2067                 PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2068         f_print(fout, "\tif (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\treturn NULL;\n",
2069                 PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2070         f_print(fout, "\treturn NULL;/*%d %s*/\n}\n",
2071                 PackageIndex, PackagePrefix[PackageIndex]);
2072
2073         return;
2074     }
2075     f_print(fout, "int %s%sExecuteRequest(struct rx_call *z_call)\n",
2076             prefix, PackagePrefix[PackageIndex]);
2077     f_print(fout, "{\n\tint op;\n");
2078     f_print(fout, "\tXDR z_xdrs;\n");
2079     f_print(fout, "\t" "afs_int32 z_result;\n\n");
2080     f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
2081     f_print(fout,
2082             "\tif (!xdr_int(&z_xdrs, &op))\n\t\tz_result = RXGEN_DECODE;\n");
2083     f_print(fout,
2084             "\telse if (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\tz_result = RXGEN_OPCODE;\n",
2085             PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2086     f_print(fout,
2087             "\telse\n\t\tz_result = (*StubProcsArray%d[op - %sLOWEST_OPCODE])(z_call, &z_xdrs);\n",
2088             PackageIndex, PackagePrefix[PackageIndex]);
2089     f_print(fout, "\treturn hton_syserr_conv(z_result);\n}\n");
2090 }
2091
2092 static void
2093 er_HeadofOldStyleProc_setup2(void)
2094 {
2095     if ( cflag ) {
2096         f_print(fout, "int %sOpCodeIndex(int op)\n{\n", (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2097         f_print(fout, "\tswitch (op) {\n");
2098     }
2099 }
2100
2101 static void
2102 er_HeadofOldStyleProc_setup(void)
2103 {
2104     if ( cflag ) {
2105         f_print(fout, "char *%sTranslateOpCode(int op)\n{\n",
2106             (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2107     }
2108     else {
2109         f_print(fout,
2110                 "\nint %s%sExecuteRequest (struct rx_call *z_call)\n",
2111                 prefix,
2112                 (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2113         f_print(fout, "{\n");
2114         f_print(fout, "\tint op;\n");
2115         f_print(fout, "\tXDR z_xdrs;\n");
2116         f_print(fout, "\t" "afs_int32 z_result;\n\n");
2117         f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
2118         f_print(fout, "\tz_result = RXGEN_DECODE;\n");
2119         f_print(fout, "\tif (!xdr_int(&z_xdrs, &op)) goto fail;\n");
2120     }
2121     f_print(fout, "\tswitch (op) {\n");
2122 }
2123
2124 static void
2125 er_BodyofOldStyleProc_setup(void)
2126 {
2127     list *listp;
2128
2129     if (combinepackages) {
2130         int temp = PackageIndex;
2131         for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
2132             for (listp = proc_defined[PackageIndex]; listp != NULL;
2133                  listp = listp->next)
2134                 proc_er_case((definition *) listp->val);
2135         }
2136         PackageIndex = temp;
2137     } else {
2138         for (listp = proc_defined[PackageIndex]; listp != NULL;
2139              listp = listp->next)
2140             proc_er_case((definition *) listp->val);
2141     }
2142 }
2143
2144
2145 static void
2146 proc_er_case(definition * defp)
2147 {
2148     if ( cflag ) {
2149         f_print(fout, "\t\tcase %d:", defp->pc.proc_opcodenum);
2150         f_print(fout, "\treturn \"%s%s\";\n",
2151                 defp->pc.proc_prefix, defp->pc.proc_name);
2152         return;
2153     }
2154     if (opcodesnotallowed[PackageIndex]) {
2155         f_print(fout, "\t\tcase %d:\n", defp->pc.proc_opcodenum);
2156     } else {
2157         f_print(fout, "\t\tcase %s:\n", defp->pc.proc_opcodename);
2158     }
2159     if (defp->pc.proc_serverstub) {
2160         f_print(fout, "\t\t\tz_result = %s(z_call, &z_xdrs);\n",
2161                 defp->pc.proc_serverstub);
2162     } else {
2163         f_print(fout, "\t\t\tz_result = _%s%s%s(z_call, &z_xdrs);\n", prefix,
2164                 defp->pc.proc_prefix, defp->pc.proc_name);
2165     }
2166     f_print(fout, "\t\t\tbreak;\n");
2167 }
2168
2169 static void
2170 proc_op_case(definition * defp)
2171 {
2172     f_print(fout, "\t\tcase %d:", defp->pc.proc_opcodenum);
2173     f_print(fout, "\treturn %d;\n",
2174             defp->statindex);
2175 }
2176
2177 static void
2178 er_BodyofOldStyleProc_setup2(void)
2179 {
2180     list *listp;
2181
2182     if (!cflag)
2183         return;
2184     if (combinepackages) {
2185         int temp = PackageIndex;
2186         for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
2187             for (listp = proc_defined[PackageIndex]; listp != NULL;
2188                  listp = listp->next)
2189                 proc_op_case((definition *) listp->val);
2190         }
2191         PackageIndex = temp;
2192     } else {
2193         for (listp = proc_defined[PackageIndex]; listp != NULL;
2194              listp = listp->next)
2195             proc_op_case((definition *) listp->val);
2196     }
2197 }
2198
2199 static void
2200 er_TailofOldStyleProc_setup2(void)
2201 {
2202     if ( cflag ) {
2203         f_print(fout, "\t\tdefault:\n");
2204         f_print(fout, "\t\t\treturn -1;\n\t}\n}\n");
2205     }
2206 }
2207
2208 static void
2209 er_TailofOldStyleProc_setup(void)
2210 {
2211     f_print(fout, "\t\tdefault:\n");
2212     if ( cflag ) {
2213         f_print(fout, "\t\t\treturn NULL;\n\t}\n}\n");
2214         return;
2215     }
2216     f_print(fout, "\t\t\tz_result = RXGEN_OPCODE;\n");
2217     f_print(fout, "\t\t\tbreak;\n\t}\n");
2218     f_print(fout, "fail:\n");
2219     f_print(fout, "\treturn z_result;\n}\n");
2220 }
2221
2222 static void
2223 h_ProcMainBody_setup(void)
2224 {
2225     f_print(fout,"\nextern int %s%sExecuteRequest(struct rx_call *);\n",
2226             prefix, PackagePrefix[PackageIndex]);
2227 }
2228
2229 static void
2230 h_HeadofOldStyleProc_setup(void)
2231 {
2232     char *pprefix = (combinepackages ? MasterPrefix :
2233                      PackagePrefix[PackageIndex]);
2234     f_print(fout,"\nstruct %sstats{\n\tint statsver;\n};", pprefix);
2235     f_print(fout,"\nextern int %s%sExecuteRequest(struct rx_call *);\n",
2236             prefix, pprefix);
2237     f_print(fout,"\nextern int %sOpCodeIndex(int op);\n", PackagePrefix[PackageIndex]);
2238 }
2239
2240 void
2241 h_Proc_CodeGeneration(void)
2242 {
2243     int temp;
2244
2245     temp = PackageIndex;
2246     if (!combinepackages)
2247         PackageIndex = 0;
2248     for (; PackageIndex <= temp; PackageIndex++) {
2249         if (combinepackages || opcode_holes_exist()) {
2250             h_HeadofOldStyleProc_setup();
2251         } else {
2252             h_ProcMainBody_setup();
2253         }
2254     }
2255     PackageIndex = temp;
2256 }
2257
2258 static void
2259 proc_h_case(definition * defp)
2260 {
2261     f_print(fout, "#define opcode_%s%s \t((afs_uint64)((%uLL << 32) + %sOpCodeIndex(%u)))\n",
2262             defp->pc.proc_prefix, defp->pc.proc_name, StatIndex,
2263             defp->pc.proc_prefix, defp->pc.proc_opcodenum);
2264 }
2265
2266 void
2267 h_opcode_stats_pkg(char *pprefix, int lowest, int highest, int nops,
2268                   int statfuncs, char *ptype, list *proclist)
2269 {
2270     list *listp;
2271
2272     if (!pprefix)
2273         return;
2274
2275     f_print(fout,
2276             "\n/* Opcode-related useful stats for %spackage: %s */\n",
2277             ptype, pprefix);
2278     f_print(fout, "#define %sLOWEST_OPCODE   %d\n", pprefix, lowest);
2279     f_print(fout, "#define %sHIGHEST_OPCODE     %d\n", pprefix, highest);
2280     f_print(fout, "#define %sNUMBER_OPCODES     %d\n\n", pprefix, nops);
2281
2282     for (listp = proclist; listp != NULL;
2283          listp = listp->next)
2284         proc_h_case((definition *) listp->val);
2285
2286     if (xflag) {
2287         f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n",
2288                 pprefix, statfuncs);
2289         f_print(fout, "AFS_RXGEN_EXPORT\n");
2290         f_print(fout, "extern const char *%sfunction_names[];\n\n",
2291                 pprefix);
2292     }
2293 }
2294
2295 void
2296 h_opcode_stats(void)
2297 {
2298     if (combinepackages) {
2299         h_opcode_stats_pkg(MasterPrefix, master_lowest_opcode, master_highest_opcode, master_no_of_opcodes, no_of_stat_funcs_header[0], "Master ", proc_defined[0]);
2300     } else {
2301         int i;
2302         for (i = 0; i <= PackageIndex; i++) {
2303             h_opcode_stats_pkg(PackagePrefix[i], lowest_opcode[i], highest_opcode[i], no_of_opcodes[i], no_of_stat_funcs_header[i], "", proc_defined[i]);
2304         }
2305     }
2306 }
2307
2308
2309 void
2310 generate_multi_macros(definition * defp)
2311 {
2312     char *startname = SplitStart, *endname = SplitEnd;
2313     proc1_list *plist;
2314     int numofparams;
2315     int first = 0;
2316
2317     if (!hflag)
2318         return;
2319     if (!Multi_Init) {
2320         Multi_Init = 1;
2321         f_print(fout, "\n#include <rx/rx_multi.h>");
2322     }
2323     f_print(fout, "\n#define multi_%s%s(", PackagePrefix[PackageIndex],
2324             defp->pc.proc_name);
2325     for (plist = defp->pc.plists; plist; plist = plist->next) {
2326         if (plist->component_kind == DEF_PARAM) {
2327             if (!first) {
2328                 first = 1;
2329                 f_print(fout, "%s", plist->pl.param_name);
2330             } else {
2331                 f_print(fout, ", %s", plist->pl.param_name);
2332             }
2333         }
2334     }
2335     f_print(fout, ") \\\n");
2336     if (!startname)
2337         startname = "Start";
2338     if (!endname)
2339         endname = "End";
2340     f_print(fout, "\tmulti_Body(%s%s%s(multi_call", startname,
2341             PackagePrefix[PackageIndex], defp->pc.proc_name);
2342     do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 0);
2343     for (plist = defp->pc.plists; plist; plist = plist->next) {
2344         if (plist->component_kind == DEF_PARAM)
2345             f_print(fout, ", %s", plist->pl.param_name);
2346     }
2347     do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 1);
2348     f_print(fout, "), %s%s%s(multi_call", endname,
2349             PackagePrefix[PackageIndex], defp->pc.proc_name);
2350     do_split(defp, IN, &numofparams, DEF_INPARAM, 0);
2351     for (plist = defp->pc.plists; plist; plist = plist->next) {
2352         if (plist->component_kind == DEF_PARAM) {
2353             f_print(fout, ", %s", plist->pl.param_name);
2354         }
2355     }
2356     do_split(defp, IN, &numofparams, DEF_INPARAM, 1);
2357     f_print(fout, "))\n\n");
2358 }
2359
2360
2361 int
2362 IsRxgenToken(token * tokp)
2363 {
2364     if (tokp->kind == TOK_PACKAGE || tokp->kind == TOK_PREFIX
2365         || tokp->kind == TOK_SPECIAL || tokp->kind == TOK_STARTINGOPCODE
2366         || tokp->kind == TOK_SPLITPREFIX || tokp->kind == TOK_PROC
2367         || tokp->kind == TOK_STATINDEX)
2368         return 1;
2369     return 0;
2370 }
2371
2372 int
2373 IsRxgenDefinition(definition * def)
2374 {
2375     if (def->def_kind == DEF_PACKAGE || def->def_kind == DEF_PREFIX
2376         || def->def_kind == DEF_SPECIAL || def->def_kind == DEF_STARTINGOPCODE
2377         || def->def_kind == DEF_SPLITPREFIX || def->def_kind == DEF_PROC)
2378         return 1;
2379     return 0;
2380 }