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