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