768e42f3bad26309939d2422be7e7a8603a0be6d
[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                 }
1439             }
1440         }
1441     }
1442     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1443         defp1 = (definition *) listp->val;
1444         for (plist = defp->pc.plists; plist; plist = plist->next) {
1445             if (plist->component_kind == DEF_PARAM) {
1446                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1447                     plist->pl.param_flag |= FREETHIS_PARAM;
1448                     switch (defp1->pc.rel) {
1449                     case REL_ARRAY:
1450                         plist->pl.string_name = alloc(40);
1451                         if (brief_flag) {
1452                             s_print(plist->pl.string_name, "val");
1453                         } else {
1454                             s_print(plist->pl.string_name, "%s_val",
1455                                     defp1->def_name);
1456                         }
1457                         break;
1458                     case REL_POINTER:
1459                         plist->pl.string_name = NULL;
1460                         break;
1461                     default:
1462                         break;
1463                     }
1464                 }
1465             }
1466         }
1467     }
1468     for (listp = complex_defined; listp != NULL; listp = listp->next) {
1469         defp1 = (definition *) listp->val;
1470         for (plist = defp->pc.plists; plist; plist = plist->next) {
1471             if (plist->component_kind == DEF_PARAM) {
1472                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1473                     plist->pl.param_flag |= FREETHIS_PARAM;
1474                 }
1475             }
1476         }
1477     }
1478
1479     for (plist = defp->pc.plists; plist; plist = plist->next) {
1480         if (plist->component_kind == DEF_PARAM) {
1481             fprintf(fout, "\n\tmemset(&%s, 0, sizeof(%s));",
1482                     plist->pl.param_name,
1483                     plist->pl.param_name);
1484         }
1485     }
1486
1487     f_print(fout, "\n");
1488 }
1489
1490
1491 static void
1492 ss_ProcUnmarshallInParams_setup(definition * defp)
1493 {
1494     int noofparams, noofoutparams, i;
1495     proc1_list *plist;
1496
1497     noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1498     noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1499     for (plist = defp->pc.plists, i = 0; plist; plist = plist->next) {
1500         if (plist->component_kind == DEF_PARAM
1501             && (plist->pl.param_kind == DEF_INPARAM
1502                 || plist->pl.param_kind == DEF_INOUTPARAM)) {
1503             if (!i) {
1504                 f_print(fout, "\n\tif ((!%s)",
1505                         (plist->scode ? plist->scode : plist->code));
1506             } else {
1507                 f_print(fout, "\n\t     || (!%s)",
1508                         (plist->scode ? plist->scode : plist->code));
1509             }
1510             if (++i == noofparams) {
1511                 if (!noofoutparams) {
1512                     f_print(fout, ") {\n");
1513                 } else {
1514                     f_print(fout, ") {\n");
1515                 }
1516                 f_print(fout,
1517                         "\t\tz_result = RXGEN_SS_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1518                 defp->can_fail = 1;
1519             }
1520         }
1521     }
1522 }
1523
1524
1525 static void
1526 ss_ProcCallRealProc_setup(definition * defp)
1527 {
1528     extern char zflag;
1529     proc1_list *plist;
1530
1531     f_print(fout, "\tz_result = %s%s%s%s(z_call", prefix, ServerPrefix,
1532             PackagePrefix[PackageIndex], defp->pc.proc_name);
1533     for (plist = defp->pc.plists; plist; plist = plist->next) {
1534         if (plist->component_kind == DEF_PARAM) {
1535             if (plist->pl.param_flag & INDIRECT_PARAM) {
1536                 f_print(fout, ", &%s", plist->pl.param_name);
1537             } else {
1538                 if (plist->pl.param_flag & OUT_STRING) {
1539                     f_print(fout, ", &%s", plist->pl.param_name);
1540                 } else {
1541                     f_print(fout, ", %s", plist->pl.param_name);
1542                 }
1543             }
1544         }
1545     }
1546     f_print(fout, ");\n");
1547     if (zflag) {
1548         f_print(fout, "\tif (z_result)\n\t\treturn z_result;\n");
1549     } else {
1550         f_print(fout, "\tif (z_result)\n\t\tgoto fail;\n");
1551     }
1552 }
1553
1554
1555 static void
1556 ss_ProcMarshallOutParams_setup(definition * defp)
1557 {
1558     proc1_list *plist;
1559     int noofparams, i;
1560
1561     noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1562     if (noofparams)
1563         f_print(fout, "\tz_xdrs->x_op = XDR_ENCODE;\n");
1564     if (noofparams) {
1565         for (plist = defp->pc.plists, i = 0; plist; plist = plist->next) {
1566             if (plist->component_kind == DEF_PARAM
1567                 && (plist->pl.param_kind == DEF_OUTPARAM
1568                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1569                 if (!i) {
1570                     f_print(fout, "\tif ((!%s)",
1571                             (plist->scode ? plist->scode : plist->code));
1572                 } else {
1573                     f_print(fout, "\n\t     || (!%s)",
1574                             (plist->scode ? plist->scode : plist->code));
1575                 }
1576                 if (++i == noofparams) {
1577                     f_print(fout, ")\n\t\tz_result = RXGEN_SS_MARSHAL;\n");
1578                 }
1579             }
1580         }
1581     }
1582 }
1583
1584 static void
1585 ss_ProcTail_frees(char *xdrfunc, int *somefrees) {
1586     if (!*somefrees) {
1587         f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1588         f_print(fout, "\tif ((!%s)", xdrfunc);
1589         *somefrees = 1;
1590     } else {
1591         f_print(fout, "\n\t    || (!%s)", xdrfunc);
1592     }
1593 }
1594
1595
1596 static void
1597 ss_ProcTail_setup(definition * defp)
1598 {
1599     proc1_list *plist;
1600     definition *defp1;
1601     list *listp;
1602     int somefrees = 0;
1603
1604     if (defp->can_fail) {
1605         f_print(fout, "fail:\n");
1606     }
1607
1608     for (plist = defp->pc.plists; plist; plist = plist->next) {
1609         if (plist->component_kind == DEF_PARAM
1610                 && (plist->pl.param_flag & FREETHIS_PARAM))
1611             ss_ProcTail_frees(plist->scode, &somefrees);
1612     }
1613
1614     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1615         defp1 = (definition *) listp->val;
1616         for (plist = defp->pc.plists; plist; plist = plist->next) {
1617             if (plist->component_kind == DEF_PARAM
1618                 && (plist->pl.param_kind == DEF_OUTPARAM
1619                     || plist->pl.param_kind == DEF_INOUTPARAM)
1620                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1621                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1622                     switch (defp1->pc.rel) {
1623                     case REL_ARRAY:
1624                     case REL_POINTER:
1625                         ss_ProcTail_frees(plist->scode, &somefrees);
1626                         break;
1627                     default:
1628                         break;
1629                     }
1630                 }
1631             }
1632         }
1633     }
1634
1635     for (listp = uniondef_defined; listp != NULL; listp = listp->next) {
1636         defp1 = (definition *) listp->val;
1637         for (plist = defp->pc.plists; plist; plist = plist->next) {
1638             if (plist->component_kind == DEF_PARAM
1639                 && (plist->pl.param_kind == DEF_OUTPARAM
1640                     || plist->pl.param_kind == DEF_INOUTPARAM)
1641                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1642                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1643                     if (plist->pl.param_flag & INDIRECT_PARAM) {
1644                         ss_ProcTail_frees(plist->scode, &somefrees);
1645                     }
1646                 }
1647             }
1648         }
1649     }
1650
1651     if (somefrees) {
1652         f_print(fout, ")\n");
1653         f_print(fout, "\t\tz_result = RXGEN_SS_XDRFREE;\n\n");
1654     }
1655
1656     if (xflag) {
1657         f_print(fout, "\tif (rx_enable_stats) {\n");
1658         f_print(fout, "\t    rx_RecordCallStatistics(z_call,");
1659         if (PackageStatIndex[PackageIndex]) {
1660             f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
1661         } else {
1662             f_print(fout,
1663                     "\n\t\t(((afs_uint32)(ntohs(rx_ServiceIdOf(rx_ConnectionOf(z_call))) << 16)) |\n"
1664                     "\t\t((afs_uint32)ntohs(rx_ServiceOf(rx_ConnectionOf(z_call))->servicePort))),\n");
1665         }
1666         f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, 0);\n",
1667                 no_of_stat_funcs, PackagePrefix[PackageIndex]);
1668         f_print(fout, "\t}\n\n");
1669     }
1670
1671     f_print(fout, "\treturn z_result;\n");
1672     f_print(fout, "}\n\n");
1673 }
1674
1675
1676 static void
1677 ucs_ProcName_setup(definition * defp, char *procheader, int split_flag)
1678 {
1679     proc1_list *plist;
1680
1681     if (!cflag) {
1682         if (ansic_flag) {
1683             f_print(fout, "int %s%s%s%s(struct ubik_client *aclient, afs_int32 aflags",
1684                           procheader, prefix, PackagePrefix[PackageIndex],
1685                           defp->pc.proc_name);
1686         } else {
1687             f_print(fout, "int %s%s%s%s(aclient, aflags", procheader, prefix,
1688                           PackagePrefix[PackageIndex], defp->pc.proc_name);
1689         }
1690     }
1691     if ((strlen(procheader) + strlen(prefix) +
1692          strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >=
1693         MAX_FUNCTION_NAME_LEN) {
1694         error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1695     }
1696     if (!cflag) {
1697         for (plist = defp->pc.plists; plist; plist = plist->next) {
1698             if (plist->component_kind == DEF_PARAM) {
1699                 f_print(fout, ",");
1700                 if (ansic_flag) {
1701                     if (plist->pl.param_kind == DEF_INPARAM &&
1702                         strcmp(plist->pl.param_type, "char *") == 0) {
1703                         f_print(fout, "const ");
1704                     }
1705                     if (plist->pl.param_flag & OUT_STRING) {
1706                         f_print(fout, "%s *%s", plist->pl.param_type,
1707                                 plist->pl.param_name);
1708                     } else {
1709                         f_print(fout, "%s %s", plist->pl.param_type,
1710                                 plist->pl.param_name);
1711                     }
1712                 } else {
1713                     plist->pl.param_flag &= ~PROCESSED_PARAM;
1714                     f_print(fout, " %s", plist->pl.param_name);
1715                 }
1716             }
1717         }
1718         f_print(fout, ")\n");
1719     }
1720 }
1721
1722
1723 static void
1724 ucs_ProcParams_setup(definition * defp, int split_flag)
1725 {
1726     proc1_list *plist, *plist1;
1727
1728     if (ansic_flag)
1729         return;
1730
1731     f_print(fout, "\tstruct ubik_client *aclient;\n\tafs_int32 aflags;\n");
1732     for (plist = defp->pc.plists; plist; plist = plist->next) {
1733         if (plist->component_kind == DEF_PARAM
1734             && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1735             if (plist->pl.param_flag & OUT_STRING) {
1736                 f_print(fout, "\t%s *%s", plist->pl.param_type,
1737                         plist->pl.param_name);
1738             } else {
1739                 f_print(fout, "\t%s %s", plist->pl.param_type,
1740                         plist->pl.param_name);
1741             }
1742             plist->pl.param_flag |= PROCESSED_PARAM;
1743             for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1744                 if ((plist1->component_kind == DEF_PARAM)
1745                     && streq(plist->pl.param_type, plist1->pl.param_type)
1746                     && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1747                     char *star = "";
1748                     char *pntr = strchr(plist1->pl.param_type, '*');
1749                     if (pntr)
1750                         star = "*";
1751                     if (plist1->pl.param_flag & OUT_STRING) {
1752                         f_print(fout, ", *%s%s", star, plist1->pl.param_name);
1753                     } else {
1754                         f_print(fout, ", %s%s", star, plist1->pl.param_name);
1755                     }
1756                     plist1->pl.param_flag |= PROCESSED_PARAM;
1757                 }
1758             }
1759             f_print(fout, ";\n");
1760         }
1761     }
1762 }
1763
1764 static void
1765 ucs_ProcTail_setup(definition * defp, int split_flag)
1766 {
1767     proc1_list *plist;
1768
1769     f_print(fout, "{\tafs_int32 rcode, code, newHost, thisHost, i, _ucount;\n");
1770     f_print(fout, "\tint chaseCount, pass, needsync;\n");
1771     f_print(fout, "\tstruct rx_connection *tc;\n");
1772     f_print(fout, "\tstruct rx_peer *rxp;\n");
1773     f_print(fout, "\tshort origLevel;\n\n");
1774     f_print(fout, "\tif (!aclient)\n");
1775     f_print(fout, "\t\treturn UNOENT;\n");
1776     f_print(fout, "\tLOCK_UBIK_CLIENT(aclient);\n\n");
1777     f_print(fout, "\t restart:\n");
1778     f_print(fout, "\torigLevel = aclient->initializationState;\n");
1779     f_print(fout, "\trcode = UNOSERVERS;\n");
1780     f_print(fout, "\tchaseCount = needsync = 0;\n\n");
1781     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");
1782     f_print(fout, "\tfor (pass = 0; pass < 2; pass++) {  /*p */\n");
1783     f_print(fout, "\t\t/* For each entry in our servers list */\n");
1784     f_print(fout, "\t\tfor (_ucount = 0;; _ucount++) {     /*s */\n\n");
1785     f_print(fout, "\t\tif (needsync) {\n");
1786     f_print(fout, "\t\t\t/* Need a sync site. Lets try to quickly find it */\n");
1787     f_print(fout, "\t\t\tif (aclient->syncSite) {\n");
1788     f_print(fout, "\t\t\t\tnewHost = aclient->syncSite;        /* already in network order */\n");
1789     f_print(fout, "\t\t\t\taclient->syncSite = 0;      /* Will reset if it works */\n");
1790     f_print(fout, "\t\t\t} else if (aclient->conns[3]) {\n");
1791     f_print(fout, "\t\t\t\t/* If there are fewer than four db servers in a cell,\n");
1792     f_print(fout, "\t\t\t\t* there's no point in making the GetSyncSite call.\n");
1793     f_print(fout, "\t\t\t\t* At best, it's a wash. At worst, it results in more\n");
1794     f_print(fout, "\t\t\t\t* RPCs than you would otherwise make.\n");
1795     f_print(fout, "\t\t\t\t*/\n");
1796     f_print(fout, "\t\t\t\ttc = aclient->conns[_ucount];\n");
1797     f_print(fout, "\t\t\t\tif (tc && rx_ConnError(tc)) {\n");
1798     f_print(fout, "\t\t\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
1799     f_print(fout, "\t\t\t\t}\n");
1800     f_print(fout, "\t\t\t\tif (!tc)\n");
1801     f_print(fout, "\t\t\t\t\tbreak;\n");
1802     f_print(fout, "\t\t\t\tcode = VOTE_GetSyncSite(tc, &newHost);\n");
1803     f_print(fout, "\t\t\t\tif (aclient->initializationState != origLevel)\n");
1804     f_print(fout, "\t\t\t\t\tgoto restart;   /* somebody did a ubik_ClientInit */\n");
1805     f_print(fout, "\t\t\t\tif (code)\n");
1806     f_print(fout, "\t\t\t\t\tnewHost = 0;\n");
1807     f_print(fout, "\t\t\t\tnewHost = htonl(newHost);   /* convert to network order */\n");
1808     f_print(fout, "\t\t\t} else {\n");
1809     f_print(fout, "\t\t\t\tnewHost = 0;\n");
1810     f_print(fout, "\t\t\t}\n");
1811     f_print(fout, "\t\t\tif (newHost) {\n");
1812     f_print(fout, "\t\t\t\t/* position count at the appropriate slot in the client\n");
1813     f_print(fout, "\t\t\t\t* structure and retry. If we can't find in slot, we'll\n");
1814     f_print(fout, "\t\t\t\t* just continue through the whole list \n");
1815     f_print(fout, "\t\t\t\t*/\n");
1816     f_print(fout, "\t\t\t\tfor (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {\n");
1817     f_print(fout, "\t\t\t\t\trxp = rx_PeerOf(aclient->conns[i]);\n");
1818     f_print(fout, "\t\t\t\t\tthisHost = rx_HostOf(rxp);\n");
1819     f_print(fout, "\t\t\t\t\tif (!thisHost)\n");
1820     f_print(fout, "\t\t\t\t\t\tbreak;\n");
1821     f_print(fout, "\t\t\t\t\tif (thisHost == newHost) {\n");
1822     f_print(fout, "\t\t\t\t\t\tif (chaseCount++ > 2)\n");
1823     f_print(fout, "\t\t\t\t\t\t\tbreak;  /* avoid loop asking */\n");
1824     f_print(fout, "\t\t\t\t\t\t_ucount = i;  /* this index is the sync site */\n");
1825     f_print(fout, "\t\t\t\t\t\tbreak;\n");
1826     f_print(fout, "\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n");
1827     f_print(fout, "\t\t/*needsync */\n");
1828     f_print(fout, "\t\ttc = aclient->conns[_ucount];\n");
1829     f_print(fout, "\t\tif (tc && rx_ConnError(tc)) {\n");
1830     f_print(fout, "\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
1831     f_print(fout, "\t\t}\n");
1832     f_print(fout, "\t\tif (!tc)\n");
1833     f_print(fout, "\t\t\tbreak;\n\n");
1834     f_print(fout, "\t\tif ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {\n");
1835     f_print(fout, "\t\t\tcontinue;       /* this guy's down */\n");
1836     f_print(fout, "\t\t}\n");
1837
1838     f_print(fout, "\t\trcode = %s%s%s(tc\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1839     for (plist = defp->pc.plists; plist; plist = plist->next) {
1840         if (plist->component_kind == DEF_PARAM) {
1841             plist->pl.param_flag &= ~PROCESSED_PARAM;
1842             f_print(fout, ", %s", plist->pl.param_name);
1843         }
1844     }
1845     f_print(fout, ");\n");
1846     f_print(fout, "\t\tif (aclient->initializationState != origLevel) {\n");
1847     f_print(fout, "\t\t\t/* somebody did a ubik_ClientInit */\n");
1848     f_print(fout, "\t\t\tif (rcode)\n");
1849     f_print(fout, "\t\t\t\tgoto restart;       /* call failed */\n");
1850     f_print(fout, "\t\t\telse\n");
1851     f_print(fout, "\t\t\t\tgoto done;  /* call suceeded */\n");
1852     f_print(fout, "\t\t}\n");
1853     f_print(fout, "\t\tif (rcode < 0) {    /* network errors */\n");
1854     f_print(fout, "\t\t\taclient->states[_ucount] |= CFLastFailed; /* Mark server down */\n");
1855     f_print(fout, "\t\t} else if (rcode == UNOTSYNC) {\n");
1856     f_print(fout, "\t\t\tneedsync = 1;\n");
1857     f_print(fout, "\t\t} else if (rcode != UNOQUORUM) {\n");
1858     f_print(fout, "\t\t\t/* either misc ubik code, or misc appl code, or success. */\n");
1859     f_print(fout, "\t\t\taclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/\n");
1860     f_print(fout, "\t\t\tgoto done;      /* all done */\n");
1861     f_print(fout, "\t\t}\n");
1862     f_print(fout, "\t\t}                       /*s */\n");
1863     f_print(fout, "\t}                           /*p */\n\n");
1864     f_print(fout, "\tdone:\n");
1865     f_print(fout, "\tif (needsync) {\n");
1866
1867     f_print(fout, "\t\tif (!rcode) {           /* Remember the sync site - cmd successful */\n");
1868     f_print(fout, "\t\t\trxp = rx_PeerOf(aclient->conns[_ucount]);\n");
1869     f_print(fout, "\t\t\taclient->syncSite = rx_HostOf(rxp);\n");
1870     f_print(fout, "\t\t}\n");
1871     f_print(fout, "\t}\n");
1872     f_print(fout, "\tUNLOCK_UBIK_CLIENT(aclient);\n");
1873     f_print(fout, "\treturn rcode;\n}\n\n");
1874 }
1875
1876
1877 static int
1878 opcode_holes_exist(void)
1879 {
1880     int i;
1881
1882     for (i = lowest_opcode[PackageIndex]; i < highest_opcode[PackageIndex];
1883          i++) {
1884         if (!opcodenum_is_defined(i))
1885             return 1;
1886     }
1887     return 0;
1888 }
1889
1890
1891 void
1892 er_Proc_CodeGeneration(void)
1893 {
1894     int temp;
1895
1896     temp = PackageIndex;
1897     if (!combinepackages)
1898         PackageIndex = 0;
1899     for (; PackageIndex <= temp; PackageIndex++) {
1900         if (proc_defined[PackageIndex] == NULL)
1901             continue;
1902         if (combinepackages || opcode_holes_exist()) {
1903             er_HeadofOldStyleProc_setup();
1904             er_BodyofOldStyleProc_setup();
1905             er_TailofOldStyleProc_setup();
1906             er_HeadofOldStyleProc_setup2();
1907             er_BodyofOldStyleProc_setup2();
1908             er_TailofOldStyleProc_setup2();
1909         } else {
1910             er_ProcDeclExterns_setup();
1911             er_ProcProcsArray_setup();
1912             er_ProcMainBody_setup();
1913         }
1914     }
1915     PackageIndex = temp;
1916 }
1917
1918
1919 static void
1920 er_ProcDeclExterns_setup(void)
1921 {
1922     list *listp;
1923     definition *defp;
1924
1925     if ( !Sflag )
1926         return;
1927
1928     f_print(fout, "\n");
1929     for (listp = proc_defined[PackageIndex]; listp != NULL;
1930          listp = listp->next) {
1931         defp = (definition *) listp->val;
1932         if (defp->pc.proc_serverstub) {
1933             f_print(fout, "afs_int32 %s();\n", defp->pc.proc_serverstub);
1934         }
1935     }
1936 }
1937
1938
1939 static void
1940 er_ProcProcsArray_setup(void)
1941 {
1942     list *listp;
1943     definition *defp;
1944
1945     if ((listp = proc_defined[PackageIndex])) {
1946         defp = (definition *) listp->val;
1947         if ( cflag )  {
1948             f_print(fout, "\nstatic char *opnames%d[] = {\"%s%s\"",
1949                         PackageIndex, defp->pc.proc_prefix, defp->pc.proc_name);
1950         }
1951         else {
1952             if (defp->pc.proc_serverstub) {
1953                 f_print(fout, "\nstatic afs_int32 (*StubProcsArray%d[])() = {%s",
1954                         PackageIndex, defp->pc.proc_serverstub);
1955             } else {
1956                 f_print(fout,
1957                         "\nstatic afs_int32 (*StubProcsArray%d[])(struct rx_call *z_call, XDR *z_xdrs) = {_%s%s%s",
1958                         PackageIndex, prefix, defp->pc.proc_prefix,
1959                         ((definition *) listp->val)->pc.proc_name);
1960             }
1961         }
1962         listp = listp->next;
1963     }
1964     for (; listp != NULL; listp = listp->next) {
1965         defp = (definition *) listp->val;
1966         if ( cflag ) {
1967             f_print(fout, ", \"%s%s\"",defp->pc.proc_prefix,defp->pc.proc_name);
1968         }
1969         else {
1970             if (defp->pc.proc_serverstub) {
1971                 f_print(fout, ",%s", defp->pc.proc_serverstub);
1972             } else {
1973                 f_print(fout, ", _%s%s%s", prefix, defp->pc.proc_prefix,
1974                         defp->pc.proc_name);
1975             }
1976         }
1977     }
1978     f_print(fout, "};\n\n");
1979 }
1980
1981
1982 static void
1983 er_ProcMainBody_setup(void)
1984 {
1985     if ( cflag ) {
1986         f_print(fout, "char *%sTranslateOpCode(int op)\n{\n",
1987                 PackagePrefix[PackageIndex]);
1988         f_print(fout, "\tif (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\treturn NULL;\n",
1989                 PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
1990         f_print(fout, "\treturn opnames%d[op - %sLOWEST_OPCODE];\n}\n",
1991                 PackageIndex, PackagePrefix[PackageIndex]);
1992         f_print(fout, "struct %sstats *%sOpCodeStats(int op)\n{\n",
1993                 PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
1994         f_print(fout, "\tif (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\treturn NULL;\n",
1995                 PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
1996         f_print(fout, "\treturn NULL;/*%d %s*/\n}\n",
1997                 PackageIndex, PackagePrefix[PackageIndex]);
1998
1999         return;
2000     }
2001     f_print(fout, "int %s%sExecuteRequest(struct rx_call *z_call)\n",
2002             prefix, PackagePrefix[PackageIndex]);
2003     f_print(fout, "{\n\tint op;\n");
2004     f_print(fout, "\tXDR z_xdrs;\n");
2005     f_print(fout, "\t" "afs_int32 z_result;\n\n");
2006     f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
2007     f_print(fout,
2008             "\tif (!xdr_int(&z_xdrs, &op))\n\t\tz_result = RXGEN_DECODE;\n");
2009     f_print(fout,
2010             "\telse if (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\tz_result = RXGEN_OPCODE;\n",
2011             PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2012     f_print(fout,
2013             "\telse\n\t\tz_result = (*StubProcsArray%d[op - %sLOWEST_OPCODE])(z_call, &z_xdrs);\n",
2014             PackageIndex, PackagePrefix[PackageIndex]);
2015     f_print(fout, "\treturn hton_syserr_conv(z_result);\n}\n");
2016 }
2017
2018 static void
2019 er_HeadofOldStyleProc_setup2(void)
2020 {
2021     if ( cflag ) {
2022         f_print(fout, "int %sOpCodeIndex(int op)\n{\n", (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2023         f_print(fout, "\tswitch (op) {\n");
2024     }
2025 }
2026
2027 static void
2028 er_HeadofOldStyleProc_setup(void)
2029 {
2030     if ( cflag ) {
2031         f_print(fout, "char *%sTranslateOpCode(int op)\n{\n",
2032             (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2033     }
2034     else {
2035         f_print(fout,
2036                 "\nint %s%sExecuteRequest (struct rx_call *z_call)\n",
2037                 prefix,
2038                 (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2039         f_print(fout, "{\n");
2040         f_print(fout, "\tint op;\n");
2041         f_print(fout, "\tXDR z_xdrs;\n");
2042         f_print(fout, "\t" "afs_int32 z_result;\n\n");
2043         f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
2044         f_print(fout, "\tz_result = RXGEN_DECODE;\n");
2045         f_print(fout, "\tif (!xdr_int(&z_xdrs, &op)) goto fail;\n");
2046     }
2047     f_print(fout, "\tswitch (op) {\n");
2048 }
2049
2050 static void
2051 er_BodyofOldStyleProc_setup(void)
2052 {
2053     list *listp;
2054
2055     if (combinepackages) {
2056         int temp = PackageIndex;
2057         for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
2058             for (listp = proc_defined[PackageIndex]; listp != NULL;
2059                  listp = listp->next)
2060                 proc_er_case((definition *) listp->val);
2061         }
2062         PackageIndex = temp;
2063     } else {
2064         for (listp = proc_defined[PackageIndex]; listp != NULL;
2065              listp = listp->next)
2066             proc_er_case((definition *) listp->val);
2067     }
2068 }
2069
2070
2071 static void
2072 proc_er_case(definition * defp)
2073 {
2074     if ( cflag ) {
2075         f_print(fout, "\t\tcase %d:", defp->pc.proc_opcodenum);
2076         f_print(fout, "\treturn \"%s%s\";\n",
2077                 defp->pc.proc_prefix, defp->pc.proc_name);
2078         return;
2079     }
2080     if (opcodesnotallowed[PackageIndex]) {
2081         f_print(fout, "\t\tcase %d:\n", defp->pc.proc_opcodenum);
2082     } else {
2083         f_print(fout, "\t\tcase %s:\n", defp->pc.proc_opcodename);
2084     }
2085     if (defp->pc.proc_serverstub) {
2086         f_print(fout, "\t\t\tz_result = %s(z_call, &z_xdrs);\n",
2087                 defp->pc.proc_serverstub);
2088     } else {
2089         f_print(fout, "\t\t\tz_result = _%s%s%s(z_call, &z_xdrs);\n", prefix,
2090                 defp->pc.proc_prefix, defp->pc.proc_name);
2091     }
2092     f_print(fout, "\t\t\tbreak;\n");
2093 }
2094
2095 static void
2096 proc_op_case(definition * defp)
2097 {
2098     f_print(fout, "\t\tcase %d:", defp->pc.proc_opcodenum);
2099     f_print(fout, "\treturn %d;\n",
2100             defp->statindex);
2101 }
2102
2103 static void
2104 er_BodyofOldStyleProc_setup2(void)
2105 {
2106     list *listp;
2107
2108     if (!cflag)
2109         return;
2110     if (combinepackages) {
2111         int temp = PackageIndex;
2112         for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
2113             for (listp = proc_defined[PackageIndex]; listp != NULL;
2114                  listp = listp->next)
2115                 proc_op_case((definition *) listp->val);
2116         }
2117         PackageIndex = temp;
2118     } else {
2119         for (listp = proc_defined[PackageIndex]; listp != NULL;
2120              listp = listp->next)
2121             proc_op_case((definition *) listp->val);
2122     }
2123 }
2124
2125 static void
2126 er_TailofOldStyleProc_setup2(void)
2127 {
2128     if ( cflag ) {
2129         f_print(fout, "\t\tdefault:\n");
2130         f_print(fout, "\t\t\treturn -1;\n\t}\n}\n");
2131     }
2132 }
2133
2134 static void
2135 er_TailofOldStyleProc_setup(void)
2136 {
2137     f_print(fout, "\t\tdefault:\n");
2138     if ( cflag ) {
2139         f_print(fout, "\t\t\treturn NULL;\n\t}\n}\n");
2140         return;
2141     }
2142     f_print(fout, "\t\t\tz_result = RXGEN_OPCODE;\n");
2143     f_print(fout, "\t\t\tbreak;\n\t}\n");
2144     f_print(fout, "fail:\n");
2145     f_print(fout, "\treturn z_result;\n}\n");
2146 }
2147
2148 static void
2149 h_ProcMainBody_setup(void)
2150 {
2151     f_print(fout,"\nextern int %s%sExecuteRequest(struct rx_call *);\n",
2152             prefix, PackagePrefix[PackageIndex]);
2153 }
2154
2155 static void
2156 h_HeadofOldStyleProc_setup(void)
2157 {
2158     char *pprefix = (combinepackages ? MasterPrefix :
2159                      PackagePrefix[PackageIndex]);
2160     f_print(fout,"\nstruct %sstats{\n\tint statsver;\n};", pprefix);
2161     f_print(fout,"\nextern int %s%sExecuteRequest(struct rx_call *);\n",
2162             prefix, pprefix);
2163     f_print(fout,"\nextern int %sOpCodeIndex(int op);\n", PackagePrefix[PackageIndex]);
2164 }
2165
2166 void
2167 h_Proc_CodeGeneration(void)
2168 {
2169     int temp;
2170
2171     temp = PackageIndex;
2172     if (!combinepackages)
2173         PackageIndex = 0;
2174     for (; PackageIndex <= temp; PackageIndex++) {
2175         if (combinepackages || opcode_holes_exist()) {
2176             h_HeadofOldStyleProc_setup();
2177         } else {
2178             h_ProcMainBody_setup();
2179         }
2180     }
2181     PackageIndex = temp;
2182 }
2183
2184 static void
2185 proc_h_case(definition * defp)
2186 {
2187     f_print(fout, "#define opcode_%s%s \t((afs_uint64)((%uLL << 32) + %sOpCodeIndex(%u)))\n",
2188             defp->pc.proc_prefix, defp->pc.proc_name, StatIndex,
2189             defp->pc.proc_prefix, defp->pc.proc_opcodenum);
2190 }
2191
2192 void
2193 h_opcode_stats_pkg(char *pprefix, int lowest, int highest, int nops,
2194                   int statfuncs, char *ptype, list *proclist)
2195 {
2196     list *listp;
2197
2198     if (!pprefix)
2199         return;
2200
2201     f_print(fout,
2202             "\n/* Opcode-related useful stats for %spackage: %s */\n",
2203             ptype, pprefix);
2204     f_print(fout, "#define %sLOWEST_OPCODE   %d\n", pprefix, lowest);
2205     f_print(fout, "#define %sHIGHEST_OPCODE     %d\n", pprefix, highest);
2206     f_print(fout, "#define %sNUMBER_OPCODES     %d\n\n", pprefix, nops);
2207
2208     for (listp = proclist; listp != NULL;
2209          listp = listp->next)
2210         proc_h_case((definition *) listp->val);
2211
2212     if (xflag) {
2213         f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n",
2214                 pprefix, statfuncs);
2215         f_print(fout, "AFS_RXGEN_EXPORT\n");
2216         f_print(fout, "extern const char *%sfunction_names[];\n\n",
2217                 pprefix);
2218     }
2219 }
2220
2221 void
2222 h_opcode_stats(void)
2223 {
2224     if (combinepackages) {
2225         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]);
2226     } else {
2227         int i;
2228         for (i = 0; i <= PackageIndex; i++) {
2229             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]);
2230         }
2231     }
2232 }
2233
2234
2235 void
2236 generate_multi_macros(definition * defp)
2237 {
2238     char *startname = SplitStart, *endname = SplitEnd;
2239     proc1_list *plist;
2240     int numofparams;
2241     int first = 0;
2242
2243     if (!hflag)
2244         return;
2245     if (!Multi_Init) {
2246         Multi_Init = 1;
2247         f_print(fout, "\n#include <rx/rx_multi.h>");
2248     }
2249     f_print(fout, "\n#define multi_%s%s(", PackagePrefix[PackageIndex],
2250             defp->pc.proc_name);
2251     for (plist = defp->pc.plists; plist; plist = plist->next) {
2252         if (plist->component_kind == DEF_PARAM) {
2253             if (!first) {
2254                 first = 1;
2255                 f_print(fout, "%s", plist->pl.param_name);
2256             } else {
2257                 f_print(fout, ", %s", plist->pl.param_name);
2258             }
2259         }
2260     }
2261     f_print(fout, ") \\\n");
2262     if (!startname)
2263         startname = "Start";
2264     if (!endname)
2265         endname = "End";
2266     f_print(fout, "\tmulti_Body(%s%s%s(multi_call", startname,
2267             PackagePrefix[PackageIndex], defp->pc.proc_name);
2268     do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 0);
2269     for (plist = defp->pc.plists; plist; plist = plist->next) {
2270         if (plist->component_kind == DEF_PARAM)
2271             f_print(fout, ", %s", plist->pl.param_name);
2272     }
2273     do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 1);
2274     f_print(fout, "), %s%s%s(multi_call", endname,
2275             PackagePrefix[PackageIndex], defp->pc.proc_name);
2276     do_split(defp, IN, &numofparams, DEF_INPARAM, 0);
2277     for (plist = defp->pc.plists; plist; plist = plist->next) {
2278         if (plist->component_kind == DEF_PARAM) {
2279             f_print(fout, ", %s", plist->pl.param_name);
2280         }
2281     }
2282     do_split(defp, IN, &numofparams, DEF_INPARAM, 1);
2283     f_print(fout, "))\n\n");
2284 }
2285
2286
2287 int
2288 IsRxgenToken(token * tokp)
2289 {
2290     if (tokp->kind == TOK_PACKAGE || tokp->kind == TOK_PREFIX
2291         || tokp->kind == TOK_SPECIAL || tokp->kind == TOK_STARTINGOPCODE
2292         || tokp->kind == TOK_SPLITPREFIX || tokp->kind == TOK_PROC
2293         || tokp->kind == TOK_STATINDEX)
2294         return 1;
2295     return 0;
2296 }
2297
2298 int
2299 IsRxgenDefinition(definition * def)
2300 {
2301     if (def->def_kind == DEF_PACKAGE || def->def_kind == DEF_PREFIX
2302         || def->def_kind == DEF_SPECIAL || def->def_kind == DEF_STARTINGOPCODE
2303         || def->def_kind == DEF_SPLITPREFIX || def->def_kind == DEF_PROC)
2304         return 1;
2305     return 0;
2306 }