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