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