/* -*- C -*- * rpcgen - Generate XDR bindings automatically. * Copyright (C) 2008 Red Hat Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include "rpcgen_int.h" static void gen_line (void); static void gen_decl (int indent, const struct decl *); static void gen_type (const struct type *); static void spaces (int n) { int i; for (i = 0; i < n; ++i) fputc (' ', yyout); } /* This generates a #line directive referring back to the * original source file. */ static void gen_line (void) { if (input_filename) fprintf (yyout, "#line %d \"%s\"\n", yylineno, input_filename); } static void write_header_def (void) { const char *p; p = strrchr (output_filename, '/') ? : output_filename; fputs ("RPCGEN_HEADER_", yyout); while (*p) { if (isalnum (*p)) fputc (toupper (*p), yyout); else fputc ('_', yyout); ++p; } } void gen_prologue (const char *filename) { char *basename; int len; fprintf (yyout, "/* This file was generated by PortableXDR rpcgen %s\n" " * ANY CHANGES YOU MAKE TO THIS FILE MAY BE LOST!\n" " * The input file was %s\n" " */\n" "\n", PACKAGE_VERSION, filename); switch (output_mode) { case output_c: len = strlen (filename); basename = malloc (len + 1); strcpy (basename, filename); if (len >= 2 && basename[len-2] == '.') basename[len-2] = '\0'; fprintf (yyout, "#include \"%s.h\"\n", basename); free (basename); break; case output_h: fprintf (yyout, "#ifndef "); write_header_def (); fprintf (yyout, "\n#define "); write_header_def (); fprintf (yyout, "\n" "\n" "#ifdef __cplusplus\n" "extern \"C\" {\n" "#endif\n" "\n" "#include \n" "#include \n" "\n"); break; } } void gen_epilogue (void) { gen_line (); switch (output_mode) { case output_c: break; case output_h: fprintf (yyout, "\n" "#ifdef __cplusplus\n" "}\n" "#endif\n" "\n" "#endif /* "); write_header_def (); fprintf (yyout, " */\n"); break; } fprintf (yyout, "\n/* EOF */\n"); } void gen_const (const char *name, const char *value) { if (output_mode == output_h) { gen_line (); fprintf (yyout, "#define %s %s\n", name, value); } } void gen_enum (const char *name, const struct cons *enum_values) { gen_line (); switch (output_mode) { case output_h: fprintf (yyout, "enum %s {\n", name); while (enum_values) { struct enum_value *enum_value = (struct enum_value *) enum_values->ptr; if (enum_value->value) fprintf (yyout, " %s = %s,\n", enum_value->ident, enum_value->value); else fprintf (yyout, " %s,\n", enum_value->ident); enum_values = enum_values->next; } fprintf (yyout, "};\n" "typedef enum %s %s;\n" "extern bool_t xdr_%s (XDR *, %s *);\n" "\n", name, name, name, name); break; case output_c: /* XXX */ break; } } void gen_struct (const char *name, const struct cons *decls) { gen_line (); switch (output_mode) { case output_h: fprintf (yyout, "struct %s {\n", name); while (decls) { gen_decl (2, (struct decl *) decls->ptr); decls = decls->next; } fprintf (yyout, "};\n" "typedef struct %s %s;\n" "extern bool_t xdr_%s (XDR *, %s *);\n" "\n", name, name, name, name); break; case output_c: /* XXX */ break; } } void gen_union (const char *name, const struct decl *discrim, const struct cons *union_cases) { gen_line (); switch (output_mode) { case output_h: fprintf (yyout, "struct %s {\n", name); gen_decl (2, discrim); fprintf (yyout, " union {\n"); while (union_cases) { struct decl *decl = ((struct union_case *) union_cases->ptr)->decl; if (decl) gen_decl (4, decl); union_cases = union_cases->next; } fprintf (yyout, " } %s_u;\n" "};\n" "typedef struct %s %s;\n" "extern bool_t xdr_%s (XDR *, %s *);\n" "\n", name, name, name, name, name); break; case output_c: /* XXX */ break; } } void gen_typedef (const struct decl *decl) { if (output_mode == output_h) { gen_line (); fputs ("typedef ", yyout); gen_decl (0, decl); fprintf (yyout, "extern bool_t xdr_%s (XDR *, %s *);\n" "\n", decl->ident, decl->ident); } } static void gen_decl (int indent, const struct decl *decl) { spaces (indent); switch (decl->decl_type) { case decl_type_simple: gen_type (decl->type); fprintf (yyout, " %s;\n", decl->ident); break; case decl_type_fixed_array: gen_type (decl->type); fprintf (yyout, " %s[%s];\n", decl->ident, decl->len); break; case decl_type_variable_array: fprintf (yyout, "struct {\n"); spaces (indent+2); fprintf (yyout, "uint32_t %s_len;\n", decl->ident); spaces (indent+2); gen_type (decl->type); fprintf (yyout, " *%s_val;\n", decl->ident); spaces (indent); fprintf (yyout, "} %s;\n", decl->ident); break; case decl_type_pointer: gen_type (decl->type); fprintf (yyout, " *%s;\n", decl->ident); break; } } static void gen_type (const struct type *type) { switch (type->type) { case type_char: if (type->sgn) fputs ("int8_t", yyout); else fputs ("uint8_t", yyout); break; case type_short: if (type->sgn) fputs ("int16_t", yyout); else fputs ("uint16_t", yyout); break; case type_int: if (type->sgn) fputs ("int32_t", yyout); else fputs ("uint32_t", yyout); break; case type_hyper: if (type->sgn) fputs ("int64_t", yyout); else fputs ("uint64_t", yyout); break; case type_double: fputs ("double", yyout); break; case type_string: fputs ("char *", yyout); break; case type_opaque: fputs ("char", yyout); break; case type_bool: fputs ("bool_t", yyout); break; case type_ident: fputs (type->ident, yyout); break; } }