2 * rpcgen - Generate XDR bindings automatically.
3 * Copyright (C) 2008 Red Hat Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "rpcgen_int.h"
29 /* If we're debugging the code generator itself, then #line directives
30 * aren't useful - we want to see the error in the generated code
31 * instead. Setting this disables #line directives in the output.
33 #define DEBUG_CODEGEN 0
35 static void gen_line (void);
36 static void gen_decl (int indent, const struct decl *);
37 static void gen_decl_xdr_call (int indent, const struct decl *, const char *);
38 static void gen_type (const struct type *);
45 for (i = 0; i < n; ++i)
49 /* This generates a #line directive referring back to the
50 * original source file.
57 fprintf (yyout, "#line %d \"%s\"\n", yylineno, input_filename);
64 const char *p = strrchr (output_filename, '/') ? : output_filename;
65 const char *q = strrchr (output_filename, '.');
67 while (*p && p != q) {
74 write_basename_caps (void)
76 const char *p = strrchr (output_filename, '/') ? : output_filename;
77 const char *q = strrchr (output_filename, '.');
79 while (*p && p != q) {
81 fputc (toupper (*p), yyout);
89 gen_prologue (const char *filename)
92 "/* This file was generated by PortableXDR rpcgen %s\n"
93 " * ANY CHANGES YOU MAKE TO THIS FILE MAY BE LOST!\n"
94 " * The input file was %s\n"
97 PACKAGE_VERSION, filename);
102 fprintf (yyout, "#include \"");
104 fprintf (yyout, ".h\"\n\n");
108 fprintf (yyout, "#ifndef RPCGEN_HEADER_");
109 write_basename_caps ();
112 "#define RPCGEN_HEADER_");
113 write_basename_caps ();
117 "#ifdef __cplusplus\n"
121 "#include <stdint.h>\n"
122 "#include <rpc/types.h>\n"
123 "#include <rpc/xdr.h>\n"
125 "/* Use the following symbol in your code to detect whether\n"
126 " * PortableXDR's rpcgen was used to compile the source file.\n"
128 "#define PORTABLE_RPCGEN_");
129 write_basename_caps ();
150 "#ifdef __cplusplus\n"
154 "#endif /* RPCGEN_HEADER_");
155 write_basename_caps ();
156 fprintf (yyout, "_H */\n");
160 fprintf (yyout, "\n/* EOF */\n");
164 gen_const (const char *name, const char *value)
166 if (output_mode == output_h) {
169 fprintf (yyout, "#define %s %s\n", name, value);
174 gen_enum (const char *name, const struct cons *enum_values)
181 fprintf (yyout, "enum %s {\n", name);
182 while (enum_values) {
183 struct enum_value *enum_value = (struct enum_value *) enum_values->ptr;
184 if (enum_value->value)
185 fprintf (yyout, " %s = %s,\n",
186 enum_value->ident, enum_value->value);
188 fprintf (yyout, " %s,\n", enum_value->ident);
189 enum_values = enum_values->next;
193 "typedef enum %s %s;\n"
194 "extern bool_t xdr_%s (XDR *, %s *);\n"
196 name, name, name, name);
202 "xdr_%s (XDR *xdrs, %s *objp)\n"
204 " if (!xdr_enum (xdrs, (enum_t *) objp))\n"
214 /* The Sun rpcgen seems to do some sort of inlining optimization based
215 * on {size of struct|number of elements}(?) We don't do any such
216 * optimization. Instead we rely on gcc doing the correct level of
217 * optimization based on inlined functions found in the header files.
220 gen_struct (const char *name, const struct cons *decls)
227 fprintf (yyout, "struct %s {\n", name);
229 gen_decl (2, (struct decl *) decls->ptr);
234 "typedef struct %s %s;\n"
235 "extern bool_t xdr_%s (XDR *, %s *);\n"
237 name, name, name, name);
243 "xdr_%s (XDR *xdrs, %s *objp)\n"
247 gen_decl_xdr_call (2, (struct decl *) decls->ptr, "&objp->");
259 gen_union (const char *name, const struct decl *discrim,
260 const struct cons *union_cases)
270 fprintf (yyout, "struct %s {\n", name);
271 gen_decl (2, discrim);
272 fprintf (yyout, " union {\n");
274 while (union_cases) {
275 struct union_case *uc = (struct union_case *) union_cases->ptr;
276 if (uc->decl) gen_decl (4, uc->decl);
277 union_cases = union_cases->next;
282 "typedef struct %s %s;\n"
283 "extern bool_t xdr_%s (XDR *, %s *);\n"
285 name, name, name, name, name);
291 "xdr_%s (XDR *xdrs, %s *objp)\n"
294 gen_decl_xdr_call (2, discrim, "&objp->");
296 " switch (objp->%s) {\n",
299 len = strlen (name) + 11;
301 snprintf (str, len, "&objp->%s_u.", name);
303 while (union_cases) {
304 struct union_case *uc = (struct union_case *) union_cases->ptr;
308 gen_decl_xdr_call (4, uc->decl, str);
311 union_cases = union_cases->next;
324 gen_typedef (const struct decl *decl)
331 fputs ("typedef ", yyout);
335 "extern bool_t xdr_%s (XDR *, %s *);\n"
337 decl->ident, decl->ident);
343 fprintf (yyout, "xdr_%s (XDR *xdrs, %s *objp)\n",
344 decl->ident, decl->ident);
345 fprintf (yyout, "{\n");
346 gen_decl_xdr_call (2, decl, "&objp->");
356 gen_decl (int indent, const struct decl *decl)
360 switch (decl->decl_type)
362 case decl_type_string:
363 fprintf (yyout, "char *%s;\n", decl->ident);
366 case decl_type_opaque_fixed:
367 fprintf (yyout, "char %s[%s];\n", decl->ident, decl->len);
370 case decl_type_opaque_variable:
371 fprintf (yyout, "struct {\n");
373 fprintf (yyout, "uint32_t %s_len;\n", decl->ident);
375 fprintf (yyout, "char *%s_val;\n", decl->ident);
377 fprintf (yyout, "} %s;\n", decl->ident);
380 case decl_type_simple:
381 gen_type (decl->type);
382 fprintf (yyout, " %s;\n", decl->ident);
385 case decl_type_fixed_array:
386 gen_type (decl->type);
387 fprintf (yyout, " %s[%s];\n", decl->ident, decl->len);
390 case decl_type_variable_array:
391 fprintf (yyout, "struct {\n");
393 fprintf (yyout, "uint32_t %s_len;\n", decl->ident);
395 gen_type (decl->type);
396 fprintf (yyout, " *%s_val;\n", decl->ident);
398 fprintf (yyout, "} %s;\n", decl->ident);
401 case decl_type_pointer:
402 gen_type (decl->type);
403 fprintf (yyout, " *%s;\n", decl->ident);
409 xdr_func_of_simple_type (const struct type *type)
413 /* The caller supplies the "xdr_" prefix. */
414 switch (type->type) {
416 if (type->sgn) r = "char"; else r = "u_char";
419 if (type->sgn) r = "short"; else r = "u_short";
422 if (type->sgn) r = "int"; else r = "u_int";
425 if (type->sgn) r = "quad_t"; else r = "u_quad_t";
439 default: abort (); /* Avoid GCC warning. */
444 /* Caller must free the result. */
446 sizeof_simple_type (const struct type *type)
451 switch (type->type) {
453 r = strdup ("1"); /* Note: fixed by the XDR RFC. */
474 len = strlen (type->ident) + 10;
476 snprintf (str, len, "sizeof (%s)", type->ident);
479 default: abort (); /* Avoid GCC warning. */
486 gen_decl_xdr_call (int indent, const struct decl *decl, const char *struct_name)
493 switch (decl->decl_type)
495 case decl_type_string:
497 fprintf (yyout, "if (!xdr_string (xdrs, objp, %s))\n", decl->len);
499 fprintf (yyout, "if (!xdr_string (xdrs, objp, ~0))\n");
502 case decl_type_opaque_fixed:
503 fprintf (yyout, "if (!xdr_opaque (xdrs, &objp, %s))\n", decl->len);
506 case decl_type_opaque_variable:
507 len_str = decl->len ? : "~0";
509 "if (!xdr_bytes (xdrs, %s%s.%s_val, %s%s.%s_len, %s))\n",
510 struct_name, decl->ident, decl->ident,
511 struct_name, decl->ident, decl->ident, len_str);
514 case decl_type_simple:
515 fprintf (yyout, "if (!xdr_%s (xdrs, %s%s))\n",
516 xdr_func_of_simple_type (decl->type), struct_name, decl->ident);
519 case decl_type_fixed_array:
520 str = sizeof_simple_type (decl->type);
522 "if (!xdr_vector (xdrs, %s%s, %s, %s, (xdrproc_t) xdr_%s))\n",
523 struct_name, decl->ident, decl->len,
524 str, xdr_func_of_simple_type (decl->type));
528 case decl_type_variable_array:
529 str = sizeof_simple_type (decl->type);
530 len_str = decl->len ? : "~0";
532 "if (!xdr_array (xdrs, %s%s.%s_val, %s%s.%s_len, %s, %s, (xdrproc_t) xdr_%s))\n",
533 struct_name, decl->ident, decl->ident,
534 struct_name, decl->ident, decl->ident,
536 str, xdr_func_of_simple_type (decl->type));
540 case decl_type_pointer:
541 str = sizeof_simple_type (decl->type);
542 fprintf (yyout, "if (!xdr_pointer (xdrs, objp, %s, (xdrproc_t) xdr_%s))\n",
543 str, xdr_func_of_simple_type (decl->type));
549 fprintf (yyout, "return FALSE;\n");
553 gen_type (const struct type *type)
558 if (type->sgn) fputs ("int8_t", yyout);
559 else fputs ("uint8_t", yyout);
563 if (type->sgn) fputs ("int16_t", yyout);
564 else fputs ("uint16_t", yyout);
568 if (type->sgn) fputs ("int32_t", yyout);
569 else fputs ("uint32_t", yyout);
573 if (type->sgn) fputs ("int64_t", yyout);
574 else fputs ("uint64_t", yyout);
578 fputs ("float", yyout);
582 fputs ("double", yyout);
586 fputs ("bool_t", yyout);
590 fputs (type->ident, yyout);