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