diff --git a/ocaml/sdk-gen/c/gen_c_binding.ml b/ocaml/sdk-gen/c/gen_c_binding.ml index 5203b86f2e0..e9035a88c7f 100644 --- a/ocaml/sdk-gen/c/gen_c_binding.ml +++ b/ocaml/sdk-gen/c/gen_c_binding.ml @@ -83,11 +83,7 @@ let rec main () = all_headers := List.map (fun x -> x.name) filtered_classes ; - TypeSet.iter (gen_enum write_enum_decl decl_filename include_dir) !enums ; - TypeSet.iter (gen_enum write_enum_impl impl_filename src_dir) !enums ; - TypeSet.iter - (gen_enum write_enum_internal_decl internal_decl_filename include_dir) - !enums ; + TypeSet.iter render_enum !enums ; maps := TypeSet.add (Map (String, Int)) !maps ; maps := TypeSet.add (Map (Int, Int)) !maps ; @@ -140,17 +136,6 @@ and gen_class f g clas targetdir = let out_chan = open_out (Filename.concat targetdir (g clas.name)) in Fun.protect (fun () -> f clas out_chan) ~finally:(fun () -> close_out out_chan) -and gen_enum f g targetdir = function - | Enum (name, _) as x -> - if not (List.mem name !all_headers) then - all_headers := name :: !all_headers ; - let out_chan = open_out (Filename.concat targetdir (g name)) in - Fun.protect - (fun () -> f x out_chan) - ~finally:(fun () -> close_out out_chan) - | _ -> - assert false - and gen_map f g targetdir = function | Map (l, r) -> let name = mapname l r in @@ -669,174 +654,49 @@ and hash_include n = else sprintf "#include <%s>" (decl_filename n) -and write_enum_decl x out_chan = - match x with - | Enum (name, contents) -> - let print format = fprintf out_chan format in - let protect = protector name in - let tn = typename name in - - print_h_header out_chan protect ; +and replace_dashes x = + Astring.String.map (fun y -> match y with '-' -> '_' | _ -> y) x - print - "\n\ - %s\n\n\n\ - enum %s\n\ - {\n\ - %s\n\ - };\n\n\n\ - typedef struct %s_set\n\ - {\n\ - \ size_t size;\n\ - \ enum %s contents[];\n\ - } %s_set;\n\n\ - %s\n\ - extern %s_set *\n\ - %s_set_alloc(size_t size);\n\n\ - %s\n\n\n\ - %s\n\ - extern const char *\n\ - %s_to_string(enum %s val);\n\n\n\ - %s\n\ - extern enum %s\n\ - %s_from_string(xen_session *session, const char *str);\n\n" - (hash_include "common") tn - (joined ",\n\n" (enum_entry name) - (contents - @ [("undefined", "Unknown to this version of the bindings.")] - ) - ) - tn tn tn - (Helper.comment true (sprintf "Allocate a %s_set of the given size." tn)) - tn tn - (decl_free (sprintf "%s_set" tn) "*set" false "set") - (Helper.comment true - "Return the name corresponding to the given code. This string must \ - not be modified or freed." - ) - tn tn - (Helper.comment true - "Return the correct code for the given string, or set the session \ - object to failure and return an undefined value if the given \ - string does not match a known code." - ) - tn tn ; - - print_h_footer out_chan - | _ -> - () - -and enum_entry enum_name = function - | n, c -> - sprintf "%s\n XEN_%s_%s" - (Helper.comment true ~indent:4 c) - (String.uppercase_ascii enum_name) - (Astring.String.map - (fun x -> match x with '-' -> '_' | _ -> x) - (String.uppercase_ascii n) - ) - -and write_enum_impl x out_chan = +and render_enum x = match x with | Enum (name, contents) -> - let print format = fprintf out_chan format in - let tn = typename name in - - print - "%s\n\n\ - #include \n\n\ - %s\n\ - %s\n\ - %s\n\n\n\ - /*\n\ - \ * Maintain this in the same order as the enum declaration!\n\ - \ */\n\ - static const char *lookup_table[] =\n\ - {\n\ - %s\n\ - };\n\n\n\ - extern %s_set *\n\ - %s_set_alloc(size_t size)\n\ - {\n\ - \ return calloc(1, sizeof(%s_set) +\n\ - \ size * sizeof(enum %s));\n\ - }\n\n\n\ - extern void\n\ - %s_set_free(%s_set *set)\n\ - {\n\ - \ free(set);\n\ - }\n\n\n\ - const char *\n\ - %s_to_string(enum %s val)\n\ - {\n\ - \ return lookup_table[val];\n\ - }\n\n\n\ - extern enum %s\n\ - %s_from_string(xen_session *session, const char *str)\n\ - {\n\ - \ (void)session;\n\ - \ return ENUM_LOOKUP(str, lookup_table);\n\ - }\n\n\n\ - const abstract_type %s_abstract_type_ =\n\ - \ {\n\ - \ .XEN_API_TYPE = ENUM,\n\ - \ .enum_marshaller =\n\ - \ (const char *(*)(int))&%s_to_string,\n\ - \ .enum_demarshaller =\n\ - \ (int (*)(xen_session *, const char *))&%s_from_string\n\ - \ };\n\n\n" - Licence.bsd_two_clause (hash_include "internal") (hash_include name) - (hash_include (name ^ "_internal")) - (enum_lookup_entries (contents @ [("undefined", "")])) - tn tn tn tn tn tn tn tn tn tn tn tn tn ; - - if name <> "event_operation" then - print - "const abstract_type %s_set_abstract_type_ =\n\ - \ {\n\ - \ .XEN_API_TYPE = SET,\n\ - \ .child = &%s_abstract_type_\n\ - \ };\n\n\n" - tn tn - | _ -> - () - -and enum_lookup_entries contents = joined ",\n" enum_lookup_entry contents - -and enum_lookup_entry = function n, _ -> sprintf " \"%s\"" n - -and write_enum_internal_decl x out_chan = - match x with - | Enum (name, _) -> - let print format = fprintf out_chan format in - let protect = protector (sprintf "%s_internal" name) in - let tn = typename name in - - let set_abstract_type = - if name = "event_operations" then - "" - else - sprintf "extern const abstract_type %s_set_abstract_type_;\n" tn + if not (List.mem name !all_headers) then + all_headers := name :: !all_headers ; + let json = + `O + [ + ("enum_name", `String name) + ; ("enum_name_upper", `String (String.uppercase_ascii name)) + ; ("event_operations", `Bool (name = "event_operation")) + ; ( "enum_values" + , `A + (List.map + (fun (n, c) -> + `O + [ + ("enum_value", `String n) + ; ("enum_value_doc", `String c) + ; ( "enum_value_upper" + , `String (replace_dashes (String.uppercase_ascii n)) + ) + ] + ) + contents + ) + ) + ] in - - print - "%s\n\n\n\ - %s\n\n\n\ - #ifndef %s\n\ - #define %s\n\n\n\ - %s\n\n\n\ - extern const abstract_type %s_abstract_type_;\n\ - %s\n\n\ - #endif\n" - Licence.bsd_two_clause - (Helper.comment false - (sprintf - "Declarations of the abstract types used during demarshalling of \ - enum %s. Internal to this library -- do not use from outside." - tn - ) + render_file + ( "xen_enum_internal.h.mustache" + , sprintf "include/xen_%s_internal.h" name ) - protect protect (hash_include "internal") tn set_abstract_type + json templates_dir destdir ; + render_file + ("xen_enum.h.mustache", sprintf "include/xen/api/xen_%s.h" name) + json templates_dir destdir ; + render_file + ("xen_enum.c.mustache", sprintf "src/xen_%s.c" name) + json templates_dir destdir | _ -> () diff --git a/ocaml/sdk-gen/c/templates/xen_enum.c.mustache b/ocaml/sdk-gen/c/templates/xen_enum.c.mustache new file mode 100644 index 00000000000..421c9015a6f --- /dev/null +++ b/ocaml/sdk-gen/c/templates/xen_enum.c.mustache @@ -0,0 +1,98 @@ +/* + * Copyright (c) Cloud Software Group, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include + +#include "xen_internal.h" +#include +#include "xen_{{{enum_name}}}_internal.h" + + +/* + * Maintain this in the same order as the enum declaration! + */ +static const char *lookup_table[] = +{ +{{#enum_values}} + "{{{enum_value}}}", +{{/enum_values}} + "undefined" +}; + + +extern xen_{{{enum_name}}}_set * +xen_{{{enum_name}}}_set_alloc(size_t size) +{ + return calloc(1, sizeof(xen_{{{enum_name}}}_set) + + size * sizeof(enum xen_{{{enum_name}}})); +} + + +extern void +xen_{{{enum_name}}}_set_free(xen_{{{enum_name}}}_set *set) +{ + free(set); +} + + +const char * +xen_{{{enum_name}}}_to_string(enum xen_{{{enum_name}}} val) +{ + return lookup_table[val]; +} + + +extern enum xen_{{{enum_name}}} +xen_{{{enum_name}}}_from_string(xen_session *session, const char *str) +{ + (void)session; + return ENUM_LOOKUP(str, lookup_table); +} + + +const abstract_type xen_{{{enum_name}}}_abstract_type_ = + { + .XEN_API_TYPE = ENUM, + .enum_marshaller = + (const char *(*)(int))&xen_{{{enum_name}}}_to_string, + .enum_demarshaller = + (int (*)(xen_session *, const char *))&xen_{{{enum_name}}}_from_string + }; + + +{{^event_operations}} +const abstract_type xen_{{{enum_name}}}_set_abstract_type_ = + { + .XEN_API_TYPE = SET, + .child = &xen_{{{enum_name}}}_abstract_type_ + }; + + +{{/event_operations}} diff --git a/ocaml/sdk-gen/c/templates/xen_enum.h.mustache b/ocaml/sdk-gen/c/templates/xen_enum.h.mustache new file mode 100644 index 00000000000..824179cf2d3 --- /dev/null +++ b/ocaml/sdk-gen/c/templates/xen_enum.h.mustache @@ -0,0 +1,91 @@ +/* + * Copyright (c) Cloud Software Group, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef XEN_{{{enum_name_upper}}}_H +#define XEN_{{{enum_name_upper}}}_H + + +#include + + +enum xen_{{{enum_name}}} +{ +{{#enum_values}} + /** + * {{{enum_value_doc}}} + */ + XEN_{{{enum_name_upper}}}_{{{enum_value_upper}}}, + +{{/enum_values}} + /** + * Unknown to this version of the bindings. + */ + XEN_{{{enum_name_upper}}}_UNDEFINED +}; + + +typedef struct xen_{{{enum_name}}}_set +{ + size_t size; + enum xen_{{{enum_name}}} contents[]; +} xen_{{{enum_name}}}_set; + +/** + * Allocate a xen_{{{enum_name}}}_set of the given size. + */ +extern xen_{{{enum_name}}}_set * +xen_{{{enum_name}}}_set_alloc(size_t size); + +/** + * Free the given xen_{{{enum_name}}}_set. The given set must have been + * allocated by this library. + */ +extern void +xen_{{{enum_name}}}_set_free(xen_{{{enum_name}}}_set *set); + + +/** + * Return the name corresponding to the given code. This string must + * not be modified or freed. + */ +extern const char * +xen_{{{enum_name}}}_to_string(enum xen_{{{enum_name}}} val); + + +/** + * Return the correct code for the given string, or set the session + * object to failure and return an undefined value if the given string does + * not match a known code. + */ +extern enum xen_{{{enum_name}}} +xen_{{{enum_name}}}_from_string(xen_session *session, const char *str); + + +#endif diff --git a/ocaml/sdk-gen/c/templates/xen_enum_internal.h.mustache b/ocaml/sdk-gen/c/templates/xen_enum_internal.h.mustache new file mode 100644 index 00000000000..b9731686edb --- /dev/null +++ b/ocaml/sdk-gen/c/templates/xen_enum_internal.h.mustache @@ -0,0 +1,51 @@ +/* + * Copyright (c) Cloud Software Group, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + + +/* + * Declarations of the abstract types used during demarshalling of enum + * xen_{{{enum_name}}}. Internal to this library -- do not use from outside. + */ + + +#ifndef XEN_{{{enum_name_upper}}}_INTERNAL_H +#define XEN_{{{enum_name_upper}}}_INTERNAL_H + + +#include "xen_internal.h" + + +extern const abstract_type xen_{{{enum_name}}}_abstract_type_; +{{^event_operations}} +extern const abstract_type xen_{{{enum_name}}}_set_abstract_type_; +{{/event_operations}} + + +#endif diff --git a/ocaml/sdk-gen/csharp/templates/XenServer.csproj.mustache b/ocaml/sdk-gen/csharp/autogen/src/XenServer.csproj similarity index 100% rename from ocaml/sdk-gen/csharp/templates/XenServer.csproj.mustache rename to ocaml/sdk-gen/csharp/autogen/src/XenServer.csproj diff --git a/ocaml/sdk-gen/csharp/gen_csharp_binding.ml b/ocaml/sdk-gen/csharp/gen_csharp_binding.ml index 0c70b85c6d6..56243c59fcd 100644 --- a/ocaml/sdk-gen/csharp/gen_csharp_binding.ml +++ b/ocaml/sdk-gen/csharp/gen_csharp_binding.ml @@ -89,18 +89,6 @@ let rec main () = ("HTTP_actions.mustache", "HTTP_actions.cs") (gen_http_actions ()) templdir destdir ; gen_relations () ; - let sorted_members = List.sort String.compare !api_members in - let json = - `O - [ - ( "api_members" - , `A (List.map (fun x -> `O [("api_member", `String x)]) sorted_members) - ) - ] - in - render_file - ("XenServer.csproj.mustache", "XenServer.csproj") - json templdir destdir ; render_file ("ApiVersion.mustache", "ApiVersion.cs") json_releases templdir destdir @@ -109,33 +97,42 @@ let rec main () = and relations = Hashtbl.create 10 and gen_relations () = - let out_chan = open_out (Filename.concat destdir "Relation.cs") in - let print format = fprintf out_chan format in List.iter process_relations (relations_of_api api) ; - print - "%s\n\n\ - using System;\n\ - using System.Collections.Generic;\n\n\ - namespace XenAPI\n\ - {\n\ - \ public partial class Relation\n\ - \ {\n\ - \ public readonly String field;\n\ - \ public readonly String manyType;\n\ - \ public readonly String manyField;\n\n\ - \ public Relation(String field, String manyType, String manyField)\n\ - \ {\n\ - \ this.field = field;\n\ - \ this.manyField = manyField;\n\ - \ this.manyType = manyType;\n\ - \ }\n\n\ - \ public static Dictionary GetRelations()\n\ - \ {\n\ - \ Dictionary relations = new Dictionary();\n\n" - Licence.bsd_two_clause ; - Hashtbl.iter (gen_relations_by_type out_chan) relations ; - print "\n return relations;\n }\n }\n}\n" + let typelist = + List.rev (Hashtbl.fold (fun k v acc -> (k, v) :: acc) relations []) + in + let json = + `O + [ + ( "types" + , `A + (List.map + (fun (k, v) -> + `O + [ + ("type", `String (exposed_class_name k)) + ; ( "relations" + , `A + (List.map + (fun (x, y, z) -> + `O + [ + ("field", `String x) + ; ("manyType", `String y) + ; ("manyField", `String z) + ] + ) + v + ) + ) + ] + ) + typelist + ) + ) + ] + in + render_file ("Relation.mustache", "Relation.cs") json templdir destdir and process_relations ((oneClass, oneField), (manyClass, manyField)) = let value = @@ -144,20 +141,6 @@ and process_relations ((oneClass, oneField), (manyClass, manyField)) = in Hashtbl.replace relations manyClass value -and gen_relations_by_type out_chan manyClass relations = - let print format = fprintf out_chan format in - print " relations.Add(typeof(%s), new Relation[] {\n" - (exposed_class_name manyClass) ; - - List.iter (gen_relation out_chan) relations ; - - print " });\n\n" - -and gen_relation out_chan (manyField, oneClass, oneField) = - let print format = fprintf out_chan format in - print " new Relation(\"%s\", \"%s\", \"%s\"),\n" manyField - oneClass oneField - (* ------------------- category: http_actions *) and gen_http_actions () = (* Each action has: @@ -841,70 +824,44 @@ and gen_enum' name contents = (* ------------------- category: maps *) and gen_maps () = - let out_chan = open_out (Filename.concat destdir "Maps.cs") in - Fun.protect - (fun () -> gen_maps' out_chan) - ~finally:(fun () -> close_out out_chan) - -and gen_maps' out_chan = - let print format = fprintf out_chan format in - - print - "%s\n\n\ - using System;\n\ - using System.Collections;\n\ - using System.Collections.Generic;\n\n\ - \ namespace XenAPI\n\ - {\n\ - \ internal class Maps\n\ - \ {" Licence.bsd_two_clause ; - - TypeSet.iter (gen_map_conversion out_chan) !maps ; - - print "\n }\n}\n" - -and gen_map_conversion out_chan = function - | Map (l, r) -> - let print format = fprintf out_chan format in - let el = exposed_type l in - let el_literal = exposed_type_as_literal l in - let er = exposed_type r in - let er_literal = exposed_type_as_literal r in - - print - "\n\ - \ internal static Dictionary<%s, %s> \ - ToDictionary_%s_%s(Hashtable table)\n\ - \ {\n\ - \ Dictionary<%s, %s> result = new Dictionary<%s, %s>();\n\ - \ if (table != null)\n\ - \ {\n\ - \ foreach (string key in table.Keys)\n\ - \ {\n\ - \ try\n\ - \ {\n\ - \ %s k = %s;\n\ - \ %s v = %s;\n\ - \ result[k] = v;\n\ - \ }\n\ - \ catch\n\ - \ {\n\ - \ // continue\n\ - \ }\n\ - \ }\n\ - \ }\n\ - \ return result;\n\ - \ }\n\n" - el er - (sanitise_function_name el_literal) - (sanitise_function_name er_literal) - el er el er el - (simple_convert_from_proxy "key" l) - er - (convert_from_proxy_hashtable_value "table[key]" r) - (***) - | _ -> - assert false + let mapList = List.rev (TypeSet.fold (fun x acc -> x :: acc) !maps []) in + let json = + `O + [ + ( "all_maps" + , `A + (List.map + (function + | Map (l, r) -> + `O + [ + ("map_key", `String (exposed_type l)) + ; ("map_value", `String (exposed_type r)) + ; ( "sanitised_key" + , `String + (sanitise_function_name (exposed_type_as_literal l)) + ) + ; ( "sanitised_value" + , `String + (sanitise_function_name (exposed_type_as_literal r)) + ) + ; ( "proxy_key" + , `String (simple_convert_from_proxy "key" l) + ) + ; ( "proxy_value" + , `String + (convert_from_proxy_hashtable_value "table[key]" r) + ) + ] + | _ -> + `Null + ) + mapList + ) + ) + ] + in + render_file ("Maps.mustache", "Maps.cs") json templdir destdir (* ------------------- category: utility *) and exposed_type_opt = function @@ -991,7 +948,6 @@ and convert_from_proxy_hashtable_value thing ty = convert_from_proxy thing ty and convert_from_proxy thing ty = - (*function*) match ty with | DateTime -> thing diff --git a/ocaml/sdk-gen/csharp/templates/Maps.mustache b/ocaml/sdk-gen/csharp/templates/Maps.mustache new file mode 100644 index 00000000000..b8942e88731 --- /dev/null +++ b/ocaml/sdk-gen/csharp/templates/Maps.mustache @@ -0,0 +1,64 @@ +/* + * Copyright (c) Cloud Software Group, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace XenAPI +{ + internal class Maps + { +{{#all_maps}} + internal static Dictionary<{{{map_key}}}, {{{map_value}}}> ToDictionary_{{{sanitised_key}}}_{{{sanitised_value}}}(Hashtable table) + { + var result = new Dictionary<{{{map_key}}}, {{{map_value}}}>(); + if (table != null) + { + foreach (string key in table.Keys) + { + try + { + {{{map_key}}} k = {{{proxy_key}}}; + {{{map_value}}} v = {{{proxy_value}}}; + result[k] = v; + } + catch + { + // continue + } + } + } + return result; + } + +{{/all_maps}} + } +} diff --git a/ocaml/sdk-gen/csharp/templates/Relation.mustache b/ocaml/sdk-gen/csharp/templates/Relation.mustache new file mode 100644 index 00000000000..69f3cd8c834 --- /dev/null +++ b/ocaml/sdk-gen/csharp/templates/Relation.mustache @@ -0,0 +1,64 @@ +/* + * Copyright (c) Cloud Software Group, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +using System; +using System.Collections.Generic; + +namespace XenAPI +{ + public partial class Relation + { + public readonly String field; + public readonly String manyType; + public readonly String manyField; + + public Relation(String field, String manyType, String manyField) + { + this.field = field; + this.manyField = manyField; + this.manyType = manyType; + } + + public static Dictionary GetRelations() + { + Dictionary relations = new Dictionary(); +{{#types}} + + relations.Add(typeof({{type}}), new Relation[] { + {{#relations}} + new Relation("{{field}}", "{{manyType}}", "{{manyField}}"), + {{/relations}} + }); +{{/types}} + + return relations; + } + } +} diff --git a/ocaml/sdk-gen/powershell/gen_powershell_binding.ml b/ocaml/sdk-gen/powershell/gen_powershell_binding.ml index 26b94fba23e..b455d010486 100644 --- a/ocaml/sdk-gen/powershell/gen_powershell_binding.ml +++ b/ocaml/sdk-gen/powershell/gen_powershell_binding.ml @@ -19,6 +19,8 @@ end) let destdir = "autogen/src" +let templdir = "templates" + type cmdlet = {filename: string; content: string} let api = @@ -67,17 +69,38 @@ let generated x = not (List.mem x.name ["blob"; "session"; "debug"; "event"; "vtpm"]) let rec main () = - gen_xenref_converters classes ; + let json = + `O + [ + ( "all_classes" + , `A + (List.map + (fun x -> + `O + [ + ("exposed_name", `String (exposed_class_name x.name)) + ; ( "var_name" + , `String (ocaml_class_to_csharp_local_var x.name) + ) + ] + ) + classes + ) + ) + ] + in + render_file + ("ConvertTo-XenRef.mustache", "ConvertTo-XenRef.cs") + json templdir destdir ; + + http_actions + |> List.filter (fun (_, (_, _, sdk, _, _, _)) -> sdk) + |> List.iter gen_http_action ; + let cmdlets = classes |> List.filter generated |> List.map gen_cmdlets |> List.concat in - let http_cmdlets = - http_actions - |> List.filter (fun (_, (_, _, sdk, _, _, _)) -> sdk) - |> List.map gen_http_action - in - let all_cmdlets = cmdlets @ http_cmdlets in - List.iter (fun x -> write_file x.filename x.content) all_cmdlets + List.iter (fun x -> write_file x.filename x.content) cmdlets (****************) (* Http actions *) @@ -87,196 +110,58 @@ and gen_http_action action = let commonVerb = get_http_action_verb name meth in let verbCategory = get_common_verb_category commonVerb in let stem = get_http_action_stem name in - let content = - sprintf - "%s\n\n\ - using System;\n\ - using System.Collections;\n\ - using System.Collections.Generic;\n\ - using System.Management.Automation;\n\ - using XenAPI;\n\n\ - namespace Citrix.XenServer.Commands\n\ - {\n\ - \ [Cmdlet(%s.%s, \"Xen%s\"%s)]\n\ - \ [OutputType(typeof(void))]\n\ - \ public class %sXen%sCommand : XenServerHttpCmdlet\n\ - \ {\n\ - \ #region Cmdlet Parameters\n\ - %s%s\n\ - \ #endregion\n\n\ - \ #region Cmdlet Methods\n\n\ - \ protected override void ProcessRecord()\n\ - \ {\n\ - \ GetSession();\n\ - %s\n\ - \ RunApiCall(() => %s);\n\ - \ }\n\n\ - \ #endregion\n\ - \ }\n\ - }\n" - Licence.bsd_two_clause verbCategory commonVerb stem - (gen_should_process_http_decl meth) - commonVerb stem - (gen_progress_tracker meth) - (gen_arg_params args) - (gen_should_process_http meth uri) - (gen_http_action_call action) + let arg_name = function + | String_query_arg x | Int64_query_arg x -> + pascal_case_rec x + | Bool_query_arg x -> + if String.lowercase_ascii x = "host" then + "IsHost" + else + pascal_case_rec x + | Varargs_query_arg -> + "Args" in - {filename= sprintf "%s-Xen%s.cs" commonVerb stem; content} - -and gen_should_process_http_decl meth = - match meth with - | Put -> - ", SupportsShouldProcess = true" - | Get -> - ", SupportsShouldProcess = false" - | _ -> - assert false - -and gen_should_process_http meth uri = - match meth with - | Put -> - sprintf - "\n if (!ShouldProcess(\"%s\"))\n return;\n" - uri - | _ -> - "" - -and gen_progress_tracker meth = - match meth with - | Get -> - "\n\ - \ [Parameter]\n\ - \ public HTTP.DataCopiedDelegate DataCopiedDelegate { get; set; }\n" - | Put -> - "\n\ - \ [Parameter]\n\ - \ public HTTP.UpdateProgressDelegate ProgressDelegate { get; set; }\n" - | _ -> - assert false - -and gen_arg_params args = - match args with - | [] -> - "" - | hd :: tl -> - sprintf "%s%s" (gen_arg_param hd) (gen_arg_params tl) - -and gen_arg_param = function - | String_query_arg x -> - sprintf - "\n [Parameter%s]\n public string %s { get; set; }\n" - ( if String.lowercase_ascii x = "uuid" then - "(ValueFromPipelineByPropertyName = true)" - else - "" + let arg_type = function + | String_query_arg _ -> + "string" + | Int64_query_arg _ -> + "long?" + | Bool_query_arg _ -> + "bool?" + | Varargs_query_arg -> + "string[]" + in + let json = + `O + [ + ("verb_category", `String verbCategory) + ; ("common_verb", `String commonVerb) + ; ("stem", `String stem) + ; ("isPut", `Bool (meth == Put)) + ; ("isGet", `Bool (meth == Get)) + ; ("uri", `String uri) + ; ("action_name", `String name) + ; ( "args" + , `A + (List.map + (fun x -> + `O + [ + ("arg_type", `String (arg_type x)) + ; ("arg_name", `String (arg_name x)) + ; ( "from_pipeline" + , `Bool (String.lowercase_ascii (arg_name x) = "uuid") + ) + ] + ) + args + ) ) - (pascal_case_rec x) - | Int64_query_arg x -> - sprintf "\n [Parameter]\n public long? %s { get; set; }\n" - (pascal_case_rec x) - | Bool_query_arg x -> - let y = if x = "host" then "is_host" else x in - sprintf "\n [Parameter]\n public bool? %s { get; set; }\n" - (pascal_case_rec y) - | Varargs_query_arg -> - sprintf - "\n\ - \ ///\n\ - \ /// Alternate names and values\n\ - \ ///\n\ - \ [Parameter]\n\ - \ public string[] Args { get; set; }\n" - -and gen_http_action_call (name, (meth, _, _, args, _, _)) = - let progressTracker = - match meth with - | Get -> - "DataCopiedDelegate" - | Put -> - "ProgressDelegate" - | _ -> - assert false + ] in - sprintf - "XenAPI.HTTP_actions.%s(%s,\n\ - \ CancellingDelegate, TimeoutMs, XenHost, Proxy, Path, \ - TaskRef,\n\ - \ session.opaque_ref%s)" name progressTracker - (gen_call_arg_params args) - -and gen_call_arg_params args = - match args with - | [] -> - "" - | hd :: tl -> - sprintf "%s%s" (gen_call_arg_param hd) (gen_call_arg_params tl) - -and gen_call_arg_param = function - | String_query_arg x -> - sprintf ", %s" (pascal_case_rec x) - | Int64_query_arg x -> - sprintf ", %s" (pascal_case_rec x) - | Bool_query_arg x -> - let y = if x = "host" then "is_host" else x in - sprintf ", %s" (pascal_case_rec y) - | Varargs_query_arg -> - sprintf ", Args" - -(***********************************) -(* Utility cmdlet ConvertTo-XenRef *) -(***********************************) -and gen_xenref_converters classes = - write_file "ConvertTo-XenRef.cs" (gen_body_xenref_converters classes) - -and gen_body_xenref_converters classes = - sprintf - "%s\n\n\ - using System;\n\ - using System.Collections;\n\ - using System.Collections.Generic;\n\ - using System.Management.Automation;\n\ - using XenAPI;\n\n\ - namespace Citrix.XenServer.Commands\n\ - {\n\ - \ [Cmdlet(VerbsData.ConvertTo, \"XenRef\")]\n\ - \ [OutputType(typeof(IXenObject))]\n\ - \ public class ConvertToXenRefCommand : PSCmdlet\n\ - \ {\n\ - \ #region Cmdlet Parameters\n\n\ - \ [Parameter(Mandatory = true, ValueFromPipeline = true, Position = \ - 0)]\n\ - \ public IXenObject XenObject { get; set; }\n\n\ - \ #endregion\n\n\ - \ #region Cmdlet Methods\n\n\ - \ protected override void ProcessRecord()\n\ - \ {%s\n\ - \ }\n\n\ - \ #endregion\n\n\ - \ }\n\ - }\n" - Licence.bsd_two_clause (print_converters classes) - -and print_converters classes = - match classes with - | [] -> - "" - | hd :: tl -> - sprintf - "\n\ - \ %s %s = XenObject as %s;\n\ - \ if (%s != null)\n\ - \ {\n\ - \ WriteObject(new XenRef<%s>(%s));\n\ - \ return;\n\ - \ }%s" - (qualified_class_name hd.name) - (ocaml_class_to_csharp_local_var hd.name) - (qualified_class_name hd.name) - (ocaml_class_to_csharp_local_var hd.name) - (qualified_class_name hd.name) - (ocaml_class_to_csharp_local_var hd.name) - (print_converters tl) + render_file + ("HttpAction.mustache", sprintf "%s-Xen%s.cs" commonVerb stem) + json templdir destdir (*************************) (* Autogenerated cmdlets *) diff --git a/ocaml/sdk-gen/powershell/templates/ConvertTo-XenRef.mustache b/ocaml/sdk-gen/powershell/templates/ConvertTo-XenRef.mustache new file mode 100644 index 00000000000..669704fa3d1 --- /dev/null +++ b/ocaml/sdk-gen/powershell/templates/ConvertTo-XenRef.mustache @@ -0,0 +1,63 @@ +/* + * Copyright (c) Cloud Software Group, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +using System.Management.Automation; +using XenAPI; + +namespace Citrix.XenServer.Commands +{ + [Cmdlet(VerbsData.ConvertTo, "XenRef")] + [OutputType(typeof(IXenObject))] + public class ConvertToXenRefCommand : PSCmdlet + { + #region Cmdlet Parameters + + [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0, + HelpMessage = "The API object to convert")] + public IXenObject XenObject { get; set; } + + #endregion + + #region Cmdlet Methods + + protected override void ProcessRecord() + { +{{#all_classes}} + if (XenObject is {{exposed_name}} {{var_name}}) + { + WriteObject(new XenRef<{{exposed_name}}>({{var_name}})); + return; + } +{{/all_classes}} + } + + #endregion + } +} diff --git a/ocaml/sdk-gen/powershell/templates/HttpAction.mustache b/ocaml/sdk-gen/powershell/templates/HttpAction.mustache new file mode 100644 index 00000000000..e346a68b8fe --- /dev/null +++ b/ocaml/sdk-gen/powershell/templates/HttpAction.mustache @@ -0,0 +1,80 @@ +/* + * Copyright (c) Cloud Software Group, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Management.Automation; +using XenAPI; + +namespace Citrix.XenServer.Commands +{ + [Cmdlet({{verb_category}}.{{common_verb}}, "Xen{{stem}}", SupportsShouldProcess = {{#isPut}}true{{/isPut}}{{#isGet}}false{{/isGet}})] + [OutputType(typeof(void))] + public class {{common_verb}}Xen{{stem}}Command : XenServerHttpCmdlet + { + #region Cmdlet Parameters +{{#isPut}} + + [Parameter] + public HTTP.UpdateProgressDelegate ProgressDelegate { get; set; } +{{/isPut}} +{{#isGet}} + + [Parameter] + public HTTP.DataCopiedDelegate DataCopiedDelegate { get; set; } +{{/isGet}} +{{#args}} + + [Parameter{{#from_pipeline}}(ValueFromPipelineByPropertyName = true){{/from_pipeline}}] + public {{arg_type}} {{arg_name}} { get; set; } +{{/args}} + + #endregion + + #region Cmdlet Methods + + protected override void ProcessRecord() + { + GetSession(); +{{#isPut}} + + if (!ShouldProcess("{{uri}}")) + return; +{{/isPut}} + + RunApiCall(() => HTTP_actions.{{action_name}}({{#isPut}}ProgressDelegate{{/isPut}}{{#isGet}}DataCopiedDelegate{{/isGet}}, + CancellingDelegate, TimeoutMs, XenHost, Proxy, Path, TaskRef, + session.opaque_ref{{#args}}, {{arg_name}}{{/args}})); + } + + #endregion + } +}