rxgen: Handle complex structures
[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, *complex_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     int special = 0;
253
254     defp->def_kind = DEF_STRUCT;
255
256     scan(TOK_IDENT, &tok);
257     defp->def_name = tok.str;
258     scan(TOK_LBRACE, &tok);
259     tailp = &defp->def.st.decls;
260     do {
261         get_declaration(&dec, DEF_STRUCT);
262         /* If a structure contains an array, then we're going
263          * to need to be clever about freeing it */
264         if (dec.rel == REL_ARRAY) {
265            special = 1;
266         }
267         decls = ALLOC(decl_list);
268         decls->decl = dec;
269         *tailp = decls;
270         tailp = &decls->next;
271         scan(TOK_SEMICOLON, &tok);
272         peek(&tok);
273     } while (tok.kind != TOK_RBRACE);
274     get_token(&tok);
275     *tailp = NULL;
276
277     if (special)
278         STOREVAL(&complex_defined, defp);
279 }
280
281 static void
282 def_program(definition * defp)
283 {
284     token tok;
285     version_list *vlist;
286     version_list **vtailp;
287     proc_list *plist;
288     proc_list **ptailp;
289
290     defp->def_kind = DEF_PROGRAM;
291     scan(TOK_IDENT, &tok);
292     defp->def_name = tok.str;
293     scan(TOK_LBRACE, &tok);
294     vtailp = &defp->def.pr.versions;
295     scan(TOK_VERSION, &tok);
296     do {
297         scan(TOK_IDENT, &tok);
298         vlist = ALLOC(version_list);
299         vlist->vers_name = tok.str;
300         scan(TOK_LBRACE, &tok);
301         ptailp = &vlist->procs;
302         do {
303             plist = ALLOC(proc_list);
304             get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM);
305             if (streq(plist->res_type, "opaque")) {
306                 error("illegal result type");
307             }
308             scan(TOK_IDENT, &tok);
309             plist->proc_name = tok.str;
310             scan(TOK_LPAREN, &tok);
311             get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM);
312             if (streq(plist->arg_type, "opaque")) {
313                 error("illegal argument type");
314             }
315             scan(TOK_RPAREN, &tok);
316             scan(TOK_EQUAL, &tok);
317             scan_num(&tok);
318             scan(TOK_SEMICOLON, &tok);
319             plist->proc_num = tok.str;
320             *ptailp = plist;
321             ptailp = &plist->next;
322             peek(&tok);
323         } while (tok.kind != TOK_RBRACE);
324         *vtailp = vlist;
325         vtailp = &vlist->next;
326         scan(TOK_RBRACE, &tok);
327         scan(TOK_EQUAL, &tok);
328         scan_num(&tok);
329         vlist->vers_num = tok.str;
330         scan(TOK_SEMICOLON, &tok);
331         scan2(TOK_VERSION, TOK_RBRACE, &tok);
332     } while (tok.kind == TOK_VERSION);
333     scan(TOK_EQUAL, &tok);
334     scan_num(&tok);
335     defp->def.pr.prog_num = tok.str;
336     *vtailp = NULL;
337 }
338
339 static void
340 def_enum(definition * defp)
341 {
342     token tok;
343     enumval_list *elist;
344     enumval_list **tailp;
345
346     defp->def_kind = DEF_ENUM;
347     scan(TOK_IDENT, &tok);
348     defp->def_name = tok.str;
349     scan(TOK_LBRACE, &tok);
350     tailp = &defp->def.en.vals;
351     do {
352         scan(TOK_IDENT, &tok);
353         elist = ALLOC(enumval_list);
354         elist->name = tok.str;
355         elist->assignment = NULL;
356         scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
357         if (tok.kind == TOK_EQUAL) {
358             scan_num(&tok);
359             elist->assignment = tok.str;
360             scan2(TOK_COMMA, TOK_RBRACE, &tok);
361         }
362         *tailp = elist;
363         tailp = &elist->next;
364     } while (tok.kind != TOK_RBRACE);
365     *tailp = NULL;
366 }
367
368 static void
369 def_const(definition * defp)
370 {
371     token tok;
372
373     defp->def_kind = DEF_CONST;
374     scan(TOK_IDENT, &tok);
375     defp->def_name = tok.str;
376     scan(TOK_EQUAL, &tok);
377     scan2(TOK_IDENT, TOK_STRCONST, &tok);
378     defp->def.co = tok.str;
379 }
380
381 static void
382 def_union(definition * defp)
383 {
384     token tok;
385     declaration dec;
386     case_list *cases;
387     case_list **tailp;
388
389     defp->def_kind = DEF_UNION;
390     scan(TOK_IDENT, &tok);
391     defp->def_name = tok.str;
392     scan(TOK_SWITCH, &tok);
393     scan(TOK_LPAREN, &tok);
394     get_declaration(&dec, DEF_UNION);
395     defp->def.un.enum_decl = dec;
396     tailp = &defp->def.un.cases;
397     scan(TOK_RPAREN, &tok);
398     scan(TOK_LBRACE, &tok);
399     scan(TOK_CASE, &tok);
400     while (tok.kind == TOK_CASE) {
401         scan(TOK_IDENT, &tok);
402         cases = ALLOC(case_list);
403         cases->case_name = tok.str;
404         scan(TOK_COLON, &tok);
405         get_declaration(&dec, DEF_UNION);
406         cases->case_decl = dec;
407         *tailp = cases;
408         tailp = &cases->next;
409         scan(TOK_SEMICOLON, &tok);
410         scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
411     }
412     *tailp = NULL;
413     if (tok.kind == TOK_DEFAULT) {
414         scan(TOK_COLON, &tok);
415         get_declaration(&dec, DEF_UNION);
416         defp->def.un.default_decl = ALLOC(declaration);
417         *defp->def.un.default_decl = dec;
418         scan(TOK_SEMICOLON, &tok);
419         scan(TOK_RBRACE, &tok);
420     } else {
421         defp->def.un.default_decl = NULL;
422     }
423 }
424
425
426 static void
427 def_typedef(definition * defp)
428 {
429     declaration dec;
430
431     defp->def_kind = DEF_TYPEDEF;
432     get_declaration(&dec, DEF_TYPEDEF);
433     defp->def_name = dec.name;
434     defp->def.ty.old_prefix = dec.prefix;
435     defp->def.ty.old_type = dec.type;
436     defp->def.ty.rel = dec.rel;
437     defp->def.ty.array_max = dec.array_max;
438 }
439
440
441 static void
442 get_declaration(declaration * dec, defkind dkind)
443 {
444     token tok;
445
446     get_type(&dec->prefix, &dec->type, dkind);
447     dec->rel = REL_ALIAS;
448     if (streq(dec->type, "void")) {
449         return;
450     }
451     scan2(TOK_STAR, TOK_IDENT, &tok);
452     if (tok.kind == TOK_STAR) {
453         dec->rel = REL_POINTER;
454         scan(TOK_IDENT, &tok);
455     }
456     dec->name = tok.str;
457     if (peekscan(TOK_LBRACKET, &tok)) {
458         if (dec->rel == REL_POINTER) {
459             error("no array-of-pointer declarations -- use typedef");
460         }
461         dec->rel = REL_VECTOR;
462         scan_num(&tok);
463         dec->array_max = tok.str;
464         scan(TOK_RBRACKET, &tok);
465     } else if (peekscan(TOK_LANGLE, &tok)) {
466         if (dec->rel == REL_POINTER) {
467             error("no array-of-pointer declarations -- use typedef");
468         }
469         dec->rel = REL_ARRAY;
470         if (peekscan(TOK_RANGLE, &tok)) {
471             dec->array_max = "~0";      /* unspecified size, use max */
472         } else {
473             scan_num(&tok);
474             dec->array_max = tok.str;
475             scan(TOK_RANGLE, &tok);
476         }
477     }
478     if (streq(dec->type, "opaque")) {
479         if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
480             error("array declaration expected");
481         }
482     } else if (streq(dec->type, "string")) {
483         if (dec->rel != REL_ARRAY) {
484             error(" variable-length array declaration expected");
485         }
486     }
487 }
488
489
490 static void
491 get_type(char **prefixp, char **typep, defkind dkind)
492 {
493     token tok;
494
495     *prefixp = NULL;
496     get_token(&tok);
497     switch (tok.kind) {
498     case TOK_IDENT:
499         *typep = tok.str;
500         break;
501     case TOK_STRUCT:
502     case TOK_ENUM:
503     case TOK_UNION:
504         *prefixp = tok.str;
505         scan(TOK_IDENT, &tok);
506         *typep = tok.str;
507         break;
508     case TOK_UNSIGNED:
509         unsigned_dec(typep);
510         break;
511     case TOK_SHORT:
512         *typep = "short";
513         (void)peekscan(TOK_INT, &tok);
514         break;
515     case TOK_INT32:
516         *typep = "afs_int32";
517         (void)peekscan(TOK_INT, &tok);
518         break;
519     case TOK_VOID:
520         if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
521             error("voids allowed only inside union and program definitions");
522         }
523         *typep = tok.str;
524         break;
525     case TOK_STRING:
526     case TOK_OPAQUE:
527     case TOK_CHAR:
528     case TOK_INT:
529     case TOK_FLOAT:
530     case TOK_DOUBLE:
531     case TOK_BOOL:
532     case TOK_AFSUUID:
533         *typep = tok.str;
534         break;
535     default:
536         error("expected type specifier");
537     }
538 }
539
540
541 static void
542 unsigned_dec(char **typep)
543 {
544     token tok;
545
546     peek(&tok);
547     switch (tok.kind) {
548     case TOK_CHAR:
549         get_token(&tok);
550         *typep = "u_char";
551         break;
552     case TOK_SHORT:
553         get_token(&tok);
554         *typep = "u_short";
555         (void)peekscan(TOK_INT, &tok);
556         break;
557     case TOK_INT32:
558         get_token(&tok);
559         *typep = "afs_uint32";
560         (void)peekscan(TOK_INT, &tok);
561         break;
562     case TOK_INT:
563         get_token(&tok);
564         *typep = "u_int";
565         break;
566     default:
567         *typep = "u_int";
568         break;
569     }
570 }
571
572
573 static void
574 def_package(definition * defp)
575 {
576     token tok;
577
578     defp->def_kind = DEF_PACKAGE;
579     scan(TOK_IDENT, &tok);
580     defp->def_name = tok.str;
581     no_of_stat_funcs = 0;
582     if (PackageIndex++ >= MAX_PACKAGES)
583         error("Exceeded upper limit of package statements\n");
584     function_list_index = 0;
585     PackagePrefix[PackageIndex] = tok.str;
586     if (MasterPrefix == NULL)
587         MasterPrefix = tok.str;
588     no_of_opcodes[PackageIndex] = highest_opcode[PackageIndex] =
589         opcodesnotallowed[PackageIndex] = 0;
590     lowest_opcode[PackageIndex] = 99999;
591     proc_defined[PackageIndex] = NULL;
592     PackageStatIndex[PackageIndex] = NULL;
593 }
594
595 static void
596 def_prefix(definition * defp)
597 {
598     token tok;
599
600     defp->def_kind = DEF_PREFIX;
601     scan(TOK_IDENT, &tok);
602     defp->def_name = tok.str;
603     ServerPrefix = tok.str;
604 }
605
606 static void
607 def_statindex(definition * defp)
608 {
609     token tok;
610     char *name;
611
612     defp->def_kind = DEF_CONST;
613     scan_num(&tok);
614     if (PackageIndex < 0)
615         error("'statindex' command must follow 'package' command!\n");
616     if (PackageStatIndex[PackageIndex])
617         error("Cannot have more then one 'statindex' per package!\n");
618     if (InvalidConstant(tok.str))
619         error("Index in 'statindex' command must be a constant!");
620     name =
621         alloc(strlen(PackagePrefix[PackageIndex]) + strlen("STATINDEX") + 1);
622     strcpy(name, PackagePrefix[PackageIndex]);
623     strcat(name, "STATINDEX");
624     defp->def_name = name;
625     defp->def.co = tok.str;
626     PackageStatIndex[PackageIndex] = name;
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)
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                 if (ansic_flag) {
1153                     if (plist->pl.param_flag & OUT_STRING) {
1154                         f_print(fout, ",%s *%s", plist->pl.param_type,
1155                                 plist->pl.param_name);
1156                     } else {
1157                         f_print(fout, ",%s %s", plist->pl.param_type,
1158                                 plist->pl.param_name);
1159                     }
1160                 } else {
1161                     f_print(fout, ", %s", plist->pl.param_name);
1162                     plist->pl.param_flag &= ~PROCESSED_PARAM;
1163                 }
1164             }
1165         }
1166         f_print(fout, ")\n");
1167     }
1168 }
1169
1170 static void
1171 cs_ProcParams_setup(definition * defp, int split_flag)
1172 {
1173     proc1_list *plist, *plist1;
1174
1175     if (ansic_flag)
1176         return;
1177
1178     if (!split_flag)
1179         f_print(fout, "\tstruct rx_connection *z_conn;\n");
1180     if (split_flag) {
1181         f_print(fout, "\tstruct rx_call *z_call;\n");
1182     }
1183     for (plist = defp->pc.plists; plist; plist = plist->next) {
1184         if (plist->component_kind == DEF_PARAM
1185             && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1186             if (plist->pl.param_flag & OUT_STRING) {
1187                 f_print(fout, "\t%s *%s", plist->pl.param_type,
1188                         plist->pl.param_name);
1189             } else {
1190                 f_print(fout, "\t%s %s", plist->pl.param_type,
1191                         plist->pl.param_name);
1192             }
1193             plist->pl.param_flag |= PROCESSED_PARAM;
1194             for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1195                 if ((plist1->component_kind == DEF_PARAM)
1196                     && streq(plist->pl.param_type, plist1->pl.param_type)
1197                     && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1198                     char *star = "";
1199                     char *pntr = strchr(plist1->pl.param_type, '*');
1200                     if (pntr)
1201                         star = "*";
1202                     if (plist1->pl.param_flag & OUT_STRING) {
1203                         f_print(fout, ", *%s%s", star, plist1->pl.param_name);
1204                     } else {
1205                         f_print(fout, ", %s%s", star, plist1->pl.param_name);
1206                     }
1207                     plist1->pl.param_flag |= PROCESSED_PARAM;
1208                 }
1209             }
1210             f_print(fout, ";\n");
1211         }
1212     }
1213 }
1214
1215
1216 static void
1217 cs_ProcMarshallInParams_setup(definition * defp, int split_flag)
1218 {
1219     int noofparams, i = 0;
1220     proc1_list *plist;
1221     decl_list *dl;
1222     int noofallparams =
1223         defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT] +
1224         defp->pc.paramtypes[OUT];
1225
1226     f_print(fout, "{\n");
1227     if (!split_flag)
1228         f_print(fout, "\tstruct rx_call *z_call = rx_NewCall(z_conn);\n");
1229     if ((!split_flag) || (split_flag == 1)) {
1230         if (opcodesnotallowed[PackageIndex]) {
1231             f_print(fout, "\tstatic int z_op = %d;\n",
1232                     defp->pc.proc_opcodenum);
1233         } else {
1234             f_print(fout, "\tstatic int z_op = %s;\n",
1235                     defp->pc.proc_opcodename);
1236         }
1237     }
1238     f_print(fout, "\tint z_result;\n");
1239     if (!(split_flag > 1) || (noofallparams != 0)) {
1240         f_print(fout, "\tXDR z_xdrs;\n");
1241     }
1242     /*
1243      * Print out client side stat gathering call
1244      */
1245     if (xflag && split_flag != 1) {
1246         f_print(fout, "\tstruct clock __QUEUE, __EXEC;\n");
1247     }
1248
1249     if ((!split_flag) || (split_flag == 1)) {
1250         f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_ENCODE);\n");
1251         f_print(fout, "\n\t/* Marshal the arguments */\n");
1252         f_print(fout, "\tif ((!xdr_int(&z_xdrs, &z_op))");
1253         noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1254         for (plist = defp->pc.plists, dl = defp->def.st.decls; plist;
1255              plist = plist->next, dl = dl->next) {
1256             if (plist->component_kind == DEF_PARAM
1257                 && (plist->pl.param_kind == DEF_INPARAM
1258                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1259                 f_print(fout, "\n\t     || (!%s)", plist->code);
1260                 if (++i == noofparams) {
1261                     f_print(fout,
1262                             ") {\n\t\tz_result = RXGEN_CC_MARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1263                     defp->can_fail = 1;
1264                 }
1265             }
1266         }
1267         if (!i) {
1268             f_print(fout,
1269                     ") {\n\t\tz_result = RXGEN_CC_MARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1270             defp->can_fail = 1;
1271         }
1272     }
1273 }
1274
1275
1276 static void
1277 cs_ProcSendPacket_setup(definition * defp, int split_flag)
1278 {
1279     int noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1280
1281     if (noofoutparams) {
1282         f_print(fout, "\t/* Un-marshal the reply arguments */\n");
1283         if (split_flag) {
1284             f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
1285         } else {
1286             f_print(fout, "\tz_xdrs.x_op = XDR_DECODE;\n");
1287         }
1288     }
1289 }
1290
1291
1292 static void
1293 cs_ProcUnmarshallOutParams_setup(definition * defp)
1294 {
1295     int noofparams, i;
1296     proc1_list *plist;
1297     decl_list *dl;
1298
1299     noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1300     if (noofparams)
1301         for (plist = defp->pc.plists, dl = defp->def.st.decls, i = 0; plist;
1302              plist = plist->next, dl = dl->next) {
1303             if (plist->component_kind == DEF_PARAM
1304                 && (plist->pl.param_kind == DEF_OUTPARAM
1305                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1306                 if (!i) {
1307                     f_print(fout, "\tif ((!%s)", plist->code);
1308                 } else {
1309                     f_print(fout, "\n\t     || (!%s)", plist->code);
1310                 }
1311                 if (++i == noofparams) {
1312                     f_print(fout,
1313                             ") {\n\t\tz_result = RXGEN_CC_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1314                     defp->can_fail = 1;
1315                 }
1316             }
1317         }
1318 }
1319
1320
1321 static void
1322 cs_ProcTail_setup(definition * defp, int split_flag)
1323 {
1324     f_print(fout, "\tz_result = RXGEN_SUCCESS;\n");
1325     if (defp->can_fail) {
1326         f_print(fout, "fail:\n");
1327     }
1328     if (!split_flag) {
1329         f_print(fout, "\tz_result = rx_EndCall(z_call, z_result);\n");
1330     }
1331     if (xflag && split_flag != 1) {
1332         f_print(fout, "\tif (rx_enable_stats) {\n");
1333         f_print(fout, "\t    clock_GetTime(&__EXEC);\n");
1334         f_print(fout, "\t    clock_Sub(&__EXEC, &z_call->startTime);\n");
1335         f_print(fout, "\t    __QUEUE = z_call->startTime;\n");
1336         f_print(fout, "\t    clock_Sub(&__QUEUE, &z_call->queueTime);\n");
1337         if (PackageStatIndex[PackageIndex]) {
1338             if (!split_flag) {
1339                 f_print(fout,
1340                         "\t    rx_IncrementTimeAndCount(z_conn->peer, %s,\n",
1341                         PackageStatIndex[PackageIndex]);
1342             } else {
1343                 f_print(fout,
1344                         "\t    rx_IncrementTimeAndCount(z_call->conn->peer, %s,\n",
1345                         PackageStatIndex[PackageIndex]);
1346             }
1347         } else {
1348             if (!split_flag) {
1349                 f_print(fout,
1350                         "\t    rx_IncrementTimeAndCount(z_conn->peer,\n"
1351                         "\t\t(((afs_uint32)(ntohs(z_conn->serviceId) << 16)) \n"
1352                         "\t\t| ((afs_uint32)ntohs(z_conn->peer->port))),\n");
1353             } else {
1354                 f_print(fout,
1355                         "\t    rx_IncrementTimeAndCount(z_call->conn->peer,\n"
1356                         "\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
1357                         "\t\t((afs_uint32)ntohs(z_call->conn->peer->port))),\n");
1358             }
1359         }
1360         if (xflag) {
1361             f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
1362                     no_of_stat_funcs, PackagePrefix[PackageIndex]);
1363             f_print(fout,
1364                     "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 1);\n");
1365         }
1366         f_print(fout, "\t}\n\n");
1367     }
1368     f_print(fout, "\treturn z_result;\n}\n\n");
1369 }
1370
1371
1372 static void
1373 ss_Proc_CodeGeneration(definition * defp)
1374 {
1375     int somefrees = 0;
1376
1377     defp->can_fail = 0;
1378     ss_ProcName_setup(defp);
1379     if (!cflag) {
1380         ss_ProcParams_setup(defp, &somefrees);
1381         ss_ProcSpecial_setup(defp, &somefrees);
1382         ss_ProcUnmarshallInParams_setup(defp);
1383         ss_ProcCallRealProc_setup(defp);
1384         ss_ProcMarshallOutParams_setup(defp);
1385         ss_ProcTail_setup(defp, somefrees);
1386     }
1387 }
1388
1389
1390 static void
1391 ss_ProcName_setup(definition * defp)
1392 {
1393     proc1_list *plist;
1394
1395     if ((strlen(prefix) + strlen(PackagePrefix[PackageIndex]) +
1396          strlen(defp->pc.proc_name)) >= MAX_FUNCTION_NAME_LEN) {
1397         error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1398     }
1399
1400     if (!cflag) {
1401         f_print(fout, "static afs_int32 _%s%s%s(", prefix,
1402                 PackagePrefix[PackageIndex], defp->pc.proc_name);
1403         f_print(fout, "struct rx_call *z_call, XDR *z_xdrs)\n{\n");
1404         f_print(fout, "\t" "afs_int32 z_result;\n");
1405         if (xflag) {
1406             f_print(fout, "\tstruct clock __QUEUE, __EXEC;\n");
1407         }
1408
1409         for (plist = defp->pc.plists; plist; plist = plist->next)
1410             if (plist->component_kind == DEF_PARAM) {
1411                 plist->pl.param_flag &= ~(PROCESSED_PARAM);
1412                 plist->pl.string_name = NULL;
1413             }
1414     }
1415 }
1416
1417
1418 static void
1419 ss_ProcParams_setup(definition * defp, int *somefrees)
1420 {
1421     proc1_list *plist, *plist1;
1422     list *listp;
1423     definition *defp1;
1424
1425     for (plist = defp->pc.plists; plist; plist = plist->next) {
1426         if ((plist->component_kind == DEF_PARAM)
1427             && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1428             if (plist->pl.param_flag & INDIRECT_PARAM) {
1429                 char pres = '\0', *pntr = strchr(plist->pl.param_type, '*');
1430                 if (pntr) {
1431                     --pntr;
1432                     pres = *pntr;
1433                     *pntr = (char)0;
1434                 }
1435                 f_print(fout, "\t%s %s", plist->pl.param_type,
1436                         plist->pl.param_name);
1437                 *pntr = pres;
1438             } else if (strchr(plist->pl.param_type, '*') == 0) {
1439                 f_print(fout, "\t%s %s", plist->pl.param_type,
1440                         plist->pl.param_name);
1441             } else {
1442                 plist->pl.param_flag |= FREETHIS_PARAM;
1443                 *somefrees = 1;
1444                 f_print(fout, "\t%s %s=(%s)0", plist->pl.param_type,
1445                         plist->pl.param_name, plist->pl.param_type);
1446             }
1447             plist->pl.param_flag |= PROCESSED_PARAM;
1448             for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1449                 if ((plist1->component_kind == DEF_PARAM)
1450                     && streq(plist->pl.param_type, plist1->pl.param_type)
1451                     && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1452                     if (plist1->pl.param_flag & INDIRECT_PARAM) {
1453                         f_print(fout, ", %s", plist1->pl.param_name);
1454                     } else if (strchr(plist1->pl.param_type, '*') == 0) {
1455                         f_print(fout, ", %s", plist1->pl.param_name);
1456                     } else {
1457                         plist1->pl.param_flag |= FREETHIS_PARAM;
1458                         *somefrees = 1;
1459                         f_print(fout, ", *%s=(%s)0", plist1->pl.param_name,
1460                                 plist1->pl.param_type);
1461                     }
1462                     plist1->pl.param_flag |= PROCESSED_PARAM;
1463                 }
1464             }
1465             f_print(fout, ";\n");
1466         }
1467     }
1468     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1469         defp1 = (definition *) listp->val;
1470         for (plist = defp->pc.plists; plist; plist = plist->next) {
1471             if (plist->component_kind == DEF_PARAM
1472                 && (plist->pl.param_kind == DEF_OUTPARAM
1473                     || plist->pl.param_kind == DEF_INOUTPARAM)
1474                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1475                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1476                     switch (defp1->pc.rel) {
1477                     case REL_ARRAY:
1478                     case REL_POINTER:
1479                     default:
1480                         break;
1481                     }
1482                 }
1483             }
1484         }
1485     }
1486     fprintf(fout, "\n");
1487 }
1488
1489
1490 static void
1491 ss_ProcSpecial_setup(definition * defp, int *somefrees)
1492 {
1493     proc1_list *plist;
1494     definition *defp1;
1495     list *listp;
1496
1497     for (listp = special_defined; listp != NULL; listp = listp->next) {
1498         defp1 = (definition *) listp->val;
1499
1500         for (plist = defp->pc.plists; plist; plist = plist->next) {
1501             if (plist->component_kind == DEF_PARAM
1502                 && (plist->pl.param_kind == DEF_INPARAM
1503                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1504                 spec_list *spec = defp1->def.sd.specs;
1505                 char string[40];
1506                 strcpy(string, structname(spec->sdef.string_value));
1507                 if (streq(string, structname(plist->pl.param_type))) {
1508                     plist->pl.string_name = spec->sdef.string_name;
1509                     plist->pl.param_flag |= FREETHIS_PARAM;
1510                     *somefrees = 1;
1511                     fprintf(fout, "\n\t%s.%s = 0;", plist->pl.param_name,
1512                             spec->sdef.string_name);
1513                 }
1514             }
1515         }
1516     }
1517     if (!*somefrees)
1518         fprintf(fout, "\n");
1519     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1520         defp1 = (definition *) listp->val;
1521         for (plist = defp->pc.plists; plist; plist = plist->next) {
1522             if (plist->component_kind == DEF_PARAM) {
1523                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1524                     plist->pl.param_flag |= FREETHIS_PARAM;
1525                     *somefrees = 1;
1526                     switch (defp1->pc.rel) {
1527                     case REL_ARRAY:
1528                         f_print(fout, "\n\t%s.%s_val = 0;",
1529                                 plist->pl.param_name, defp1->def_name);
1530                         f_print(fout, "\n\t%s.%s_len = 0;",
1531                                 plist->pl.param_name, defp1->def_name);
1532                         plist->pl.string_name = alloc(40);
1533                         s_print(plist->pl.string_name, "%s_val",
1534                                 defp1->def_name);
1535                         break;
1536                     case REL_POINTER:
1537                         f_print(fout, "\n\t%s = 0;", plist->pl.param_name);
1538                         plist->pl.string_name = NULL;
1539                         break;
1540                     default:
1541                         break;
1542                     }
1543                 }
1544             }
1545         }
1546     }
1547     for (listp = complex_defined; listp != NULL; listp = listp->next) {
1548         defp1 = (definition *) listp->val;
1549         for (plist = defp->pc.plists; plist; plist = plist->next) {
1550             if (plist->component_kind == DEF_PARAM) {
1551                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1552                     plist->pl.param_flag |= FREETHIS_PARAM;
1553                     *somefrees = 1;
1554                     fprintf(fout, "\n\tmemset(&%s, 0, sizeof(%s));",
1555                                  plist->pl.param_name, defp1->def_name);
1556                 }
1557             }
1558         }
1559     }
1560
1561     f_print(fout, "\n");
1562 }
1563
1564
1565 static void
1566 ss_ProcUnmarshallInParams_setup(definition * defp)
1567 {
1568     int noofparams, noofoutparams, i;
1569     proc1_list *plist;
1570
1571     noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1572     noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1573     for (plist = defp->pc.plists, i = 0; plist; plist = plist->next) {
1574         if (plist->component_kind == DEF_PARAM
1575             && (plist->pl.param_kind == DEF_INPARAM
1576                 || plist->pl.param_kind == DEF_INOUTPARAM)) {
1577             if (!i) {
1578                 f_print(fout, "\n\tif ((!%s)",
1579                         (plist->scode ? plist->scode : plist->code));
1580             } else {
1581                 f_print(fout, "\n\t     || (!%s)",
1582                         (plist->scode ? plist->scode : plist->code));
1583             }
1584             if (++i == noofparams) {
1585                 if (!noofoutparams) {
1586                     f_print(fout, ") {\n");
1587                 } else {
1588                     f_print(fout, ") {\n");
1589                 }
1590                 f_print(fout,
1591                         "\t\tz_result = RXGEN_SS_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1592                 defp->can_fail = 1;
1593             }
1594         }
1595     }
1596 }
1597
1598
1599 static void
1600 ss_ProcCallRealProc_setup(definition * defp)
1601 {
1602     extern char zflag;
1603     proc1_list *plist;
1604
1605     f_print(fout, "\tz_result = %s%s%s%s(z_call", prefix, ServerPrefix,
1606             PackagePrefix[PackageIndex], defp->pc.proc_name);
1607     for (plist = defp->pc.plists; plist; plist = plist->next) {
1608         if (plist->component_kind == DEF_PARAM) {
1609             if (plist->pl.param_flag & INDIRECT_PARAM) {
1610                 f_print(fout, ", &%s", plist->pl.param_name);
1611             } else {
1612                 if (plist->pl.param_flag & OUT_STRING) {
1613                     f_print(fout, ", &%s", plist->pl.param_name);
1614                 } else {
1615                     f_print(fout, ", %s", plist->pl.param_name);
1616                 }
1617             }
1618         }
1619     }
1620     f_print(fout, ");\n");
1621     if (zflag) {
1622         f_print(fout, "\tif (z_result)\n\t\treturn z_result;\n");
1623     }
1624 }
1625
1626
1627 static void
1628 ss_ProcMarshallOutParams_setup(definition * defp)
1629 {
1630     proc1_list *plist;
1631     int noofparams, i;
1632
1633     noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1634     if (noofparams)
1635         f_print(fout, "\tz_xdrs->x_op = XDR_ENCODE;\n");
1636     if (noofparams) {
1637         for (plist = defp->pc.plists, i = 0; plist; plist = plist->next) {
1638             if (plist->component_kind == DEF_PARAM
1639                 && (plist->pl.param_kind == DEF_OUTPARAM
1640                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1641                 if (!i) {
1642                     f_print(fout, "\tif ((!%s)",
1643                             (plist->scode ? plist->scode : plist->code));
1644                 } else {
1645                     f_print(fout, "\n\t     || (!%s)",
1646                             (plist->scode ? plist->scode : plist->code));
1647                 }
1648                 if (++i == noofparams) {
1649                     f_print(fout, ")\n\t\tz_result = RXGEN_SS_MARSHAL;\n");
1650                 }
1651             }
1652         }
1653     }
1654 }
1655
1656
1657 static void
1658 ss_ProcTail_setup(definition * defp, int somefrees)
1659 {
1660     proc1_list *plist;
1661     definition *defp1;
1662     list *listp;
1663     int firsttime = 0;
1664
1665     if (defp->can_fail) {
1666         f_print(fout, "fail:\n");
1667     }
1668     for (plist = defp->pc.plists; plist; plist = plist->next) {
1669         if (plist->component_kind == DEF_PARAM
1670             && (plist->pl.param_flag & FREETHIS_PARAM))
1671             somefrees = 1;
1672     }
1673     if (somefrees)
1674         f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1675     for (plist = defp->pc.plists; plist; plist = plist->next) {
1676         if (plist->component_kind == DEF_PARAM
1677                 && (plist->pl.param_flag & FREETHIS_PARAM))
1678             f_print(fout, "\tif (!%s) goto fail1;\n", plist->scode);
1679     }
1680     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1681         defp1 = (definition *) listp->val;
1682         for (plist = defp->pc.plists; plist; plist = plist->next) {
1683             if (plist->component_kind == DEF_PARAM
1684                 && (plist->pl.param_kind == DEF_OUTPARAM
1685                     || plist->pl.param_kind == DEF_INOUTPARAM)
1686                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1687                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1688                     switch (defp1->pc.rel) {
1689                     case REL_ARRAY:
1690                     case REL_POINTER:
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                         break;
1699                     default:
1700                         break;
1701                     }
1702                 }
1703             }
1704         }
1705     }
1706     for (listp = uniondef_defined; listp != NULL; listp = listp->next) {
1707         defp1 = (definition *) listp->val;
1708         for (plist = defp->pc.plists; plist; plist = plist->next) {
1709             if (plist->component_kind == DEF_PARAM
1710                 && (plist->pl.param_kind == DEF_OUTPARAM
1711                     || plist->pl.param_kind == DEF_INOUTPARAM)
1712                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1713                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1714                     if (plist->pl.param_flag & INDIRECT_PARAM) {
1715                         if (!somefrees && !firsttime) {
1716                             firsttime = 1;
1717                             f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1718                         }
1719                         somefrees = 1;
1720                         f_print(fout, "\tif (!%s) goto fail1;\n",
1721                                 plist->scode);
1722                     }
1723                 }
1724             }
1725         }
1726     }
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, "\t    rx_IncrementTimeAndCount(z_call->conn->peer,");
1735         if (PackageStatIndex[PackageIndex]) {
1736             f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
1737         } else {
1738             f_print(fout,
1739                     "\n\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
1740                     "\t\t((afs_uint32)ntohs(z_call->conn->service->servicePort))),\n");
1741         }
1742         f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
1743                 no_of_stat_funcs, PackagePrefix[PackageIndex]);
1744         f_print(fout, "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 0);\n");
1745         f_print(fout, "\t}\n\n");
1746     }
1747
1748     f_print(fout, "\treturn z_result;\n");
1749     if (somefrees) {
1750         f_print(fout, "fail1:\n");
1751
1752         if (xflag) {
1753             f_print(fout, "\tif (rx_enable_stats) {\n");
1754             f_print(fout, "\t    clock_GetTime(&__EXEC);\n");
1755             f_print(fout, "\t    clock_Sub(&__EXEC, &z_call->startTime);\n");
1756             f_print(fout, "\t    __QUEUE = z_call->startTime;\n");
1757             f_print(fout, "\t    clock_Sub(&__QUEUE, &z_call->queueTime);\n");
1758             f_print(fout,
1759                     "\t    rx_IncrementTimeAndCount(z_call->conn->peer,");
1760             if (PackageStatIndex[PackageIndex]) {
1761                 f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
1762             } else {
1763                 f_print(fout,
1764                         "\n\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
1765                         "\t\t((afs_uint32)ntohs(z_call->conn->service->servicePort))),\n");
1766             }
1767             f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
1768                     no_of_stat_funcs, PackagePrefix[PackageIndex]);
1769             f_print(fout,
1770                     "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 0);\n");
1771             f_print(fout, "\t}\n\n");
1772         }
1773
1774         f_print(fout, "\treturn RXGEN_SS_XDRFREE;\n}\n\n");
1775     } else {
1776         f_print(fout, "}\n\n");
1777     }
1778 }
1779
1780
1781 static void
1782 ucs_ProcName_setup(definition * defp, char *procheader, int split_flag)
1783 {
1784     proc1_list *plist;
1785
1786     if (!cflag) {
1787         if (ansic_flag) {
1788             f_print(fout, "int %s%s%s%s(struct ubik_client *aclient, afs_int32 aflags",
1789                           procheader, prefix, PackagePrefix[PackageIndex],
1790                           defp->pc.proc_name);
1791         } else {
1792             f_print(fout, "int %s%s%s%s(aclient, aflags", procheader, prefix,
1793                           PackagePrefix[PackageIndex], defp->pc.proc_name);
1794         }
1795     }
1796     if ((strlen(procheader) + strlen(prefix) +
1797          strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >=
1798         MAX_FUNCTION_NAME_LEN) {
1799         error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1800     }
1801     if (!cflag) {
1802         for (plist = defp->pc.plists; plist; plist = plist->next) {
1803             if (plist->component_kind == DEF_PARAM) {
1804                 if (ansic_flag) {
1805                     if (plist->pl.param_flag & OUT_STRING) {
1806                         f_print(fout, ",%s *%s", plist->pl.param_type,
1807                                 plist->pl.param_name);
1808                     } else {
1809                         f_print(fout, ",%s %s", plist->pl.param_type,
1810                                 plist->pl.param_name);
1811                     }
1812                 } else {
1813                     plist->pl.param_flag &= ~PROCESSED_PARAM;
1814                     f_print(fout, ", %s", plist->pl.param_name);
1815                 }
1816             }
1817         }
1818         f_print(fout, ")\n");
1819     }
1820 }
1821
1822
1823 static void
1824 ucs_ProcParams_setup(definition * defp, int split_flag)
1825 {
1826     proc1_list *plist, *plist1;
1827
1828     if (ansic_flag)
1829         return;
1830
1831     f_print(fout, "\tstruct ubik_client *aclient;\n\tafs_int32 aflags;\n");
1832     for (plist = defp->pc.plists; plist; plist = plist->next) {
1833         if (plist->component_kind == DEF_PARAM
1834             && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1835             if (plist->pl.param_flag & OUT_STRING) {
1836                 f_print(fout, "\t%s *%s", plist->pl.param_type,
1837                         plist->pl.param_name);
1838             } else {
1839                 f_print(fout, "\t%s %s", plist->pl.param_type,
1840                         plist->pl.param_name);
1841             }
1842             plist->pl.param_flag |= PROCESSED_PARAM;
1843             for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1844                 if ((plist1->component_kind == DEF_PARAM)
1845                     && streq(plist->pl.param_type, plist1->pl.param_type)
1846                     && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1847                     char *star = "";
1848                     char *pntr = strchr(plist1->pl.param_type, '*');
1849                     if (pntr)
1850                         star = "*";
1851                     if (plist1->pl.param_flag & OUT_STRING) {
1852                         f_print(fout, ", *%s%s", star, plist1->pl.param_name);
1853                     } else {
1854                         f_print(fout, ", %s%s", star, plist1->pl.param_name);
1855                     }
1856                     plist1->pl.param_flag |= PROCESSED_PARAM;
1857                 }
1858             }
1859             f_print(fout, ";\n");
1860         }
1861     }
1862 }
1863
1864 static void
1865 ucs_ProcTail_setup(definition * defp, int split_flag)
1866 {
1867     proc1_list *plist;
1868
1869     f_print(fout, "{\tafs_int32 rcode, code, newHost, thisHost, i, _ucount;\n");
1870     f_print(fout, "\tint chaseCount, pass, needsync;\n");
1871 #if 0 /* goes with block below */
1872     f_print(fout, "\tint j, inlist;\n");
1873 #endif
1874     f_print(fout, "\tstruct rx_connection *tc;\n");
1875     f_print(fout, "\tstruct rx_peer *rxp;\n");
1876     f_print(fout, "\tshort origLevel;\n\n");
1877     f_print(fout, "\tif (!aclient)\n");
1878     f_print(fout, "\t\treturn UNOENT;\n");
1879     f_print(fout, "\tLOCK_UBIK_CLIENT(aclient);\n\n");
1880     f_print(fout, "\t restart:\n");
1881     f_print(fout, "\torigLevel = aclient->initializationState;\n");
1882     f_print(fout, "\trcode = UNOSERVERS;\n");
1883     f_print(fout, "\tchaseCount = needsync = 0;\n\n");
1884 #if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
1885     f_print(fout, "\tinlist = 0;\n");
1886     f_print(fout, "\tLOCK_UCLNT_CACHE;\n");
1887     f_print(fout, "\tfor (j = 0; ((j < SYNCCOUNT) && calls_needsync[j]); j++) {\n");
1888     f_print(fout, "\t\tif (calls_needsync[j] == (int *)%s%s%s) {\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1889     f_print(fout, "\t\t\tinlist = needsync = 1;\n");
1890     f_print(fout, "\t\t\tbreak;\n");
1891     f_print(fout, "\t\t}\n");
1892     f_print(fout, "\t}\n");
1893     f_print(fout, "\tUNLOCK_UCLNT_CACHE;\n");
1894 #endif
1895     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");
1896     f_print(fout, "\tfor (pass = 0; pass < 2; pass++) {  /*p */\n");
1897     f_print(fout, "\t\t/* For each entry in our servers list */\n");
1898     f_print(fout, "\t\tfor (_ucount = 0;; _ucount++) {     /*s */\n\n");
1899     f_print(fout, "\t\tif (needsync) {\n");
1900     f_print(fout, "\t\t\t/* Need a sync site. Lets try to quickly find it */\n");
1901     f_print(fout, "\t\t\tif (aclient->syncSite) {\n");
1902     f_print(fout, "\t\t\t\tnewHost = aclient->syncSite;        /* already in network order */\n");
1903     f_print(fout, "\t\t\t\taclient->syncSite = 0;      /* Will reset if it works */\n");
1904     f_print(fout, "\t\t\t} else if (aclient->conns[3]) {\n");
1905     f_print(fout, "\t\t\t\t/* If there are fewer than four db servers in a cell,\n");
1906     f_print(fout, "\t\t\t\t* there's no point in making the GetSyncSite call.\n");
1907     f_print(fout, "\t\t\t\t* At best, it's a wash. At worst, it results in more\n");
1908     f_print(fout, "\t\t\t\t* RPCs than you would otherwise make.\n");
1909     f_print(fout, "\t\t\t\t*/\n");
1910     f_print(fout, "\t\t\t\ttc = aclient->conns[_ucount];\n");
1911     f_print(fout, "\t\t\t\tif (tc && rx_ConnError(tc)) {\n");
1912     f_print(fout, "\t\t\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
1913     f_print(fout, "\t\t\t\t}\n");
1914     f_print(fout, "\t\t\t\tif (!tc)\n");
1915     f_print(fout, "\t\t\t\t\tbreak;\n");
1916     f_print(fout, "\t\t\t\tcode = VOTE_GetSyncSite(tc, &newHost);\n");
1917     f_print(fout, "\t\t\t\tif (aclient->initializationState != origLevel)\n");
1918     f_print(fout, "\t\t\t\t\tgoto restart;   /* somebody did a ubik_ClientInit */\n");
1919     f_print(fout, "\t\t\t\tif (code)\n");
1920     f_print(fout, "\t\t\t\t\tnewHost = 0;\n");
1921     f_print(fout, "\t\t\t\tnewHost = htonl(newHost);   /* convert to network order */\n");
1922     f_print(fout, "\t\t\t} else {\n");
1923     f_print(fout, "\t\t\t\tnewHost = 0;\n");
1924     f_print(fout, "\t\t\t}\n");
1925     f_print(fout, "\t\t\tif (newHost) {\n");
1926     f_print(fout, "\t\t\t\t/* position count at the appropriate slot in the client\n");
1927     f_print(fout, "\t\t\t\t* structure and retry. If we can't find in slot, we'll\n");
1928     f_print(fout, "\t\t\t\t* just continue through the whole list \n");
1929     f_print(fout, "\t\t\t\t*/\n");
1930     f_print(fout, "\t\t\t\tfor (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {\n");
1931     f_print(fout, "\t\t\t\t\trxp = rx_PeerOf(aclient->conns[i]);\n");
1932     f_print(fout, "\t\t\t\t\tthisHost = rx_HostOf(rxp);\n");
1933     f_print(fout, "\t\t\t\t\tif (!thisHost)\n");
1934     f_print(fout, "\t\t\t\t\t\tbreak;\n");
1935     f_print(fout, "\t\t\t\t\tif (thisHost == newHost) {\n");
1936     f_print(fout, "\t\t\t\t\t\tif (chaseCount++ > 2)\n");
1937     f_print(fout, "\t\t\t\t\t\t\tbreak;  /* avoid loop asking */\n");
1938     f_print(fout, "\t\t\t\t\t\t_ucount = i;  /* this index is the sync site */\n");
1939     f_print(fout, "\t\t\t\t\t\tbreak;\n");
1940     f_print(fout, "\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n");
1941     f_print(fout, "\t\t/*needsync */\n");
1942     f_print(fout, "\t\ttc = aclient->conns[_ucount];\n");
1943     f_print(fout, "\t\tif (tc && rx_ConnError(tc)) {\n");
1944     f_print(fout, "\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
1945     f_print(fout, "\t\t}\n");
1946     f_print(fout, "\t\tif (!tc)\n");
1947     f_print(fout, "\t\t\tbreak;\n\n");
1948     f_print(fout, "\t\tif ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {\n");
1949     f_print(fout, "\t\t\tcontinue;       /* this guy's down */\n");
1950     f_print(fout, "\t\t}\n");
1951
1952     f_print(fout, "\t\trcode = %s%s%s(tc\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1953     for (plist = defp->pc.plists; plist; plist = plist->next) {
1954         if (plist->component_kind == DEF_PARAM) {
1955             plist->pl.param_flag &= ~PROCESSED_PARAM;
1956             f_print(fout, ", %s", plist->pl.param_name);
1957         }
1958     }
1959     f_print(fout, ");\n");
1960     f_print(fout, "\t\tif (aclient->initializationState != origLevel) {\n");
1961     f_print(fout, "\t\t\t/* somebody did a ubik_ClientInit */\n");
1962     f_print(fout, "\t\t\tif (rcode)\n");
1963     f_print(fout, "\t\t\t\tgoto restart;       /* call failed */\n");
1964     f_print(fout, "\t\t\telse\n");
1965     f_print(fout, "\t\t\t\tgoto done;  /* call suceeded */\n");
1966     f_print(fout, "\t\t}\n");
1967     f_print(fout, "\t\tif (rcode < 0) {    /* network errors */\n");
1968     f_print(fout, "\t\t\taclient->states[_ucount] |= CFLastFailed; /* Mark server down */\n");
1969     f_print(fout, "\t\t} else if (rcode == UNOTSYNC) {\n");
1970     f_print(fout, "\t\t\tneedsync = 1;\n");
1971     f_print(fout, "\t\t} else if (rcode != UNOQUORUM) {\n");
1972     f_print(fout, "\t\t\t/* either misc ubik code, or misc appl code, or success. */\n");
1973     f_print(fout, "\t\t\taclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/\n");
1974     f_print(fout, "\t\t\tgoto done;      /* all done */\n");
1975     f_print(fout, "\t\t}\n");
1976     f_print(fout, "\t\t}                       /*s */\n");
1977     f_print(fout, "\t}                           /*p */\n\n");
1978     f_print(fout, "\tdone:\n");
1979     f_print(fout, "\tif (needsync) {\n");
1980
1981 #if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
1982     f_print(fout, "\t\tif (!inlist) {          /* Remember proc call that needs sync site */\n");
1983     f_print(fout, "\t\t\tLOCK_UCLNT_CACHE;\n");
1984     f_print(fout, "\t\t\tcalls_needsync[synccount % SYNCCOUNT] = (int *)%s%s%s;\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1985     f_print(fout, "\t\t\tsynccount++;\n");
1986     f_print(fout, "\t\t\tUNLOCK_UCLNT_CACHE;\n");
1987     f_print(fout, "\t\t\tinlist = 1;\n");
1988     f_print(fout, "\t\t}\n");
1989 #endif
1990     f_print(fout, "\t\tif (!rcode) {           /* Remember the sync site - cmd successful */\n");
1991     f_print(fout, "\t\t\trxp = rx_PeerOf(aclient->conns[_ucount]);\n");
1992     f_print(fout, "\t\t\taclient->syncSite = rx_HostOf(rxp);\n");
1993     f_print(fout, "\t\t}\n");
1994     f_print(fout, "\t}\n");
1995     f_print(fout, "\tUNLOCK_UBIK_CLIENT(aclient);\n");
1996     f_print(fout, "\treturn rcode;\n}\n\n");
1997 }
1998
1999
2000 static int
2001 opcode_holes_exist(void)
2002 {
2003     int i;
2004
2005     for (i = lowest_opcode[PackageIndex]; i < highest_opcode[PackageIndex];
2006          i++) {
2007         if (!opcodenum_is_defined(i))
2008             return 1;
2009     }
2010     return 0;
2011 }
2012
2013
2014 void
2015 er_Proc_CodeGeneration(void)
2016 {
2017     int temp;
2018
2019     temp = PackageIndex;
2020     if (!combinepackages)
2021         PackageIndex = 0;
2022     for (; PackageIndex <= temp; PackageIndex++) {
2023         if (proc_defined[PackageIndex] == NULL)
2024             continue;
2025         if (combinepackages || opcode_holes_exist()) {
2026             er_HeadofOldStyleProc_setup();
2027             er_BodyofOldStyleProc_setup();
2028             er_TailofOldStyleProc_setup();
2029         } else {
2030             er_ProcDeclExterns_setup();
2031             er_ProcProcsArray_setup();
2032             er_ProcMainBody_setup();
2033         }
2034     }
2035     PackageIndex = temp;
2036 }
2037
2038
2039 static void
2040 er_ProcDeclExterns_setup(void)
2041 {
2042     list *listp;
2043     definition *defp;
2044
2045     f_print(fout, "\n");
2046     for (listp = proc_defined[PackageIndex]; listp != NULL;
2047          listp = listp->next) {
2048         defp = (definition *) listp->val;
2049         if (defp->pc.proc_serverstub) {
2050             f_print(fout, "afs_int32 %s();\n", defp->pc.proc_serverstub);
2051         }
2052     }
2053 }
2054
2055
2056 static void
2057 er_ProcProcsArray_setup(void)
2058 {
2059     list *listp;
2060     definition *defp;
2061
2062     if ((listp = proc_defined[PackageIndex])) {
2063         defp = (definition *) listp->val;
2064         if (defp->pc.proc_serverstub) {
2065             f_print(fout, "\nstatic afs_int32 (*StubProcsArray%d[])() = {%s",
2066                     PackageIndex, defp->pc.proc_serverstub);
2067         } else {
2068             f_print(fout,
2069                     "\nstatic afs_int32 (*StubProcsArray%d[])(struct rx_call *z_call, XDR *z_xdrs) = {_%s%s%s",
2070                     PackageIndex, prefix, defp->pc.proc_prefix,
2071                     ((definition *) listp->val)->pc.proc_name);
2072             defp = (definition *) listp->val;
2073         }
2074         listp = listp->next;
2075     }
2076     for (; listp != NULL; listp = listp->next) {
2077         defp = (definition *) listp->val;
2078         if (defp->pc.proc_serverstub) {
2079             f_print(fout, ",%s", defp->pc.proc_serverstub);
2080         } else {
2081             f_print(fout, ", _%s%s%s", prefix, defp->pc.proc_prefix,
2082                     defp->pc.proc_name);
2083         }
2084     }
2085     f_print(fout, "};\n\n");
2086 }
2087
2088
2089 static void
2090 er_ProcMainBody_setup(void)
2091 {
2092     f_print(fout, "int %s%sExecuteRequest(struct rx_call *z_call)\n",
2093             prefix, PackagePrefix[PackageIndex]);
2094     f_print(fout, "{\n\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,
2099             "\tif (!xdr_int(&z_xdrs, &op))\n\t\tz_result = RXGEN_DECODE;\n");
2100     f_print(fout,
2101             "\telse if (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\tz_result = RXGEN_OPCODE;\n",
2102             PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2103     f_print(fout,
2104             "\telse\n\t\tz_result = (*StubProcsArray%d[op - %sLOWEST_OPCODE])(z_call, &z_xdrs);\n",
2105             PackageIndex, PackagePrefix[PackageIndex]);
2106     f_print(fout, "\treturn hton_syserr_conv(z_result);\n}\n");
2107 }
2108
2109
2110 static void
2111 er_HeadofOldStyleProc_setup(void)
2112 {
2113     f_print(fout,
2114             "\nint %s%sExecuteRequest (struct rx_call *z_call)\n",
2115             prefix,
2116             (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2117     f_print(fout, "{\n");
2118     f_print(fout, "\tint op;\n");
2119     f_print(fout, "\tXDR z_xdrs;\n");
2120     f_print(fout, "\t" "afs_int32 z_result;\n\n");
2121     f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
2122     f_print(fout, "\tz_result = RXGEN_DECODE;\n");
2123     f_print(fout, "\tif (!xdr_int(&z_xdrs, &op)) goto fail;\n");
2124     f_print(fout, "\tswitch (op) {\n");
2125 }
2126
2127 static void
2128 er_BodyofOldStyleProc_setup(void)
2129 {
2130     list *listp;
2131
2132     if (combinepackages) {
2133         int temp = PackageIndex;
2134         for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
2135             for (listp = proc_defined[PackageIndex]; listp != NULL;
2136                  listp = listp->next)
2137                 proc_er_case((definition *) listp->val);
2138         }
2139         PackageIndex = temp;
2140     } else {
2141         for (listp = proc_defined[PackageIndex]; listp != NULL;
2142              listp = listp->next)
2143             proc_er_case((definition *) listp->val);
2144     }
2145 }
2146
2147
2148 static void
2149 proc_er_case(definition * defp)
2150 {
2151     if (opcodesnotallowed[PackageIndex]) {
2152         f_print(fout, "\t\tcase %d:\n", defp->pc.proc_opcodenum);
2153     } else {
2154         f_print(fout, "\t\tcase %s:\n", defp->pc.proc_opcodename);
2155     }
2156     if (defp->pc.proc_serverstub) {
2157         f_print(fout, "\t\t\tz_result = %s(z_call, &z_xdrs);\n",
2158                 defp->pc.proc_serverstub);
2159     } else {
2160         f_print(fout, "\t\t\tz_result = _%s%s%s(z_call, &z_xdrs);\n", prefix,
2161                 defp->pc.proc_prefix, defp->pc.proc_name);
2162     }
2163     f_print(fout, "\t\t\tbreak;\n");
2164 }
2165
2166
2167 static void
2168 er_TailofOldStyleProc_setup(void)
2169 {
2170     f_print(fout, "\t\tdefault:\n");
2171     f_print(fout, "\t\t\tz_result = RXGEN_OPCODE;\n");
2172     f_print(fout, "\t\t\tbreak;\n\t}\n");
2173     f_print(fout, "fail:\n");
2174     f_print(fout, "\treturn z_result;\n}\n");
2175 }
2176
2177 static void
2178 h_ProcMainBody_setup(void)
2179 {
2180     f_print(fout,"\nextern int %s%sExecuteRequest(struct rx_call *);\n",
2181             prefix, PackagePrefix[PackageIndex]);
2182 }
2183
2184 static void
2185 h_HeadofOldStyleProc_setup(void)
2186 {
2187     f_print(fout,"\nextern int %s%sExecuteRequest(struct rx_call *);\n",
2188             prefix,
2189             (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2190 }
2191
2192 void
2193 h_Proc_CodeGeneration(void)
2194 {
2195     int temp;
2196
2197     temp = PackageIndex;
2198     if (!combinepackages)
2199         PackageIndex = 0;
2200     for (; PackageIndex <= temp; PackageIndex++) {
2201         if (combinepackages || opcode_holes_exist()) {
2202             h_HeadofOldStyleProc_setup();
2203         } else {
2204             h_ProcMainBody_setup();
2205         }
2206     }
2207     PackageIndex = temp;
2208 }
2209
2210 void
2211 h_opcode_stats(void)
2212 {
2213     if (combinepackages) {
2214         f_print(fout,
2215                 "\n/* Opcode-related useful stats for Master package: %s */\n",
2216                 MasterPrefix);
2217         f_print(fout, "#define %sLOWEST_OPCODE   %d\n", MasterPrefix,
2218                 master_lowest_opcode);
2219         f_print(fout, "#define %sHIGHEST_OPCODE %d\n", MasterPrefix,
2220                 master_highest_opcode);
2221         f_print(fout, "#define %sNUMBER_OPCODES %d\n\n", MasterPrefix,
2222                 master_no_of_opcodes);
2223         if (xflag) {
2224             f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n", MasterPrefix,
2225                     no_of_stat_funcs_header[0]);
2226             f_print(fout, "AFS_RXGEN_EXPORT\n");
2227             f_print(fout, "extern const char *%sfunction_names[];\n\n",
2228                     MasterPrefix);
2229         }
2230     } else {
2231         int i;
2232         for (i = 0; i <= PackageIndex; i++) {
2233             f_print(fout,
2234                     "\n/* Opcode-related useful stats for package: %s */\n",
2235                     PackagePrefix[i]);
2236             f_print(fout, "#define %sLOWEST_OPCODE   %d\n", PackagePrefix[i],
2237                     lowest_opcode[i]);
2238             f_print(fout, "#define %sHIGHEST_OPCODE     %d\n",
2239                     PackagePrefix[i], highest_opcode[i]);
2240             f_print(fout, "#define %sNUMBER_OPCODES     %d\n\n",
2241                     PackagePrefix[i], no_of_opcodes[i]);
2242             if (xflag) {
2243                 f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n",
2244                         PackagePrefix[i], no_of_stat_funcs_header[i]);
2245                 f_print(fout, "AFS_RXGEN_EXPORT\n");
2246                 f_print(fout, "extern const char *%sfunction_names[];\n\n",
2247                         PackagePrefix[i]);
2248             }
2249         }
2250     }
2251 }
2252
2253
2254 void
2255 generate_multi_macros(definition * defp)
2256 {
2257     char *startname = SplitStart, *endname = SplitEnd;
2258     proc1_list *plist;
2259     int numofparams;
2260     int first = 0;
2261
2262     if (!hflag)
2263         return;
2264     if (!Multi_Init) {
2265         Multi_Init = 1;
2266         f_print(fout, "\n#include <rx/rx_multi.h>");
2267     }
2268     f_print(fout, "\n#define multi_%s%s(", PackagePrefix[PackageIndex],
2269             defp->pc.proc_name);
2270     for (plist = defp->pc.plists; plist; plist = plist->next) {
2271         if (plist->component_kind == DEF_PARAM) {
2272             if (!first) {
2273                 first = 1;
2274                 f_print(fout, "%s", plist->pl.param_name);
2275             } else {
2276                 f_print(fout, ", %s", plist->pl.param_name);
2277             }
2278         }
2279     }
2280     f_print(fout, ") \\\n");
2281     if (!startname)
2282         startname = "Start";
2283     if (!endname)
2284         endname = "End";
2285     f_print(fout, "\tmulti_Body(%s%s%s(multi_call", startname,
2286             PackagePrefix[PackageIndex], defp->pc.proc_name);
2287     do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 0);
2288     for (plist = defp->pc.plists; plist; plist = plist->next) {
2289         if (plist->component_kind == DEF_PARAM)
2290             f_print(fout, ", %s", plist->pl.param_name);
2291     }
2292     do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 1);
2293     f_print(fout, "), %s%s%s(multi_call", endname,
2294             PackagePrefix[PackageIndex], defp->pc.proc_name);
2295     do_split(defp, IN, &numofparams, DEF_INPARAM, 0);
2296     for (plist = defp->pc.plists; plist; plist = plist->next) {
2297         if (plist->component_kind == DEF_PARAM) {
2298             f_print(fout, ", %s", plist->pl.param_name);
2299         }
2300     }
2301     do_split(defp, IN, &numofparams, DEF_INPARAM, 1);
2302     f_print(fout, "))\n\n");
2303 }
2304
2305
2306 int
2307 IsRxgenToken(token * tokp)
2308 {
2309     if (tokp->kind == TOK_PACKAGE || tokp->kind == TOK_PREFIX
2310         || tokp->kind == TOK_SPECIAL || tokp->kind == TOK_STARTINGOPCODE
2311         || tokp->kind == TOK_SPLITPREFIX || tokp->kind == TOK_PROC
2312         || tokp->kind == TOK_STATINDEX)
2313         return 1;
2314     return 0;
2315 }
2316
2317 int
2318 IsRxgenDefinition(definition * def)
2319 {
2320     if (def->def_kind == DEF_PACKAGE || def->def_kind == DEF_PREFIX
2321         || def->def_kind == DEF_SPECIAL || def->def_kind == DEF_STARTINGOPCODE
2322         || def->def_kind == DEF_SPLITPREFIX || def->def_kind == DEF_PROC)
2323         return 1;
2324     return 0;
2325 }