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