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