2 * Copyright (c) 1995 - 2004 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
52 * The name of the current package that we're generating stubs for
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
72 * File handles for the generated files themselves.
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
);
123 print_type (char *name
, Type
*type
, enum argtype argtype
,
124 DeclType decl
, FILE *f
)
126 switch (type
->type
) {
128 fprintf (f
, "char %s", name
);
131 fprintf (f
, "unsigned char %s", name
);
134 fprintf (f
, "int16_t %s", name
);
137 fprintf (f
, "uint16_t %s", name
);
140 fprintf (f
, "int32_t %s", name
);
143 fprintf (f
, "uint32_t %s", name
);
146 fprintf (f
, "int64_t %s", name
);
149 fprintf (f
, "uint64_t %s", name
);
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
);
157 fprintf (f
, "char *%s", name
);
163 tmp
= (char *)emalloc (strlen(name
) + 2);
165 strcpy (tmp
+1, name
);
166 print_type (tmp
, type
->subtype
, argtype
, decl
, f
);
171 if(type
->symbol
->type
== YDR_TSTRUCT
)
172 fprintf (f
, "struct %s %s", type
->symbol
->name
, name
);
174 fprintf (f
, "%s %s", type
->symbol
->name
, name
);
180 s
= (char *)emalloc (strlen (name
) + 6);
182 strcpy (s
+ 1, name
);
185 fprintf (f
, "struct {\n");
187 print_type ("len", type
->indextype
, argtype
, decl
, f
);
189 fprintf (f
, "unsigned %s", "len");
191 strcpy(s
+ strlen(s
) - 3, "val");
192 print_type ("*val", type
->subtype
, argtype
, decl
, f
);
193 fprintf (f
, ";\n} %s", name
);
198 print_type (name
, type
->subtype
, argtype
, decl
, f
);
199 fprintf (f
, "[ %d ]", type
->size
);
202 fprintf (f
, "char %s", name
);
210 print_entry (List
*list
, Listitem
*item
, void *i
)
212 StructEntry
*s
= (StructEntry
*)listdata (item
);
216 print_type (s
->name
, s
->type
, TIN
, VDECL
, f
);
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.
228 sizeof_struct_iter (List
*list
, Listitem
*item
, void *arg
)
230 int *tot
= (int *)arg
;
231 StructEntry
*s
= (StructEntry
*)listdata (item
);
234 sz
= sizeof_type (s
->type
);
238 } else if (sz
< 0 || *tot
< 0) {
239 *tot
= -1 * (abs(*tot
) + abs(sz
));
248 sizeof_struct (Symbol
*s
)
253 listiter (s
->u
.list
, sizeof_struct_iter
, &tot
);
258 sizeof_type (Type
*t
)
269 case YDR_TULONGLONG
:
279 return sizeof_symbol (t
->symbol
);
282 int sz
= sizeof_type (t
->subtype
);
293 sz
= sizeof_type(t
->subtype
);
296 return -1 * (t
->size
* abs(sz
) + 4); /* 4 is size of the var part */
306 sizeof_symbol (Symbol
*s
)
309 case YDR_TUNDEFINED
:
310 fprintf (stderr
, "What is %s doing in sizeof_type?", s
->name
);
313 return sizeof_struct (s
);
321 return sizeof_type (s
->u
.type
);
328 * Generate header contents
332 generate_hdr_struct (Symbol
*s
, FILE *f
)
334 fprintf (f
, "struct %s {\n", s
->name
);
336 listiter (s
->u
.list
, print_entry
, f
);
337 fprintf (f
, "};\ntypedef struct %s %s;\n", s
->name
, s
->name
);
341 generate_hdr_enum (Symbol
*s
, FILE *f
)
346 fprintf (f
, "enum %s {\n", s
->name
);
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",
364 generate_hdr_const (Symbol
*s
, FILE *f
)
366 fprintf (f
, "#define %s %d\n", s
->name
, s
->u
.val
);
370 generate_hdr_typedef (Symbol
*s
, FILE *f
)
372 fprintf (f
, "typedef ");
373 print_type (s
->name
, s
->u
.type
, TIN
, VDECL
, f
);
378 generate_sizeof (Symbol
*s
, FILE *f
)
382 if (s
->type
== YDR_TCONST
)
385 sz
= sizeof_symbol (s
);
387 ; /* the size is unknown */
389 char *name
, *ms
= "";
393 name
= estrdup (s
->name
);
394 fprintf (f
, "#define %s_%sSIZE %d\n", strupr (name
), ms
, abs(sz
));
400 generate_header (Symbol
*s
, FILE *f
)
403 case YDR_TUNDEFINED
:
404 fprintf (f
, "What is %s doing in generate_header?", s
->name
);
407 generate_hdr_struct (s
, f
);
410 generate_hdr_enum (s
, f
);
413 generate_hdr_const (s
, f
);
418 generate_hdr_typedef (s
, f
);
426 * Generate functions for encoding and decoding.
430 encode_function (Type
*type
, EncodeType encodetype
)
432 if (type
->flags
& TASIS
)
434 else if (encodetype
== ENCODE_RX
|| encodetype
== ENCODE_MEM
) {
435 switch (type
->type
) {
443 } else if (encodetype
== DECODE_RX
|| encodetype
== DECODE_MEM
) {
444 switch (type
->type
) {
457 * encode/decode long/longlong
461 encode_int_type (char *name
, char *tname
, Type
*type
,
462 FILE *f
, EncodeType encodetype
)
464 switch (encodetype
) {
466 fprintf (f
, "{ u%s u;\n"
468 "if(rx_Write(call, &u, sizeof(u)) != sizeof(u))\n"
472 encode_function (type
, encodetype
),
476 fprintf (f
, "{ u%s u;\n"
477 "if(rx_Read(call, &u, sizeof(u)) != sizeof(u))\n"
481 encode_function (type
, encodetype
));
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",
490 encode_function (type
, encodetype
),
494 fprintf (f
, "{ %s tmp; "
495 "if (*total_len < sizeof(tmp)) goto fail;"
496 "memcpy ((char*)&tmp, ptr, sizeof(tmp)); "
498 "ptr += sizeof(tmp); "
499 "*total_len -= sizeof(tmp);}\n",
502 encode_function (type
, encodetype
));
510 encode_long (char *name
, Type
*type
, FILE *f
, EncodeType encodetype
)
512 encode_int_type(name
, "int32_t", type
, f
, encodetype
);
516 encode_longlong (char *name
, Type
*type
, FILE *f
, EncodeType encodetype
)
518 encode_int_type(name
, "int64_t", type
, f
, encodetype
);
526 print_long (char *where
, char *name
, Type
*type
, FILE *f
)
528 fprintf (f
, "printf(\" %s = %%d\", %s%s);", name
, where
, name
);
536 print_longlong (char *where
, char *name
, Type
*type
, FILE *f
)
538 fprintf (f
, "printf(\" %s = %%d\", (int32_t)%s%s);", name
, where
, name
);
546 gen_check_overflow(Type
*indextype
, Type
*subtype
, char *num
, FILE *f
)
548 /* Check if we will overflow */
550 print_type ("overI", indextype
, TIN
, VDECL
, f
);
552 fprintf(f
, "overI = ((");
553 print_type ("", indextype
, TIN
, VDECL
, f
);
555 print_type ("", indextype
, TIN
, VDECL
, f
);
556 fprintf(f
, ")0) >> 1) / sizeof(");
557 print_type ("", subtype
, TIN
, VDECL
, f
);
559 fprintf(f
, "if (overI < %s) goto fail;\n", num
);
567 static void __attribute__ ((unused
))
568 encode_char (char *name
, Type
*type
, FILE *f
, EncodeType encodetype
)
570 switch (encodetype
) {
573 "if(rx_Write(call, &%s, sizeof(%s)) != sizeof(%s))\n"
579 "if(rx_Read(call, &%s, sizeof(%s)) != sizeof(%s))\n"
584 fprintf (f
, "{ if (*total_len < sizeof(char)) goto fail;\n"
585 "*((char *)ptr) = %s; "
586 "ptr += sizeof(char); *total_len -= sizeof(char);}\n",
590 fprintf (f
, "{ if (*total_len < sizeof(char)) goto fail;\n"
591 "%s = *((char *)ptr); "
592 "ptr += sizeof(char); *total_len -= sizeof(char);}\n",
600 static void __attribute__ ((unused
))
601 encode_short (char *name
, Type
*type
, FILE *f
, EncodeType encodetype
)
603 switch (encodetype
) {
605 fprintf (f
, "{ int16_t u;\n"
607 "if(rx_Write(call, &u, sizeof(u)) != sizeof(u))\n"
610 encode_function (type
, encodetype
),
614 fprintf (f
, "{ int16_t u;\n"
615 "if(rx_Read(call, &u, sizeof(u)) != sizeof(u))\n"
619 encode_function (type
, encodetype
));
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
),
631 fprintf (f
, "{ int16_t tmp; "
632 "if (*total_len < sizeof(int16_t)) goto fail;\n"
633 "memcpy ((char *)&tmp, ptr, sizeof(int16_t)); "
635 "ptr += sizeof(int16_t); "
636 "*total_len -= sizeof(int16_t); }\n",
638 encode_function (type
, encodetype
));
646 * encode/decode TSTRING
650 encode_string (char *name
, Type
*type
, FILE *f
, EncodeType encodetype
,
653 Type lentype
= {YDR_TULONG
};
656 asprintf (&nname
, "(%s%s)",
657 ((type
->size
== 0) && side
== CLIENT
658 && (encodetype
== ENCODE_RX
|| encodetype
== ENCODE_MEM
))
661 switch (encodetype
) {
663 fprintf (f
, "{ unsigned len;\n"
664 "char zero[4] = {0, 0, 0, 0};\n"
666 "len = strlen(%s);\n"
667 "padlen = (4 - (len %% 4)) %% 4;\n",
669 encode_type ("len", &lentype
, f
, encodetype
, side
);
671 "if(rx_Write(call, %s, len) != len)\n"
673 "if(rx_Write(call, zero, padlen) != padlen)\n"
678 fprintf (f
, "{ unsigned len;\n"
680 "char zero[4] = {0, 0, 0, 0};\n");
681 encode_type ("len", &lentype
, f
, encodetype
, side
);
682 if (type
->size
!= 0) {
685 "rx_SetCallError(call, ENOMEM);\n"
690 fprintf(f
, "if (len == (uint32_t) -1) {\n"
691 "rx_SetCallError(call, ENOMEM);\n"
694 fprintf(f
, "%s = malloc(len + 1);\n"
695 "if (%s == NULL) {\n"
696 "rx_SetCallError(call, ENOMEM);\n"
703 "if(rx_Read(call, %s, len) != len)\n"
706 "padlen = (4 - (len %% 4)) %% 4;\n"
707 "if(rx_Read(call, zero, padlen) != padlen)\n"
709 "}\n", nname
, nname
);
713 "{\nunsigned len = strlen(%s);\n"
714 "if (*total_len < len) goto fail;\n"
715 "*total_len -= len;\n",
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");
724 "{\nunsigned len;\n");
725 encode_type ("len", &lentype
, f
, encodetype
, side
);
727 "if (*total_len < len) goto fail;\n"
728 "*total_len -= len;\n");
729 if (type
->size
!= 0) {
735 fprintf(f
, "if (len == (uint32_t) -1) {\n"
738 fprintf(f
, "%s = malloc(len + 1);\n"
739 "if (%s == NULL) {\n"
745 "memcpy (%s, ptr, len);\n"
747 "ptr += len + (4 - (len %% 4)) %% 4;\n"
748 "*total_len -= len + (4 - (len %% 4)) %% 4;\n}\n",
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
);
774 free_string (char *where
, char *name
, Type
*type
, FILE *f
)
776 fprintf (f
, "free(%s%s);\n", where
, name
);
781 * encode/decode TARRAY
785 encode_array (char *name
, Type
*type
, FILE *f
, EncodeType encodetype
,
788 if (type
->subtype
->type
== YDR_TOPAQUE
) {
789 if (type
->size
% 4 != 0)
790 error_message (1, "Opaque array should be"
792 switch (encodetype
) {
795 "if(rx_Write (call, %s, %d) != %d)\n"
797 name
, type
->size
, type
->size
);
801 "if(rx_Read (call, %s, %d) != %d)\n"
803 name
, type
->size
, type
->size
);
806 fprintf (f
, "if (*total_len < %u) goto fail;\n"
807 "memcpy (ptr, %s, %u);\n", type
->size
, name
,
809 fprintf (f
, "ptr += %u; *total_len -= %u;\n",
810 type
->size
, type
->size
);
813 fprintf (f
, "if (*total_len < %u) goto fail;"
814 "memcpy (%s, ptr, %u);\n", type
->size
, name
,
816 fprintf (f
, "ptr += %u; *total_len -= %u;\n",
817 type
->size
, type
->size
);
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
);
830 type
->subtype
->flags
|= type
->flags
;
831 encode_type (tmp
, type
->subtype
, f
, encodetype
, side
);
833 fprintf (f
, "}\n}\n");
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"
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]);",
858 type
->size
, tmpcnt
, tmpcnt
);
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
);
866 display_type (ptr
, "", type
->subtype
, f
);
869 fprintf (f
, "\nif (i%lu != %d - 1) printf(\",\");\n",
882 free_array (char *where
, char *name
, Type
*type
, FILE *f
)
884 if (type
->subtype
->type
== YDR_TOPAQUE
) {
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
);
894 type
->subtype
->flags
|= type
->flags
;
895 free_type (tmp
, "", type
->subtype
, f
);
897 fprintf (f
, "}\n}\n");
902 * encode/decode TVARRAY
906 encode_varray (char *name
, Type
*type
, FILE *f
, EncodeType encodetype
,
910 Type lentype
= {YDR_TULONG
};
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
) {
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
) {
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"
945 "if(rx_Write (call, zero, padlen) != padlen)\n"
948 tmp
, name
, tmp
, tmp
);
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"
956 "if(rx_Read (call, zero, padlen) != padlen)\n"
959 tmp
, name
, tmp
, tmp
);
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"
970 tmp
, tmp
, name
, tmp
, tmp
, tmp
);
975 "memcpy (%s.val, ptr, %s);\n"
976 "ptr += %s + (4 - (%s %% 4)) %% 4;\n"
978 name
, tmp
, tmp
, tmp
);
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
);
989 type
->subtype
->flags
|= type
->flags
;
990 encode_type (tmp
, type
->subtype
, f
, encodetype
, side
);
992 fprintf (f
, "}\n}\n");
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]);",
1013 where
, name
, tmpcnt
, tmpcnt
);
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
);
1020 display_type (ptr
, "", type
->subtype
, f
);
1023 fprintf (f
, "\nif (i%lu != %s%s.len - 1) printf(\",\");\n",
1024 tmpcnt
, where
, name
);
1036 free_varray (char *where
, char *name
, Type
*type
, FILE *f
)
1038 if (type
->subtype
->type
!= YDR_TOPAQUE
) {
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
);
1046 free_type (ptr
, "", type
->subtype
, f
);
1052 fprintf (f
, "free((%s%s).val);\n", where
, name
);
1056 * encode/decode pointer
1060 encode_pointer (char *name
, Type
*type
, FILE *f
, EncodeType encodetype
,
1063 Type booltype
= {YDR_TULONG
};
1066 sprintf (tmp
, "*(%s)", name
);
1068 switch(encodetype
) {
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
);
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",
1089 encode_type (tmp
, type
->subtype
, f
, encodetype
, side
);
1090 fprintf (f
, "} else {\n"
1105 free_pointer (char *where
, char *name
, Type
*type
, FILE *f
)
1109 asprintf (&tmp
, "*(%s%s)", where
, name
);
1110 fprintf (f
, "if(%s%s)", where
, name
);
1111 free_type(tmp
, "", type
->subtype
, f
);
1120 encode_type (char *name
, Type
*type
, FILE *f
, EncodeType encodetype
,
1123 switch (type
->type
) {
1130 encode_long (name
, type
, f
, encodetype
);
1132 case YDR_TLONGLONG
:
1133 case YDR_TULONGLONG
:
1134 encode_longlong (name
, type
, f
, encodetype
);
1137 encode_string (name
, type
, f
, encodetype
, side
);
1141 "Type opaque only allowed as part of an array");
1144 encode_symbol (type
->symbol
, name
, f
, encodetype
, side
);
1147 encode_array (name
, type
, f
, encodetype
, side
);
1150 encode_varray (name
, type
, f
, encodetype
, side
);
1153 encode_pointer (name
, type
, f
, encodetype
, side
);
1165 display_type (char *where
, char *name
, Type
*type
, FILE *f
)
1169 switch (type
->type
) {
1176 print_long (where
, name
, type
, f
);
1178 case YDR_TLONGLONG
:
1179 case YDR_TULONGLONG
:
1180 print_longlong (where
, name
, type
, f
);
1183 print_string (where
, name
, type
, f
);
1186 fprintf (f
, "printf(\"printing TOPAQUE\\n\");");
1189 print_symbol (where
, type
->symbol
, name
, f
);
1192 print_array (where
, name
, type
, f
);
1195 print_varray (where
, name
, type
, f
);
1198 fprintf (f
, "printf(\"printing TPOINTER\\n\");");
1210 free_type (char *where
, char *name
, Type
*type
, FILE *f
)
1212 switch (type
->type
) {
1219 case YDR_TLONGLONG
:
1220 case YDR_TULONGLONG
:
1224 free_string (where
, name
, type
, f
);
1230 free_symbol (where
, type
->symbol
, name
, f
);
1233 free_array (where
, name
, type
, f
);
1236 free_varray (where
, name
, type
, f
);
1239 free_pointer (where
, name
, type
, f
);
1250 EncodeType encodetype
;
1255 * helpfunction for encode_struct
1259 encode_entry (List
*list
, Listitem
*item
, void *arg
)
1261 StructEntry
*s
= (StructEntry
*)listdata (item
);
1263 struct context
*context
= (struct context
*)arg
;
1265 strcpy (tmp
, context
->name
);
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
,
1279 encode_type (tmp
, s
->type
, context
->f
, context
->encodetype
,
1287 * encode/decode TSTRUCT
1291 encode_struct (Symbol
*s
, char *name
, FILE *f
, EncodeType encodetype
,
1294 struct context context
;
1296 context
.name
= name
;
1299 context
.encodetype
= encodetype
;
1300 context
.side
= side
;
1303 listiter (s
->u
.list
, encode_entry
, (void *)&context
);
1307 * help function for print_struct
1310 struct printcontext
{
1318 print_structentry (List
*list
, Listitem
*item
, void *arg
)
1320 StructEntry
*s
= (StructEntry
*)listdata (item
);
1321 struct printcontext
*context
= (struct printcontext
*)arg
;
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",
1337 context
->symbol
->name
,
1341 display_type (tmp2
, tmp
, s
->type
, context
->f
);
1347 fprintf (context
->f
, "\n");
1357 print_struct (char *where
, Symbol
*s
, char *name
, FILE *f
)
1359 struct printcontext context
;
1361 context
.name
= name
;
1364 context
.where
= where
;
1366 fprintf (f
, "/* printing TSTRUCT %s%s */\n", where
, name
);
1369 listiter (s
->u
.list
, print_structentry
, (void *)&context
);
1373 * help function for free_struct
1376 struct freecontext
{
1384 free_structentry (List
*list
, Listitem
*item
, void *arg
)
1386 StructEntry
*s
= (StructEntry
*)listdata (item
);
1387 struct freecontext
*context
= (struct freecontext
*)arg
;
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",
1403 context
->symbol
->name
,
1407 free_type (tmp2
, tmp
, s
->type
, context
->f
);
1421 free_struct (char *where
, Symbol
*s
, char *name
, FILE *f
)
1423 struct freecontext context
;
1425 context
.name
= name
;
1428 context
.where
= where
;
1431 listiter (s
->u
.list
, free_structentry
, (void *)&context
);
1435 * encode/decode TENUM
1439 encode_enum (Symbol
*s
, char *name
, FILE *f
, EncodeType encodetype
,
1442 Type type
= {YDR_TLONG
};
1444 encode_type (name
, &type
, f
, encodetype
, side
);
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"
1460 (int) s
->u
.val
, s
->name
);
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
);
1473 listiter (s
->u
.list
, gen_printenum
, f
);
1476 "printf(\" unknown enum %%d\", %s);\n"
1482 * encode/decode TTYPEDEF
1486 encode_typedef (Symbol
*s
, char *name
, FILE *f
, EncodeType encodetype
,
1489 encode_type (name
, s
->u
.type
, f
, encodetype
, side
);
1497 print_typedef (char *where
, Symbol
*s
, char *name
, FILE *f
)
1499 display_type (where
, name
, s
->u
.type
, f
);
1507 free_typedef (char *where
, Symbol
*s
, char *name
, FILE *f
)
1509 free_type (where
, name
, s
->u
.type
, f
);
1513 * Encode symbol/TUSERDEF
1517 encode_symbol (Symbol
*s
, char *name
, FILE *f
, EncodeType encodetype
,
1522 encode_struct (s
, name
, f
, encodetype
, side
);
1525 encode_enum (s
, name
, f
, encodetype
, side
);
1528 encode_typedef (s
, name
, f
, encodetype
, side
);
1536 * print symbol/TUSERDEF
1540 print_symbol (char *where
, Symbol
*s
, char *name
, FILE *f
)
1544 print_struct (where
, s
, name
, f
);
1547 print_enum (where
, s
, name
, f
);
1550 print_typedef (where
, s
, name
, f
);
1558 * Generate a free function for symbol
1562 free_symbol (char *where
, Symbol
*s
, char *name
, FILE *f
)
1566 free_struct (where
, s
, name
, f
);
1571 free_typedef (where
, s
, name
, f
);
1579 * Generate the definition of an encode/decode function.
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
)
1590 "%schar *ydr_%scode_%s(%s%s *o, %schar *ptr, size_t *total_len)",
1591 encodep
? "" : "const ",
1592 encodep
? "en" : "de",
1594 encodep
? "const " : "",
1596 encodep
? "" : "const ");
1597 } else if (s
->type
== YDR_TCONST
1598 || s
->type
== YDR_TENUMVAL
1599 || s
->type
== YDR_TTYPEDEF
)
1602 error_message (1, "What is %s (type %d) doing here?\n",
1607 * Generate the definition of a print function.
1611 generate_printfunction_definition (Symbol
*s
, FILE *f
)
1613 if (s
->type
== YDR_TSTRUCT
1614 || s
->type
== YDR_TENUM
1615 || s
->type
== YDR_TTYPEDEF
)
1618 "void ydr_print_%s(%s *o)",
1620 } else if (s
->type
== YDR_TCONST
1621 || s
->type
== YDR_TENUMVAL
1622 || s
->type
== YDR_TTYPEDEF
)
1625 error_message (1, "What is %s (type %d) doing here?\n",
1630 * Generate a definition for a function to free `s', writing it to `f'
1634 generate_freefunction_definition (Symbol
*s
, FILE *f
)
1636 if (s
->type
== YDR_TSTRUCT
1637 || s
->type
== YDR_TENUM
1638 || s
->type
== YDR_TTYPEDEF
)
1641 "void ydr_free_%s(%s *o)",
1643 } else if (s
->type
== YDR_TCONST
1644 || s
->type
== YDR_TENUMVAL
1645 || s
->type
== YDR_TTYPEDEF
)
1648 error_message (1, "What is %s (type %d) doing here?\n",
1653 * Generate an encode/decode function
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");
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"
1672 free_symbol ("", s
, "(*o)", f
);
1673 fprintf (f
, "errno = EINVAL;\n"
1675 } else if (s
->type
== YDR_TCONST
1676 || s
->type
== YDR_TENUMVAL
1677 || s
->type
== YDR_TTYPEDEF
)
1680 error_message (1, "What is %s (type %d) doing here?\n",
1685 * Generate a print function
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
)
1703 error_message (1, "What is %s (type %d) doing here?\n",
1708 * Generate a free function for the type `s' and print it on `f'.
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
)
1726 error_message (1, "What is %s (type %d) doing here?\n",
1731 * Generate an prototype for an encode/decode function
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
);
1743 } else if (s
->type
== YDR_TCONST
1744 || s
->type
== YDR_TENUMVAL
1745 || s
->type
== YDR_TTYPEDEF
)
1748 error_message (1, "What is %s (type %d) doing here?\n",
1753 * Generate an prototype for a print function
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
);
1764 } else if (s
->type
== YDR_TCONST
1765 || s
->type
== YDR_TENUMVAL
1766 || s
->type
== YDR_TTYPEDEF
)
1769 error_message (1, "What is %s (type %d) doing here?\n",
1774 * Generate a prototype for a free function for the `s' type
1775 * and output it to `f'
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
);
1786 } else if (s
->type
== YDR_TCONST
1787 || s
->type
== YDR_TENUMVAL
1788 || s
->type
== YDR_TTYPEDEF
)
1791 error_message (1, "What is %s (type %d) doing here?\n",
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",
1807 if (a
->argtype
== TIN
)
1808 fprintf (f
, "const ");
1809 print_type (a
->name
, a
->type
, a
->argtype
, FDECL
, f
);
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
);
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
);
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
);
1848 print_type (a
->name
, a
->type
, TIN
, VDECL
, f
);
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",
1865 genfree_isarrayp(Type
*type
)
1867 if (type
->type
== YDR_TVARRAY
)
1869 if (type
->type
== YDR_TPOINTER
)
1870 return genfree_isarrayp(type
->subtype
);
1871 if (type
->type
== YDR_TUSERDEF
&&
1873 type
->symbol
->type
== YDR_TTYPEDEF
)
1874 return genfree_isarrayp(type
->symbol
->u
.type
);
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
);
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
);
1909 encode_type (a
->name
, a
->type
, f
, ENCODE_RX
, CLIENT
);
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
);
1928 } else if(a
->type
->type
== YDR_TSTRING
) {
1929 encode_type (a
->name
, a
->type
, f
, DECODE_RX
, CLIENT
);
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
)
1944 if (a
->type
->type
== YDR_TPOINTER
) {
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
);
1953 encode_type (a
->name
, a
->type
->subtype
, f
, DECODE_RX
, SERVER
);
1955 encode_type (a
->name
, a
->type
, f
, DECODE_RX
, SERVER
);
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
);
1970 encode_type (a
->name
, a
->type
, f
, ENCODE_RX
, SERVER
);
1976 findargtypeiter (List
*list
, Listitem
*item
, void *arg
)
1978 Argument
*a
= (Argument
*)listdata (item
);
1979 int *type
= (int *)arg
;
1981 if (a
->argtype
== *type
) {
1989 findargtype(List
*list
, int type
)
1991 int savedtype
= type
;
1992 listiter(list
, findargtypeiter
, &type
);
1993 if (type
!= savedtype
)
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))
2009 if (listnext (list
, item
))
2015 * Generate the stub functions for this RPC call
2019 generate_simple_stub (Symbol
*s
, FILE *f
, FILE *headerf
)
2021 Type type
= {YDR_TLONG
};
2024 fprintf (headerf
, "int %s%s(\nstruct rx_connection *connection\n",
2026 listiter (s
->u
.proc
.arguments
, gen1
, headerf
);
2027 fprintf (headerf
, ");\n\n");
2029 fprintf (f
, "int %s%s(\nstruct rx_connection *connection\n",
2031 listiter (s
->u
.proc
.arguments
, gen1
, f
);
2032 fprintf (f
, ")\n{\n"
2033 "struct rx_call *call;\n"
2035 "call = rx_NewCall (connection);\n");
2037 asprintf (&op
, "%u", s
->u
.proc
.id
);
2039 encode_type (op
, &type
, f
, ENCODE_RX
, CLIENT
);
2041 listiter (s
->u
.proc
.arguments
, genencodein
, f
);
2042 listiter (s
->u
.proc
.arguments
, gendecodeout
, f
);
2044 "return %s(rx_EndCall (call,0));\n"
2046 "ret = %s(rx_GetCallError(call));\n"
2047 "rx_EndCall (call, 0);\n"
2055 generate_split_stub (Symbol
*s
, FILE *f
, FILE *headerf
)
2057 Type type
= {YDR_TLONG
};
2060 fprintf (headerf
, "int Start%s%s(\nstruct rx_call *call\n",
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",
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
);
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",
2083 fprintf (f
, "}\n\n");
2085 fprintf (headerf
, "int End%s%s(\nstruct rx_call *call\n",
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",
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",
2104 fprintf (f
, "}\n\n");
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
);
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
);
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
);
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
);
2147 gen_args
.firstp
= 0;
2148 gen_args
.arg_type
= TOUT
;
2149 listiter (s
->u
.proc
.arguments
, genmacro
, f
);
2150 fprintf (f
, "))\n");
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
;
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
);
2189 "/* crap for operationssystem that doesn't "
2190 "provide us 64 bit ops */\n"
2192 "#if BYTE_ORDER == LITTLE_ENDIAN\n"
2193 "static inline uint64_t\n"
2194 "ydr_swap64(uint64_t x)\n"
2196 "#define LT(n) n##ULL\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"
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
2225 cppfilesymbolname(const char *fn
)
2227 char *symname
, *tmp
;
2229 symname
= estrdup(fn
);
2231 for (tmp
= symname
; *tmp
; tmp
++) {
2232 if (tmp
== symname
&& isdigit((unsigned char)*tmp
))
2234 if (!isalpha((unsigned char)*tmp
))
2245 init_generate (const char *filename
)
2250 func_list
= listnew ();
2252 asprintf (&tmp
, "%s.h", filename
);
2255 ydr_fopen (tmp
, "w", &headerfile
);
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");
2265 asprintf (&tmp
, "%s.ydr.c", filename
);
2268 ydr_fopen (tmp
, "w", &ydrfile
);
2269 generate_standard_c_prologue (ydrfile
.stream
, tmp
, filename
);
2272 asprintf (&tmp
, "%s.cs.c", filename
);
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
);
2280 asprintf (&tmp
, "%s.ss.c", filename
);
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
);
2288 asprintf (&tmp
, "%s.cs.h", filename
);
2291 ydr_fopen (tmp
, "w", &clienthdrfile
);
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
);
2300 ydr_fopen (tmp
, "w", &serverhdrfile
);
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");
2312 close_generator (const char *filename
)
2316 fileupr
= cppfilesymbolname(filename
);
2317 fprintf (headerfile
.stream
, "\n#endif /* %s */\n", 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.
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",
2343 "int32_t _result;\n");
2344 listiter (s
->u
.proc
.arguments
, gendeclare
, f
);
2345 listiter (s
->u
.proc
.arguments
, genzero
, f
);
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
))
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"
2370 listaddtail (func_list
, s
);
2371 if (s
->u
.proc
.flags
& TMULTI
)
2372 generate_multi (s
, h_file
);
2375 struct gencase_context
{
2381 gencase (List
*list
, Listitem
*item
, void *arg
)
2383 Symbol
*s
= (Symbol
*)listdata (item
);
2384 struct gencase_context
*c
= (struct gencase_context
*)arg
;
2387 if (c
->package
== s
->u
.proc
.package
) {
2388 fprintf (f
, "case %u: {\n"
2389 "_result = ydr_ps_%s%s(call);\n"
2392 s
->u
.proc
.id
, s
->u
.proc
.package
, s
->name
);
2402 generate_server_switch (FILE *c_file
,
2405 Type optype
= {YDR_TULONG
};
2407 struct gencase_context c
;
2411 li
= listhead (packagelist
);
2413 c
.package
= (char *)listdata (li
);
2416 "int32_t %sExecuteRequest(struct rx_call *call);\n",
2420 "int32_t %sExecuteRequest(struct rx_call *call)\n"
2422 "unsigned opcode;\n"
2423 "int32_t _result;\n",
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"
2436 "return rx_GetCallError(call);\n"
2439 li
= listnext (packagelist
, li
);
2448 ydr_fopen (const char *name
, const char *mode
, ydr_file
*f
)
2452 asprintf (&f
->curname
, "%sXXXXXX", name
);
2453 if (f
->curname
== NULL
)
2456 streamfd
= mkstemp(f
->curname
);
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
);
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
);