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