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