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