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