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