(* wrappi * Copyright (C) 2011 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *) open Camlp4.PreCast open Wrappi_types open Wrappi_utils open Printf let extend_api api = let eps = ref api.api_entry_points in iter_enums api ( fun en -> let name = en.en_name in (* Add an entry point wrap__enum_to_string. *) let fname = sprintf "%s_enum_to_string" name in let code = let b = Buffer.create 512 in bprintf b " switch (v) {\n"; Array.iter ( fun id -> bprintf b " case WRAP_%s_%s: return \"%s\";\n" (String.uppercase name) (String.uppercase id) id; ) en.en_identifiers; bprintf b " default:\n"; bprintf b " set_error (\"unknown enum case %%d\", v);\n"; bprintf b " return NULL;\n"; bprintf b " }\n"; Buffer.contents b in let c_code = { cc_loc = Loc.ghost; cc_code = code; } in let ep = { ep_loc = Loc.ghost; ep_local = true; ep_name = fname; ep_ftype = RStaticString, ["v", TEnum name, None], []; ep_code = Some c_code; ep_includes = [] } in eps := StringMap.add fname ep !eps; (* Add an entry point wrap__string_to_enum. *) let fname = sprintf "%s_string_to_enum" name in let code = let b = Buffer.create 512 in Array.iter ( fun id -> bprintf b " if (STREQ (v, \"%s\"))\n" id; bprintf b " return WRAP_%s_%s;\n" (String.uppercase name) (String.uppercase id); ) en.en_identifiers; bprintf b " set_error (\"unknown enum case %%s\", v);\n"; bprintf b " return -1;\n"; Buffer.contents b in let c_code = { cc_loc = Loc.ghost; cc_code = code; } in let ep = { ep_loc = Loc.ghost; ep_local = true; ep_name = fname; ep_ftype = Return (TEnum name), ["v", TString, None], []; ep_code = Some c_code; ep_includes = [] } in eps := StringMap.add fname ep !eps; (* Add an entry point wrap__enum_nr. *) let fname = sprintf "%s_enum_nr" name in let code = sprintf " return %d;\n" (Array.length en.en_identifiers) in let c_code = { cc_loc = Loc.ghost; cc_code = code; } in let ep = { ep_loc = Loc.ghost; ep_local = true; ep_name = fname; ep_ftype = Return TInt, [], []; ep_code = Some c_code; ep_includes = [] } in eps := StringMap.add fname ep !eps; ); { api with api_entry_points = !eps }