misc-build-cleanup-20010917
[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_STRING_H
44 #include <string.h>
45 #else
46 #ifdef HAVE_STRINGS_H
47 #include <strings.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         memset((char *)defp, 0, 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         memset((char *)Proc_list, 0, sizeof(proc1_list));
886         Proc_list->pl.param_flag = 0;
887         switch (tokp->kind) {
888             case TOK_IN:
889                 hdle_param_tok(defp, &dec, tokp, DEF_INPARAM);
890                 break;
891             case TOK_OUT:
892                 hdle_param_tok(defp, &dec, tokp, DEF_OUTPARAM);
893                 break;
894             case TOK_INOUT:
895                 hdle_param_tok(defp, &dec, tokp, DEF_INOUTPARAM);
896                 break;
897             case TOK_RPAREN:
898                 break;
899             default:
900                 unget_token(tokp);
901                 hdle_param_tok(defp, &dec, tokp, DEF_NULL);
902                 break;
903         }
904         *Proc_listp = Proc_list;
905         Proc_listp = &Proc_list->next;
906         decls = ALLOC(decl_list);
907         memset((char *)decls, 0, sizeof(decl_list));
908         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 = strchr(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 = strchr(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 (strchr(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 (strchr(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         f_print(fout, "#ifndef KERNEL\n");
1455         f_print(fout, "\tafs_int32 %s%s%s%s();\n", prefix, ServerPrefix, 
1456                 PackagePrefix[PackageIndex], defp->pc.proc_name);
1457         f_print(fout, "#endif\n");
1458 }
1459
1460
1461 static
1462 ss_ProcSpecial_setup(defp, somefrees)
1463 definition *defp;
1464 int *somefrees;
1465 {
1466     proc1_list *plist;
1467     definition *defp1;
1468     list *listp;
1469
1470    for (listp = special_defined; listp != NULL; listp = listp->next) {
1471         defp1 = (definition *)listp->val;
1472         for (plist=defp->pc.plists; plist; plist=plist->next) {
1473             if (plist->component_kind == DEF_PARAM && (plist->pl.param_kind == DEF_INPARAM || plist->pl.param_kind == DEF_INOUTPARAM)) {
1474                 spec_list *spec = defp1->def.sd.specs;
1475                 char string[40];
1476                 strcpy(string, structname(spec->sdef.string_value));
1477                 if (streq(string, structname(plist->pl.param_type))) {
1478                     plist->pl.string_name = spec->sdef.string_name;
1479                     plist->pl.param_flag |= FREETHIS_PARAM;
1480                     *somefrees = 1;
1481                     fprintf(fout, "\n\t%s.%s = 0;", plist->pl.param_name, spec->sdef.string_name);
1482                 }
1483             }
1484         }
1485     }
1486     if (!*somefrees)
1487         fprintf(fout, "\n");
1488     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1489         defp1 = (definition *)listp->val;
1490         for (plist=defp->pc.plists; plist; plist=plist->next) {
1491             if (plist->component_kind == DEF_PARAM ) {
1492                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1493                     plist->pl.param_flag |= FREETHIS_PARAM;
1494                     *somefrees = 1;
1495                     switch (defp1->pc.rel) {
1496                         case REL_ARRAY:
1497                             f_print(fout, "\n\t%s.%s_val = 0;", plist->pl.param_name, defp1->def_name);
1498                             f_print(fout, "\n\t%s.%s_len = 0;", plist->pl.param_name, defp1->def_name);
1499                             plist->pl.string_name = alloc(40);
1500                             s_print(plist->pl.string_name, "%s_val", defp1->def_name);
1501                             break;
1502                         case REL_POINTER:
1503                             f_print(fout, "\n\t%s = 0;", plist->pl.param_name);
1504                             plist->pl.string_name = NULL;
1505                             break;
1506                     }
1507                 }
1508             }
1509         }
1510     }   
1511     f_print(fout, "\n");
1512 }
1513
1514
1515 static
1516 ss_ProcUnmarshallInParams_setup(defp)
1517 definition *defp;
1518 {
1519     int noofparams, noofoutparams, i;
1520     proc1_list *plist;
1521
1522     noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1523     noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1524     for (plist = defp->pc.plists, i=0; plist; plist = plist->next) {
1525         if (plist->component_kind == DEF_PARAM && (plist->pl.param_kind == DEF_INPARAM || plist->pl.param_kind == DEF_INOUTPARAM)) {
1526                 if (!i) {
1527                     f_print(fout, "\n\tif ((!%s)", (plist->scode ? plist->scode : plist->code));
1528                 } else {
1529                     f_print(fout, "\n\t     || (!%s)", (plist->scode ? plist->scode : plist->code));
1530                 }
1531             if (++i == noofparams) {
1532                 if (!noofoutparams) {
1533                     f_print(fout, ") {\n");
1534                 } else {
1535                     f_print(fout, ") {\n");
1536                 }
1537                 f_print(fout, "\t\tz_result = RXGEN_SS_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1538                 defp->can_fail = 1;
1539             }
1540         }
1541     }
1542 }
1543
1544
1545 static
1546 ss_ProcCallRealProc_setup(defp)
1547 definition *defp;
1548 {
1549     extern char zflag;
1550     proc1_list *plist;
1551
1552     f_print(fout, "\tz_result = %s%s%s%s(z_call", prefix, ServerPrefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1553     for (plist = defp->pc.plists; plist; plist = plist->next) {
1554         if (plist->component_kind == DEF_PARAM) {
1555             if (plist->pl.param_flag & INDIRECT_PARAM) {
1556                     f_print(fout, ", &%s", plist->pl.param_name);
1557             } else {
1558                 if (plist->pl.param_flag & OUT_STRING) {
1559                     f_print(fout, ", &%s", plist->pl.param_name);
1560                 } else {
1561                     f_print(fout, ", %s", plist->pl.param_name);
1562                 }
1563             }
1564         }
1565     }
1566     f_print(fout, ");\n");
1567     if (zflag) {
1568         f_print(fout, "\tif (z_result)\n\t\treturn z_result;\n");
1569     }
1570 }
1571
1572
1573 static
1574 ss_ProcMarshallOutParams_setup(defp)
1575 definition *defp;
1576 {
1577     proc1_list *plist;
1578     int noofparams, i;
1579
1580     noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1581     if (noofparams)
1582         f_print(fout, "\tz_xdrs->x_op = XDR_ENCODE;\n");
1583     if (noofparams) {
1584         for (plist = defp->pc.plists, i=0; plist; plist = plist->next) {
1585             if (plist->component_kind == DEF_PARAM && (plist->pl.param_kind == DEF_OUTPARAM || plist->pl.param_kind == DEF_INOUTPARAM)) {
1586                 if (!i) {
1587                     f_print(fout, "\tif ((!%s)", (plist->scode ? plist->scode : plist->code));
1588                 } else {
1589                     f_print(fout, "\n\t     || (!%s)", (plist->scode ? plist->scode : plist->code));
1590                 }
1591                 if (++i == noofparams) {
1592                     f_print(fout, ")\n\t\tz_result = RXGEN_SS_MARSHAL;\n");
1593                 }
1594             }
1595         }               
1596     }
1597 }
1598
1599
1600 static
1601 ss_ProcTail_setup(defp, somefrees)
1602 definition *defp;
1603 int somefrees;
1604 {
1605     proc1_list *plist;
1606     definition *defp1;
1607     list *listp;
1608     int firsttime = 0;
1609
1610     if (defp->can_fail) {
1611         f_print(fout, "fail:\n");
1612     }
1613     for (plist = defp->pc.plists; plist; plist = plist->next) {    
1614         if (plist->component_kind == DEF_PARAM && (plist->pl.param_flag & FREETHIS_PARAM))
1615             somefrees = 1;
1616     }
1617     if (somefrees)
1618         f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1619     for (plist = defp->pc.plists; plist; plist = plist->next) {    
1620         if (plist->component_kind == DEF_PARAM && (plist->pl.param_flag & FREETHIS_PARAM)) {
1621             char *dot = "", *extens = "";
1622             if (plist->pl.string_name) {
1623                 dot = ".";
1624                 extens = plist->pl.string_name;
1625             }
1626             f_print(fout, "\tif (!%s) goto fail1;\n", plist->scode);
1627         }
1628     }
1629     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1630         defp1 = (definition *)listp->val;
1631         for (plist=defp->pc.plists; plist; plist=plist->next) {
1632             if (plist->component_kind == DEF_PARAM && (plist->pl.param_kind == DEF_OUTPARAM || plist->pl.param_kind == DEF_INOUTPARAM) && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1633                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1634                     switch (defp1->pc.rel) {
1635                         case REL_ARRAY:
1636                         case REL_POINTER:
1637                             if (!somefrees && !firsttime) {
1638                                 firsttime = 1;
1639                                 f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1640                             }
1641                             somefrees = 1;
1642                             f_print(fout, "\tif (!%s) goto fail1;\n", plist->scode);
1643                             break;
1644                     }
1645                 }
1646             }
1647         }
1648     }   
1649     for (listp = uniondef_defined; listp != NULL; listp = listp->next) {
1650         defp1 = (definition *)listp->val;
1651         for (plist=defp->pc.plists; plist; plist=plist->next) {
1652             if (plist->component_kind == DEF_PARAM && (plist->pl.param_kind == DEF_OUTPARAM || plist->pl.param_kind == DEF_INOUTPARAM) && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1653                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1654                     if (plist->pl.param_flag & INDIRECT_PARAM) {
1655                         if (!somefrees && !firsttime) {
1656                             firsttime = 1;
1657                             f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1658                         }
1659                         somefrees = 1;
1660                         f_print(fout, "\tif (!%s) goto fail1;\n", plist->scode);
1661                     }
1662                 }
1663             }
1664         }
1665     }   
1666
1667     if (xflag) {
1668         f_print(fout, "\tif (rx_enable_stats) {\n");
1669         f_print(fout, "\t    clock_GetTime(&__EXEC);\n");
1670         f_print(fout, "\t    clock_Sub(&__EXEC, &z_call->startTime);\n");
1671         f_print(fout, "\t    __QUEUE = z_call->startTime;\n");
1672         f_print(fout, "\t    clock_Sub(&__QUEUE, &z_call->queueTime);\n");
1673         f_print(fout, "\t    rx_IncrementTimeAndCount(z_call->conn->peer,");
1674         if (PackageStatIndex[PackageIndex]) {
1675             f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
1676         } else {
1677             f_print(fout, 
1678                 "\n\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
1679                 "\t\t((afs_uint32)ntohs(z_call->conn->service->servicePort))),\n");
1680         }
1681         f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
1682                       no_of_stat_funcs,
1683                       PackagePrefix[PackageIndex]);
1684         f_print(fout, "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 0);\n");
1685         f_print(fout, "\t}\n\n");
1686     }
1687
1688     f_print(fout, "\treturn z_result;\n");
1689     if (somefrees) {
1690         f_print(fout, "fail1:\n");
1691
1692         if (xflag) {
1693             f_print(fout, "\tif (rx_enable_stats) {\n");
1694             f_print(fout, "\t    clock_GetTime(&__EXEC);\n");
1695             f_print(fout, "\t    clock_Sub(&__EXEC, &z_call->startTime);\n");
1696             f_print(fout, "\t    __QUEUE = z_call->startTime;\n");
1697             f_print(fout, "\t    clock_Sub(&__QUEUE, &z_call->queueTime);\n");
1698             f_print(fout, "\t    rx_IncrementTimeAndCount(z_call->conn->peer,");
1699             if (PackageStatIndex[PackageIndex]) {
1700                 f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
1701             } else {
1702                 f_print(fout,
1703                     "\n\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
1704                     "\t\t((afs_uint32)ntohs(z_call->conn->service->servicePort))),\n");
1705             }
1706             f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
1707                           no_of_stat_funcs,
1708                           PackagePrefix[PackageIndex]);
1709             f_print(fout, "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 0);\n");
1710             f_print(fout, "\t}\n\n");
1711         }
1712
1713         f_print(fout, "\treturn RXGEN_SS_XDRFREE;\n}\n\n");
1714     } else {
1715         f_print(fout, "}\n\n");
1716     }
1717 }
1718
1719
1720 static
1721 opcode_holes_exist()
1722 {
1723     int i;
1724     
1725     for (i=lowest_opcode[PackageIndex]; i<highest_opcode[PackageIndex]; i++) {
1726         if (!opcodenum_is_defined(i))
1727             return 1;
1728     }
1729     return 0;
1730 }
1731
1732         
1733 int
1734 er_Proc_CodeGeneration()
1735 {
1736     int temp;
1737
1738     temp = PackageIndex;
1739     if (!combinepackages) PackageIndex = 0;
1740     for (; PackageIndex <= temp; PackageIndex++) {
1741         if (proc_defined[PackageIndex] == NULL) continue;
1742         if (combinepackages || opcode_holes_exist()) {
1743             er_HeadofOldStyleProc_setup();
1744             er_BodyofOldStyleProc_setup();
1745             er_TailofOldStyleProc_setup();
1746         } else {
1747             er_ProcDeclExterns_setup();
1748             er_ProcProcsArray_setup();
1749             er_ProcMainBody_setup();
1750         }
1751     }
1752     PackageIndex = temp;
1753 }
1754
1755
1756 static
1757 er_ProcDeclExterns_setup()
1758 {
1759     list *listp;
1760     definition *defp;
1761
1762     f_print(fout, "\n");
1763     for (listp = proc_defined[PackageIndex]; listp != NULL; listp = listp->next) {
1764         defp = (definition *)listp->val;
1765         if (defp->pc.proc_serverstub) {
1766             f_print(fout, "afs_int32 %s();\n", defp->pc.proc_serverstub);
1767         } else {
1768             f_print(fout, "afs_int32 _%s%s%s();\n", prefix, defp->pc.proc_prefix, defp->pc.proc_name);
1769         }
1770     }
1771 }
1772
1773
1774 static
1775 er_ProcProcsArray_setup()
1776 {
1777     list *listp;
1778     definition *defp;
1779
1780     if (listp = proc_defined[PackageIndex]) {
1781         defp = (definition *)listp->val;
1782         if (defp->pc.proc_serverstub){
1783             f_print(fout, "\nstatic afs_int32 (*StubProcsArray%d[])() = {%s", PackageIndex, defp->pc.proc_serverstub);
1784         } else {
1785             f_print(fout, "\nstatic afs_int32 (*StubProcsArray%d[])() = {_%s%s%s", PackageIndex, prefix, defp->pc.proc_prefix, (defp = (definition *)listp->val)->pc.proc_name);
1786         }
1787         listp = listp->next;
1788     }
1789     for (; listp != NULL; listp = listp->next) {
1790         defp = (definition *)listp->val;
1791         if (defp->pc.proc_serverstub) {
1792             f_print(fout, ",%s", defp->pc.proc_serverstub);
1793         } else {
1794             f_print(fout, ", _%s%s%s", prefix, defp->pc.proc_prefix, defp->pc.proc_name);
1795         }
1796     }
1797     f_print(fout, "};\n\n");
1798 }
1799
1800
1801 static
1802 er_ProcMainBody_setup()
1803 {
1804     f_print(fout, "int %s%sExecuteRequest(z_call)\n", prefix,  PackagePrefix[PackageIndex]);
1805     f_print(fout, "\tregister struct rx_call *z_call;\n");
1806     f_print(fout, "{\n\tint op;\n");
1807     f_print(fout, "\tXDR z_xdrs;\n");
1808     f_print(fout, "\t" "afs_int32 z_result;\n\n");
1809     f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
1810     f_print(fout, "\tif (!xdr_int(&z_xdrs, &op))\n\t\tz_result = RXGEN_DECODE;\n");
1811     f_print(fout, "\telse if (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\tz_result = RXGEN_OPCODE;\n", PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
1812     f_print(fout, "\telse\n\t\tz_result = (*StubProcsArray%d[op - %sLOWEST_OPCODE])(z_call, &z_xdrs);\n", PackageIndex, PackagePrefix[PackageIndex]);
1813     f_print(fout, "\treturn hton_syserr_conv(z_result);\n}\n");
1814 }
1815
1816
1817 static
1818 er_HeadofOldStyleProc_setup()
1819 {
1820     f_print(fout, "\nint %s%sExecuteRequest (z_call)\n", prefix, (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
1821     f_print(fout, "\tregister struct rx_call *z_call;\n");
1822     f_print(fout, "{\n");
1823     f_print(fout, "\tint op;\n");
1824     f_print(fout, "\tXDR z_xdrs;\n");
1825     f_print(fout, "\t" "afs_int32 z_result;\n\n");
1826     f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
1827     f_print(fout, "\tz_result = RXGEN_DECODE;\n");
1828     f_print(fout, "\tif (!xdr_int(&z_xdrs, &op)) goto fail;\n");
1829     f_print(fout, "\tswitch (op) {\n");
1830 }
1831
1832 static
1833 er_BodyofOldStyleProc_setup()
1834 {
1835     list *listp;
1836
1837     if (combinepackages) {
1838         int temp = PackageIndex;
1839         for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
1840             for (listp = proc_defined[PackageIndex]; listp != NULL; listp = listp->next)
1841                 proc_er_case((definition *)listp->val);     
1842         }
1843         PackageIndex = temp;
1844     } else {
1845     for (listp = proc_defined[PackageIndex]; listp != NULL; listp = listp->next)
1846         proc_er_case((definition *)listp->val);
1847     }
1848 }
1849
1850
1851 static
1852 proc_er_case(defp)
1853 definition *defp;
1854 {
1855     if (opcodesnotallowed[PackageIndex]) {
1856         f_print(fout, "\t\tcase %d: {\n", defp->pc.proc_opcodenum);
1857     } else {
1858         f_print(fout, "\t\tcase %s: {\n", defp->pc.proc_opcodename);
1859     }
1860     if (defp->pc.proc_serverstub) {
1861         f_print(fout, "\t\t\t" "afs_int32 %s();\n", defp->pc.proc_serverstub);
1862         f_print(fout, "\t\t\tz_result = %s(z_call, &z_xdrs);\n", defp->pc.proc_serverstub);
1863     } else {
1864         f_print(fout, "\t\t\t" "afs_int32 _%s%s%s();\n", prefix, defp->pc.proc_prefix, defp->pc.proc_name);
1865         f_print(fout, "\t\t\tz_result = _%s%s%s(z_call, &z_xdrs);\n", prefix, defp->pc.proc_prefix, defp->pc.proc_name);
1866     }
1867     f_print(fout, "\t\t\tbreak;\n\t\t}\n");     
1868 }
1869
1870
1871 static
1872 er_TailofOldStyleProc_setup()
1873 {
1874     f_print(fout, "\t\tdefault:\n");
1875     f_print(fout, "\t\t\tz_result = RXGEN_OPCODE;\n");
1876     f_print(fout, "\t\t\tbreak;\n\t}\n");
1877     f_print(fout, "fail:\n");
1878     f_print(fout, "\treturn z_result;\n}\n");
1879 }
1880
1881
1882 int h_opcode_stats()
1883 {
1884     if (combinepackages) {
1885         f_print(fout, "\n/* Opcode-related useful stats for Master package: %s */\n", MasterPrefix);
1886         f_print(fout, "#define %sLOWEST_OPCODE   %d\n", MasterPrefix, master_lowest_opcode);
1887         f_print(fout, "#define %sHIGHEST_OPCODE %d\n", MasterPrefix, master_highest_opcode);
1888         f_print(fout, "#define %sNUMBER_OPCODES %d\n\n", MasterPrefix, master_no_of_opcodes);
1889         if (xflag) {
1890             f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n", MasterPrefix, no_of_stat_funcs_header[0]);
1891             f_print(fout, "AFS_RXGEN_EXPORT\n");
1892             f_print(fout, "extern const char *%sfunction_names[];\n\n", MasterPrefix);
1893         }
1894     } else {
1895         int i;
1896         for (i=0; i <= PackageIndex; i++) {
1897             f_print(fout, "\n/* Opcode-related useful stats for package: %s */\n", PackagePrefix[i]); 
1898             f_print(fout, "#define %sLOWEST_OPCODE   %d\n", PackagePrefix[i], lowest_opcode[i]);
1899             f_print(fout, "#define %sHIGHEST_OPCODE     %d\n", PackagePrefix[i], highest_opcode[i]);
1900             f_print(fout, "#define %sNUMBER_OPCODES     %d\n\n", PackagePrefix[i], no_of_opcodes[i]);
1901             if (xflag) {
1902                 f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n", PackagePrefix[i], no_of_stat_funcs_header[i]);
1903                 f_print(fout, "AFS_RXGEN_EXPORT\n");
1904                 f_print(fout, "extern const char *%sfunction_names[];\n\n", PackagePrefix[i]);
1905             }
1906         }
1907     }
1908 }
1909
1910
1911 int generate_multi_macros(defp)
1912 definition *defp;
1913 {
1914     char *startname = SplitStart, *endname = SplitEnd;
1915     proc1_list *plist;
1916     int numofparams;
1917     int first = 0;
1918
1919     if (!hflag) return;
1920     if (!Multi_Init) {
1921         Multi_Init = 1;
1922         f_print(fout, "\n#include <rx/rx_multi.h>");
1923     }
1924     f_print(fout, "\n#define multi_%s%s(", PackagePrefix[PackageIndex],defp->pc.proc_name);
1925     for (plist = defp->pc.plists; plist; plist = plist->next) {
1926         if (plist->component_kind == DEF_PARAM) {
1927             if (!first) {
1928                 first = 1;
1929                 f_print(fout, "%s", plist->pl.param_name);
1930             } else {
1931                 f_print(fout, ", %s", plist->pl.param_name);
1932             }
1933         }
1934     }
1935     f_print(fout, ") \\\n");
1936     if (!startname) startname = "Start";
1937     if (!endname) endname = "End";
1938     f_print(fout, "\tmulti_Body(%s%s%s(multi_call", startname, PackagePrefix[PackageIndex], defp->pc.proc_name);
1939     do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 0);
1940     for (plist = defp->pc.plists; plist; plist = plist->next) {
1941         if (plist->component_kind == DEF_PARAM)
1942             f_print(fout, ", %s", plist->pl.param_name);
1943     }
1944     do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 1);
1945     f_print(fout, "), %s%s%s(multi_call", endname, PackagePrefix[PackageIndex], defp->pc.proc_name);
1946     do_split(defp, IN, &numofparams, DEF_INPARAM, 0);
1947     for (plist = defp->pc.plists; plist; plist = plist->next) {
1948         if (plist->component_kind == DEF_PARAM) {
1949             f_print(fout, ", %s", plist->pl.param_name);
1950         }
1951     }
1952     do_split(defp, IN, &numofparams, DEF_INPARAM, 1);
1953     f_print(fout, "))\n\n");
1954 }
1955
1956
1957 int
1958 IsRxgenToken(tokp)
1959 token *tokp;
1960 {
1961     if (tokp->kind == TOK_PACKAGE || tokp->kind == TOK_PREFIX ||
1962          tokp->kind == TOK_SPECIAL || tokp->kind == TOK_STARTINGOPCODE ||
1963          tokp->kind == TOK_SPLITPREFIX || tokp->kind == TOK_PROC ||
1964          tokp->kind == TOK_STATINDEX)
1965         return 1;
1966     return 0;
1967 }
1968
1969 int
1970 IsRxgenDefinition(def)
1971 definition *def;
1972 {
1973     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)
1974         return 1;
1975     return 0;
1976 }