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