*** empty log message ***
[arla.git] / ydr / output.c
bloba1184244ac9a4b737d01f5d4cd3f0f67b49227e3
1 /*
2 * Copyright (c) 1995 - 2004 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 RCSID("$Id$");
37 #endif
39 #include <stdio.h>
40 #include <assert.h>
41 #include <string.h>
42 #include <list.h>
43 #include <ctype.h>
44 #include <err.h>
45 #include <roken.h>
46 #include "sym.h"
47 #include "output.h"
48 #include "types.h"
49 #include "lex.h"
52 * The name of the current package that we're generating stubs for
55 char *package = "";
58 * This is the list of packages so we know how to generate
59 * all Execute_package().
62 List *packagelist = NULL;
65 * Add this in front of the real functions implementing the server
66 * functions called.
69 char *prefix = "";
72 * File handles for the generated files themselves.
75 ydr_file headerfile,
76 clientfile,
77 serverfile,
78 clienthdrfile,
79 serverhdrfile,
80 ydrfile;
82 static long tmpcnt = 0;
85 * Function to convert error codes with.
86 * (the default, the empty string, conveniently means no conversion.)
89 char *error_function = "";
91 typedef enum { ENCODE_RX, DECODE_RX, ENCODE_MEM, DECODE_MEM } EncodeType;
93 typedef enum { CLIENT, SERVER } Side;
95 typedef enum { FDECL, VDECL } DeclType;
97 static void print_type (char *name, Type *type, enum argtype argtype,
98 DeclType decl, FILE *f);
99 static Bool print_entry (List *list, Listitem *item, void *i);
100 static void generate_hdr_struct (Symbol *s, FILE *f);
101 static void generate_hdr_enum (Symbol *s, FILE *f);
102 static void generate_hdr_const (Symbol *s, FILE *f);
103 static void generate_hdr_typedef (Symbol *s, FILE *f);
104 static int sizeof_type (Type *type);
105 static int sizeof_symbol (Symbol *);
106 static void encode_type (char *name, Type *type, FILE *f,
107 EncodeType encodetype, Side side);
108 static void display_type (char *where, char *name, Type *type, FILE *f);
109 static Bool encode_entry (List *list, Listitem *item, void *arg);
110 static void encode_struct (Symbol *s, char *name, FILE *f,
111 EncodeType encodetype, Side side);
112 static void encode_enum (Symbol *s, char *name, FILE *f,
113 EncodeType encodetype, Side side);
114 static void encode_typedef (Symbol *s, char *name, FILE *f,
115 EncodeType encodetype, Side side);
116 static void encode_symbol (Symbol *s, char *name, FILE *f,
117 EncodeType encodetype, Side side);
118 static void print_symbol (char *where, Symbol *s, char *name, FILE *f);
119 static void free_symbol (char *where, Symbol *s, char *name, FILE *f);
120 static void free_type (char *where, char *name, Type *type, FILE *f);
122 static void
123 print_type (char *name, Type *type, enum argtype argtype,
124 DeclType decl, FILE *f)
126 switch (type->type) {
127 case YDR_TCHAR :
128 fprintf (f, "char %s", name);
129 break;
130 case YDR_TUCHAR :
131 fprintf (f, "unsigned char %s", name);
132 break;
133 case YDR_TSHORT :
134 fprintf (f, "int16_t %s", name);
135 break;
136 case YDR_TUSHORT :
137 fprintf (f, "uint16_t %s", name);
138 break;
139 case YDR_TLONG :
140 fprintf (f, "int32_t %s", name);
141 break;
142 case YDR_TULONG :
143 fprintf (f, "uint32_t %s", name);
144 break;
145 case YDR_TLONGLONG:
146 fprintf (f, "int64_t %s", name);
147 break;
148 case YDR_TULONGLONG:
149 fprintf (f, "uint64_t %s", name);
150 break;
151 case YDR_TSTRING :
152 if (type->size && decl == VDECL)
153 fprintf (f, "char %s[%d]", name, type->size);
154 else if (argtype != TIN && type->size == 0)
155 fprintf (f, "char **%s", name);
156 else
157 fprintf (f, "char *%s", name);
158 break;
159 case YDR_TPOINTER :
161 char *tmp;
163 tmp = (char *)emalloc (strlen(name) + 2);
164 *tmp = '*';
165 strcpy (tmp+1, name);
166 print_type (tmp, type->subtype, argtype, decl, f);
167 free (tmp);
168 break;
170 case YDR_TUSERDEF :
171 if(type->symbol->type == YDR_TSTRUCT)
172 fprintf (f, "struct %s %s", type->symbol->name, name);
173 else
174 fprintf (f, "%s %s", type->symbol->name, name);
175 break;
176 case YDR_TVARRAY :
178 char *s;
180 s = (char *)emalloc (strlen (name) + 6);
181 *s = '*';
182 strcpy (s + 1, name);
183 strcat (s, "_len");
185 fprintf (f, "struct {\n");
186 if (type->indextype)
187 print_type ("len", type->indextype, argtype, decl, f);
188 else
189 fprintf (f, "unsigned %s", "len");
190 fprintf (f, ";\n");
191 strcpy(s + strlen(s) - 3, "val");
192 print_type ("*val", type->subtype, argtype, decl, f);
193 fprintf (f, ";\n} %s", name);
194 free(s);
195 break;
197 case YDR_TARRAY :
198 print_type (name, type->subtype, argtype, decl, f);
199 fprintf (f, "[ %d ]", type->size);
200 break;
201 case YDR_TOPAQUE :
202 fprintf (f, "char %s", name);
203 break;
204 default :
205 abort();
209 static Bool
210 print_entry (List *list, Listitem *item, void *i)
212 StructEntry *s = (StructEntry *)listdata (item);
213 FILE *f = (FILE *)i;
215 fprintf (f, " ");
216 print_type (s->name, s->type, TIN, VDECL, f);
217 fprintf (f, ";\n");
218 return FALSE;
222 * Return the size of this type in bytes.
223 * In the case of a variable-sized type, return -1 (unknown) or
224 * the negative maxsize.
227 static Bool
228 sizeof_struct_iter (List *list, Listitem *item, void *arg)
230 int *tot = (int *)arg;
231 StructEntry *s = (StructEntry *)listdata (item);
232 int sz;
234 sz = sizeof_type (s->type);
235 if (sz == -1) {
236 *tot = -1;
237 return TRUE;
238 } else if (sz < 0 || *tot < 0) {
239 *tot = -1 * (abs(*tot) + abs(sz));
240 return FALSE;
241 } else {
242 *tot = *tot + sz;
243 return FALSE;
247 static int
248 sizeof_struct (Symbol *s)
250 int tot = 0;
252 if (s->u.list)
253 listiter (s->u.list, sizeof_struct_iter, &tot);
254 return tot;
257 static int
258 sizeof_type (Type *t)
260 switch (t->type) {
261 case YDR_TCHAR :
262 case YDR_TUCHAR :
263 case YDR_TSHORT :
264 case YDR_TUSHORT :
265 case YDR_TLONG :
266 case YDR_TULONG :
267 return 4;
268 case YDR_TLONGLONG :
269 case YDR_TULONGLONG :
270 return 8;
271 case YDR_TSTRING :
272 if (t->size == 0)
273 return -1;
274 else
275 return t->size;
276 case YDR_TOPAQUE :
277 return 1;
278 case YDR_TUSERDEF :
279 return sizeof_symbol (t->symbol);
280 case YDR_TARRAY :
282 int sz = sizeof_type (t->subtype);
284 if (sz == -1)
285 return -1;
286 return t->size * sz;
288 case YDR_TVARRAY :
290 int sz;
291 if (t->size == 0)
292 return -1;
293 sz = sizeof_type(t->subtype);
294 if (sz == -1)
295 return -1;
296 return -1 * (t->size * abs(sz) + 4); /* 4 is size of the var part */
298 case YDR_TPOINTER :
299 return -1;
300 default :
301 abort ();
305 static int
306 sizeof_symbol (Symbol *s)
308 switch (s->type) {
309 case YDR_TUNDEFINED :
310 fprintf (stderr, "What is %s doing in sizeof_type?", s->name);
311 return 0;
312 case YDR_TSTRUCT :
313 return sizeof_struct (s);
314 case YDR_TENUM :
315 return 4;
316 case YDR_TCONST :
317 return 0;
318 case YDR_TENUMVAL :
319 return 0;
320 case YDR_TTYPEDEF :
321 return sizeof_type (s->u.type);
322 default :
323 abort ();
328 * Generate header contents
331 static void
332 generate_hdr_struct (Symbol *s, FILE *f)
334 fprintf (f, "struct %s {\n", s->name);
335 if (s->u.list)
336 listiter (s->u.list, print_entry, f);
337 fprintf (f, "};\ntypedef struct %s %s;\n", s->name, s->name);
340 static void
341 generate_hdr_enum (Symbol *s, FILE *f)
343 Listitem *item;
344 Symbol *e;
346 fprintf (f, "enum %s {\n", s->name);
347 if (s->u.list) {
348 for (item = listhead (s->u.list);
349 item && listnext (s->u.list, item);
350 item = listnext (s->u.list, item))
352 e = (Symbol *)listdata (item);
354 fprintf (f, " %s = %d,\n", e->name, e->u.val);
356 e = (Symbol *)listdata (item);
357 fprintf (f, " %s = %d\n};\n", e->name, e->u.val);
359 fprintf (f, "typedef enum %s %s;\n",
360 s->name, s->name);
363 static void
364 generate_hdr_const (Symbol *s, FILE *f)
366 fprintf (f, "#define %s %d\n", s->name, s->u.val);
369 static void
370 generate_hdr_typedef (Symbol *s, FILE *f)
372 fprintf (f, "typedef ");
373 print_type (s->name, s->u.type, TIN, VDECL, f);
374 fprintf (f, ";\n");
377 void
378 generate_sizeof (Symbol *s, FILE *f)
380 int sz;
382 if (s->type == YDR_TCONST)
383 return;
385 sz = sizeof_symbol (s);
386 if (sz == -1) {
387 ; /* the size is unknown */
388 } else {
389 char *name, *ms = "";
390 if (sz < 0)
391 ms = "MAX_";
393 name = estrdup (s->name);
394 fprintf (f, "#define %s_%sSIZE %d\n", strupr (name), ms, abs(sz));
395 free (name);
399 void
400 generate_header (Symbol *s, FILE *f)
402 switch (s->type) {
403 case YDR_TUNDEFINED :
404 fprintf (f, "What is %s doing in generate_header?", s->name);
405 break;
406 case YDR_TSTRUCT :
407 generate_hdr_struct (s, f);
408 break;
409 case YDR_TENUM :
410 generate_hdr_enum (s, f);
411 break;
412 case YDR_TCONST :
413 generate_hdr_const (s, f);
414 break;
415 case YDR_TENUMVAL :
416 break;
417 case YDR_TTYPEDEF :
418 generate_hdr_typedef (s, f);
419 default :
420 break;
422 putc ('\n', f);
426 * Generate functions for encoding and decoding.
429 static char *
430 encode_function (Type *type, EncodeType encodetype)
432 if (type->flags & TASIS)
433 return "";
434 else if (encodetype == ENCODE_RX || encodetype == ENCODE_MEM) {
435 switch (type->type) {
436 case YDR_TLONGLONG:
437 case YDR_TULONGLONG:
438 return "htobe64";
439 default:
440 return "htonl";
441 break;
443 } else if (encodetype == DECODE_RX || encodetype == DECODE_MEM) {
444 switch (type->type) {
445 case YDR_TLONGLONG:
446 case YDR_TULONGLONG:
447 return "be64toh";
448 default:
449 return "ntohl";
450 break;
452 } else
453 abort();
457 * encode/decode long/longlong
460 static void
461 encode_int_type (char *name, char *tname, Type *type,
462 FILE *f, EncodeType encodetype)
464 switch (encodetype) {
465 case ENCODE_RX :
466 fprintf (f, "{ u%s u;\n"
467 "u = %s (%s);\n"
468 "if(rx_Write(call, &u, sizeof(u)) != sizeof(u))\n"
469 "goto fail;\n"
470 "}\n",
471 tname,
472 encode_function (type, encodetype),
473 name);
474 break;
475 case DECODE_RX :
476 fprintf (f, "{ u%s u;\n"
477 "if(rx_Read(call, &u, sizeof(u)) != sizeof(u))\n"
478 "goto fail;\n"
479 "%s = %s (u);\n"
480 "}\n", tname, name,
481 encode_function (type, encodetype));
482 break;
483 case ENCODE_MEM :
484 fprintf (f, "{ %s tmp = %s(%s); "
485 "if (*total_len < sizeof(tmp)) goto fail;\n"
486 "memcpy (ptr, (char*)&tmp, sizeof(tmp)); "
487 "ptr += sizeof(tmp); "
488 "*total_len -= sizeof(tmp);}\n",
489 tname,
490 encode_function (type, encodetype),
491 name);
492 break;
493 case DECODE_MEM :
494 fprintf (f, "{ %s tmp; "
495 "if (*total_len < sizeof(tmp)) goto fail;"
496 "memcpy ((char*)&tmp, ptr, sizeof(tmp)); "
497 "%s = %s(tmp); "
498 "ptr += sizeof(tmp); "
499 "*total_len -= sizeof(tmp);}\n",
500 tname,
501 name,
502 encode_function (type, encodetype));
503 break;
504 default :
505 abort ();
509 static void
510 encode_long (char *name, Type *type, FILE *f, EncodeType encodetype)
512 encode_int_type(name, "int32_t", type, f, encodetype);
515 static void
516 encode_longlong (char *name, Type *type, FILE *f, EncodeType encodetype)
518 encode_int_type(name, "int64_t", type, f, encodetype);
522 * print long
525 static void
526 print_long (char *where, char *name, Type *type, FILE *f)
528 fprintf (f, "printf(\" %s = %%d\", %s%s);", name, where, name);
532 * print longlong
535 static void
536 print_longlong (char *where, char *name, Type *type, FILE *f)
538 fprintf (f, "printf(\" %s = %%d\", (int32_t)%s%s);", name, where, name);
545 static void
546 gen_check_overflow(Type *indextype, Type *subtype, char *num, FILE *f)
548 /* Check if we will overflow */
549 fprintf(f, "{\n");
550 print_type ("overI", indextype, TIN, VDECL, f);
551 fprintf(f, ";\n");
552 fprintf(f, "overI = ((");
553 print_type ("", indextype, TIN, VDECL, f);
554 fprintf(f, ")~((");
555 print_type ("", indextype, TIN, VDECL, f);
556 fprintf(f, ")0) >> 1) / sizeof(");
557 print_type ("", subtype, TIN, VDECL, f);
558 fprintf(f, ");\n");
559 fprintf(f, "if (overI < %s) goto fail;\n", num);
560 fprintf(f, "}\n");
567 static void __attribute__ ((unused))
568 encode_char (char *name, Type *type, FILE *f, EncodeType encodetype)
570 switch (encodetype) {
571 case ENCODE_RX :
572 fprintf (f,
573 "if(rx_Write(call, &%s, sizeof(%s)) != sizeof(%s))\n"
574 "goto fail;\n",
575 name, name, name);
576 break;
577 case DECODE_RX :
578 fprintf (f,
579 "if(rx_Read(call, &%s, sizeof(%s)) != sizeof(%s))\n"
580 "goto fail;\n",
581 name, name, name);
582 break;
583 case ENCODE_MEM :
584 fprintf (f, "{ if (*total_len < sizeof(char)) goto fail;\n"
585 "*((char *)ptr) = %s; "
586 "ptr += sizeof(char); *total_len -= sizeof(char);}\n",
587 name);
588 break;
589 case DECODE_MEM :
590 fprintf (f, "{ if (*total_len < sizeof(char)) goto fail;\n"
591 "%s = *((char *)ptr); "
592 "ptr += sizeof(char); *total_len -= sizeof(char);}\n",
593 name);
594 break;
595 default :
596 abort ();
600 static void __attribute__ ((unused))
601 encode_short (char *name, Type *type, FILE *f, EncodeType encodetype)
603 switch (encodetype) {
604 case ENCODE_RX :
605 fprintf (f, "{ int16_t u;\n"
606 "u = %s (%s);\n"
607 "if(rx_Write(call, &u, sizeof(u)) != sizeof(u))\n"
608 "goto fail;\n"
609 "}\n",
610 encode_function (type, encodetype),
611 name);
612 break;
613 case DECODE_RX :
614 fprintf (f, "{ int16_t u;\n"
615 "if(rx_Read(call, &u, sizeof(u)) != sizeof(u))\n"
616 "goto fail;\n"
617 "%s = %s (u);\n"
618 "}\n", name,
619 encode_function (type, encodetype));
620 break;
621 case ENCODE_MEM :
622 fprintf (f, "{ in16_t tmp = %s(%s); "
623 "if (*total_len < sizeof(int16_t)) goto fail;\n"
624 "memcpy (ptr, (char*)&tmp, sizeof(int16_t)); "
625 "ptr += sizeof(int16_t); "
626 "*total_len -= sizeof(int16_t);}\n",
627 encode_function (type, encodetype),
628 name);
629 break;
630 case DECODE_MEM :
631 fprintf (f, "{ int16_t tmp; "
632 "if (*total_len < sizeof(int16_t)) goto fail;\n"
633 "memcpy ((char *)&tmp, ptr, sizeof(int16_t)); "
634 "%s = %s(tmp); "
635 "ptr += sizeof(int16_t); "
636 "*total_len -= sizeof(int16_t); }\n",
637 name,
638 encode_function (type, encodetype));
639 break;
640 default :
641 abort ();
646 * encode/decode TSTRING
649 static void
650 encode_string (char *name, Type *type, FILE *f, EncodeType encodetype,
651 Side side)
653 Type lentype = {YDR_TULONG};
654 char *nname;
656 asprintf (&nname, "(%s%s)",
657 ((type->size == 0) && side == CLIENT
658 && (encodetype == ENCODE_RX || encodetype == ENCODE_MEM))
659 ? "*" : "", name);
661 switch (encodetype) {
662 case ENCODE_RX :
663 fprintf (f, "{ unsigned len;\n"
664 "char zero[4] = {0, 0, 0, 0};\n"
665 "unsigned padlen;\n"
666 "len = strlen(%s);\n"
667 "padlen = (4 - (len %% 4)) %% 4;\n",
668 name);
669 encode_type ("len", &lentype, f, encodetype, side);
670 fprintf (f,
671 "if(rx_Write(call, %s, len) != len)\n"
672 "goto fail;\n"
673 "if(rx_Write(call, zero, padlen) != padlen)\n"
674 "goto fail;\n"
675 "}\n", name);
676 break;
677 case DECODE_RX :
678 fprintf (f, "{ unsigned len;\n"
679 "unsigned padlen;\n"
680 "char zero[4] = {0, 0, 0, 0};\n");
681 encode_type ("len", &lentype, f, encodetype, side);
682 if (type->size != 0) {
683 fprintf (f,
684 "if (len >= %u) {\n"
685 "rx_SetCallError(call, ENOMEM);\n"
686 "goto fail;\n"
687 "}\n",
688 type->size);
689 } else {
690 fprintf(f, "if (len == (uint32_t) -1) {\n"
691 "rx_SetCallError(call, ENOMEM);\n"
692 "goto fail;\n"
693 "}\n");
694 fprintf(f, "%s = malloc(len + 1);\n"
695 "if (%s == NULL) {\n"
696 "rx_SetCallError(call, ENOMEM);\n"
697 "goto fail;\n"
698 "}\n",
699 nname, nname);
702 fprintf (f,
703 "if(rx_Read(call, %s, len) != len)\n"
704 "goto fail;\n"
705 "%s[len] = '\\0';\n"
706 "padlen = (4 - (len %% 4)) %% 4;\n"
707 "if(rx_Read(call, zero, padlen) != padlen)\n"
708 "goto fail;\n"
709 "}\n", nname, nname);
710 break;
711 case ENCODE_MEM :
712 fprintf (f,
713 "{\nunsigned len = strlen(%s);\n"
714 "if (*total_len < len) goto fail;\n"
715 "*total_len -= len;\n",
716 name);
717 encode_type ("len", &lentype, f, encodetype, side);
718 fprintf (f, "strncpy (ptr, %s, len);\n", name);
719 fprintf (f, "ptr += len + (4 - (len %% 4)) %% 4;\n"
720 "*total_len -= len + (4 - (len %% 4)) %% 4;\n}\n");
721 break;
722 case DECODE_MEM :
723 fprintf (f,
724 "{\nunsigned len;\n");
725 encode_type ("len", &lentype, f, encodetype, side);
726 fprintf (f,
727 "if (*total_len < len) goto fail;\n"
728 "*total_len -= len;\n");
729 if (type->size != 0) {
730 fprintf (f,
731 "if(len >= %u)\n"
732 "goto fail;\n",
733 type->size);
734 } else {
735 fprintf(f, "if (len == (uint32_t) -1) {\n"
736 "goto fail;\n"
737 "}\n");
738 fprintf(f, "%s = malloc(len + 1);\n"
739 "if (%s == NULL) {\n"
740 "goto fail;\n"
741 "}\n",
742 nname, nname);
744 fprintf (f,
745 "memcpy (%s, ptr, len);\n"
746 "%s[len] = '\\0';\n"
747 "ptr += len + (4 - (len %% 4)) %% 4;\n"
748 "*total_len -= len + (4 - (len %% 4)) %% 4;\n}\n",
749 nname, nname);
750 break;
751 default :
752 abort ();
754 free (nname);
758 * print TSTRING
761 static void
762 print_string (char *where, char *name, Type *type, FILE *f)
764 fprintf (f, "/* printing TSTRING %s%s */\n", where, name);
765 fprintf (f, "printf(\" %s = %%s\", %s%s);", name, where, name);
768 #if 0
770 * free TSTRING
773 static void
774 free_string (char *where, char *name, Type *type, FILE *f)
776 fprintf (f, "free(%s%s);\n", where, name);
778 #endif
781 * encode/decode TARRAY
784 static void
785 encode_array (char *name, Type *type, FILE *f, EncodeType encodetype,
786 Side side)
788 if (type->subtype->type == YDR_TOPAQUE) {
789 if (type->size % 4 != 0)
790 error_message (1, "Opaque array should be"
791 "multiple of 4");
792 switch (encodetype) {
793 case ENCODE_RX :
794 fprintf (f,
795 "if(rx_Write (call, %s, %d) != %d)\n"
796 "goto fail;",
797 name, type->size, type->size);
798 break;
799 case DECODE_RX :
800 fprintf (f,
801 "if(rx_Read (call, %s, %d) != %d)\n"
802 "goto fail;",
803 name, type->size, type->size);
804 break;
805 case ENCODE_MEM :
806 fprintf (f, "if (*total_len < %u) goto fail;\n"
807 "memcpy (ptr, %s, %u);\n", type->size, name,
808 type->size);
809 fprintf (f, "ptr += %u; *total_len -= %u;\n",
810 type->size, type->size);
811 break;
812 case DECODE_MEM :
813 fprintf (f, "if (*total_len < %u) goto fail;"
814 "memcpy (%s, ptr, %u);\n", type->size, name,
815 type->size);
816 fprintf (f, "ptr += %u; *total_len -= %u;\n",
817 type->size, type->size);
818 break;
819 default :
820 abort ();
822 } else {
823 char tmp[256];
825 fprintf (f, "{\nint i%lu;\nfor(i%lu = 0; i%lu < %u;"
826 "++i%lu){\n", tmpcnt, tmpcnt, tmpcnt, type->size,tmpcnt);
827 snprintf(tmp, sizeof(tmp)-1, "%s[i%lu]", name, tmpcnt);
828 tmpcnt++;
829 if (type->flags)
830 type->subtype->flags |= type->flags;
831 encode_type (tmp , type->subtype, f, encodetype, side);
832 tmpcnt--;
833 fprintf (f, "}\n}\n");
838 * print ARRAY
841 static void
842 print_array (char *where, char *name, Type *type, FILE *f)
844 fprintf (f, "{\nunsigned int i%lu;\n", tmpcnt);
846 fprintf (f, "/* printing ARRAY %s%s */\n", where, name);
848 if (type->subtype->type == YDR_TOPAQUE) {
849 if (type->size % 4 != 0)
850 error_message (1, "print_array: Opaque array should be"
851 "multiple of 4");
853 fprintf (f, "char *ptr = %s%s;\n", where, name);
854 fprintf (f, "printf(\"0x\");");
855 fprintf (f, "for (i%lu = 0; i%lu < %d; ++i%lu)\n"
856 "printf(\"%%x\", ptr[i%lu]);",
857 tmpcnt, tmpcnt,
858 type->size, tmpcnt, tmpcnt);
860 } else {
861 char *ptr;
862 fprintf (f, "for (i%lu = 0; i%lu < %d; ++i%lu) {\n",
863 tmpcnt, tmpcnt, type->size, tmpcnt);
864 asprintf(&ptr, "%s%s[i%ld]", where, name, tmpcnt);
865 tmpcnt++;
866 display_type (ptr, "", type->subtype, f);
867 tmpcnt--;
868 free(ptr);
869 fprintf (f, "\nif (i%lu != %d - 1) printf(\",\");\n",
870 tmpcnt, type->size);
872 fprintf (f, "}\n");
874 fprintf (f, "}\n");
878 * free TARRAY
881 static void
882 free_array (char *where, char *name, Type *type, FILE *f)
884 if (type->subtype->type == YDR_TOPAQUE) {
885 ; /* nothing */
886 } else {
887 char tmp[256];
889 fprintf (f, "{\nint i%lu;\nfor(i%lu = 0; i%lu < %u;"
890 "++i%lu){\n", tmpcnt, tmpcnt, tmpcnt, type->size,tmpcnt);
891 snprintf(tmp, sizeof(tmp)-1, "%s[i%lu]", name, tmpcnt);
892 tmpcnt++;
893 if (type->flags)
894 type->subtype->flags |= type->flags;
895 free_type (tmp, "", type->subtype, f);
896 tmpcnt--;
897 fprintf (f, "}\n}\n");
902 * encode/decode TVARRAY
905 static void
906 encode_varray (char *name, Type *type, FILE *f, EncodeType encodetype,
907 Side side)
909 char tmp[256];
910 Type lentype = {YDR_TULONG};
911 Type *indextype;
913 strcpy (tmp, name);
914 strcat (tmp, ".len");
916 indextype = type->indextype ? type->indextype : &lentype;
918 encode_type (tmp, indextype, f, encodetype, side);
919 if (encodetype == DECODE_MEM || encodetype == DECODE_RX) {
920 if (type->size != 0)
921 fprintf (f, "if (%s > %d) goto fail;\n", tmp, type->size);
922 if (encodetype == DECODE_MEM) {
923 fprintf (f, "if ((%s * sizeof(", tmp);
924 print_type ("", type->subtype, TIN, VDECL, f);
925 fprintf (f, ")) > *total_len) goto fail;\n");
928 gen_check_overflow(indextype, type->subtype, tmp, f);
929 if (encodetype == DECODE_MEM || encodetype == DECODE_RX) {
930 fprintf (f, "%s.val = (", name);
931 print_type ("*", type->subtype, TIN, VDECL, f);
932 fprintf (f, ")malloc(sizeof(");
933 print_type ("", type->subtype, TIN, VDECL, f);
934 fprintf (f, ") * %s);\n", tmp);
935 fprintf (f, "if (%s.val == NULL) goto fail;\n", name);
937 if (type->subtype->type == YDR_TOPAQUE) {
938 switch (encodetype) {
939 case ENCODE_RX :
940 fprintf (f, "{\n"
941 "char zero[4] = {0, 0, 0, 0};\n"
942 "unsigned padlen = (4 - (%s %% 4)) %% 4;\n"
943 "if(rx_Write (call, %s.val, %s) != %s)\n"
944 "goto fail;\n"
945 "if(rx_Write (call, zero, padlen) != padlen)\n"
946 "goto fail;\n"
947 "}\n",
948 tmp, name, tmp, tmp);
949 break;
950 case DECODE_RX :
951 fprintf (f, "{\n"
952 "char zero[4] = {0, 0, 0, 0};\n"
953 "unsigned padlen = (4 - (%s %% 4)) %% 4;\n"
954 "if(rx_Read (call, %s.val, %s) != %s)\n"
955 "goto fail;\n"
956 "if(rx_Read (call, zero, padlen) != padlen)\n"
957 "goto fail;\n"
958 "}\n",
959 tmp, name, tmp, tmp);
960 break;
961 case ENCODE_MEM :
962 fprintf (f, "{\n"
963 "char zero[4] = {0, 0, 0, 0};\n"
964 "size_t sz = %s + (4 - (%s %% 4)) %% 4;\n"
965 "if (*total_len < sz) goto fail;\n"
966 "memcpy (ptr, %s.val, %s);\n"
967 "memcpy (ptr + %s, zero, (4 - (%s %% 4)) %% 4);\n"
968 "ptr += sz; *total_len -= sz;\n"
969 "}\n",
970 tmp, tmp, name, tmp, tmp, tmp);
971 break;
972 case DECODE_MEM :
973 fprintf (f,
974 "{\n"
975 "memcpy (%s.val, ptr, %s);\n"
976 "ptr += %s + (4 - (%s %% 4)) %% 4;\n"
977 "}\n",
978 name, tmp, tmp, tmp);
979 break;
980 default :
981 abort ();
983 } else {
984 fprintf (f, "{\nint i%lu;\nfor(i%lu = 0; i%lu < %s;"
985 "++i%lu){\n", tmpcnt, tmpcnt, tmpcnt, tmp, tmpcnt);
986 snprintf(tmp, sizeof(tmp)-1, "%s.val[i%lu]", name, tmpcnt);
987 tmpcnt++;
988 if (type->flags)
989 type->subtype->flags |= type->flags;
990 encode_type (tmp , type->subtype, f, encodetype, side);
991 tmpcnt--;
992 fprintf (f, "}\n}\n");
997 * print TVARRAY
1000 static void
1001 print_varray (char *where, char *name, Type *type, FILE *f)
1003 fprintf (f, "{\nunsigned int i%lu;\n", tmpcnt);
1005 fprintf (f, "/* printing YDR_TVARRAY %s%s */\n", where, name);
1007 if (type->subtype->type == YDR_TOPAQUE) {
1008 fprintf (f, "char *ptr = %s%s.val;\n", where, name);
1009 fprintf (f, "printf(\"0x\");");
1010 fprintf (f, "for (i%lu = 0; i%lu < %s%s.len; ++i%lu)\n"
1011 "printf(\"%%x\", ptr[i%lu]);",
1012 tmpcnt, tmpcnt,
1013 where, name, tmpcnt, tmpcnt);
1014 } else {
1015 char *ptr;
1016 fprintf (f, "for (i%lu = 0; i%lu < %s%s.len; ++i%lu) {\n",
1017 tmpcnt, tmpcnt, where, name, tmpcnt);
1018 asprintf(&ptr, "%s%s.val[i%ld]", where, name, tmpcnt);
1019 tmpcnt++;
1020 display_type (ptr, "", type->subtype, f);
1021 tmpcnt--;
1022 free(ptr);
1023 fprintf (f, "\nif (i%lu != %s%s.len - 1) printf(\",\");\n",
1024 tmpcnt, where, name);
1026 fprintf (f, "}\n");
1028 fprintf (f, "}\n");
1032 * free TVARRAY
1035 static void
1036 free_varray (char *where, char *name, Type *type, FILE *f)
1038 if (type->subtype->type != YDR_TOPAQUE) {
1039 char *ptr;
1040 fprintf (f, "{\n"
1041 "unsigned int i%lu;\n", tmpcnt);
1042 fprintf (f, "for (i%lu = 0; i%lu < %s%s.len; ++i%lu) {\n",
1043 tmpcnt, tmpcnt, where, name, tmpcnt);
1044 asprintf(&ptr, "%s%s.val[i%ld]", where, name, tmpcnt);
1045 tmpcnt++;
1046 free_type (ptr, "", type->subtype, f);
1047 tmpcnt--;
1048 free(ptr);
1049 fprintf (f, "}\n");
1050 fprintf (f, "}\n");
1052 fprintf (f, "free((%s%s).val);\n", where, name);
1056 * encode/decode pointer
1059 static void
1060 encode_pointer (char *name, Type *type, FILE *f, EncodeType encodetype,
1061 Side side)
1063 Type booltype = {YDR_TULONG};
1064 char tmp[256];
1066 sprintf (tmp, "*(%s)", name);
1068 switch(encodetype) {
1069 case ENCODE_RX:
1070 abort ();
1071 case ENCODE_MEM:
1072 fprintf(f, "{ unsigned bool;\n"
1073 "bool = %s != NULL;\n", name);
1074 encode_type ("bool", &booltype, f, encodetype, side);
1075 fprintf (f, "if(%s) {\n", name);
1076 encode_type (tmp, type->subtype, f, encodetype, side);
1077 fprintf (f, "}\n"
1078 "}\n");
1079 break;
1080 case DECODE_RX:
1081 abort();
1082 case DECODE_MEM:
1083 fprintf(f, "{ unsigned bool;\n");
1084 encode_type ("bool", &booltype, f, encodetype, side);
1085 fprintf (f, "if(bool) {\n");
1086 fprintf (f, "%s = malloc(sizeof(%s));\n"
1087 "if (%s == NULL) return ENOMEM;\n",
1088 name, tmp, name);
1089 encode_type (tmp, type->subtype, f, encodetype, side);
1090 fprintf (f, "} else {\n"
1091 "%s = NULL;\n"
1092 "}\n"
1093 "}\n", name);
1094 break;
1095 default:
1096 abort ();
1101 * free pointer
1104 static void
1105 free_pointer (char *where, char *name, Type *type, FILE *f)
1107 char *tmp;
1109 asprintf (&tmp, "*(%s%s)", where, name);
1110 fprintf (f, "if(%s%s)", where, name);
1111 free_type(tmp, "", type->subtype, f);
1112 free(tmp);
1116 * encode type
1119 static void
1120 encode_type (char *name, Type *type, FILE *f, EncodeType encodetype,
1121 Side side)
1123 switch (type->type) {
1124 case YDR_TCHAR :
1125 case YDR_TUCHAR :
1126 case YDR_TSHORT :
1127 case YDR_TUSHORT :
1128 case YDR_TLONG :
1129 case YDR_TULONG :
1130 encode_long (name, type, f, encodetype);
1131 break;
1132 case YDR_TLONGLONG :
1133 case YDR_TULONGLONG :
1134 encode_longlong (name, type, f, encodetype);
1135 break;
1136 case YDR_TSTRING :
1137 encode_string (name, type, f, encodetype, side);
1138 break;
1139 case YDR_TOPAQUE :
1140 error_message (1,
1141 "Type opaque only allowed as part of an array");
1142 break;
1143 case YDR_TUSERDEF :
1144 encode_symbol (type->symbol, name, f, encodetype, side);
1145 break;
1146 case YDR_TARRAY :
1147 encode_array (name, type, f, encodetype, side);
1148 break;
1149 case YDR_TVARRAY :
1150 encode_varray (name, type, f, encodetype, side);
1151 break;
1152 case YDR_TPOINTER :
1153 encode_pointer (name, type, f, encodetype, side);
1154 break;
1155 default :
1156 abort();
1161 * print type
1164 static void
1165 display_type (char *where, char *name, Type *type, FILE *f)
1167 assert (where);
1169 switch (type->type) {
1170 case YDR_TCHAR :
1171 case YDR_TUCHAR :
1172 case YDR_TSHORT :
1173 case YDR_TUSHORT :
1174 case YDR_TLONG :
1175 case YDR_TULONG :
1176 print_long (where, name, type, f);
1177 break;
1178 case YDR_TLONGLONG :
1179 case YDR_TULONGLONG :
1180 print_longlong (where, name, type, f);
1181 break;
1182 case YDR_TSTRING :
1183 print_string (where, name, type, f);
1184 break;
1185 case YDR_TOPAQUE :
1186 fprintf (f, "printf(\"printing TOPAQUE\\n\");");
1187 break;
1188 case YDR_TUSERDEF :
1189 print_symbol (where, type->symbol, name, f);
1190 break;
1191 case YDR_TARRAY :
1192 print_array (where, name, type, f);
1193 break;
1194 case YDR_TVARRAY :
1195 print_varray (where, name, type, f);
1196 break;
1197 case YDR_TPOINTER :
1198 fprintf (f, "printf(\"printing TPOINTER\\n\");");
1199 break;
1200 default :
1201 abort();
1206 * free type
1209 static void
1210 free_type (char *where, char *name, Type *type, FILE *f)
1212 switch (type->type) {
1213 case YDR_TCHAR :
1214 case YDR_TUCHAR :
1215 case YDR_TSHORT :
1216 case YDR_TUSHORT :
1217 case YDR_TLONG :
1218 case YDR_TULONG :
1219 case YDR_TLONGLONG :
1220 case YDR_TULONGLONG :
1221 break;
1222 case YDR_TSTRING :
1223 #if 0
1224 free_string (where, name, type, f);
1225 #endif
1226 break;
1227 case YDR_TOPAQUE :
1228 break;
1229 case YDR_TUSERDEF :
1230 free_symbol (where, type->symbol, name, f);
1231 break;
1232 case YDR_TARRAY :
1233 free_array (where, name, type, f);
1234 break;
1235 case YDR_TVARRAY :
1236 free_varray (where, name, type, f);
1237 break;
1238 case YDR_TPOINTER :
1239 free_pointer (where, name, type, f);
1240 break;
1241 default :
1242 abort();
1246 struct context {
1247 char *name;
1248 FILE *f;
1249 Symbol *symbol;
1250 EncodeType encodetype;
1251 Side side;
1255 * helpfunction for encode_struct
1258 static Bool
1259 encode_entry (List *list, Listitem *item, void *arg)
1261 StructEntry *s = (StructEntry *)listdata (item);
1262 char tmp[256];
1263 struct context *context = (struct context *)arg;
1265 strcpy (tmp, context->name);
1266 strcat (tmp, ".");
1267 strcat (tmp, s->name);
1269 if (s->type->type == YDR_TPOINTER
1270 && s->type->subtype->type == YDR_TUSERDEF
1271 && s->type->subtype->symbol->type == YDR_TSTRUCT
1272 && strcmp(s->type->subtype->symbol->name,
1273 context->symbol->name) == 0) {
1274 fprintf (context->f,
1275 "ptr = ydr_encode_%s(%s, ptr);\n",
1276 context->symbol->name,
1277 tmp);
1278 } else {
1279 encode_type (tmp, s->type, context->f, context->encodetype,
1280 context->side);
1283 return FALSE;
1287 * encode/decode TSTRUCT
1290 static void
1291 encode_struct (Symbol *s, char *name, FILE *f, EncodeType encodetype,
1292 Side side)
1294 struct context context;
1296 context.name = name;
1297 context.symbol = s;
1298 context.f = f;
1299 context.encodetype = encodetype;
1300 context.side = side;
1302 if (s->u.list)
1303 listiter (s->u.list, encode_entry, (void *)&context);
1307 * help function for print_struct
1310 struct printcontext {
1311 char *where;
1312 char *name;
1313 FILE *f;
1314 Symbol *symbol;
1317 static Bool
1318 print_structentry (List *list, Listitem *item, void *arg)
1320 StructEntry *s = (StructEntry *)listdata (item);
1321 struct printcontext *context = (struct printcontext *)arg;
1323 char *tmp;
1324 char *tmp2;
1326 asprintf(&tmp, ".%s", s->name);
1327 asprintf(&tmp2, "%s%s", context->where, context->name);
1329 if (s->type->type == YDR_TPOINTER
1330 && s->type->subtype->type == YDR_TUSERDEF
1331 && s->type->subtype->symbol->type == YDR_TSTRUCT
1332 && strcmp(s->type->subtype->symbol->name,
1333 context->symbol->name) == 0) {
1334 fprintf (context->f,
1335 "ydr_print_%s%s(%s%s, ptr);\n",
1336 package,
1337 context->symbol->name,
1338 tmp2,
1339 tmp);
1340 } else {
1341 display_type (tmp2, tmp, s->type, context->f);
1344 free(tmp);
1345 free(tmp2);
1347 fprintf (context->f, "\n");
1349 return FALSE;
1353 * print TSTRUCT
1356 static void
1357 print_struct (char *where, Symbol *s, char *name, FILE *f)
1359 struct printcontext context;
1361 context.name = name;
1362 context.symbol = s;
1363 context.f = f;
1364 context.where = where ;
1366 fprintf (f, "/* printing TSTRUCT %s%s */\n", where, name);
1368 if (s->u.list)
1369 listiter (s->u.list, print_structentry, (void *)&context);
1373 * help function for free_struct
1376 struct freecontext {
1377 char *where;
1378 char *name;
1379 FILE *f;
1380 Symbol *symbol;
1383 static Bool
1384 free_structentry (List *list, Listitem *item, void *arg)
1386 StructEntry *s = (StructEntry *)listdata (item);
1387 struct freecontext *context = (struct freecontext *)arg;
1389 char *tmp;
1390 char *tmp2;
1392 asprintf(&tmp, ".%s", s->name);
1393 asprintf(&tmp2, "%s%s", context->where, context->name);
1395 if (s->type->type == YDR_TPOINTER
1396 && s->type->subtype->type == YDR_TUSERDEF
1397 && s->type->subtype->symbol->type == YDR_TSTRUCT
1398 && strcmp(s->type->subtype->symbol->name,
1399 context->symbol->name) == 0) {
1400 fprintf (context->f,
1401 "ydr_free_%s%s(%s%s, ptr);\n",
1402 package,
1403 context->symbol->name,
1404 tmp2,
1405 tmp);
1406 } else {
1407 free_type (tmp2, tmp, s->type, context->f);
1410 free(tmp);
1411 free(tmp2);
1413 return FALSE;
1417 * free TSTRUCT
1420 static void
1421 free_struct (char *where, Symbol *s, char *name, FILE *f)
1423 struct freecontext context;
1425 context.name = name;
1426 context.symbol = s;
1427 context.f = f;
1428 context.where = where;
1430 if (s->u.list)
1431 listiter (s->u.list, free_structentry, (void *)&context);
1435 * encode/decode TENUM
1438 static void
1439 encode_enum (Symbol *s, char *name, FILE *f, EncodeType encodetype,
1440 Side side)
1442 Type type = {YDR_TLONG};
1444 encode_type (name, &type, f, encodetype, side);
1448 * print TENUM
1451 static Bool
1452 gen_printenum (List *list, Listitem *item, void *arg)
1454 Symbol *s = (Symbol *)listdata (item);
1455 FILE *f = (FILE *)arg;
1457 fprintf (f, "case %d:\n"
1458 "printf(\"%s\");\n"
1459 "break;\n",
1460 (int) s->u.val, s->name);
1462 return FALSE;
1465 static void
1466 print_enum (char *where, Symbol *s, char *name, FILE *f)
1468 fprintf (f, "/* print ENUM %s */\n", where);
1470 fprintf (f, "printf(\"%s = \");", name);
1471 fprintf (f, "switch(%s) {\n", where);
1472 if (s->u.list)
1473 listiter (s->u.list, gen_printenum, f);
1474 fprintf (f,
1475 "default:\n"
1476 "printf(\" unknown enum %%d\", %s);\n"
1477 "}\n",
1478 where);
1482 * encode/decode TTYPEDEF
1485 static void
1486 encode_typedef (Symbol *s, char *name, FILE *f, EncodeType encodetype,
1487 Side side)
1489 encode_type (name, s->u.type, f, encodetype, side);
1493 * print TTYPEDEF
1496 static void
1497 print_typedef (char *where, Symbol *s, char *name, FILE *f)
1499 display_type (where, name, s->u.type, f);
1503 * free TTYPEDEF
1506 static void
1507 free_typedef (char *where, Symbol *s, char *name, FILE *f)
1509 free_type (where, name, s->u.type, f);
1513 * Encode symbol/TUSERDEF
1516 static void
1517 encode_symbol (Symbol *s, char *name, FILE *f, EncodeType encodetype,
1518 Side side)
1520 switch (s->type) {
1521 case YDR_TSTRUCT :
1522 encode_struct (s, name, f, encodetype, side);
1523 break;
1524 case YDR_TENUM :
1525 encode_enum (s, name, f, encodetype, side);
1526 break;
1527 case YDR_TTYPEDEF :
1528 encode_typedef (s, name, f, encodetype, side);
1529 break;
1530 default :
1531 abort();
1536 * print symbol/TUSERDEF
1539 static void
1540 print_symbol (char *where, Symbol *s, char *name, FILE *f)
1542 switch (s->type) {
1543 case YDR_TSTRUCT :
1544 print_struct (where, s, name, f);
1545 break;
1546 case YDR_TENUM :
1547 print_enum (where, s, name, f);
1548 break;
1549 case YDR_TTYPEDEF :
1550 print_typedef (where, s, name, f);
1551 break;
1552 default :
1553 abort();
1558 * Generate a free function for symbol
1561 static void
1562 free_symbol (char *where, Symbol *s, char *name, FILE *f)
1564 switch (s->type) {
1565 case YDR_TSTRUCT :
1566 free_struct (where, s, name, f);
1567 break;
1568 case YDR_TENUM :
1569 break;
1570 case YDR_TTYPEDEF :
1571 free_typedef (where, s, name, f);
1572 break;
1573 default :
1574 abort();
1579 * Generate the definition of an encode/decode function.
1582 static void
1583 generate_function_definition (Symbol *s, FILE *f, Bool encodep)
1585 if (s->type == YDR_TSTRUCT
1586 || s->type == YDR_TENUM
1587 || s->type == YDR_TTYPEDEF)
1589 fprintf (f,
1590 "%schar *ydr_%scode_%s(%s%s *o, %schar *ptr, size_t *total_len)",
1591 encodep ? "" : "const ",
1592 encodep ? "en" : "de",
1593 s->name,
1594 encodep ? "const " : "",
1595 s->name,
1596 encodep ? "" : "const ");
1597 } else if (s->type == YDR_TCONST
1598 || s->type == YDR_TENUMVAL
1599 || s->type == YDR_TTYPEDEF)
1601 else
1602 error_message (1, "What is %s (type %d) doing here?\n",
1603 s->name, s->type);
1607 * Generate the definition of a print function.
1610 static void
1611 generate_printfunction_definition (Symbol *s, FILE *f)
1613 if (s->type == YDR_TSTRUCT
1614 || s->type == YDR_TENUM
1615 || s->type == YDR_TTYPEDEF)
1617 fprintf (f,
1618 "void ydr_print_%s(%s *o)",
1619 s->name, s->name);
1620 } else if (s->type == YDR_TCONST
1621 || s->type == YDR_TENUMVAL
1622 || s->type == YDR_TTYPEDEF)
1624 else
1625 error_message (1, "What is %s (type %d) doing here?\n",
1626 s->name, s->type);
1630 * Generate a definition for a function to free `s', writing it to `f'
1633 static void
1634 generate_freefunction_definition (Symbol *s, FILE *f)
1636 if (s->type == YDR_TSTRUCT
1637 || s->type == YDR_TENUM
1638 || s->type == YDR_TTYPEDEF)
1640 fprintf (f,
1641 "void ydr_free_%s(%s *o)",
1642 s->name, s->name);
1643 } else if (s->type == YDR_TCONST
1644 || s->type == YDR_TENUMVAL
1645 || s->type == YDR_TTYPEDEF)
1647 else
1648 error_message (1, "What is %s (type %d) doing here?\n",
1649 s->name, s->type);
1653 * Generate an encode/decode function
1656 void
1657 generate_function (Symbol *s, FILE *f, Bool encodep)
1659 if (s->type == YDR_TSTRUCT
1660 || s->type == YDR_TENUM
1661 || s->type == YDR_TTYPEDEF)
1663 generate_function_definition (s, f, encodep);
1664 fprintf (f, "\n{\n");
1665 if (!encodep)
1666 fprintf (f, "memset(o, 0, sizeof(*o));\n");
1667 encode_symbol (s, "(*o)", f,
1668 encodep ? ENCODE_MEM : DECODE_MEM, CLIENT);
1669 fprintf (f, "return ptr;\n"
1670 "fail:\n");
1671 if (!encodep)
1672 free_symbol ("", s, "(*o)", f);
1673 fprintf (f, "errno = EINVAL;\n"
1674 "return NULL;}\n");
1675 } else if (s->type == YDR_TCONST
1676 || s->type == YDR_TENUMVAL
1677 || s->type == YDR_TTYPEDEF)
1679 else
1680 error_message (1, "What is %s (type %d) doing here?\n",
1681 s->name, s->type);
1685 * Generate a print function
1688 void
1689 generate_printfunction (Symbol *s, FILE *f)
1691 if (s->type == YDR_TSTRUCT
1692 || s->type == YDR_TENUM
1693 || s->type == YDR_TTYPEDEF) {
1694 generate_printfunction_definition (s, f);
1695 fprintf (f, "\n{\n");
1696 print_symbol ("(*o)", s, "", f);
1697 fprintf (f, "return;\n}\n");
1698 } else if (s->type == YDR_TCONST
1699 || s->type == YDR_TENUMVAL
1700 || s->type == YDR_TTYPEDEF)
1702 else
1703 error_message (1, "What is %s (type %d) doing here?\n",
1704 s->name, s->type);
1708 * Generate a free function for the type `s' and print it on `f'.
1711 void
1712 generate_freefunction (Symbol *s, FILE *f)
1714 if (s->type == YDR_TSTRUCT
1715 || s->type == YDR_TENUM
1716 || s->type == YDR_TTYPEDEF) {
1717 generate_freefunction_definition (s, f);
1718 fprintf (f, "\n{\n");
1719 free_symbol("(*o)", s, "", f);
1720 fprintf (f, "return;\n}\n");
1721 } else if (s->type == YDR_TCONST
1722 || s->type == YDR_TENUMVAL
1723 || s->type == YDR_TTYPEDEF)
1725 else
1726 error_message (1, "What is %s (type %d) doing here?\n",
1727 s->name, s->type);
1731 * Generate an prototype for an encode/decode function
1734 void
1735 generate_function_prototype (Symbol *s, FILE *f, Bool encodep)
1737 if (s->type == YDR_TSTRUCT
1738 || s->type == YDR_TENUM
1739 || s->type == YDR_TTYPEDEF)
1741 generate_function_definition (s, f, encodep);
1742 fprintf (f, ";\n");
1743 } else if (s->type == YDR_TCONST
1744 || s->type == YDR_TENUMVAL
1745 || s->type == YDR_TTYPEDEF)
1747 else
1748 error_message (1, "What is %s (type %d) doing here?\n",
1749 s->name, s->type);
1753 * Generate an prototype for a print function
1756 void
1757 generate_printfunction_prototype (Symbol *s, FILE *f)
1759 if (s->type == YDR_TSTRUCT
1760 || s->type == YDR_TENUM
1761 || s->type == YDR_TTYPEDEF) {
1762 generate_printfunction_definition (s, f);
1763 fprintf (f, ";\n");
1764 } else if (s->type == YDR_TCONST
1765 || s->type == YDR_TENUMVAL
1766 || s->type == YDR_TTYPEDEF)
1768 else
1769 error_message (1, "What is %s (type %d) doing here?\n",
1770 s->name, s->type);
1774 * Generate a prototype for a free function for the `s' type
1775 * and output it to `f'
1778 void
1779 generate_freefunction_prototype(Symbol *s, FILE *f)
1781 if (s->type == YDR_TSTRUCT
1782 || s->type == YDR_TENUM
1783 || s->type == YDR_TTYPEDEF) {
1784 generate_freefunction_definition (s, f);
1785 fprintf (f, ";\n");
1786 } else if (s->type == YDR_TCONST
1787 || s->type == YDR_TENUMVAL
1788 || s->type == YDR_TTYPEDEF)
1790 else
1791 error_message (1, "What is %s (type %d) doing here?\n",
1792 s->name, s->type);
1795 static Bool
1796 gen1 (List *list, Listitem *item, void *arg)
1798 Argument *a = (Argument *)listdata (item);
1799 FILE *f = (FILE *)arg;
1801 if ((a->argtype == TOUT || a->argtype == TINOUT)
1802 && a->type->type != YDR_TPOINTER
1803 && a->type->type != YDR_TSTRING)
1804 error_message (1, "Argument %s is OUT and not pointer or string.\n",
1805 a->name);
1806 fprintf (f, ", ");
1807 if (a->argtype == TIN)
1808 fprintf (f, "const ");
1809 print_type (a->name, a->type, a->argtype, FDECL, f);
1810 fprintf (f, "\n");
1811 return FALSE;
1814 static Bool
1815 genin (List *list, Listitem *item, void *arg)
1817 Argument *a = (Argument *)listdata (item);
1818 FILE *f = (FILE *)arg;
1820 if (a->argtype == TIN || a->argtype == TINOUT) {
1821 fprintf (f, ", %s ", a->argtype == TIN ? "const" : "");
1822 print_type (a->name, a->type, a->argtype, FDECL, f);
1823 fprintf (f, "\n");
1825 return FALSE;
1828 static Bool
1829 genout (List *list, Listitem *item, void *arg)
1831 Argument *a = (Argument *)listdata (item);
1833 if (a->argtype == TOUT || a->argtype == TINOUT)
1834 return gen1 (list, item, arg);
1835 else
1836 return FALSE;
1839 static Bool
1840 gendeclare (List *list, Listitem *item, void *arg)
1842 Argument *a = (Argument *)listdata (item);
1843 FILE *f = (FILE *)arg;
1845 if (a->type->type == YDR_TPOINTER)
1846 print_type (a->name, a->type->subtype, TIN, VDECL, f);
1847 else
1848 print_type (a->name, a->type, TIN, VDECL, f);
1849 fprintf (f, ";\n");
1850 return FALSE;
1853 static Bool
1854 genzero (List *list, Listitem *item, void *arg)
1856 Argument *a = (Argument *)listdata (item);
1857 FILE *f = (FILE *)arg;
1859 fprintf (f, "memset(&%s, 0, sizeof(%s));\n",
1860 a->name, a->name);
1861 return FALSE;
1864 static Bool
1865 genfree_isarrayp(Type *type)
1867 if (type->type == YDR_TVARRAY)
1868 return TRUE;
1869 if (type->type == YDR_TPOINTER)
1870 return genfree_isarrayp(type->subtype);
1871 if (type->type == YDR_TUSERDEF &&
1872 type->symbol &&
1873 type->symbol->type == YDR_TTYPEDEF)
1874 return genfree_isarrayp(type->symbol->u.type);
1876 return FALSE;
1880 static Bool
1881 genfree (List *list, Listitem *item, void *arg)
1883 Argument *a = (Argument *)listdata (item);
1884 FILE *f = (FILE *)arg;
1886 if (genfree_isarrayp(a->type))
1887 fprintf(f, "free(%s.val);\n", a->name);
1888 else if (a->argtype != TIN
1889 && a->type->type == YDR_TSTRING && a->type->size == 0)
1890 fprintf (f, "free(%s);\n", a->name);
1891 return FALSE;
1894 static Bool
1895 genencodein (List *list, Listitem *item, void *arg)
1897 Argument *a = (Argument *)listdata (item);
1898 FILE *f = (FILE *)arg;
1900 if (a->argtype == TIN || a->argtype == TINOUT) {
1901 if (a->type->type == YDR_TPOINTER) {
1902 char *tmp = (char *)emalloc (strlen (a->name) + 4);
1904 sprintf (tmp, "(*%s)", a->name);
1906 encode_type (tmp, a->type->subtype, f, ENCODE_RX, CLIENT);
1907 free (tmp);
1908 } else
1909 encode_type (a->name, a->type, f, ENCODE_RX, CLIENT);
1911 return FALSE;
1914 static Bool
1915 gendecodeout (List *list, Listitem *item, void *arg)
1917 Argument *a = (Argument *)listdata (item);
1918 FILE *f = (FILE *)arg;
1920 if (a->argtype == TOUT || a->argtype == TINOUT) {
1921 if (a->type->type == YDR_TPOINTER) {
1922 char *tmp = (char *)emalloc (strlen (a->name) + 4);
1924 sprintf (tmp, "(*%s)", a->name);
1926 encode_type (tmp, a->type->subtype, f, DECODE_RX, CLIENT);
1927 free (tmp);
1928 } else if(a->type->type == YDR_TSTRING) {
1929 encode_type (a->name, a->type, f, DECODE_RX, CLIENT);
1932 return FALSE;
1935 static Bool
1936 gendecodein (List *list, Listitem *item, void *arg)
1938 Argument *a = (Argument *)listdata (item);
1939 FILE *f = (FILE *)arg;
1941 if (a->argtype != TIN && a->argtype != TINOUT)
1942 return TRUE;
1943 else {
1944 if (a->type->type == YDR_TPOINTER) {
1945 #if 0
1946 char *tmp = (char *)emalloc (strlen (a->name) + 4);
1948 sprintf (tmp, "(*%s)", a->name);
1950 encode_type (tmp, a->type->subtype, f, DECODE_RX, SERVER);
1951 free (tmp);
1952 #endif
1953 encode_type (a->name, a->type->subtype, f, DECODE_RX, SERVER);
1954 } else
1955 encode_type (a->name, a->type, f, DECODE_RX, SERVER);
1956 return FALSE;
1960 static Bool
1961 genencodeout (List *list, Listitem *item, void *arg)
1963 Argument *a = (Argument *)listdata (item);
1964 FILE *f = (FILE *)arg;
1966 if (a->argtype == TOUT || a->argtype == TINOUT) {
1967 if (a->type->type == YDR_TPOINTER)
1968 encode_type (a->name, a->type->subtype, f, ENCODE_RX, SERVER);
1969 else
1970 encode_type (a->name, a->type, f, ENCODE_RX, SERVER);
1972 return FALSE;
1975 static Bool
1976 findargtypeiter (List *list, Listitem *item, void *arg)
1978 Argument *a = (Argument *)listdata (item);
1979 int *type = (int *)arg;
1981 if (a->argtype == *type) {
1982 (*type)++;
1983 return TRUE;
1985 return FALSE;
1988 static Bool
1989 findargtype(List *list, int type)
1991 int savedtype = type;
1992 listiter(list, findargtypeiter, &type);
1993 if (type != savedtype)
1994 return TRUE;
1995 return FALSE;
1998 static Bool
1999 genargs (List *list, Listitem *item, void *arg)
2001 Argument *a = (Argument *)listdata (item);
2002 FILE *f = (FILE *)arg;
2004 if (a->type->type == YDR_TPOINTER
2005 || (a->argtype != TIN
2006 && a->type->type == YDR_TSTRING && a->type->size == 0))
2007 putc ('&', f);
2008 fputs (a->name, f);
2009 if (listnext (list, item))
2010 fprintf (f, ", ");
2011 return FALSE;
2015 * Generate the stub functions for this RPC call
2018 static void
2019 generate_simple_stub (Symbol *s, FILE *f, FILE *headerf)
2021 Type type = {YDR_TLONG};
2022 char *op;
2024 fprintf (headerf, "int %s%s(\nstruct rx_connection *connection\n",
2025 package, s->name);
2026 listiter (s->u.proc.arguments, gen1, headerf);
2027 fprintf (headerf, ");\n\n");
2029 fprintf (f, "int %s%s(\nstruct rx_connection *connection\n",
2030 package, s->name);
2031 listiter (s->u.proc.arguments, gen1, f);
2032 fprintf (f, ")\n{\n"
2033 "struct rx_call *call;\n"
2034 "int ret = 0;\n"
2035 "call = rx_NewCall (connection);\n");
2037 asprintf (&op, "%u", s->u.proc.id);
2039 encode_type (op, &type, f, ENCODE_RX, CLIENT);
2040 free (op);
2041 listiter (s->u.proc.arguments, genencodein, f);
2042 listiter (s->u.proc.arguments, gendecodeout, f);
2043 fprintf (f,
2044 "return %s(rx_EndCall (call,0));\n"
2045 "fail:\n"
2046 "ret = %s(rx_GetCallError(call));\n"
2047 "rx_EndCall (call, 0);\n"
2048 "return ret;\n"
2049 "}\n",
2050 error_function,
2051 error_function);
2054 static void
2055 generate_split_stub (Symbol *s, FILE *f, FILE *headerf)
2057 Type type = {YDR_TLONG};
2058 char *op;
2060 fprintf (headerf, "int Start%s%s(\nstruct rx_call *call\n",
2061 package, s->name);
2062 listiter (s->u.proc.arguments, genin, headerf);
2063 fprintf (headerf, ");\n\n");
2065 fprintf (f, "int Start%s%s(\nstruct rx_call *call\n",
2066 package, s->name);
2067 listiter (s->u.proc.arguments, genin, f);
2068 fprintf (f, ")\n{\n");
2071 asprintf (&op, "%u", s->u.proc.id);
2072 encode_type (op, &type, f, ENCODE_RX, CLIENT);
2073 free (op);
2074 listiter (s->u.proc.arguments, genencodein, f);
2075 fprintf (f, "return 0;\n");
2076 /* XXX only in arg */
2077 if (findargtype(s->u.proc.arguments, TIN) ||
2078 findargtype(s->u.proc.arguments, TINOUT))
2079 fprintf (f, "fail:\n"
2080 "return %s(rx_GetCallError(call));\n",
2081 error_function);
2083 fprintf (f, "}\n\n");
2085 fprintf (headerf, "int End%s%s(\nstruct rx_call *call\n",
2086 package, s->name);
2087 listiter (s->u.proc.arguments, genout, headerf);
2088 fprintf (headerf, ");\n\n");
2090 fprintf (f, "int End%s%s(\nstruct rx_call *call\n",
2091 package, s->name);
2092 listiter (s->u.proc.arguments, genout, f);
2093 fprintf (f, ")\n{\n");
2095 listiter (s->u.proc.arguments, gendecodeout, f);
2096 fprintf (f, "return 0;\n");
2097 /* XXX only out arg */
2098 if (findargtype(s->u.proc.arguments, TOUT) ||
2099 findargtype(s->u.proc.arguments, TINOUT))
2100 fprintf (f, "fail:\n"
2101 "return %s(rx_GetCallError(call));\n",
2102 error_function);
2104 fprintf (f, "}\n\n");
2107 struct gen_args {
2108 FILE *f;
2109 int firstp;
2110 int arg_type;
2113 static Bool
2114 genmacro (List *list, Listitem *item, void *arg)
2116 Argument *a = (Argument *)listdata (item);
2117 struct gen_args *args = (struct gen_args *)arg;
2119 if (a->argtype == args->arg_type || a->argtype == TINOUT) {
2120 fprintf (args->f, "%s%s",
2121 args->firstp ? "" : ", ", a->name);
2122 args->firstp = 0;
2125 return FALSE;
2128 static void
2129 generate_multi (Symbol *s, FILE *f)
2131 struct gen_args gen_args;
2133 fprintf (f, "\n#include <rx/rx_multi.h>");
2134 fprintf (f, "\n#define multi_%s%s(", package, s->name);
2135 gen_args.f = f;
2136 gen_args.firstp = 1;
2137 gen_args.arg_type = TIN;
2138 listiter (s->u.proc.arguments, genmacro, &gen_args);
2139 fprintf (f, ") multi_Body(");
2140 fprintf (f, "Start%s%s(multi_call", package, s->name);
2141 gen_args.f = f;
2142 gen_args.firstp = 0;
2143 gen_args.arg_type = TIN;
2144 listiter (s->u.proc.arguments, genmacro, &gen_args);
2145 fprintf (f, "), End%s%s(multi_call", package, s->name);
2146 gen_args.f = f;
2147 gen_args.firstp = 0;
2148 gen_args.arg_type = TOUT;
2149 listiter (s->u.proc.arguments, genmacro, f);
2150 fprintf (f, "))\n");
2153 void
2154 generate_client_stub (Symbol *s, FILE *f, FILE *headerf)
2156 if (s->u.proc.flags & TSPLIT)
2157 generate_split_stub (s, f, headerf);
2158 if (s->u.proc.flags & TSIMPLE)
2159 generate_simple_stub (s, f, headerf);
2163 * A list of all the functions that are to be recognized by the
2164 * server, later used in generate_server_switch.
2167 static List *func_list;
2169 static void
2170 generate_standard_c_prologue (FILE *f,
2171 const char *filename,
2172 const char *basename)
2174 fprintf (f, "/* Generated from %s.xg */\n", basename);
2175 fprintf (f, "#include \"%s.h\"\n\n", basename);
2176 fprintf (f, "#ifndef _GNU_SOURCE\n");
2177 fprintf (f, "#define _GNU_SOURCE 1\n");
2178 fprintf (f, "#endif /* _GNU_SOURCE */\n");
2179 fprintf (f, "#include <sys/types.h>\n");
2180 fprintf (f, "#include <stdio.h>\n");
2181 fprintf (f, "#include <stdlib.h>\n");
2182 fprintf (f, "#include <string.h>\n");
2183 fprintf (f, "#include <netinet/in.h>\n");
2184 fprintf (f, "#include <errno.h>\n");
2185 fprintf (f, "#ifdef RCSID\n"
2186 "RCSID(\"%s generated from %s.xg with $Id$\");\n"
2187 "#endif\n\n", filename, basename);
2188 fprintf(f,
2189 "/* crap for operationssystem that doesn't "
2190 "provide us 64 bit ops */\n"
2191 "#ifndef be64toh\n"
2192 "#if BYTE_ORDER == LITTLE_ENDIAN\n"
2193 "static inline uint64_t\n"
2194 "ydr_swap64(uint64_t x)\n"
2195 "{\n"
2196 "#define LT(n) n##ULL\n"
2197 " return \n"
2198 " ((LT(0x00000000000000ff) & x) << 56) | \n"
2199 " ((LT(0x000000000000ff00) & x) << 40) | \n"
2200 " ((LT(0x0000000000ff0000) & x) << 24) | \n"
2201 " ((LT(0x00000000ff000000) & x) << 8) | \n"
2202 " ((LT(0x000000ff00000000) & x) >> 8) | \n"
2203 " ((LT(0x0000ff0000000000) & x) >> 24) | \n"
2204 " ((LT(0x00ff000000000000) & x) >> 40) | \n"
2205 " ((LT(0xff00000000000000) & x) >> 56) ; \n"
2206 "#undef LT\n"
2207 "}\n"
2208 "\n"
2209 "#define be64toh(x) ydr_swap64((x))\n"
2210 "#define htobe64(x) ydr_swap64((x))\n"
2211 "#endif /* BYTE_ORDER */\n"
2212 "#if BYTE_ORDER == BIG_ENDIAN\n"
2213 "#define be64toh(x) (x)\n"
2214 "#define htobe64(x) (x)\n"
2215 "#endif /* BYTE_ORDER */\n"
2216 "#endif /* be64toh */\n"
2221 * Convert filename into a cpp symbol
2224 static char *
2225 cppfilesymbolname(const char *fn)
2227 char *symname, *tmp;
2229 symname = estrdup(fn);
2230 estrdup (symname);
2231 for (tmp = symname; *tmp; tmp++) {
2232 if (tmp == symname && isdigit((unsigned char)*tmp))
2233 *tmp = '_';
2234 if (!isalpha((unsigned char)*tmp))
2235 *tmp = '_';
2237 return symname;
2241 * open all files
2244 void
2245 init_generate (const char *filename)
2247 char *tmp;
2248 char *fileupr;
2250 func_list = listnew ();
2252 asprintf (&tmp, "%s.h", filename);
2253 if (tmp == NULL)
2254 err (1, "malloc");
2255 ydr_fopen (tmp, "w", &headerfile);
2256 free (tmp);
2258 fileupr = cppfilesymbolname(filename);
2259 fprintf (headerfile.stream, "/* Generated from %s.xg */\n", filename);
2260 fprintf (headerfile.stream, "#ifndef _%s_\n"
2261 "#define _%s_\n\n", fileupr, fileupr);
2262 fprintf (headerfile.stream, "#include <atypes.h>\n\n");
2263 free (fileupr);
2265 asprintf (&tmp, "%s.ydr.c", filename);
2266 if (tmp == NULL)
2267 err (1, "malloc");
2268 ydr_fopen (tmp, "w", &ydrfile);
2269 generate_standard_c_prologue (ydrfile.stream, tmp, filename);
2270 free (tmp);
2272 asprintf (&tmp, "%s.cs.c", filename);
2273 if (tmp == NULL)
2274 err (1, "malloc");
2275 ydr_fopen (tmp, "w", &clientfile);
2276 generate_standard_c_prologue (clientfile.stream, tmp, filename);
2277 fprintf (clientfile.stream, "#include \"%s.cs.h\"\n\n", filename);
2278 free (tmp);
2280 asprintf (&tmp, "%s.ss.c", filename);
2281 if (tmp == NULL)
2282 err (1, "malloc");
2283 ydr_fopen (tmp, "w", &serverfile);
2284 generate_standard_c_prologue (serverfile.stream, tmp, filename);
2285 fprintf (serverfile.stream, "#include \"%s.ss.h\"\n\n", filename);
2286 free (tmp);
2288 asprintf (&tmp, "%s.cs.h", filename);
2289 if (tmp == NULL)
2290 err (1, "malloc");
2291 ydr_fopen (tmp, "w", &clienthdrfile);
2292 free (tmp);
2293 fprintf (clienthdrfile.stream, "/* Generated from %s.xg */\n", filename);
2294 fprintf (clienthdrfile.stream, "#include <rx/rx.h>\n");
2295 fprintf (clienthdrfile.stream, "#include \"%s.h\"\n\n", filename);
2297 asprintf (&tmp, "%s.ss.h", filename);
2298 if (tmp == NULL)
2299 err (1, "malloc");
2300 ydr_fopen (tmp, "w", &serverhdrfile);
2301 free (tmp);
2302 fprintf (serverhdrfile.stream, "/* Generated from %s.xg */\n", filename);
2303 fprintf (serverhdrfile.stream, "#include <rx/rx.h>\n");
2304 fprintf (serverhdrfile.stream, "#include \"%s.h\"\n\n", filename);
2306 packagelist = listnew();
2307 if (packagelist == NULL)
2308 err (1, "init_generate: listnew: packagelist");
2311 void
2312 close_generator (const char *filename)
2314 char *fileupr;
2316 fileupr = cppfilesymbolname(filename);
2317 fprintf (headerfile.stream, "\n#endif /* %s */\n", fileupr);
2318 free(fileupr);
2319 ydr_fclose (&headerfile);
2320 ydr_fclose (&clientfile);
2321 ydr_fclose (&serverfile);
2322 ydr_fclose (&clienthdrfile);
2323 ydr_fclose (&serverhdrfile);
2324 ydr_fclose (&ydrfile);
2328 * Generate the server-side stub function for the function in s and
2329 * write it to the file f.
2332 void
2333 generate_server_stub (Symbol *s, FILE *f, FILE *headerf, FILE *h_file)
2335 fprintf (headerf, "int S%s%s%s(\nstruct rx_call *call\n",
2336 prefix, package, s->name);
2337 listiter (s->u.proc.arguments, gen1, headerf);
2338 fprintf (headerf, ");\n\n");
2340 fprintf (f, "static int ydr_ps_%s%s(\nstruct rx_call *call)\n",
2341 package, s->name);
2342 fprintf (f, "{\n"
2343 "int32_t _result;\n");
2344 listiter (s->u.proc.arguments, gendeclare, f);
2345 listiter (s->u.proc.arguments, genzero, f);
2346 fprintf (f, "\n");
2347 listiter (s->u.proc.arguments, gendecodein, f);
2348 fprintf (f, "_result = S%s%s%s(", prefix, package, s->name);
2349 if (/* s->u.proc.splitp */ 1) {
2350 fprintf (f, "call");
2351 if (!listemptyp (s->u.proc.arguments))
2352 fprintf (f, ", ");
2354 listiter (s->u.proc.arguments, genargs, f);
2355 fprintf (f, ");\n");
2356 fprintf (f, "if (_result) goto funcfail;\n");
2357 listiter (s->u.proc.arguments, genencodeout, f);
2358 listiter (s->u.proc.arguments, genfree, f);
2359 fprintf (f, "return _result;\n");
2360 if (!listemptyp(s->u.proc.arguments)) {
2361 fprintf(f, "fail:\n");
2362 listiter (s->u.proc.arguments, genfree, f);
2363 fprintf(f, "return rx_GetCallError(call);\n");
2366 fprintf(f, "funcfail:\n"
2367 "return _result;\n"
2368 "}\n\n");
2370 listaddtail (func_list, s);
2371 if (s->u.proc.flags & TMULTI)
2372 generate_multi (s, h_file);
2375 struct gencase_context {
2376 FILE *f;
2377 char *package;
2380 static Bool
2381 gencase (List *list, Listitem *item, void *arg)
2383 Symbol *s = (Symbol *)listdata (item);
2384 struct gencase_context *c = (struct gencase_context *)arg;
2385 FILE *f = c->f;
2387 if (c->package == s->u.proc.package) {
2388 fprintf (f, "case %u: {\n"
2389 "_result = ydr_ps_%s%s(call);\n"
2390 "break;\n"
2391 "}\n",
2392 s->u.proc.id, s->u.proc.package, s->name);
2394 return FALSE;
2401 void
2402 generate_server_switch (FILE *c_file,
2403 FILE *h_file)
2405 Type optype = {YDR_TULONG};
2406 Listitem *li;
2407 struct gencase_context c;
2409 c.f = c_file;
2411 li = listhead (packagelist);
2412 while (li) {
2413 c.package = (char *)listdata (li);
2415 fprintf (h_file,
2416 "int32_t %sExecuteRequest(struct rx_call *call);\n",
2417 c.package);
2419 fprintf (c_file,
2420 "int32_t %sExecuteRequest(struct rx_call *call)\n"
2421 "{\n"
2422 "unsigned opcode;\n"
2423 "int32_t _result;\n",
2424 c.package);
2426 encode_type ("opcode", &optype, c_file, DECODE_RX, SERVER);
2427 fprintf (c_file, "switch(opcode) {\n");
2429 listiter (func_list, gencase, &c);
2431 fprintf (c_file, "default:\n"
2432 "_result = RXGEN_OPCODE;\n"
2433 "}\n"
2434 "return _result;\n"
2435 "fail:\n"
2436 "return rx_GetCallError(call);\n"
2437 "}\n\n");
2439 li = listnext (packagelist, li);
2447 void
2448 ydr_fopen (const char *name, const char *mode, ydr_file *f)
2450 int streamfd;
2452 asprintf (&f->curname, "%sXXXXXX", name);
2453 if (f->curname == NULL)
2454 err (1, "malloc");
2456 streamfd = mkstemp(f->curname);
2457 if (streamfd < 0)
2458 err (1, "mkstemp %s failed", f->curname);
2459 f->stream = fdopen (streamfd, mode);
2460 if (f->stream == NULL)
2461 err (1, "open %s mode %s", f->curname, mode);
2462 f->newname = estrdup(name);
2465 void
2466 ydr_fclose (ydr_file *f)
2468 if (fclose (f->stream))
2469 err (1, "close %s", f->curname);
2470 if (rename(f->curname, f->newname))
2471 err (1, "rename %s, %s", f->curname, f->newname);
2472 free(f->curname);
2473 free(f->newname);