+static const char *
+xdr_func_of_simple_type (const struct type *type)
+{
+ const char *r;
+
+ /* The caller supplies the "xdr_" prefix. */
+ switch (type->type) {
+ case type_char:
+ if (type->sgn) r = "char"; else r = "u_char";
+ break;
+ case type_short:
+ if (type->sgn) r = "short"; else r = "u_short";
+ break;
+ case type_int:
+ if (type->sgn) r = "int"; else r = "u_int";
+ break;
+ case type_hyper:
+ if (type->sgn) r = "quad_t"; else r = "u_quad_t";
+ break;
+ case type_double:
+ r = "double";
+ break;
+ case type_bool:
+ r = "bool";
+ break;
+ case type_ident:
+ r = type->ident;
+ break;
+ default: abort (); /* Avoid GCC warning. */
+ }
+ return r;
+}
+
+/* Caller must free the result. */
+static char *
+sizeof_simple_type (const struct type *type)
+{
+ int len;
+ char *str, *r;
+
+ switch (type->type) {
+ case type_char:
+ r = strdup ("1"); /* Note: fixed by the XDR RFC. */
+ break;
+ case type_short:
+ r = strdup ("2");
+ break;
+ case type_int:
+ r = strdup ("4");
+ break;
+ case type_hyper:
+ r = strdup ("8");
+ break;
+ case type_double:
+ r = strdup ("8");
+ break;
+ case type_bool:
+ r = strdup ("4");
+ break;
+ case type_ident:
+ len = strlen (type->ident) + 10;
+ str = malloc (len);
+ snprintf (str, len, "sizeof (%s)", type->ident);
+ r = str;
+ break;
+ default: abort (); /* Avoid GCC warning. */
+ }
+
+ return r;
+}
+
+static void
+gen_decl_xdr_call (int indent, const struct decl *decl, const char *struct_name)
+{
+ char *str;
+ char *len_str;
+
+ spaces (indent);
+
+ switch (decl->decl_type)
+ {
+ case decl_type_string:
+ if (decl->len)
+ fprintf (yyout, "if (!xdr_string (xdrs, objp, %s))\n", decl->len);
+ else
+ fprintf (yyout, "if (!xdr_string (xdrs, objp, ~0))\n");
+ break;
+
+ case decl_type_opaque_fixed:
+ fprintf (yyout, "if (!xdr_opaque (xdrs, &objp, %s))\n", decl->len);
+ break;
+
+ case decl_type_opaque_variable:
+ len_str = decl->len ? : "~0";
+ fprintf (yyout,
+ "if (!xdr_bytes (xdrs, %s%s.%s_val, %s%s.%s_len, %s))\n",
+ struct_name, decl->ident, decl->ident,
+ struct_name, decl->ident, decl->ident, len_str);
+ break;
+
+ case decl_type_simple:
+ fprintf (yyout, "if (!xdr_%s (xdrs, %s%s))\n",
+ xdr_func_of_simple_type (decl->type), struct_name, decl->ident);
+ break;
+
+ case decl_type_fixed_array:
+ str = sizeof_simple_type (decl->type);
+ fprintf (yyout,
+ "if (!xdr_vector (xdrs, %s%s, %s, %s, (xdrproc_t) xdr_%s))\n",
+ struct_name, decl->ident, decl->len,
+ str, xdr_func_of_simple_type (decl->type));
+ free (str);
+ break;
+
+ case decl_type_variable_array:
+ str = sizeof_simple_type (decl->type);
+ len_str = decl->len ? : "~0";
+ fprintf (yyout,
+ "if (!xdr_array (xdrs, %s%s.%s_val, %s%s.%s_len, %s, %s, (xdrproc_t) xdr_%s))\n",
+ struct_name, decl->ident, decl->ident,
+ struct_name, decl->ident, decl->ident,
+ len_str,
+ str, xdr_func_of_simple_type (decl->type));
+ free (str);
+ break;
+
+ case decl_type_pointer:
+ str = sizeof_simple_type (decl->type);
+ fprintf (yyout, "if (!xdr_pointer (xdrs, objp, %s, (xdrproc_t) xdr_%s))\n",
+ str, xdr_func_of_simple_type (decl->type));
+ free (str);
+ break;
+ }
+
+ spaces (indent+2);
+ fprintf (yyout, "return FALSE;\n");
+}
+