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