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