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