Add structs.
[wrappi.git] / generator / wrappi_c_impl.ml
index 2c3c143..74f4d39 100644 (file)
@@ -40,7 +40,9 @@ let c_of_ptype ~param = function
   | 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"
@@ -115,8 +117,25 @@ pr "\
   (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
   );