rxgen: Fix NULL pointer dereference
[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 #include <roken.h>
39
40 #include <ctype.h>
41
42 #include "rpc_scan.h"
43 #include "rpc_parse.h"
44 #include "rpc_util.h"
45
46 list *proc_defined[MAX_PACKAGES], *special_defined, *typedef_defined,
47     *uniondef_defined, *complex_defined;
48 char *SplitStart = NULL;
49 char *SplitEnd = NULL;
50 char *MasterPrefix = NULL;
51 char *ServerPrefix = "";
52 char *PackagePrefix[MAX_PACKAGES];
53 char *PackageStatIndex[MAX_PACKAGES];
54 int no_of_stat_funcs = 0;       /*
55                                  * current function number in client interface
56                                  * starts at 0
57                                  */
58 int no_of_stat_funcs_header[MAX_PACKAGES];      /*
59                                                  * Total number of functions in client
60                                                  * interface
61                                                  */
62 int no_of_opcodes[MAX_PACKAGES], master_no_of_opcodes = 0;
63 int lowest_opcode[MAX_PACKAGES], master_lowest_opcode = 99999;
64 int highest_opcode[MAX_PACKAGES], master_highest_opcode = 0;
65 int master_opcodenumber = 99999;
66 int opcodesnotallowed[MAX_PACKAGES];
67 int combinepackages = 0;
68 int PackageIndex = -1;
69 int PerProcCounter = 0;
70 int Multi_Init = 0;
71 int StatIndex = -1;
72
73 /*
74  * Character arrays to keep list of function names as we process the file
75  */
76
77 char function_list[MAX_PACKAGES]
78     [MAX_FUNCTIONS_PER_PACKAGE]
79     [MAX_FUNCTION_NAME_LEN];
80 int function_list_index;
81
82 /* static prototypes */
83 static void isdefined(definition * defp);
84 static void def_struct(definition * defp);
85 static void def_program(definition * defp);
86 static void def_enum(definition * defp);
87 static void def_const(definition * defp);
88 static void def_union(definition * defp);
89 static void def_typedef(definition * defp);
90 static void get_declaration(declaration * dec, defkind dkind);
91 static void get_type(char **prefixp, char **typep, defkind dkind);
92 static void unsigned_dec(char **typep);
93 static void def_package(definition * defp);
94 static void def_prefix(definition * defp);
95 static void def_statindex(definition * defp);
96 static void def_startingopcode(definition * defp);
97 static void def_split(definition * defp);
98 static void customize_struct(definition * defp);
99 static char *structname(char *name);
100 static void def_special(declaration * dec, definition * defp);
101 static void check_proc(definition * defp, token * tokp, int noname);
102 static int InvalidConstant(char *name);
103 static int opcodenum_is_defined(int opcode_num);
104 static void analyze_ProcParams(definition * defp, token * tokp);
105 static void generate_code(definition * defp, int proc_split_flag,
106                           int multi_flag);
107 static void handle_split_proc(definition * defp, int multi_flag);
108 static void do_split(definition * defp, int direction, int *numofparams,
109                      defkind param_kind, int restore_flag);
110 static void hdle_param_tok(definition * defp, declaration * dec, token * tokp,
111                            defkind par_kind);
112 static void get1_param_type(definition * defp, declaration * dec,
113                             char **param_type);
114 static void get_param_type(definition * defp, declaration * dec,
115                            char **param_type, char **typename);
116 #ifdef undef
117 static void hndle_param_tail(definition * defp, declaration * dec,
118                              token * tokp, char *typename);
119 #endif
120 static void cs_Proc_CodeGeneration(definition * defp, int split_flag,
121                                    char *procheader);
122 static void cs_ProcName_setup(definition * defp, char *procheader,
123                               int split_flag);
124 static void cs_ProcParams_setup(definition * defp, int split_flag);
125 static void cs_ProcMarshallInParams_setup(definition * defp, int split_flag);
126 static void cs_ProcSendPacket_setup(definition * defp, int split_flag);
127 static void cs_ProcUnmarshallOutParams_setup(definition * defp);
128 static void cs_ProcTail_setup(definition * defp, int split_flag);
129 static void ucs_ProcName_setup(definition * defp, char *procheader,
130                               int split_flag);
131 static void ucs_ProcParams_setup(definition * defp, int split_flag);
132 static void ucs_ProcTail_setup(definition * defp, int split_flag);
133 static void ss_Proc_CodeGeneration(definition * defp);
134 static void ss_ProcName_setup(definition * defp);
135 static void ss_ProcParams_setup(definition * defp);
136 static void ss_ProcSpecial_setup(definition * defp);
137 static void ss_ProcUnmarshallInParams_setup(definition * defp);
138 static void ss_ProcCallRealProc_setup(definition * defp);
139 static void ss_ProcMarshallOutParams_setup(definition * defp);
140 static void ss_ProcTail_setup(definition * defp);
141 static int opcode_holes_exist(void);
142 static void er_ProcDeclExterns_setup(void);
143 static void er_ProcProcsArray_setup(void);
144 static void er_ProcMainBody_setup(void);
145 static void er_HeadofOldStyleProc_setup(void);
146 static void er_HeadofOldStyleProc_setup2(void);
147 static void er_BodyofOldStyleProc_setup(void);
148 static void er_BodyofOldStyleProc_setup2(void);
149 static void proc_er_case(definition * defp);
150 static void er_TailofOldStyleProc_setup(void);
151 static void er_TailofOldStyleProc_setup2(void);
152
153
154
155 /*
156  * return the next definition you see
157  */
158 definition *
159 get_definition(void)
160 {
161     definition *defp;
162     token tok;
163
164     defp = ALLOC(definition);
165     memset(defp, 0, sizeof(definition));
166     get_token(&tok);
167     switch (tok.kind) {
168     case TOK_STRUCT:
169         def_struct(defp);
170         break;
171     case TOK_UNION:
172         def_union(defp);
173         break;
174     case TOK_TYPEDEF:
175         def_typedef(defp);
176         break;
177     case TOK_ENUM:
178         def_enum(defp);
179         break;
180     case TOK_PROGRAM:
181         def_program(defp);
182         break;
183     case TOK_CONST:
184         def_const(defp);
185         break;
186     case TOK_EOF:
187         return (NULL);
188     case TOK_PACKAGE:
189         def_package(defp);
190         break;
191     case TOK_PREFIX:
192         def_prefix(defp);
193         break;
194     case TOK_STATINDEX:
195         def_statindex(defp);
196         break;
197     case TOK_SPECIAL:
198         {
199             declaration dec;
200             def_special(&dec, defp);
201             break;
202         }
203     case TOK_STARTINGOPCODE:
204         def_startingopcode(defp);
205         break;
206     case TOK_CUSTOMIZED:
207         get_token(&tok);
208         def_struct(defp);
209         customize_struct(defp);
210         break;
211     case TOK_SPLITPREFIX:
212         def_split(defp);
213         break;
214     case TOK_PROC:
215         get_token(&tok);
216         if (tok.kind == TOK_LPAREN) {
217             unget_token(&tok);
218             check_proc(defp, &tok, 1);
219         } else
220             check_proc(defp, &tok, 0);
221         break;
222     case TOK_IDENT:
223         check_proc(defp, &tok, 0);
224         break;
225     case TOK_LPAREN:
226         unget_token(&tok);
227         check_proc(defp, &tok, 1);
228         break;
229     default:
230         error("definition keyword expected");
231     }
232     if (!IsRxgenToken(&tok)) {
233         scan(TOK_SEMICOLON, &tok);
234         isdefined(defp);
235     } else
236         pushed = 0;
237     return (defp);
238 }
239
240 static void
241 isdefined(definition * defp)
242 {
243     STOREVAL(&defined, defp);
244 }
245
246
247 static void
248 def_struct(definition * defp)
249 {
250     token tok;
251     declaration dec;
252     decl_list *decls;
253     decl_list **tailp;
254     int special = 0;
255
256     defp->def_kind = DEF_STRUCT;
257
258     scan(TOK_IDENT, &tok);
259     defp->def_name = tok.str;
260     scan(TOK_LBRACE, &tok);
261     tailp = &defp->def.st.decls;
262     do {
263         get_declaration(&dec, DEF_STRUCT);
264         /* If a structure contains an array, then we're going
265          * to need to be clever about freeing it */
266         if (dec.rel == REL_ARRAY) {
267            special = 1;
268         }
269         decls = ALLOC(decl_list);
270         decls->decl = dec;
271         *tailp = decls;
272         tailp = &decls->next;
273         scan(TOK_SEMICOLON, &tok);
274         peek(&tok);
275     } while (tok.kind != TOK_RBRACE);
276     get_token(&tok);
277     *tailp = NULL;
278
279     if (special)
280         STOREVAL(&complex_defined, defp);
281 }
282
283 static void
284 def_program(definition * defp)
285 {
286     token tok;
287     version_list *vlist;
288     version_list **vtailp;
289     proc_list *plist;
290     proc_list **ptailp;
291
292     defp->def_kind = DEF_PROGRAM;
293     scan(TOK_IDENT, &tok);
294     defp->def_name = tok.str;
295     scan(TOK_LBRACE, &tok);
296     vtailp = &defp->def.pr.versions;
297     scan(TOK_VERSION, &tok);
298     do {
299         scan(TOK_IDENT, &tok);
300         vlist = ALLOC(version_list);
301         vlist->vers_name = tok.str;
302         scan(TOK_LBRACE, &tok);
303         ptailp = &vlist->procs;
304         do {
305             plist = ALLOC(proc_list);
306             get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM);
307             if (streq(plist->res_type, "opaque")) {
308                 error("illegal result type");
309             }
310             scan(TOK_IDENT, &tok);
311             plist->proc_name = tok.str;
312             scan(TOK_LPAREN, &tok);
313             get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM);
314             if (streq(plist->arg_type, "opaque")) {
315                 error("illegal argument type");
316             }
317             scan(TOK_RPAREN, &tok);
318             scan(TOK_EQUAL, &tok);
319             scan_num(&tok);
320             scan(TOK_SEMICOLON, &tok);
321             plist->proc_num = tok.str;
322             *ptailp = plist;
323             ptailp = &plist->next;
324             peek(&tok);
325         } while (tok.kind != TOK_RBRACE);
326         *vtailp = vlist;
327         vtailp = &vlist->next;
328         scan(TOK_RBRACE, &tok);
329         scan(TOK_EQUAL, &tok);
330         scan_num(&tok);
331         vlist->vers_num = tok.str;
332         scan(TOK_SEMICOLON, &tok);
333         scan2(TOK_VERSION, TOK_RBRACE, &tok);
334     } while (tok.kind == TOK_VERSION);
335     scan(TOK_EQUAL, &tok);
336     scan_num(&tok);
337     defp->def.pr.prog_num = tok.str;
338     *vtailp = NULL;
339 }
340
341 static void
342 def_enum(definition * defp)
343 {
344     token tok;
345     enumval_list *elist;
346     enumval_list **tailp;
347
348     defp->def_kind = DEF_ENUM;
349     scan(TOK_IDENT, &tok);
350     defp->def_name = tok.str;
351     scan(TOK_LBRACE, &tok);
352     tailp = &defp->def.en.vals;
353     do {
354         scan(TOK_IDENT, &tok);
355         elist = ALLOC(enumval_list);
356         elist->name = tok.str;
357         elist->assignment = NULL;
358         scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
359         if (tok.kind == TOK_EQUAL) {
360             scan_num(&tok);
361             elist->assignment = tok.str;
362             scan2(TOK_COMMA, TOK_RBRACE, &tok);
363         }
364         *tailp = elist;
365         tailp = &elist->next;
366     } while (tok.kind != TOK_RBRACE);
367     *tailp = NULL;
368 }
369
370 static void
371 def_const(definition * defp)
372 {
373     token tok;
374
375     defp->def_kind = DEF_CONST;
376     scan(TOK_IDENT, &tok);
377     defp->def_name = tok.str;
378     scan(TOK_EQUAL, &tok);
379     scan2(TOK_IDENT, TOK_STRCONST, &tok);
380     defp->def.co = tok.str;
381 }
382
383 static void
384 def_union(definition * defp)
385 {
386     token tok;
387     declaration dec;
388     case_list *cases;
389     case_list **tailp;
390
391     defp->def_kind = DEF_UNION;
392     scan(TOK_IDENT, &tok);
393     defp->def_name = tok.str;
394     scan(TOK_SWITCH, &tok);
395     scan(TOK_LPAREN, &tok);
396     get_declaration(&dec, DEF_UNION);
397     defp->def.un.enum_decl = dec;
398     tailp = &defp->def.un.cases;
399     scan(TOK_RPAREN, &tok);
400     scan(TOK_LBRACE, &tok);
401     scan(TOK_CASE, &tok);
402     while (tok.kind == TOK_CASE) {
403         scan(TOK_IDENT, &tok);
404         cases = ALLOC(case_list);
405         cases->case_name = tok.str;
406         scan(TOK_COLON, &tok);
407         get_declaration(&dec, DEF_UNION);
408         cases->case_decl = dec;
409         *tailp = cases;
410         tailp = &cases->next;
411         scan(TOK_SEMICOLON, &tok);
412         scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
413     }
414     *tailp = NULL;
415     if (tok.kind == TOK_DEFAULT) {
416         scan(TOK_COLON, &tok);
417         get_declaration(&dec, DEF_UNION);
418         defp->def.un.default_decl = ALLOC(declaration);
419         *defp->def.un.default_decl = dec;
420         scan(TOK_SEMICOLON, &tok);
421         scan(TOK_RBRACE, &tok);
422     } else {
423         defp->def.un.default_decl = NULL;
424     }
425 }
426
427
428 static void
429 def_typedef(definition * defp)
430 {
431     declaration dec;
432
433     memset(&dec, 0, sizeof(dec));
434
435     defp->def_kind = DEF_TYPEDEF;
436     get_declaration(&dec, DEF_TYPEDEF);
437     defp->def_name = dec.name;
438     defp->def.ty.old_prefix = dec.prefix;
439     defp->def.ty.old_type = dec.type;
440     defp->def.ty.rel = dec.rel;
441     defp->def.ty.array_max = dec.array_max;
442 }
443
444
445 static void
446 get_declaration(declaration * dec, defkind dkind)
447 {
448     token tok;
449
450     get_type(&dec->prefix, &dec->type, dkind);
451     dec->rel = REL_ALIAS;
452     if (streq(dec->type, "void")) {
453         return;
454     }
455     scan2(TOK_STAR, TOK_IDENT, &tok);
456     if (tok.kind == TOK_STAR) {
457         dec->rel = REL_POINTER;
458         scan(TOK_IDENT, &tok);
459     }
460     dec->name = tok.str;
461     if (peekscan(TOK_LBRACKET, &tok)) {
462         if (dec->rel == REL_POINTER) {
463             error("no array-of-pointer declarations -- use typedef");
464         }
465         dec->rel = REL_VECTOR;
466         scan_num(&tok);
467         dec->array_max = tok.str;
468         scan(TOK_RBRACKET, &tok);
469     } else if (peekscan(TOK_LANGLE, &tok)) {
470         if (dec->rel == REL_POINTER) {
471             error("no array-of-pointer declarations -- use typedef");
472         }
473         dec->rel = REL_ARRAY;
474         if (peekscan(TOK_RANGLE, &tok)) {
475             dec->array_max = "~0";      /* unspecified size, use max */
476         } else {
477             scan_num(&tok);
478             dec->array_max = tok.str;
479             scan(TOK_RANGLE, &tok);
480         }
481     }
482     if (streq(dec->type, "opaque")) {
483         if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
484             error("array declaration expected");
485         }
486     } else if (streq(dec->type, "string")) {
487         if (dec->rel != REL_ARRAY) {
488             error(" variable-length array declaration expected");
489         }
490     }
491 }
492
493
494 static void
495 get_type(char **prefixp, char **typep, defkind dkind)
496 {
497     token tok;
498
499     *prefixp = NULL;
500     get_token(&tok);
501     switch (tok.kind) {
502     case TOK_IDENT:
503         *typep = tok.str;
504         break;
505     case TOK_STRUCT:
506     case TOK_ENUM:
507     case TOK_UNION:
508         *prefixp = tok.str;
509         scan(TOK_IDENT, &tok);
510         *typep = tok.str;
511         break;
512     case TOK_UNSIGNED:
513         unsigned_dec(typep);
514         break;
515     case TOK_SHORT:
516         *typep = "short";
517         (void)peekscan(TOK_INT, &tok);
518         break;
519     case TOK_INT32:
520         *typep = "afs_int32";
521         (void)peekscan(TOK_INT, &tok);
522         break;
523     case TOK_VOID:
524         if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
525             error("voids allowed only inside union and program definitions");
526         }
527         *typep = tok.str;
528         break;
529     case TOK_STRING:
530     case TOK_OPAQUE:
531     case TOK_CHAR:
532     case TOK_INT:
533     case TOK_FLOAT:
534     case TOK_DOUBLE:
535     case TOK_BOOL:
536     case TOK_AFSUUID:
537         *typep = tok.str;
538         break;
539     default:
540         error("expected type specifier");
541     }
542 }
543
544
545 static void
546 unsigned_dec(char **typep)
547 {
548     token tok;
549
550     peek(&tok);
551     switch (tok.kind) {
552     case TOK_CHAR:
553         get_token(&tok);
554         *typep = "u_char";
555         break;
556     case TOK_SHORT:
557         get_token(&tok);
558         *typep = "u_short";
559         (void)peekscan(TOK_INT, &tok);
560         break;
561     case TOK_INT32:
562         get_token(&tok);
563         *typep = "afs_uint32";
564         (void)peekscan(TOK_INT, &tok);
565         break;
566     case TOK_INT:
567         get_token(&tok);
568         *typep = "u_int";
569         break;
570     default:
571         *typep = "u_int";
572         break;
573     }
574 }
575
576
577 static void
578 def_package(definition * defp)
579 {
580     token tok;
581
582     defp->def_kind = DEF_PACKAGE;
583     scan(TOK_IDENT, &tok);
584     defp->def_name = tok.str;
585     no_of_stat_funcs = 0;
586     if (PackageIndex++ >= MAX_PACKAGES)
587         error("Exceeded upper limit of package statements\n");
588     function_list_index = 0;
589     PackagePrefix[PackageIndex] = tok.str;
590     if (MasterPrefix == NULL)
591         MasterPrefix = tok.str;
592     no_of_opcodes[PackageIndex] = highest_opcode[PackageIndex] =
593         opcodesnotallowed[PackageIndex] = 0;
594     lowest_opcode[PackageIndex] = 99999;
595     proc_defined[PackageIndex] = NULL;
596     PackageStatIndex[PackageIndex] = NULL;
597 }
598
599 static void
600 def_prefix(definition * defp)
601 {
602     token tok;
603
604     defp->def_kind = DEF_PREFIX;
605     scan(TOK_IDENT, &tok);
606     defp->def_name = tok.str;
607     ServerPrefix = tok.str;
608 }
609
610 static void
611 def_statindex(definition * defp)
612 {
613     token tok;
614     char *name;
615
616     defp->def_kind = DEF_CONST;
617     scan_num(&tok);
618     if (PackageIndex < 0)
619         error("'statindex' command must follow 'package' command!\n");
620     if (PackageStatIndex[PackageIndex])
621         error("Cannot have more then one 'statindex' per package!\n");
622     if (InvalidConstant(tok.str))
623         error("Index in 'statindex' command must be a constant!");
624     name =
625         alloc(strlen(PackagePrefix[PackageIndex]) + strlen("STATINDEX") + 1);
626     strcpy(name, PackagePrefix[PackageIndex]);
627     strcat(name, "STATINDEX");
628     defp->def_name = name;
629     defp->def.co = tok.str;
630     PackageStatIndex[PackageIndex] = name;
631     StatIndex = atoi(tok.str);
632 }
633
634 static void
635 def_startingopcode(definition * defp)
636 {
637     token tok;
638
639     defp->def_kind = DEF_STARTINGOPCODE;
640     scan(TOK_IDENT, &tok);
641     defp->def_name = tok.str;
642     if (InvalidConstant(defp->def_name))
643         error("Opcode in 'startingopcode' command must be a constant!");
644     lowest_opcode[PackageIndex] = master_lowest_opcode = atoi(tok.str);
645     if (lowest_opcode[PackageIndex] < 0
646         || lowest_opcode[PackageIndex] > 99999)
647         error
648             ("startingopcode number is out of bounds (must be >= 0 < 100000)");
649     master_opcodenumber = lowest_opcode[PackageIndex];
650     opcodesnotallowed[PackageIndex] = 1;
651 }
652
653 static void
654 def_split(definition * defp)
655 {
656     token tok;
657
658     defp->def_kind = DEF_SPLITPREFIX;
659     do {
660         get_token(&tok);
661         switch (tok.kind) {
662         case TOK_IN:
663             scan(TOK_EQUAL, &tok);
664             scan(TOK_IDENT, &tok);
665             SplitStart = tok.str;
666             break;
667         case TOK_OUT:
668             scan(TOK_EQUAL, &tok);
669             scan(TOK_IDENT, &tok);
670             SplitEnd = tok.str;
671             break;
672         case TOK_SEMICOLON:
673             break;
674         default:
675             error("syntax error in the 'splitprefix' line");
676         }
677     } while (tok.kind != TOK_SEMICOLON);
678     if (!SplitStart && !SplitEnd)
679         error("At least one param should be passed to 'splitprefix' cmd");
680 }
681
682
683 static void
684 customize_struct(definition * defp)
685 {
686     decl_list *listp;
687     declaration *dec;
688     definition *defp1 = ALLOC(definition);
689     spec_list *specs, **tailp;
690
691     defp->def_kind = DEF_CUSTOMIZED;
692     defp1->def_kind = DEF_SPECIAL;
693     tailp = &defp1->def.sd.specs;
694     for (listp = defp->def.st.decls; listp; listp = listp->next) {
695         dec = &listp->decl;
696         if (streq(dec->type, "string") || (dec->rel == REL_POINTER)) {
697             specs = ALLOC(spec_list);
698             specs->sdef.string_name = dec->name;
699             specs->sdef.string_value = defp->def_name;
700             *tailp = specs;
701             tailp = &specs->next;
702         }
703     }
704     tailp = NULL;
705     STOREVAL(&special_defined, defp1);
706 }
707
708 static char *
709 structname(char *name)
710 {
711     static char namecontents[150];
712     char *pnt, *pnt1;
713
714     strcpy(namecontents, name);
715     pnt = namecontents;
716     if (!strncmp(pnt, "struct", 6))
717         pnt += 6;
718     while (isspace(*pnt))
719         pnt++;
720     pnt1 = pnt;
721     while (*pnt != ' ' && *pnt != '\0')
722         pnt++;
723     *pnt = '\0';
724     return pnt1;
725 }
726
727
728 static void
729 def_special(declaration * dec, definition * defp)
730 {
731     char *typename;
732     spec_list *specs, **tailp;
733     token tok;
734
735     defp->def_kind = DEF_SPECIAL;
736     get_type(&dec->prefix, &dec->type, DEF_SPECIAL);
737     dec->rel = REL_POINTER;
738     scan(TOK_IDENT, &tok);
739     tailp = &defp->def.sd.specs;
740     do {
741         specs = ALLOC(spec_list);
742         specs->sdef.string_name = tok.str;
743         get_param_type(defp, dec, &specs->sdef.string_value, &typename);
744         *tailp = specs;
745         tailp = &specs->next;
746         scan2(TOK_COMMA, TOK_SEMICOLON, &tok);
747         if (tok.kind == TOK_SEMICOLON)
748             break;
749         get_token(&tok);
750     } while (tok.kind == TOK_IDENT);
751     tailp = NULL;
752     STOREVAL(&special_defined, defp);
753 }
754
755
756 proc1_list *Proc_list, **Proc_listp;
757
758 static void
759 check_proc(definition * defp, token * tokp, int noname)
760 {
761     token tok;
762     int proc_split = 0;
763     int proc_multi = 0;
764
765     if (PackageIndex < 0)
766         error("Procedure must be in a package!\n");
767
768     tokp->kind = TOK_PROC;
769     defp->def_kind = DEF_PROC;
770     if (noname)
771         defp->pc.proc_name = "";
772     else
773         defp->pc.proc_name = tokp->str;
774     PerProcCounter = 0;
775     defp->pc.proc_prefix = alloc(strlen(PackagePrefix[PackageIndex]) + 1);
776     strcpy(defp->pc.proc_prefix, PackagePrefix[PackageIndex]);
777     scan2(TOK_LPAREN, TOK_IDENT, &tok);
778     defp->pc.proc_serverstub = NULL;
779     if (tok.kind == TOK_IDENT) {
780         defp->pc.proc_serverstub = tok.str;
781         scan(TOK_LPAREN, &tok);
782     }
783     analyze_ProcParams(defp, &tok);
784     defp->pc.proc_opcodenum = -1;
785     scan4(TOK_SPLIT, TOK_MULTI, TOK_EQUAL, TOK_SEMICOLON, &tok);
786     if (tok.kind == TOK_MULTI) {
787         proc_multi = 1;
788         defp->pc.multi_flag = 1;
789         scan2(TOK_EQUAL, TOK_SEMICOLON, &tok);
790     } else {
791         defp->pc.multi_flag = 0;
792     }
793     if (tok.kind == TOK_SPLIT) {
794         proc_split = 1;
795         defp->pc.split_flag = 1;
796         scan2(TOK_EQUAL, TOK_SEMICOLON, &tok);
797     } else {
798         defp->pc.split_flag = 0;
799     }
800     if (tok.kind == TOK_EQUAL) {
801         if (opcodesnotallowed[PackageIndex])
802             error("Opcode assignment isn't allowed here!");
803         scan_num(&tok);
804         if (InvalidConstant(tok.str))
805             error("Illegal Opcode assignment (Must be a constant opcode!)");
806         if (opcodenum_is_defined(atoi(tok.str)))
807             error("The opcode number is already used by a previous proc");
808         defp->pc.proc_opcodename = tok.str;
809         defp->pc.proc_opcodenum = atoi(tok.str);
810         if (defp->pc.proc_opcodenum < lowest_opcode[PackageIndex])
811             lowest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
812         if (defp->pc.proc_opcodenum < master_lowest_opcode)
813             master_lowest_opcode = defp->pc.proc_opcodenum;
814         if (defp->pc.proc_opcodenum > highest_opcode[PackageIndex])
815             highest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
816         if (defp->pc.proc_opcodenum > master_highest_opcode)
817             master_highest_opcode = defp->pc.proc_opcodenum;
818         scan(TOK_SEMICOLON, &tok);
819     } else {
820         if (master_opcodenumber == 99999)
821             master_opcodenumber = 0;
822         defp->pc.proc_opcodenum = master_opcodenumber++;
823         if (defp->pc.proc_opcodenum < lowest_opcode[PackageIndex])
824             lowest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
825         if (defp->pc.proc_opcodenum > highest_opcode[PackageIndex])
826             highest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
827         if (defp->pc.proc_opcodenum > master_highest_opcode)
828             master_highest_opcode = defp->pc.proc_opcodenum;
829         opcodesnotallowed[PackageIndex] = 1;    /* force it */
830     }
831     no_of_opcodes[PackageIndex]++, master_no_of_opcodes++;
832     if (proc_multi) {
833         generate_code(defp, 0, 1);
834         if (Cflag || cflag) {
835             generate_code(defp, 1, 1);
836         }
837         generate_multi_macros(defp);
838     } else {
839         generate_code(defp, proc_split, 0);
840     }
841
842     if (function_list_index >= MAX_FUNCTIONS_PER_INTERFACE) {
843         error("too many functions in interface, "
844               "increase MAX_FUNCTIONS_PER_INTERFACE");
845     }
846     sprintf(function_list[PackageIndex][function_list_index], "%s%s%s",
847             prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
848
849     function_list_index++;
850     defp->statindex = no_of_stat_funcs;
851     no_of_stat_funcs_header[PackageIndex]++;
852     no_of_stat_funcs++;
853     *Proc_listp = NULL;
854 }
855
856
857 #define LEGALNUMS "0123456789"
858 static int
859 InvalidConstant(char *name)
860 {
861     char *map;
862     int slen;
863
864     map = LEGALNUMS;
865     slen = (int)strlen(name);
866     return (slen != strspn(name, map));
867 }
868
869 static int
870 opcodenum_is_defined(int opcode_num)
871 {
872     list *listp;
873     definition *defp;
874
875     for (listp = proc_defined[PackageIndex]; listp != NULL;
876          listp = listp->next) {
877         defp = (definition *) listp->val;
878         if (opcode_num == defp->pc.proc_opcodenum)
879             return 1;
880     }
881     return 0;
882 }
883
884
885 static void
886 analyze_ProcParams(definition * defp, token * tokp)
887 {
888     declaration dec;
889     decl_list *decls, **tailp;
890
891     Proc_listp = &defp->pc.plists;
892     tailp = &defp->def.st.decls;
893     do {
894         get_token(tokp);
895         Proc_list = ALLOC(proc1_list);
896         memset(Proc_list, 0, sizeof(proc1_list));
897         Proc_list->pl.param_flag = 0;
898         switch (tokp->kind) {
899         case TOK_IN:
900             hdle_param_tok(defp, &dec, tokp, DEF_INPARAM);
901             break;
902         case TOK_OUT:
903             hdle_param_tok(defp, &dec, tokp, DEF_OUTPARAM);
904             break;
905         case TOK_INOUT:
906             hdle_param_tok(defp, &dec, tokp, DEF_INOUTPARAM);
907             break;
908         case TOK_RPAREN:
909             break;
910         default:
911             unget_token(tokp);
912             hdle_param_tok(defp, &dec, tokp, DEF_NULL);
913             break;
914         }
915         *Proc_listp = Proc_list;
916         Proc_listp = &Proc_list->next;
917         decls = ALLOC(decl_list);
918         memset(decls, 0, sizeof(decl_list));
919     if (tokp->kind != TOK_RPAREN)
920         decls->decl = dec;
921         *tailp = decls;
922         tailp = &decls->next;
923     } while (tokp->kind != TOK_RPAREN);
924     *tailp = NULL;
925 }
926
927
928 static void
929 generate_code(definition * defp, int proc_split_flag, int multi_flag)
930 {
931     if (proc_split_flag)
932         handle_split_proc(defp, multi_flag);
933     else {
934         if (Cflag || cflag) {
935             cs_Proc_CodeGeneration(defp, 0, "");
936         }
937         if (Sflag || cflag)
938             ss_Proc_CodeGeneration(defp);
939     }
940     if (Sflag || (cflag && xflag && !proc_split_flag) || hflag)
941         STOREVAL(&proc_defined[PackageIndex], defp);
942 }
943
944
945 static void
946 handle_split_proc(definition * defp, int multi_flag)
947 {
948     char *startname = SplitStart, *endname = SplitEnd;
949     int numofparams = 0;
950
951     if (!startname)
952         startname = "Start";
953     if (!endname)
954         endname = "End";
955     if (Cflag || cflag) {
956         if (!cflag) {
957             do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 0);
958         }
959         cs_Proc_CodeGeneration(defp, 1, startname);
960         if (!cflag) {
961             do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 1);
962             do_split(defp, IN, &numofparams, DEF_INPARAM, 0);
963         }
964         cs_Proc_CodeGeneration(defp, (multi_flag ? 3 : 2), endname);
965         if (!cflag) {
966             do_split(defp, IN, &numofparams, DEF_INPARAM, 1);
967         }
968     }
969     if (Sflag || cflag)
970         ss_Proc_CodeGeneration(defp);
971 }
972
973
974 static void
975 do_split(definition * defp, int direction, int *numofparams,
976          defkind param_kind, int restore_flag)
977 {
978     proc1_list *plist;
979
980     if (restore_flag) {
981         defp->pc.paramtypes[direction] = *numofparams;
982         for (plist = defp->pc.plists; plist; plist = plist->next) {
983             if (plist->component_kind == DEF_NULL
984                 && plist->pl.param_kind == param_kind)
985                 plist->component_kind = DEF_PARAM;
986         }
987     } else {
988         *numofparams = defp->pc.paramtypes[direction];
989         defp->pc.paramtypes[direction] = 0;
990         for (plist = defp->pc.plists; plist; plist = plist->next) {
991             if (plist->component_kind == DEF_PARAM
992                 && plist->pl.param_kind == param_kind)
993                 plist->component_kind = DEF_NULL;
994         }
995     }
996 }
997
998
999 static void
1000 hdle_param_tok(definition * defp, declaration * dec, token * tokp,
1001                defkind par_kind)
1002 {
1003     static defkind last_param_kind = DEF_NULL;
1004
1005     if (par_kind == DEF_NULL)
1006         Proc_list->pl.param_kind = last_param_kind;
1007     else
1008         Proc_list->pl.param_kind = par_kind;
1009     last_param_kind = Proc_list->pl.param_kind;
1010     defp->pc.paramtypes[(int)last_param_kind]++;
1011     Proc_list->component_kind = DEF_PARAM;
1012     Proc_list->code = alloc(250);
1013     Proc_list->scode = alloc(250);
1014     get_declaration(dec, DEF_PARAM);
1015     Proc_list->pl.param_name = dec->name;
1016     get1_param_type(defp, dec, &Proc_list->pl.param_type);
1017     print_param(dec);
1018     scan2(TOK_COMMA, TOK_RPAREN, tokp);
1019     if (tokp->kind == TOK_COMMA)
1020         peek(tokp);
1021 }
1022
1023
1024 static void
1025 get1_param_type(definition * defp, declaration * dec, char **param_type)
1026 {
1027     char typecontents[100];
1028
1029     if (streq(dec->type, "string")) {
1030         *param_type = "char *";
1031     } else {
1032         if (dec->prefix) {
1033             strcpy(typecontents, dec->prefix);
1034             strcat(typecontents, " ");
1035             strcat(typecontents, dec->type);
1036             strcat(typecontents, " *");
1037         } else if (dec->rel == REL_POINTER) {
1038             strcpy(typecontents, dec->type);
1039             strcat(typecontents, " *");
1040         } else
1041             strcpy(typecontents, dec->type);
1042         *param_type = alloc(100);
1043         strcpy(*param_type, typecontents);
1044     }
1045 }
1046
1047
1048 static void
1049 get_param_type(definition * defp, declaration * dec, char **param_type,
1050                char **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 #ifdef undef
1077 static void
1078 hndle_param_tail(definition * defp, declaration * dec, token * tokp,
1079                  char *typename)
1080 {
1081     char *amp;
1082
1083     if (dec->rel == REL_POINTER)
1084         Proc_list->pl.param_flag |= INDIRECT_PARAM;
1085     else
1086         Proc_list->pl.param_flag &= ~INDIRECT_PARAM;
1087     amp = "";
1088     if (!(Proc_list->pl.param_flag & INDIRECT_PARAM))
1089         amp = "&";
1090
1091     sprintf(Proc_list->code, "xdr_%s(&z_xdrs, %s%s)", typename, amp,
1092             Proc_list->pl.param_name);
1093     sprintf(Proc_list->scode, "xdr_%s(z_xdrs, &%s)", typename,
1094             Proc_list->pl.param_name);
1095     scan2(TOK_COMMA, TOK_RPAREN, tokp);
1096     if (tokp->kind == TOK_COMMA)
1097         peek(tokp);
1098 }
1099 #endif
1100
1101
1102 static void
1103 cs_Proc_CodeGeneration(definition * defp, int split_flag, char *procheader)
1104 {
1105     defp->can_fail = 0;
1106     cs_ProcName_setup(defp, procheader, split_flag);
1107     if (!cflag) {
1108         cs_ProcParams_setup(defp, split_flag);
1109         cs_ProcMarshallInParams_setup(defp, split_flag);
1110         if (split_flag != 1) {
1111             cs_ProcSendPacket_setup(defp, split_flag);
1112             cs_ProcUnmarshallOutParams_setup(defp);
1113         }
1114         cs_ProcTail_setup(defp, split_flag);
1115     }
1116
1117     if (!kflag && !split_flag && uflag) {
1118         ucs_ProcName_setup(defp, "ubik_", split_flag);
1119         if (!cflag) {
1120             ucs_ProcParams_setup(defp, split_flag);
1121             ucs_ProcTail_setup(defp, split_flag);
1122         }
1123     }
1124 }
1125
1126 static void
1127 cs_ProcName_setup(definition * defp, char *procheader, int split_flag)
1128 {
1129     proc1_list *plist;
1130     char *first_arg;
1131
1132     if (ansic_flag) {
1133         if (split_flag) {
1134             first_arg = "struct rx_call *z_call";
1135         } else {
1136             first_arg = "struct rx_connection *z_conn";
1137         }
1138     } else {
1139         if (split_flag) {
1140             first_arg = "z_call";
1141         } else {
1142             first_arg = "z_conn";
1143         }
1144     }
1145
1146     if (!cflag) {
1147         f_print(fout, "int %s%s%s%s(%s", procheader, prefix,
1148                 PackagePrefix[PackageIndex], defp->pc.proc_name, first_arg);
1149     }
1150     if ((strlen(procheader) + strlen(prefix) +
1151          strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >=
1152         MAX_FUNCTION_NAME_LEN) {
1153         error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1154     }
1155     if (!cflag) {
1156         for (plist = defp->pc.plists; plist; plist = plist->next) {
1157             if (plist->component_kind == DEF_PARAM) {
1158                 f_print(fout, ",");
1159                 if (ansic_flag) {
1160                     if (plist->pl.param_kind == DEF_INPARAM &&
1161                         strcmp(plist->pl.param_type, "char *") == 0) {
1162                         f_print(fout, "const ");
1163                     }
1164                     if (plist->pl.param_flag & OUT_STRING) {
1165                         f_print(fout, "%s *%s", plist->pl.param_type,
1166                                 plist->pl.param_name);
1167                     } else {
1168                         f_print(fout, "%s %s", plist->pl.param_type,
1169                                 plist->pl.param_name);
1170                     }
1171                 } else {
1172                     f_print(fout, " %s", plist->pl.param_name);
1173                     plist->pl.param_flag &= ~PROCESSED_PARAM;
1174                 }
1175             }
1176         }
1177         f_print(fout, ")\n");
1178     }
1179 }
1180
1181 static void
1182 cs_ProcParams_setup(definition * defp, int split_flag)
1183 {
1184     proc1_list *plist, *plist1;
1185
1186     if (ansic_flag)
1187         return;
1188
1189     if (!split_flag)
1190         f_print(fout, "\tstruct rx_connection *z_conn;\n");
1191     if (split_flag) {
1192         f_print(fout, "\tstruct rx_call *z_call;\n");
1193     }
1194     for (plist = defp->pc.plists; plist; plist = plist->next) {
1195         if (plist->component_kind == DEF_PARAM
1196             && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1197             if (plist->pl.param_flag & OUT_STRING) {
1198                 f_print(fout, "\t%s *%s", plist->pl.param_type,
1199                         plist->pl.param_name);
1200             } else {
1201                 f_print(fout, "\t%s %s", plist->pl.param_type,
1202                         plist->pl.param_name);
1203             }
1204             plist->pl.param_flag |= PROCESSED_PARAM;
1205             for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1206                 if ((plist1->component_kind == DEF_PARAM)
1207                     && streq(plist->pl.param_type, plist1->pl.param_type)
1208                     && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1209                     char *star = "";
1210                     char *pntr = strchr(plist1->pl.param_type, '*');
1211                     if (pntr)
1212                         star = "*";
1213                     if (plist1->pl.param_flag & OUT_STRING) {
1214                         f_print(fout, ", *%s%s", star, plist1->pl.param_name);
1215                     } else {
1216                         f_print(fout, ", %s%s", star, plist1->pl.param_name);
1217                     }
1218                     plist1->pl.param_flag |= PROCESSED_PARAM;
1219                 }
1220             }
1221             f_print(fout, ";\n");
1222         }
1223     }
1224 }
1225
1226
1227 static void
1228 cs_ProcMarshallInParams_setup(definition * defp, int split_flag)
1229 {
1230     int noofparams, i = 0;
1231     proc1_list *plist;
1232     decl_list *dl;
1233     int noofallparams =
1234         defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT] +
1235         defp->pc.paramtypes[OUT];
1236
1237     f_print(fout, "{\n");
1238     if (!split_flag)
1239         f_print(fout, "\tstruct rx_call *z_call = rx_NewCall(z_conn);\n");
1240     if ((!split_flag) || (split_flag == 1)) {
1241         if (opcodesnotallowed[PackageIndex]) {
1242             f_print(fout, "\tstatic int z_op = %d;\n",
1243                     defp->pc.proc_opcodenum);
1244         } else {
1245             f_print(fout, "\tstatic int z_op = %s;\n",
1246                     defp->pc.proc_opcodename);
1247         }
1248     }
1249     f_print(fout, "\tint z_result;\n");
1250     if (!(split_flag > 1) || (noofallparams != 0)) {
1251         f_print(fout, "\tXDR z_xdrs;\n");
1252     }
1253
1254     if ((!split_flag) || (split_flag == 1)) {
1255         f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_ENCODE);\n");
1256         f_print(fout, "\n\t/* Marshal the arguments */\n");
1257         f_print(fout, "\tif ((!xdr_int(&z_xdrs, &z_op))");
1258         noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1259         for (plist = defp->pc.plists, dl = defp->def.st.decls; plist;
1260              plist = plist->next, dl = dl->next) {
1261             if (plist->component_kind == DEF_PARAM
1262                 && (plist->pl.param_kind == DEF_INPARAM
1263                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1264                 f_print(fout, "\n\t     || (!%s)", plist->code);
1265                 if (++i == noofparams) {
1266                     f_print(fout,
1267                             ") {\n\t\tz_result = RXGEN_CC_MARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1268                     defp->can_fail = 1;
1269                 }
1270             }
1271         }
1272         if (!i) {
1273             f_print(fout,
1274                     ") {\n\t\tz_result = RXGEN_CC_MARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1275             defp->can_fail = 1;
1276         }
1277     }
1278 }
1279
1280
1281 static void
1282 cs_ProcSendPacket_setup(definition * defp, int split_flag)
1283 {
1284     int noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1285
1286     if (noofoutparams) {
1287         f_print(fout, "\t/* Un-marshal the reply arguments */\n");
1288         if (split_flag) {
1289             f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
1290         } else {
1291             f_print(fout, "\tz_xdrs.x_op = XDR_DECODE;\n");
1292         }
1293     }
1294 }
1295
1296
1297 static void
1298 cs_ProcUnmarshallOutParams_setup(definition * defp)
1299 {
1300     int noofparams, i;
1301     proc1_list *plist;
1302     decl_list *dl;
1303
1304     noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1305     if (noofparams)
1306         for (plist = defp->pc.plists, dl = defp->def.st.decls, i = 0; plist;
1307              plist = plist->next, dl = dl->next) {
1308             if (plist->component_kind == DEF_PARAM
1309                 && (plist->pl.param_kind == DEF_OUTPARAM
1310                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1311                 if (!i) {
1312                     f_print(fout, "\tif ((!%s)", plist->code);
1313                 } else {
1314                     f_print(fout, "\n\t     || (!%s)", plist->code);
1315                 }
1316                 if (++i == noofparams) {
1317                     f_print(fout,
1318                             ") {\n\t\tz_result = RXGEN_CC_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1319                     defp->can_fail = 1;
1320                 }
1321             }
1322         }
1323 }
1324
1325
1326 static void
1327 cs_ProcTail_setup(definition * defp, int split_flag)
1328 {
1329     f_print(fout, "\tz_result = RXGEN_SUCCESS;\n");
1330     if (defp->can_fail) {
1331         f_print(fout, "fail:\n");
1332     }
1333     if (!split_flag) {
1334         f_print(fout, "\tz_result = rx_EndCall(z_call, z_result);\n");
1335     }
1336     if (xflag && split_flag != 1) {
1337         f_print(fout, "\tif (rx_enable_stats) {\n");
1338         if (PackageStatIndex[PackageIndex]) {
1339             f_print(fout,
1340                     "\t    rx_RecordCallStatistics(z_call, %s,\n",
1341                     PackageStatIndex[PackageIndex]);
1342         } else {
1343             f_print(fout,
1344                     "\t    rx_RecordCallStatistics(z_call, \n"
1345                     "\t\t(((afs_uint32)(ntohs(rx_ServiceIdOf(rx_ConnectionOf(z_call))) << 16)) |\n"
1346                     "\t\t((afs_uint32)ntohs(rx_PortOf(rx_PeerOf(rx_ConnectionOf(z_call)))))),\n");
1347         }
1348         f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, 1);\n",
1349                 no_of_stat_funcs, PackagePrefix[PackageIndex]);
1350         f_print(fout, "\t}\n\n");
1351     }
1352     f_print(fout, "\treturn z_result;\n}\n\n");
1353 }
1354
1355
1356 static void
1357 ss_Proc_CodeGeneration(definition * defp)
1358 {
1359     defp->can_fail = 0;
1360     ss_ProcName_setup(defp);
1361     if (!cflag) {
1362         ss_ProcParams_setup(defp);
1363         ss_ProcSpecial_setup(defp);
1364         ss_ProcUnmarshallInParams_setup(defp);
1365         ss_ProcCallRealProc_setup(defp);
1366         ss_ProcMarshallOutParams_setup(defp);
1367         ss_ProcTail_setup(defp);
1368     }
1369 }
1370
1371
1372 static void
1373 ss_ProcName_setup(definition * defp)
1374 {
1375     proc1_list *plist;
1376
1377     if ((strlen(prefix) + strlen(PackagePrefix[PackageIndex]) +
1378          strlen(defp->pc.proc_name)) >= MAX_FUNCTION_NAME_LEN) {
1379         error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1380     }
1381
1382     if (!cflag) {
1383         f_print(fout, "static afs_int32 _%s%s%s(", prefix,
1384                 PackagePrefix[PackageIndex], defp->pc.proc_name);
1385         f_print(fout, "struct rx_call *z_call, XDR *z_xdrs)\n{\n");
1386         f_print(fout, "\t" "afs_int32 z_result;\n");
1387
1388         for (plist = defp->pc.plists; plist; plist = plist->next)
1389             if (plist->component_kind == DEF_PARAM) {
1390                 plist->pl.param_flag &= ~(PROCESSED_PARAM);
1391                 plist->pl.string_name = NULL;
1392             }
1393     }
1394 }
1395
1396
1397 static void
1398 ss_ProcParams_setup(definition * defp)
1399 {
1400     proc1_list *plist, *plist1;
1401     list *listp;
1402     definition *defp1;
1403
1404     for (plist = defp->pc.plists; plist; plist = plist->next) {
1405         if ((plist->component_kind == DEF_PARAM)
1406             && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1407             if (plist->pl.param_flag & INDIRECT_PARAM) {
1408                 char pres = '\0', *pntr = strchr(plist->pl.param_type, '*');
1409                 if (pntr) {
1410                     --pntr;
1411                     pres = *pntr;
1412                     *pntr = (char)0;
1413                 }
1414                 f_print(fout, "\t%s %s", plist->pl.param_type,
1415                         plist->pl.param_name);
1416                 if (pntr)
1417                     *pntr = pres;
1418             } else if (strchr(plist->pl.param_type, '*') == 0) {
1419                 f_print(fout, "\t%s %s", plist->pl.param_type,
1420                         plist->pl.param_name);
1421             } else {
1422                 plist->pl.param_flag |= FREETHIS_PARAM;
1423                 f_print(fout, "\t%s %s=(%s)0", plist->pl.param_type,
1424                         plist->pl.param_name, plist->pl.param_type);
1425             }
1426             plist->pl.param_flag |= PROCESSED_PARAM;
1427             for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1428                 if ((plist1->component_kind == DEF_PARAM)
1429                     && streq(plist->pl.param_type, plist1->pl.param_type)
1430                     && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1431                     if (plist1->pl.param_flag & INDIRECT_PARAM) {
1432                         f_print(fout, ", %s", plist1->pl.param_name);
1433                     } else if (strchr(plist1->pl.param_type, '*') == 0) {
1434                         f_print(fout, ", %s", plist1->pl.param_name);
1435                     } else {
1436                         plist1->pl.param_flag |= FREETHIS_PARAM;
1437                         f_print(fout, ", *%s=(%s)0", plist1->pl.param_name,
1438                                 plist1->pl.param_type);
1439                     }
1440                     plist1->pl.param_flag |= PROCESSED_PARAM;
1441                 }
1442             }
1443             f_print(fout, ";\n");
1444         }
1445     }
1446     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1447         defp1 = (definition *) listp->val;
1448         for (plist = defp->pc.plists; plist; plist = plist->next) {
1449             if (plist->component_kind == DEF_PARAM
1450                 && (plist->pl.param_kind == DEF_OUTPARAM
1451                     || plist->pl.param_kind == DEF_INOUTPARAM)
1452                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1453                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1454                     switch (defp1->pc.rel) {
1455                     case REL_ARRAY:
1456                     case REL_POINTER:
1457                     default:
1458                         break;
1459                     }
1460                 }
1461             }
1462         }
1463     }
1464     fprintf(fout, "\n");
1465 }
1466
1467
1468 static void
1469 ss_ProcSpecial_setup(definition * defp)
1470 {
1471     proc1_list *plist;
1472     definition *defp1;
1473     list *listp;
1474
1475     for (listp = special_defined; listp != NULL; listp = listp->next) {
1476         defp1 = (definition *) listp->val;
1477
1478         for (plist = defp->pc.plists; plist; plist = plist->next) {
1479             if (plist->component_kind == DEF_PARAM
1480                 && (plist->pl.param_kind == DEF_INPARAM
1481                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1482                 spec_list *spec = defp1->def.sd.specs;
1483                 char string[40];
1484                 strcpy(string, structname(spec->sdef.string_value));
1485                 if (streq(string, structname(plist->pl.param_type))) {
1486                     plist->pl.string_name = spec->sdef.string_name;
1487                     plist->pl.param_flag |= FREETHIS_PARAM;
1488                     fprintf(fout, "\n\t%s.%s = 0;", plist->pl.param_name,
1489                             spec->sdef.string_name);
1490                 }
1491             }
1492         }
1493     }
1494     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1495         defp1 = (definition *) listp->val;
1496         for (plist = defp->pc.plists; plist; plist = plist->next) {
1497             if (plist->component_kind == DEF_PARAM) {
1498                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1499                     plist->pl.param_flag |= FREETHIS_PARAM;
1500                     switch (defp1->pc.rel) {
1501                     case REL_ARRAY:
1502                         plist->pl.string_name = alloc(40);
1503                         if (brief_flag) {
1504                             f_print(fout, "\n\t%s.val = 0;",
1505                                     plist->pl.param_name);
1506                             f_print(fout, "\n\t%s.len = 0;",
1507                                     plist->pl.param_name);
1508                             s_print(plist->pl.string_name, "val");
1509                         } else {
1510                             f_print(fout, "\n\t%s.%s_val = 0;",
1511                                     plist->pl.param_name, defp1->def_name);
1512                             f_print(fout, "\n\t%s.%s_len = 0;",
1513                                     plist->pl.param_name, defp1->def_name);
1514                             s_print(plist->pl.string_name, "%s_val",
1515                                     defp1->def_name);
1516                         }
1517                         break;
1518                     case REL_POINTER:
1519                         f_print(fout, "\n\t%s = 0;", plist->pl.param_name);
1520                         plist->pl.string_name = NULL;
1521                         break;
1522                     default:
1523                         break;
1524                     }
1525                 }
1526             }
1527         }
1528     }
1529     for (listp = complex_defined; listp != NULL; listp = listp->next) {
1530         defp1 = (definition *) listp->val;
1531         for (plist = defp->pc.plists; plist; plist = plist->next) {
1532             if (plist->component_kind == DEF_PARAM) {
1533                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1534                     plist->pl.param_flag |= FREETHIS_PARAM;
1535                     fprintf(fout, "\n\tmemset(&%s, 0, sizeof(%s));",
1536                                  plist->pl.param_name, defp1->def_name);
1537                 }
1538             }
1539         }
1540     }
1541
1542     f_print(fout, "\n");
1543 }
1544
1545
1546 static void
1547 ss_ProcUnmarshallInParams_setup(definition * defp)
1548 {
1549     int noofparams, noofoutparams, i;
1550     proc1_list *plist;
1551
1552     noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1553     noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1554     for (plist = defp->pc.plists, i = 0; plist; plist = plist->next) {
1555         if (plist->component_kind == DEF_PARAM
1556             && (plist->pl.param_kind == DEF_INPARAM
1557                 || plist->pl.param_kind == DEF_INOUTPARAM)) {
1558             if (!i) {
1559                 f_print(fout, "\n\tif ((!%s)",
1560                         (plist->scode ? plist->scode : plist->code));
1561             } else {
1562                 f_print(fout, "\n\t     || (!%s)",
1563                         (plist->scode ? plist->scode : plist->code));
1564             }
1565             if (++i == noofparams) {
1566                 if (!noofoutparams) {
1567                     f_print(fout, ") {\n");
1568                 } else {
1569                     f_print(fout, ") {\n");
1570                 }
1571                 f_print(fout,
1572                         "\t\tz_result = RXGEN_SS_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1573                 defp->can_fail = 1;
1574             }
1575         }
1576     }
1577 }
1578
1579
1580 static void
1581 ss_ProcCallRealProc_setup(definition * defp)
1582 {
1583     extern char zflag;
1584     proc1_list *plist;
1585
1586     f_print(fout, "\tz_result = %s%s%s%s(z_call", prefix, ServerPrefix,
1587             PackagePrefix[PackageIndex], defp->pc.proc_name);
1588     for (plist = defp->pc.plists; plist; plist = plist->next) {
1589         if (plist->component_kind == DEF_PARAM) {
1590             if (plist->pl.param_flag & INDIRECT_PARAM) {
1591                 f_print(fout, ", &%s", plist->pl.param_name);
1592             } else {
1593                 if (plist->pl.param_flag & OUT_STRING) {
1594                     f_print(fout, ", &%s", plist->pl.param_name);
1595                 } else {
1596                     f_print(fout, ", %s", plist->pl.param_name);
1597                 }
1598             }
1599         }
1600     }
1601     f_print(fout, ");\n");
1602     if (zflag) {
1603         f_print(fout, "\tif (z_result)\n\t\treturn z_result;\n");
1604     }
1605 }
1606
1607
1608 static void
1609 ss_ProcMarshallOutParams_setup(definition * defp)
1610 {
1611     proc1_list *plist;
1612     int noofparams, i;
1613
1614     noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1615     if (noofparams)
1616         f_print(fout, "\tz_xdrs->x_op = XDR_ENCODE;\n");
1617     if (noofparams) {
1618         for (plist = defp->pc.plists, i = 0; plist; plist = plist->next) {
1619             if (plist->component_kind == DEF_PARAM
1620                 && (plist->pl.param_kind == DEF_OUTPARAM
1621                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1622                 if (!i) {
1623                     f_print(fout, "\tif ((!%s)",
1624                             (plist->scode ? plist->scode : plist->code));
1625                 } else {
1626                     f_print(fout, "\n\t     || (!%s)",
1627                             (plist->scode ? plist->scode : plist->code));
1628                 }
1629                 if (++i == noofparams) {
1630                     f_print(fout, ")\n\t\tz_result = RXGEN_SS_MARSHAL;\n");
1631                 }
1632             }
1633         }
1634     }
1635 }
1636
1637 static void
1638 ss_ProcTail_frees(char *xdrfunc, int *somefrees) {
1639     if (!*somefrees) {
1640         f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1641         f_print(fout, "\tif ((!%s)", xdrfunc);
1642         *somefrees = 1;
1643     } else {
1644         f_print(fout, "\n\t    || (!%s)", xdrfunc);
1645     }
1646 }
1647
1648
1649 static void
1650 ss_ProcTail_setup(definition * defp)
1651 {
1652     proc1_list *plist;
1653     definition *defp1;
1654     list *listp;
1655     int somefrees = 0;
1656
1657     if (defp->can_fail) {
1658         f_print(fout, "fail:\n");
1659     }
1660
1661     for (plist = defp->pc.plists; plist; plist = plist->next) {
1662         if (plist->component_kind == DEF_PARAM
1663                 && (plist->pl.param_flag & FREETHIS_PARAM))
1664             ss_ProcTail_frees(plist->scode, &somefrees);
1665     }
1666
1667     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1668         defp1 = (definition *) listp->val;
1669         for (plist = defp->pc.plists; plist; plist = plist->next) {
1670             if (plist->component_kind == DEF_PARAM
1671                 && (plist->pl.param_kind == DEF_OUTPARAM
1672                     || plist->pl.param_kind == DEF_INOUTPARAM)
1673                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1674                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1675                     switch (defp1->pc.rel) {
1676                     case REL_ARRAY:
1677                     case REL_POINTER:
1678                         ss_ProcTail_frees(plist->scode, &somefrees);
1679                         break;
1680                     default:
1681                         break;
1682                     }
1683                 }
1684             }
1685         }
1686     }
1687
1688     for (listp = uniondef_defined; listp != NULL; listp = listp->next) {
1689         defp1 = (definition *) listp->val;
1690         for (plist = defp->pc.plists; plist; plist = plist->next) {
1691             if (plist->component_kind == DEF_PARAM
1692                 && (plist->pl.param_kind == DEF_OUTPARAM
1693                     || plist->pl.param_kind == DEF_INOUTPARAM)
1694                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1695                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1696                     if (plist->pl.param_flag & INDIRECT_PARAM) {
1697                         ss_ProcTail_frees(plist->scode, &somefrees);
1698                     }
1699                 }
1700             }
1701         }
1702     }
1703
1704     if (somefrees) {
1705         f_print(fout, ")\n");
1706         f_print(fout, "\t\tz_result = RXGEN_SS_XDRFREE;\n\n");
1707     }
1708
1709     if (xflag) {
1710         f_print(fout, "\tif (rx_enable_stats) {\n");
1711         f_print(fout, "\t    rx_RecordCallStatistics(z_call,");
1712         if (PackageStatIndex[PackageIndex]) {
1713             f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
1714         } else {
1715             f_print(fout,
1716                     "\n\t\t(((afs_uint32)(ntohs(rx_ServiceIdOf(rx_ConnectionOf(z_call))) << 16)) |\n"
1717                     "\t\t((afs_uint32)ntohs(rx_ServiceOf(rx_ConnectionOf(z_call))->servicePort))),\n");
1718         }
1719         f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, 0);\n",
1720                 no_of_stat_funcs, PackagePrefix[PackageIndex]);
1721         f_print(fout, "\t}\n\n");
1722     }
1723
1724     f_print(fout, "\treturn z_result;\n");
1725     f_print(fout, "}\n\n");
1726 }
1727
1728
1729 static void
1730 ucs_ProcName_setup(definition * defp, char *procheader, int split_flag)
1731 {
1732     proc1_list *plist;
1733
1734     if (!cflag) {
1735         if (ansic_flag) {
1736             f_print(fout, "int %s%s%s%s(struct ubik_client *aclient, afs_int32 aflags",
1737                           procheader, prefix, PackagePrefix[PackageIndex],
1738                           defp->pc.proc_name);
1739         } else {
1740             f_print(fout, "int %s%s%s%s(aclient, aflags", procheader, prefix,
1741                           PackagePrefix[PackageIndex], defp->pc.proc_name);
1742         }
1743     }
1744     if ((strlen(procheader) + strlen(prefix) +
1745          strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >=
1746         MAX_FUNCTION_NAME_LEN) {
1747         error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1748     }
1749     if (!cflag) {
1750         for (plist = defp->pc.plists; plist; plist = plist->next) {
1751             if (plist->component_kind == DEF_PARAM) {
1752                 f_print(fout, ",");
1753                 if (ansic_flag) {
1754                     if (plist->pl.param_kind == DEF_INPARAM &&
1755                         strcmp(plist->pl.param_type, "char *") == 0) {
1756                         f_print(fout, "const ");
1757                     }
1758                     if (plist->pl.param_flag & OUT_STRING) {
1759                         f_print(fout, "%s *%s", plist->pl.param_type,
1760                                 plist->pl.param_name);
1761                     } else {
1762                         f_print(fout, "%s %s", plist->pl.param_type,
1763                                 plist->pl.param_name);
1764                     }
1765                 } else {
1766                     plist->pl.param_flag &= ~PROCESSED_PARAM;
1767                     f_print(fout, " %s", plist->pl.param_name);
1768                 }
1769             }
1770         }
1771         f_print(fout, ")\n");
1772     }
1773 }
1774
1775
1776 static void
1777 ucs_ProcParams_setup(definition * defp, int split_flag)
1778 {
1779     proc1_list *plist, *plist1;
1780
1781     if (ansic_flag)
1782         return;
1783
1784     f_print(fout, "\tstruct ubik_client *aclient;\n\tafs_int32 aflags;\n");
1785     for (plist = defp->pc.plists; plist; plist = plist->next) {
1786         if (plist->component_kind == DEF_PARAM
1787             && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1788             if (plist->pl.param_flag & OUT_STRING) {
1789                 f_print(fout, "\t%s *%s", plist->pl.param_type,
1790                         plist->pl.param_name);
1791             } else {
1792                 f_print(fout, "\t%s %s", plist->pl.param_type,
1793                         plist->pl.param_name);
1794             }
1795             plist->pl.param_flag |= PROCESSED_PARAM;
1796             for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1797                 if ((plist1->component_kind == DEF_PARAM)
1798                     && streq(plist->pl.param_type, plist1->pl.param_type)
1799                     && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1800                     char *star = "";
1801                     char *pntr = strchr(plist1->pl.param_type, '*');
1802                     if (pntr)
1803                         star = "*";
1804                     if (plist1->pl.param_flag & OUT_STRING) {
1805                         f_print(fout, ", *%s%s", star, plist1->pl.param_name);
1806                     } else {
1807                         f_print(fout, ", %s%s", star, plist1->pl.param_name);
1808                     }
1809                     plist1->pl.param_flag |= PROCESSED_PARAM;
1810                 }
1811             }
1812             f_print(fout, ";\n");
1813         }
1814     }
1815 }
1816
1817 static void
1818 ucs_ProcTail_setup(definition * defp, int split_flag)
1819 {
1820     proc1_list *plist;
1821
1822     f_print(fout, "{\tafs_int32 rcode, code, newHost, thisHost, i, _ucount;\n");
1823     f_print(fout, "\tint chaseCount, pass, needsync;\n");
1824 #if 0 /* goes with block below */
1825     f_print(fout, "\tint j, inlist;\n");
1826 #endif
1827     f_print(fout, "\tstruct rx_connection *tc;\n");
1828     f_print(fout, "\tstruct rx_peer *rxp;\n");
1829     f_print(fout, "\tshort origLevel;\n\n");
1830     f_print(fout, "\tif (!aclient)\n");
1831     f_print(fout, "\t\treturn UNOENT;\n");
1832     f_print(fout, "\tLOCK_UBIK_CLIENT(aclient);\n\n");
1833     f_print(fout, "\t restart:\n");
1834     f_print(fout, "\torigLevel = aclient->initializationState;\n");
1835     f_print(fout, "\trcode = UNOSERVERS;\n");
1836     f_print(fout, "\tchaseCount = needsync = 0;\n\n");
1837 #if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
1838     f_print(fout, "\tinlist = 0;\n");
1839     f_print(fout, "\tLOCK_UCLNT_CACHE;\n");
1840     f_print(fout, "\tfor (j = 0; ((j < SYNCCOUNT) && calls_needsync[j]); j++) {\n");
1841     f_print(fout, "\t\tif (calls_needsync[j] == (int *)%s%s%s) {\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1842     f_print(fout, "\t\t\tinlist = needsync = 1;\n");
1843     f_print(fout, "\t\t\tbreak;\n");
1844     f_print(fout, "\t\t}\n");
1845     f_print(fout, "\t}\n");
1846     f_print(fout, "\tUNLOCK_UCLNT_CACHE;\n");
1847 #endif
1848     f_print(fout, "\t/* \n\t* First  pass, we try all servers that are up.\n\t* Second pass, we try all servers.\n\t*/\n");
1849     f_print(fout, "\tfor (pass = 0; pass < 2; pass++) {  /*p */\n");
1850     f_print(fout, "\t\t/* For each entry in our servers list */\n");
1851     f_print(fout, "\t\tfor (_ucount = 0;; _ucount++) {     /*s */\n\n");
1852     f_print(fout, "\t\tif (needsync) {\n");
1853     f_print(fout, "\t\t\t/* Need a sync site. Lets try to quickly find it */\n");
1854     f_print(fout, "\t\t\tif (aclient->syncSite) {\n");
1855     f_print(fout, "\t\t\t\tnewHost = aclient->syncSite;        /* already in network order */\n");
1856     f_print(fout, "\t\t\t\taclient->syncSite = 0;      /* Will reset if it works */\n");
1857     f_print(fout, "\t\t\t} else if (aclient->conns[3]) {\n");
1858     f_print(fout, "\t\t\t\t/* If there are fewer than four db servers in a cell,\n");
1859     f_print(fout, "\t\t\t\t* there's no point in making the GetSyncSite call.\n");
1860     f_print(fout, "\t\t\t\t* At best, it's a wash. At worst, it results in more\n");
1861     f_print(fout, "\t\t\t\t* RPCs than you would otherwise make.\n");
1862     f_print(fout, "\t\t\t\t*/\n");
1863     f_print(fout, "\t\t\t\ttc = aclient->conns[_ucount];\n");
1864     f_print(fout, "\t\t\t\tif (tc && rx_ConnError(tc)) {\n");
1865     f_print(fout, "\t\t\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
1866     f_print(fout, "\t\t\t\t}\n");
1867     f_print(fout, "\t\t\t\tif (!tc)\n");
1868     f_print(fout, "\t\t\t\t\tbreak;\n");
1869     f_print(fout, "\t\t\t\tcode = VOTE_GetSyncSite(tc, &newHost);\n");
1870     f_print(fout, "\t\t\t\tif (aclient->initializationState != origLevel)\n");
1871     f_print(fout, "\t\t\t\t\tgoto restart;   /* somebody did a ubik_ClientInit */\n");
1872     f_print(fout, "\t\t\t\tif (code)\n");
1873     f_print(fout, "\t\t\t\t\tnewHost = 0;\n");
1874     f_print(fout, "\t\t\t\tnewHost = htonl(newHost);   /* convert to network order */\n");
1875     f_print(fout, "\t\t\t} else {\n");
1876     f_print(fout, "\t\t\t\tnewHost = 0;\n");
1877     f_print(fout, "\t\t\t}\n");
1878     f_print(fout, "\t\t\tif (newHost) {\n");
1879     f_print(fout, "\t\t\t\t/* position count at the appropriate slot in the client\n");
1880     f_print(fout, "\t\t\t\t* structure and retry. If we can't find in slot, we'll\n");
1881     f_print(fout, "\t\t\t\t* just continue through the whole list \n");
1882     f_print(fout, "\t\t\t\t*/\n");
1883     f_print(fout, "\t\t\t\tfor (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {\n");
1884     f_print(fout, "\t\t\t\t\trxp = rx_PeerOf(aclient->conns[i]);\n");
1885     f_print(fout, "\t\t\t\t\tthisHost = rx_HostOf(rxp);\n");
1886     f_print(fout, "\t\t\t\t\tif (!thisHost)\n");
1887     f_print(fout, "\t\t\t\t\t\tbreak;\n");
1888     f_print(fout, "\t\t\t\t\tif (thisHost == newHost) {\n");
1889     f_print(fout, "\t\t\t\t\t\tif (chaseCount++ > 2)\n");
1890     f_print(fout, "\t\t\t\t\t\t\tbreak;  /* avoid loop asking */\n");
1891     f_print(fout, "\t\t\t\t\t\t_ucount = i;  /* this index is the sync site */\n");
1892     f_print(fout, "\t\t\t\t\t\tbreak;\n");
1893     f_print(fout, "\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n");
1894     f_print(fout, "\t\t/*needsync */\n");
1895     f_print(fout, "\t\ttc = aclient->conns[_ucount];\n");
1896     f_print(fout, "\t\tif (tc && rx_ConnError(tc)) {\n");
1897     f_print(fout, "\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
1898     f_print(fout, "\t\t}\n");
1899     f_print(fout, "\t\tif (!tc)\n");
1900     f_print(fout, "\t\t\tbreak;\n\n");
1901     f_print(fout, "\t\tif ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {\n");
1902     f_print(fout, "\t\t\tcontinue;       /* this guy's down */\n");
1903     f_print(fout, "\t\t}\n");
1904
1905     f_print(fout, "\t\trcode = %s%s%s(tc\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1906     for (plist = defp->pc.plists; plist; plist = plist->next) {
1907         if (plist->component_kind == DEF_PARAM) {
1908             plist->pl.param_flag &= ~PROCESSED_PARAM;
1909             f_print(fout, ", %s", plist->pl.param_name);
1910         }
1911     }
1912     f_print(fout, ");\n");
1913     f_print(fout, "\t\tif (aclient->initializationState != origLevel) {\n");
1914     f_print(fout, "\t\t\t/* somebody did a ubik_ClientInit */\n");
1915     f_print(fout, "\t\t\tif (rcode)\n");
1916     f_print(fout, "\t\t\t\tgoto restart;       /* call failed */\n");
1917     f_print(fout, "\t\t\telse\n");
1918     f_print(fout, "\t\t\t\tgoto done;  /* call suceeded */\n");
1919     f_print(fout, "\t\t}\n");
1920     f_print(fout, "\t\tif (rcode < 0) {    /* network errors */\n");
1921     f_print(fout, "\t\t\taclient->states[_ucount] |= CFLastFailed; /* Mark server down */\n");
1922     f_print(fout, "\t\t} else if (rcode == UNOTSYNC) {\n");
1923     f_print(fout, "\t\t\tneedsync = 1;\n");
1924     f_print(fout, "\t\t} else if (rcode != UNOQUORUM) {\n");
1925     f_print(fout, "\t\t\t/* either misc ubik code, or misc appl code, or success. */\n");
1926     f_print(fout, "\t\t\taclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/\n");
1927     f_print(fout, "\t\t\tgoto done;      /* all done */\n");
1928     f_print(fout, "\t\t}\n");
1929     f_print(fout, "\t\t}                       /*s */\n");
1930     f_print(fout, "\t}                           /*p */\n\n");
1931     f_print(fout, "\tdone:\n");
1932     f_print(fout, "\tif (needsync) {\n");
1933
1934 #if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
1935     f_print(fout, "\t\tif (!inlist) {          /* Remember proc call that needs sync site */\n");
1936     f_print(fout, "\t\t\tLOCK_UCLNT_CACHE;\n");
1937     f_print(fout, "\t\t\tcalls_needsync[synccount % SYNCCOUNT] = (int *)%s%s%s;\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1938     f_print(fout, "\t\t\tsynccount++;\n");
1939     f_print(fout, "\t\t\tUNLOCK_UCLNT_CACHE;\n");
1940     f_print(fout, "\t\t\tinlist = 1;\n");
1941     f_print(fout, "\t\t}\n");
1942 #endif
1943     f_print(fout, "\t\tif (!rcode) {           /* Remember the sync site - cmd successful */\n");
1944     f_print(fout, "\t\t\trxp = rx_PeerOf(aclient->conns[_ucount]);\n");
1945     f_print(fout, "\t\t\taclient->syncSite = rx_HostOf(rxp);\n");
1946     f_print(fout, "\t\t}\n");
1947     f_print(fout, "\t}\n");
1948     f_print(fout, "\tUNLOCK_UBIK_CLIENT(aclient);\n");
1949     f_print(fout, "\treturn rcode;\n}\n\n");
1950 }
1951
1952
1953 static int
1954 opcode_holes_exist(void)
1955 {
1956     int i;
1957
1958     for (i = lowest_opcode[PackageIndex]; i < highest_opcode[PackageIndex];
1959          i++) {
1960         if (!opcodenum_is_defined(i))
1961             return 1;
1962     }
1963     return 0;
1964 }
1965
1966
1967 void
1968 er_Proc_CodeGeneration(void)
1969 {
1970     int temp;
1971
1972     temp = PackageIndex;
1973     if (!combinepackages)
1974         PackageIndex = 0;
1975     for (; PackageIndex <= temp; PackageIndex++) {
1976         if (proc_defined[PackageIndex] == NULL)
1977             continue;
1978         if (combinepackages || opcode_holes_exist()) {
1979             er_HeadofOldStyleProc_setup();
1980             er_BodyofOldStyleProc_setup();
1981             er_TailofOldStyleProc_setup();
1982             er_HeadofOldStyleProc_setup2();
1983             er_BodyofOldStyleProc_setup2();
1984             er_TailofOldStyleProc_setup2();
1985         } else {
1986             er_ProcDeclExterns_setup();
1987             er_ProcProcsArray_setup();
1988             er_ProcMainBody_setup();
1989         }
1990     }
1991     PackageIndex = temp;
1992 }
1993
1994
1995 static void
1996 er_ProcDeclExterns_setup(void)
1997 {
1998     list *listp;
1999     definition *defp;
2000
2001     if ( !Sflag )
2002         return;
2003
2004     f_print(fout, "\n");
2005     for (listp = proc_defined[PackageIndex]; listp != NULL;
2006          listp = listp->next) {
2007         defp = (definition *) listp->val;
2008         if (defp->pc.proc_serverstub) {
2009             f_print(fout, "afs_int32 %s();\n", defp->pc.proc_serverstub);
2010         }
2011     }
2012 }
2013
2014
2015 static void
2016 er_ProcProcsArray_setup(void)
2017 {
2018     list *listp;
2019     definition *defp;
2020
2021     if ((listp = proc_defined[PackageIndex])) {
2022         defp = (definition *) listp->val;
2023         if ( cflag )  {
2024             f_print(fout, "\nstatic char *opnames%d[] = {\"%s%s\"",
2025                         PackageIndex, defp->pc.proc_prefix, defp->pc.proc_name);
2026         }
2027         else {
2028             if (defp->pc.proc_serverstub) {
2029                 f_print(fout, "\nstatic afs_int32 (*StubProcsArray%d[])() = {%s",
2030                         PackageIndex, defp->pc.proc_serverstub);
2031             } else {
2032                 f_print(fout,
2033                         "\nstatic afs_int32 (*StubProcsArray%d[])(struct rx_call *z_call, XDR *z_xdrs) = {_%s%s%s",
2034                         PackageIndex, prefix, defp->pc.proc_prefix,
2035                         ((definition *) listp->val)->pc.proc_name);
2036                 defp = (definition *) listp->val;
2037             }
2038         }
2039         listp = listp->next;
2040     }
2041     for (; listp != NULL; listp = listp->next) {
2042         defp = (definition *) listp->val;
2043         if ( cflag ) {
2044             f_print(fout, ", \"%s%s\"",defp->pc.proc_prefix,defp->pc.proc_name);
2045         }
2046         else {
2047             if (defp->pc.proc_serverstub) {
2048                 f_print(fout, ",%s", defp->pc.proc_serverstub);
2049             } else {
2050                 f_print(fout, ", _%s%s%s", prefix, defp->pc.proc_prefix,
2051                         defp->pc.proc_name);
2052             }
2053         }
2054     }
2055     f_print(fout, "};\n\n");
2056 }
2057
2058
2059 static void
2060 er_ProcMainBody_setup(void)
2061 {
2062     if ( cflag ) {
2063         f_print(fout, "char *%sTranslateOpCode(int op)\n{\n",
2064                 PackagePrefix[PackageIndex]);
2065         f_print(fout, "\tif (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\treturn NULL;\n",
2066                 PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2067         f_print(fout, "\treturn opnames%d[op - %sLOWEST_OPCODE];\n}\n",
2068                 PackageIndex, PackagePrefix[PackageIndex]);
2069         f_print(fout, "struct %sstats *%sOpCodeStats(int op)\n{\n",
2070                 PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2071         f_print(fout, "\tif (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\treturn NULL;\n",
2072                 PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2073         f_print(fout, "\treturn NULL;/*%d %s*/\n}\n",
2074                 PackageIndex, PackagePrefix[PackageIndex]);
2075
2076         return;
2077     }
2078     f_print(fout, "int %s%sExecuteRequest(struct rx_call *z_call)\n",
2079             prefix, PackagePrefix[PackageIndex]);
2080     f_print(fout, "{\n\tint op;\n");
2081     f_print(fout, "\tXDR z_xdrs;\n");
2082     f_print(fout, "\t" "afs_int32 z_result;\n\n");
2083     f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
2084     f_print(fout,
2085             "\tif (!xdr_int(&z_xdrs, &op))\n\t\tz_result = RXGEN_DECODE;\n");
2086     f_print(fout,
2087             "\telse if (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\tz_result = RXGEN_OPCODE;\n",
2088             PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2089     f_print(fout,
2090             "\telse\n\t\tz_result = (*StubProcsArray%d[op - %sLOWEST_OPCODE])(z_call, &z_xdrs);\n",
2091             PackageIndex, PackagePrefix[PackageIndex]);
2092     f_print(fout, "\treturn hton_syserr_conv(z_result);\n}\n");
2093 }
2094
2095 static void
2096 er_HeadofOldStyleProc_setup2(void)
2097 {
2098     if ( cflag ) {
2099         f_print(fout, "int %sOpCodeIndex(int op)\n{\n", (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2100         f_print(fout, "\tswitch (op) {\n");
2101     }
2102 }
2103
2104 static void
2105 er_HeadofOldStyleProc_setup(void)
2106 {
2107     if ( cflag ) {
2108         f_print(fout, "char *%sTranslateOpCode(int op)\n{\n",
2109             (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2110     }
2111     else {
2112         f_print(fout,
2113                 "\nint %s%sExecuteRequest (struct rx_call *z_call)\n",
2114                 prefix,
2115                 (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2116         f_print(fout, "{\n");
2117         f_print(fout, "\tint op;\n");
2118         f_print(fout, "\tXDR z_xdrs;\n");
2119         f_print(fout, "\t" "afs_int32 z_result;\n\n");
2120         f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
2121         f_print(fout, "\tz_result = RXGEN_DECODE;\n");
2122         f_print(fout, "\tif (!xdr_int(&z_xdrs, &op)) goto fail;\n");
2123     }
2124     f_print(fout, "\tswitch (op) {\n");
2125 }
2126
2127 static void
2128 er_BodyofOldStyleProc_setup(void)
2129 {
2130     list *listp;
2131
2132     if (combinepackages) {
2133         int temp = PackageIndex;
2134         for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
2135             for (listp = proc_defined[PackageIndex]; listp != NULL;
2136                  listp = listp->next)
2137                 proc_er_case((definition *) listp->val);
2138         }
2139         PackageIndex = temp;
2140     } else {
2141         for (listp = proc_defined[PackageIndex]; listp != NULL;
2142              listp = listp->next)
2143             proc_er_case((definition *) listp->val);
2144     }
2145 }
2146
2147
2148 static void
2149 proc_er_case(definition * defp)
2150 {
2151     if ( cflag ) {
2152         f_print(fout, "\t\tcase %d:", defp->pc.proc_opcodenum);
2153         f_print(fout, "\treturn \"%s%s\";\n",
2154                 defp->pc.proc_prefix, defp->pc.proc_name);
2155         return;
2156     }
2157     if (opcodesnotallowed[PackageIndex]) {
2158         f_print(fout, "\t\tcase %d:\n", defp->pc.proc_opcodenum);
2159     } else {
2160         f_print(fout, "\t\tcase %s:\n", defp->pc.proc_opcodename);
2161     }
2162     if (defp->pc.proc_serverstub) {
2163         f_print(fout, "\t\t\tz_result = %s(z_call, &z_xdrs);\n",
2164                 defp->pc.proc_serverstub);
2165     } else {
2166         f_print(fout, "\t\t\tz_result = _%s%s%s(z_call, &z_xdrs);\n", prefix,
2167                 defp->pc.proc_prefix, defp->pc.proc_name);
2168     }
2169     f_print(fout, "\t\t\tbreak;\n");
2170 }
2171
2172 static void
2173 proc_op_case(definition * defp)
2174 {
2175     f_print(fout, "\t\tcase %d:", defp->pc.proc_opcodenum);
2176     f_print(fout, "\treturn %d;\n",
2177             defp->statindex);
2178 }
2179
2180 static void
2181 er_BodyofOldStyleProc_setup2(void)
2182 {
2183     list *listp;
2184
2185     if (!cflag)
2186         return;
2187     if (combinepackages) {
2188         int temp = PackageIndex;
2189         for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
2190             for (listp = proc_defined[PackageIndex]; listp != NULL;
2191                  listp = listp->next)
2192                 proc_op_case((definition *) listp->val);
2193         }
2194         PackageIndex = temp;
2195     } else {
2196         for (listp = proc_defined[PackageIndex]; listp != NULL;
2197              listp = listp->next)
2198             proc_op_case((definition *) listp->val);
2199     }
2200 }
2201
2202 static void
2203 er_TailofOldStyleProc_setup2(void)
2204 {
2205     if ( cflag ) {
2206         f_print(fout, "\t\tdefault:\n");
2207         f_print(fout, "\t\t\treturn -1;\n\t}\n}\n");
2208     }
2209 }
2210
2211 static void
2212 er_TailofOldStyleProc_setup(void)
2213 {
2214     f_print(fout, "\t\tdefault:\n");
2215     if ( cflag ) {
2216         f_print(fout, "\t\t\treturn NULL;\n\t}\n}\n");
2217         return;
2218     }
2219     f_print(fout, "\t\t\tz_result = RXGEN_OPCODE;\n");
2220     f_print(fout, "\t\t\tbreak;\n\t}\n");
2221     f_print(fout, "fail:\n");
2222     f_print(fout, "\treturn z_result;\n}\n");
2223 }
2224
2225 static void
2226 h_ProcMainBody_setup(void)
2227 {
2228     f_print(fout,"\nextern int %s%sExecuteRequest(struct rx_call *);\n",
2229             prefix, PackagePrefix[PackageIndex]);
2230 }
2231
2232 static void
2233 h_HeadofOldStyleProc_setup(void)
2234 {
2235     char *pprefix = (combinepackages ? MasterPrefix :
2236                      PackagePrefix[PackageIndex]);
2237     f_print(fout,"\nstruct %sstats{\n\tint statsver;\n};", pprefix);
2238     f_print(fout,"\nextern int %s%sExecuteRequest(struct rx_call *);\n",
2239             prefix, pprefix);
2240     f_print(fout,"\nextern int %sOpCodeIndex(int op);\n", PackagePrefix[PackageIndex]);
2241 }
2242
2243 void
2244 h_Proc_CodeGeneration(void)
2245 {
2246     int temp;
2247
2248     temp = PackageIndex;
2249     if (!combinepackages)
2250         PackageIndex = 0;
2251     for (; PackageIndex <= temp; PackageIndex++) {
2252         if (combinepackages || opcode_holes_exist()) {
2253             h_HeadofOldStyleProc_setup();
2254         } else {
2255             h_ProcMainBody_setup();
2256         }
2257     }
2258     PackageIndex = temp;
2259 }
2260
2261 static void
2262 proc_h_case(definition * defp)
2263 {
2264     f_print(fout, "#define opcode_%s%s \t((afs_uint64)((%uLL << 32) + %sOpCodeIndex(%u)))\n",
2265             defp->pc.proc_prefix, defp->pc.proc_name, StatIndex,
2266             defp->pc.proc_prefix, defp->pc.proc_opcodenum);
2267 }
2268
2269 void
2270 h_opcode_stats_pkg(char *pprefix, int lowest, int highest, int nops,
2271                   int statfuncs, char *ptype, list *proclist)
2272 {
2273     list *listp;
2274
2275     if (!pprefix)
2276         return;
2277
2278     f_print(fout,
2279             "\n/* Opcode-related useful stats for %spackage: %s */\n",
2280             ptype, pprefix);
2281     f_print(fout, "#define %sLOWEST_OPCODE   %d\n", pprefix, lowest);
2282     f_print(fout, "#define %sHIGHEST_OPCODE     %d\n", pprefix, highest);
2283     f_print(fout, "#define %sNUMBER_OPCODES     %d\n\n", pprefix, nops);
2284
2285     for (listp = proclist; listp != NULL;
2286          listp = listp->next)
2287         proc_h_case((definition *) listp->val);
2288
2289     if (xflag) {
2290         f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n",
2291                 pprefix, statfuncs);
2292         f_print(fout, "AFS_RXGEN_EXPORT\n");
2293         f_print(fout, "extern const char *%sfunction_names[];\n\n",
2294                 pprefix);
2295     }
2296 }
2297
2298 void
2299 h_opcode_stats(void)
2300 {
2301     if (combinepackages) {
2302         h_opcode_stats_pkg(MasterPrefix, master_lowest_opcode, master_highest_opcode, master_no_of_opcodes, no_of_stat_funcs_header[0], "Master ", proc_defined[0]);
2303     } else {
2304         int i;
2305         for (i = 0; i <= PackageIndex; i++) {
2306             h_opcode_stats_pkg(PackagePrefix[i], lowest_opcode[i], highest_opcode[i], no_of_opcodes[i], no_of_stat_funcs_header[i], "", proc_defined[i]);
2307         }
2308     }
2309 }
2310
2311
2312 void
2313 generate_multi_macros(definition * defp)
2314 {
2315     char *startname = SplitStart, *endname = SplitEnd;
2316     proc1_list *plist;
2317     int numofparams;
2318     int first = 0;
2319
2320     if (!hflag)
2321         return;
2322     if (!Multi_Init) {
2323         Multi_Init = 1;
2324         f_print(fout, "\n#include <rx/rx_multi.h>");
2325     }
2326     f_print(fout, "\n#define multi_%s%s(", PackagePrefix[PackageIndex],
2327             defp->pc.proc_name);
2328     for (plist = defp->pc.plists; plist; plist = plist->next) {
2329         if (plist->component_kind == DEF_PARAM) {
2330             if (!first) {
2331                 first = 1;
2332                 f_print(fout, "%s", plist->pl.param_name);
2333             } else {
2334                 f_print(fout, ", %s", plist->pl.param_name);
2335             }
2336         }
2337     }
2338     f_print(fout, ") \\\n");
2339     if (!startname)
2340         startname = "Start";
2341     if (!endname)
2342         endname = "End";
2343     f_print(fout, "\tmulti_Body(%s%s%s(multi_call", startname,
2344             PackagePrefix[PackageIndex], defp->pc.proc_name);
2345     do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 0);
2346     for (plist = defp->pc.plists; plist; plist = plist->next) {
2347         if (plist->component_kind == DEF_PARAM)
2348             f_print(fout, ", %s", plist->pl.param_name);
2349     }
2350     do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 1);
2351     f_print(fout, "), %s%s%s(multi_call", endname,
2352             PackagePrefix[PackageIndex], defp->pc.proc_name);
2353     do_split(defp, IN, &numofparams, DEF_INPARAM, 0);
2354     for (plist = defp->pc.plists; plist; plist = plist->next) {
2355         if (plist->component_kind == DEF_PARAM) {
2356             f_print(fout, ", %s", plist->pl.param_name);
2357         }
2358     }
2359     do_split(defp, IN, &numofparams, DEF_INPARAM, 1);
2360     f_print(fout, "))\n\n");
2361 }
2362
2363
2364 int
2365 IsRxgenToken(token * tokp)
2366 {
2367     if (tokp->kind == TOK_PACKAGE || tokp->kind == TOK_PREFIX
2368         || tokp->kind == TOK_SPECIAL || tokp->kind == TOK_STARTINGOPCODE
2369         || tokp->kind == TOK_SPLITPREFIX || tokp->kind == TOK_PROC
2370         || tokp->kind == TOK_STATINDEX)
2371         return 1;
2372     return 0;
2373 }
2374
2375 int
2376 IsRxgenDefinition(definition * def)
2377 {
2378     if (def->def_kind == DEF_PACKAGE || def->def_kind == DEF_PREFIX
2379         || def->def_kind == DEF_SPECIAL || def->def_kind == DEF_STARTINGOPCODE
2380         || def->def_kind == DEF_SPLITPREFIX || def->def_kind == DEF_PROC)
2381         return 1;
2382     return 0;
2383 }