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