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