| TNullable TString -> if param then "const char *" else "char *"
| TNullable _ -> assert false (* XXX may be implemented in future *)
| TString -> if param then "const char *" else "char *"
- | TStruct name -> sprintf "struct wrap_%s" name
+ | TStruct name ->
+ if param then sprintf "const struct wrap_%s *" name
+ else sprintf "struct wrap_%s *" name
| TTypedef name -> assert false (* should never happen *)
| TUInt32 -> "uint32_t"
| TUInt64 -> "uint64_t"
(match ep.ep_code with
| None -> () (* XXX implicit code *)
| Some { cc_loc = loc; cc_code = code } ->
+ (* If the return is a struct/union/list then allocate the structure
+ * in a local variable called 'ret' which the function should
+ * assign to.
+ *)
+ let ret, _, _ = ep.ep_ftype in
+ (match ret with
+ | Return (TStruct name) ->
+ pr " struct wrap_%s *ret = malloc (sizeof *ret);\n" name;
+ pr " if (!ret) {\n";
+ pr " set_error_errno (\"malloc: struct wrap_%%s\", \"%s\");\n" name;
+ pr " return NULL;\n";
+ pr " }\n"
+ | _ -> () (* XXX union, list, etc. *)
+ );
+
+ (* Make sure included code has correct line numbers. *)
if not (Loc.is_ghost loc) then
pr "#line %d \"%s\"\n" (Loc.start_line loc) (Loc.file_name loc);
+
pr "%s" code
);