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