diff --git a/.github/workflows/generate-and-build-sdks.yml b/.github/workflows/generate-and-build-sdks.yml index 80b32b5c8d9..db28438062f 100644 --- a/.github/workflows/generate-and-build-sdks.yml +++ b/.github/workflows/generate-and-build-sdks.yml @@ -24,6 +24,12 @@ jobs: shell: bash run: opam exec -- make sdk + - name: Store C SDK source + uses: actions/upload-artifact@v4 + with: + name: SDK_Source_C + path: _build/install/default/xapi/sdk/c/* + - name: Store C# SDK source uses: actions/upload-artifact@v4 with: @@ -39,6 +45,30 @@ jobs: - name: Cleanup XenAPI environment uses: ./.github/workflows/cleanup-xapi-environment + build-c-sdk: + name: Build C SDK + runs-on: ubuntu-latest + needs: generate-sdk-sources + steps: + - name: Install dependencies + run: sudo apt-get install libxml2-dev + + - name: Retrieve C SDK source + uses: actions/download-artifact@v4 + with: + name: SDK_Source_C + path: source/ + + - name: Build C SDK + shell: bash + run: make -C source + + - name: Store C SDK + uses: actions/upload-artifact@v4 + with: + name: SDK_Artifacts_C + path: source/* + build-csharp-sdk: name: Build C# SDK runs-on: windows-2022 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 87d5cc8721f..c4d133d2fa1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,6 +52,12 @@ jobs: name: XenAPI path: dist/ + - name: Retrieve C SDK distribution binaries + uses: actions/download-artifact@v4 + with: + name: SDK_Artifacts_C + path: libxenserver/usr/local/ + - name: Retrieve C# SDK distribution artifacts uses: actions/download-artifact@v4 with: @@ -70,10 +76,19 @@ jobs: name: SDK_Binaries_XenServerPowerShell_NET6 path: sdk_powershell_7x/ + - name: Package C SDK artifacts for deployment + shell: bash + run: | + mkdir -p libxenserver/usr/local/lib + mv libxenserver/usr/local/libxenserver.* libxenserver/usr/local/lib/ + tar -zcvf libxenserver-prerelease.tar.gz -C ./libxenserver usr/local/lib/ usr/local/include/xen/api + rm -rf libxenserver/usr/local/lib/ + tar -zcvf libxenserver-prerelease.src.tar.gz -C ./libxenserver/usr/local . + - name: Zip PowerShell 5.x SDK artifacts for deployment shell: bash run: zip PowerShell-SDK-5.x-prerelease-unsigned.zip ./sdk_powershell_5x -r - + - name: Zip PowerShell 7.x SDK artifacts for deployment shell: bash run: zip PowerShell-SDK-7.x-prerelease-unsigned.zip ./sdk_powershell_7x -r @@ -83,7 +98,8 @@ jobs: run: | gh release create ${{ github.ref_name }} --repo ${{ github.repository }} --generate-notes dist/* \ PowerShell-SDK-5.x-prerelease-unsigned.zip \ - PowerShell-SDK-7.x-prerelease-unsigned.zip + PowerShell-SDK-7.x-prerelease-unsigned.zip \ + libxenserver-prerelease.tar.gz libxenserver-prerelease.src.tar.gz env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Makefile b/Makefile index d7f3db993be..43ebc394d85 100644 --- a/Makefile +++ b/Makefile @@ -117,15 +117,10 @@ sdk: sh ocaml/sdk-gen/windows-line-endings.sh $(XAPISDK)/csharp sh ocaml/sdk-gen/windows-line-endings.sh $(XAPISDK)/powershell -.PHONY: sdk-build-c sdk sdksanity +.PHONY: sdk-build-c sdk-build-c: sdk - cd _build/install/default/xapi/sdk/c && make -j $(JOBS) - -# workaround for no .resx generation, just for compilation testing -sdksanity: sdk - sed -i 's/FriendlyErrorNames.ResourceManager/null/g' ./_build/install/default/xapi/sdk/csharp/src/Failure.cs - cd _build/install/default/xapi/sdk/csharp/src && dotnet add package Newtonsoft.Json && dotnet build -f netstandard2.0 + cd _build/install/default/xapi/sdk/c && make clean && make -j $(JOBS) .PHONY: sdk-build-java diff --git a/ocaml/idl/datamodel.ml b/ocaml/idl/datamodel.ml index a9f219e91af..11442e2494e 100644 --- a/ocaml/idl/datamodel.ml +++ b/ocaml/idl/datamodel.ml @@ -6070,7 +6070,7 @@ module Event = struct ~doc: "Blocking call which returns a (possibly empty) batch of events. This \ method is only recommended for legacy use. New development should use \ - event.from which supercedes this method." + event.from which supersedes this method." ~custom_marshaller:true ~flags:[`Session] ~result:(Set (Record _event), "A set of events") ~errs:[Api_errors.session_not_registered; Api_errors.events_lost] diff --git a/ocaml/idl/datamodel_observer.ml b/ocaml/idl/datamodel_observer.ml index bbda9021898..1d80d030a62 100644 --- a/ocaml/idl/datamodel_observer.ml +++ b/ocaml/idl/datamodel_observer.ml @@ -95,7 +95,7 @@ let set_components = call ~name:"set_components" ~in_oss_since:None ~lifecycle:[] ~doc: "Set the components on which the observer will broadcast to. i.e. xapi, \ - xenopsd, networkd, etc" + xenopsd, networkd, etc." ~params: [ (Ref _observer, "self", "The observer") @@ -106,7 +106,7 @@ let set_components = let t = create_obj ~name:_observer ~descr: - "Describes a observer which will control observability activity in the \ + "Describes an observer which will control observability activity in the \ Toolstack" ~doccomments:[] ~gen_constructor_destructor:true ~gen_events:true ~in_db:true ~lifecycle:[] ~persist:PersistEverything ~in_oss_since:None diff --git a/ocaml/sdk-gen/c/README.dist b/ocaml/sdk-gen/c/README.dist index dfe92390216..e5fb8622069 100644 --- a/ocaml/sdk-gen/c/README.dist +++ b/ocaml/sdk-gen/c/README.dist @@ -58,4 +58,3 @@ Compiling from source --------------------- To build, simply type "make" in the libxenserver/src directory. -To build on Windows with cygwin type "make CYGWIN=1". diff --git a/ocaml/sdk-gen/c/gen_c_binding.ml b/ocaml/sdk-gen/c/gen_c_binding.ml index 2302fc6cf99..757046ac336 100644 --- a/ocaml/sdk-gen/c/gen_c_binding.ml +++ b/ocaml/sdk-gen/c/gen_c_binding.ml @@ -2,7 +2,7 @@ * Copyright (c) Cloud Software Group, Inc. *) -(* Generator of C bindings from the datamodel *) +(* Generator of the C SDK from the datamodel *) open Printf open Datamodel_types @@ -55,31 +55,23 @@ let enum_maps = ref TypeSet.empty let all_headers = ref [] -let joined sep f l = - let r = List.map f l in - String.concat sep (List.filter (fun x -> String.compare x "" != 0) r) +let rec is_last x list = + match list with + | [] -> + false + | hd :: [] -> + if hd = x then true else false + | hd :: tl -> + if hd = x then false else is_last x tl let rec main () = - let include_dir = Filename.concat destdir "include" in - let src_dir = Filename.concat destdir "src" in - - gen_failure_h () ; - gen_failure_c () ; - let filtered_classes = List.filter (fun x -> not (List.mem x.name ["session"; "debug"; "data_source"])) classes in - List.iter - (fun x -> - ( gen_class write_predecl predecl_filename x include_dir ; - gen_class write_decl decl_filename x include_dir ; - gen_class write_impl impl_filename x - ) - src_dir - ) - filtered_classes ; + List.iter gen_decl filtered_classes ; + List.iter gen_impl filtered_classes ; all_headers := List.map (fun x -> x.name) filtered_classes ; @@ -89,11 +81,12 @@ let rec main () = maps := TypeSet.add (Map (Int, Int)) !maps ; maps := TypeSet.add (Map (String, Set String)) !maps ; maps := TypeSet.add (Map (String, Map (String, String))) !maps ; - TypeSet.iter (gen_map write_map_decl decl_filename include_dir) !maps ; - TypeSet.iter (gen_map write_map_impl impl_filename src_dir) !maps ; + + TypeSet.iter (function Map (l, r) -> render_map_decl l r | _ -> ()) !maps ; + TypeSet.iter (function Map (l, r) -> render_map_impl l r | _ -> ()) !maps ; TypeSet.iter - (gen_map write_enum_map_internal_decl internal_decl_filename include_dir) + (function Map (l, r) -> render_enum_map l r | _ -> ()) !enum_maps ; let class_records = @@ -118,7 +111,10 @@ let rec main () = json1 templates_dir destdir ; let sorted_headers = - List.sort String.compare (List.map decl_filename !all_headers) + !all_headers + |> List.filter (fun x -> not (Astring.String.is_suffix ~affix:"internal" x)) + |> List.map String.lowercase_ascii + |> List.sort String.compare in let json2 = `O @@ -132,295 +128,305 @@ let rec main () = ("xen_all.h.mustache", "include/xen/api/xen_all.h") json2 templates_dir destdir -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_map f g targetdir = function - | Map (l, r) -> - let name = mapname l r in - 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 name l r out_chan) - ~finally:(fun () -> close_out out_chan) - | _ -> - assert false - -and write_predecl {name= classname; _} out_chan = - let print format = fprintf out_chan format in - let protect = protector (classname ^ "_decl") in - let tn = typename classname in - let record_tn = record_typename classname in - let record_opt_tn = record_opt_typename classname in - - print_h_header out_chan protect ; - - if classname <> "event" then ( - print "typedef void *%s;\n\n" tn ; - print "%s\n" (predecl_set tn) - ) ; - print "%s\n" (predecl record_tn) ; - print "%s\n" (predecl_set record_tn) ; - if classname <> "event" then ( - print "%s\n" (predecl record_opt_tn) ; - print "%s\n" (predecl_set record_opt_tn) - ) ; - print_h_footer out_chan +and gen_decl cls = + let headers = ref (StringSet.add (cls.name ^ "_decl") StringSet.empty) in + let rec get_needed = function + | Field fr -> + find_needed headers fr.ty + | Namespace (_, cs) -> + List.iter get_needed cs + in + List.iter get_needed cls.contents ; -and write_decl {name= classname; contents; description; messages; _} out_chan = - let print format = fprintf out_chan format in - let protect = protector classname in - let tn = typename classname in - let record_tn = record_typename classname in - let record_opt_tn = record_opt_typename classname in - let class_has_refs = true (* !!! *) in - let needed = ref (StringSet.add (classname ^ "_decl") StringSet.empty) in - let record = decl_record needed tn record_tn contents in - let record_opt = decl_record_opt tn record_tn record_opt_tn in - let message_decls = - decl_messages needed classname - (List.filter - (fun x -> not (classname = "event" && x.msg_name = "from")) - messages - ) + let asyncParams x = + if x.msg_async then + { + param_type= Ref "task" + ; param_name= "*result" + ; param_doc= "" + ; param_release= x.msg_release + ; param_default= None + } + :: x.msg_params + else + x.msg_params in - let full_stop = - if Astring.String.is_suffix ~affix:"." description then "" else "." + let syncParams x = + match x.msg_result with + | Some res -> + { + param_type= fst res + ; param_name= "*result" + ; param_doc= "" + ; param_release= x.msg_release + ; param_default= None + } + :: x.msg_params + | None -> + x.msg_params + in + let paramJson x = + `O + [ + ("param_name", `String (paramname x.param_name)) + ; ("param_type", `String (c_type_of_ty headers false x.param_type)) + ] in + let json = + `O + [ + ("class_upper", `String (String.uppercase_ascii cls.name)) + ; ("class_lower", `String (String.lowercase_ascii cls.name)) + ; ("class_doc", `String (Helper.comment false (full_class_doc cls))) + ; ("is_event", `Bool (cls.name = "event")) + ; ( "headers" + , `A + (List.map + (fun x -> `O [("header", `String x)]) + ("common" :: StringSet.elements !headers + |> List.map String.lowercase_ascii + |> List.sort String.compare + |> List.filter (fun x -> + not (Astring.String.is_suffix ~affix:"internal" x) + ) + ) + ) + ) + ; ( "fields" + , `A + (cls + |> Datamodel_utils.fields_of_obj + |> List.map (fun field -> + `O + [ + ( "field_name_lower" + , `String (fieldname (String.concat "_" field.full_name)) + ) + ; ( "field_type" + , `String (c_type_of_ty headers true field.ty) + ) + ] + ) + ) + ) + ; ( "messages" + , `A + (cls.messages + |> List.filter (fun x -> + not (cls.name = "event" && x.msg_name = "from") + ) + |> List.map (fun x -> + `O + [ + ( "msg_name_lower" + , `String (String.lowercase_ascii x.msg_name) + ) + ; ( "msg_doc" + , `String (Helper.comment true (full_msg_doc x)) + ) + ; ("is_async", `Bool x.msg_async) + ; ("sync_params", `A (List.map paramJson (syncParams x))) + ; ("async_params", `A (List.map paramJson (asyncParams x))) + ] + ) + ) + ) + ] + in + render_file + ( "class_decl.h.mustache" + , sprintf "include/xen/api/xen_%s_decl.h" (String.lowercase_ascii cls.name) + ) + json templates_dir destdir ; + render_file + ( "class.h.mustache" + , sprintf "include/xen/api/xen_%s.h" (String.lowercase_ascii cls.name) + ) + json templates_dir destdir - let rec get_needed x = - match x with +and gen_impl cls = + let headers = ref StringSet.empty in + let rec get_needed = function | Field fr -> - find_needed'' needed fr.ty + find_needed headers fr.ty | Namespace (_, cs) -> List.iter get_needed cs in - List.iter get_needed contents ; - - print_h_header out_chan protect ; - print "%s\n" (hash_includes !needed) ; - - print "\n\n%s\n\n\n" - (Helper.comment false - (sprintf "The %s class.\n\n%s%s" classname description full_stop) - ) ; + List.iter get_needed cls.contents ; - if classname <> "event" then ( - print "%s\n\n" - (decl_free tn (String.lowercase_ascii classname) false "handle") ; - print "%s\n" (decl_set tn false) - ) ; - print "%s\n" record ; - if classname <> "event" then - print "%s\n" record_opt ; - print "%s\n\n" (decl_set record_tn class_has_refs) ; - if classname <> "event" then - print "%s\n\n" (decl_set record_opt_tn true) ; - print "%s\n" message_decls ; - print_h_footer out_chan - -and predecl_set tn = predecl (tn ^ "_set") - -and predecl tn = sprintf "struct %s;" tn - -and decl_set tn referenced = - let alloc_com = - Helper.comment true (sprintf "Allocate a %s_set of the given size." tn) - in - - sprintf - "\n\ - typedef struct %s_set\n\ - {\n\ - \ size_t size;\n\ - \ %s *contents[];\n\ - } %s_set;\n\n\ - %s\n\ - extern %s_set *\n\ - %s_set_alloc(size_t size);\n\n\ - %s\n" - tn tn tn alloc_com tn tn - (decl_free (sprintf "%s_set" tn) "*set" referenced "set") + List.iter + (fun x -> + List.iter (fun p -> find_needed headers p.param_type) x.msg_params ; + match x.msg_result with + | Some res -> + find_needed headers (fst res) + | None -> + () + ) + cls.messages ; -and decl_free tn cn referenced thing = - let com = - Helper.comment true - (sprintf - "Free the given %s%s. The given %s must have been allocated by this \ - library." - tn - (if referenced then ", and all referenced values" else "") - thing - ) + let allFields = cls |> Datamodel_utils.fields_of_obj in + let result_type message = + match message.msg_result with + | Some res -> + abstract_type false (fst res) + | None -> + "" in - - sprintf "%s\nextern void\n%s_free(%s %s);" com tn tn cn - -and decl_record needed tn record_tn contents = - sprintf - "\n\ - typedef struct %s\n\ - {\n\ - %s %s\n\ - } %s;\n\n\ - %s\n\ - extern %s *\n\ - %s_alloc(void);\n\n\ - %s\n" - record_tn - (if tn <> "xen_event" then sprintf " %s handle;\n" tn else "") - (record_fields contents needed) - record_tn - (Helper.comment true (sprintf "Allocate a %s." record_tn)) - record_tn record_tn - (decl_free record_tn "*record" true "record") - -and decl_record_opt tn record_tn record_opt_tn = - sprintf - "\n\ - typedef struct %s\n\ - {\n\ - \ bool is_record;\n\ - \ union\n\ - \ {\n\ - \ %s handle;\n\ - \ %s *record;\n\ - \ } u;\n\ - } %s;\n\n\ - %s\n\ - extern %s *\n\ - %s_alloc(void);\n\n\ - %s\n" - record_opt_tn tn record_tn record_opt_tn - (Helper.comment true (sprintf "Allocate a %s." record_opt_tn)) - record_opt_tn record_opt_tn - (decl_free record_opt_tn "*record_opt" true "record_opt") - -and record_fields contents needed = - joined "\n " (record_field needed "") contents - -and record_field needed prefix content = - match content with - | Field fr -> - sprintf "%s%s%s;" - (c_type_of_ty needed true fr.ty) - prefix (fieldname fr.field_name) - | Namespace (p, c) -> - joined "\n " (record_field needed (prefix ^ fieldname p ^ "_")) c - -and decl_messages needed classname messages = - joined "\n\n" (decl_message needed classname) messages - -and decl_message needed classname message = - let message_sig = message_signature needed classname message in - let messageAsyncVersion = decl_message_async needed classname message in - sprintf "%s\n%sextern %s;\n%s" - (get_message_comment message) - (get_deprecated_message message) - message_sig messageAsyncVersion - -and decl_message_async needed classname message = - if message.msg_async then ( - let messageSigAsync = message_signature_async needed classname message in - needed := StringSet.add "task_decl" !needed ; - sprintf "\n%s\n%sextern %s;\n" - (get_message_comment message) - (get_deprecated_message message) - messageSigAsync - ) else - "" - -and get_message_comment message = - let full_stop = - if Astring.String.is_suffix ~affix:"." message.msg_doc then "" else "." + let init_result message = + match message.msg_result with + | Some res -> ( + match fst res with + | SecretString | String | Ref _ | Set _ | Map _ | Record _ -> + true + | _ -> + false + ) + | None -> + false in - let minimum_allowed_role = get_minimum_allowed_role message in - let content = - sprintf "%s%s\nMinimum allowed role: %s." message.msg_doc full_stop - minimum_allowed_role + let is_result_record message = + match message.msg_result with + | Some res -> ( + match fst res with Record _ -> true | _ -> false + ) + | None -> + false in - Helper.comment true content - -and impl_messages needed classname messages = - joined "\n\n" (impl_message needed classname) messages - -and impl_message needed classname message = - let message_sig = message_signature needed classname message in - let param_count = List.length message.msg_params in - - let param_decl, param_call = - if param_count = 0 then - ("", "NULL") + let asyncParams x = + if x.msg_async then + { + param_type= Ref "task" + ; param_name= "*result" + ; param_doc= "" + ; param_release= x.msg_release + ; param_default= None + } + :: x.msg_params else - let param_pieces = abstract_params message.msg_params in - - ( sprintf - " abstract_value param_values[] =\n\ - \ {\n\ - \ %s\n\ - \ };\n" - param_pieces - , "param_values" - ) + x.msg_params in - - let result_bits = - match message.msg_result with + let syncParams x = + match x.msg_result with | Some res -> - abstract_result_handling classname message.msg_name param_count res + { + param_type= fst res + ; param_name= "*result" + ; param_doc= "" + ; param_release= x.msg_release + ; param_default= None + } + :: x.msg_params | None -> - sprintf - " xen_call_(session, \"%s.%s\", %s, %d, NULL, NULL);\n\ - \ return session->ok;\n" - classname message.msg_name - (if param_count = 0 then "NULL" else param_call) - param_count + x.msg_params in - - let messageAsyncImpl = impl_message_async needed classname message in - sprintf "%s%s\n{\n%s\n%s}\n%s" - (get_deprecated_message message) - message_sig param_decl result_bits messageAsyncImpl - -and impl_message_async needed classname message = - if message.msg_async then - let messageSigAsync = message_signature_async needed classname message in - let param_count = List.length message.msg_params in - - let param_decl, _ = - if param_count = 0 then - ("", "NULL") - else - let param_pieces = abstract_params message.msg_params in - - ( sprintf - " abstract_value param_values[] =\n\ - \ {\n\ - \ %s\n\ - \ };\n" - param_pieces - , "param_values" - ) + let messageJson msg = + let paramJson p = + `O + [ + ("param_name", `String (paramname p.param_name)) + ; ("param_type", `String (c_type_of_ty headers false p.param_type)) + ; ("abstract_param_type", `String (abstract_type false p.param_type)) + ; ("abstract_member", `String (abstract_member p.param_type)) + ; ( "abstract_member_conv" + , `String (abstract_param_conv p.param_name p.param_type) + ) + ; ("is_last", `Bool (is_last p msg.msg_params)) + ] in + `O + [ + ("msg_name_lower", `String (String.lowercase_ascii msg.msg_name)) + ; ("msg_name", `String msg.msg_name) + ; ("msg_doc", `String (Helper.comment true (full_msg_doc msg))) + ; ("is_async", `Bool msg.msg_async) + ; ("sync_params", `A (List.map paramJson (syncParams msg))) + ; ("async_params", `A (List.map paramJson (asyncParams msg))) + ; ("msg_params", `A (List.map paramJson msg.msg_params)) + ; ("abstract_result_type", `String (result_type msg)) + ; ("has_params", `Bool (List.length msg.msg_params <> 0)) + ; ("param_count", `String (string_of_int (List.length msg.msg_params))) + ; ("has_result", `Bool (String.compare (result_type msg) "" <> 0)) + ; ("init_result", `Bool (init_result msg)) + ; ("is_result_record", `Bool (is_result_record msg)) + ] + in + let fieldJson field = + let fullName = String.concat "_" field.full_name in + let freeing = free_impl ("record->" ^ fieldname fullName) true field.ty in + `O + [ + ("field_name_lower", `String (fieldname fullName)) + ; ("field_name", `String fullName) + ; ("abstract_field_type", `String (abstract_type true field.ty)) + ; ("can_free", `Bool (freeing <> "")) + ; ("free_record_field", `String freeing) + ; ("is_last", `Bool (is_last field allFields)) + ] + in + let json = + `O + [ + ("class_name", `String cls.name) + ; ("class_lower", `String (String.lowercase_ascii cls.name)) + ; ("is_event", `Bool (cls.name = "event")) + ; ( "has_all_records" + , `Bool + (List.exists (fun x -> x.msg_name = "get_all_records") cls.messages) + ) + ; ( "headers" + , `A + (List.map + (fun x -> `O [("header", `String x)]) + (["common"; String.lowercase_ascii cls.name] + |> List.sort String.compare + ) + ) + ) + ; ( "internal_headers" + , `A + (List.map + (fun x -> `O [("header", `String x)]) + ("internal" :: StringSet.elements !headers + |> List.map String.lowercase_ascii + |> List.sort String.compare + |> List.filter (fun x -> + Astring.String.is_suffix ~affix:"internal" x + ) + ) + ) + ) + ; ("fields", `A (allFields |> List.map fieldJson)) + ; ( "messages" + , `A + (cls.messages + |> List.filter (fun x -> + not (cls.name = "event" && x.msg_name = "from") + ) + |> List.map messageJson + ) + ) + ] + in + render_file + ( "class.c.mustache" + , sprintf "src/xen_%s.c" (String.lowercase_ascii cls.name) + ) + json templates_dir destdir - let result_bits = - abstract_result_handling_async classname message.msg_name param_count - in - sprintf "\n%s%s\n{\n%s\n%s}" - (get_deprecated_message message) - messageSigAsync param_decl result_bits - else - "" +and full_stop x = if Astring.String.is_suffix ~affix:"." x then "" else "." -and abstract_params params = joined ",\n " abstract_param params +and full_class_doc cls = + let intro = sprintf "The %s class.\n\n" cls.name in + intro ^ cls.description ^ full_stop cls.description -and abstract_param p = - let ab_typ = abstract_type false p.param_type in - sprintf "{ .type = &%s,\n .u.%s_val = %s }" ab_typ - (abstract_member p.param_type) - (abstract_param_conv p.param_name p.param_type) +and full_msg_doc message = + let role = + sprintf "\nMinimum allowed role: %s." (get_minimum_allowed_role message) + in + let deprecated = get_deprecated_info_message message in + let deprecated = if deprecated = "" then "" else "\n" ^ deprecated in + message.msg_doc ^ full_stop message.msg_doc ^ role ^ deprecated and abstract_param_conv name = function | Set _ | Map _ -> @@ -443,9 +449,7 @@ and abstract_member = function "bool" | DateTime -> "datetime" - | Set _ -> - "set" - | Map _ -> + | Set _ | Map _ -> "set" | Record _ -> "struct" @@ -453,81 +457,6 @@ and abstract_member = function eprintf "%s" (Types.to_string x) ; assert false -and abstract_result_handling classname msg_name param_count = function - | typ, _ -> ( - let call = - if param_count = 0 then - sprintf - "xen_call_(session, \"%s.%s\", NULL, 0, &result_type, result);" - classname msg_name - else - sprintf "XEN_CALL_(\"%s.%s\");" classname msg_name - in - - match typ with - | String | Ref _ | Int | Float | Bool | DateTime | Set _ | Map _ -> - sprintf "%s\n\n%s %s\n return session->ok;\n" - (abstract_result_type typ) (initialiser_of_ty typ) call - | Record n -> - let record_tn = record_typename n in - sprintf - " abstract_type result_type = %s_abstract_type_;\n\n\ - %s %s\n\n\ - \ if (session->ok)\n\ - \ {\n\ - \ (*result)->handle = xen_strdup_((*result)->uuid);\n\ - \ }\n\n\ - \ return session->ok;\n" - record_tn - (initialiser_of_ty (Record n)) - call - | Enum (_, _) -> - sprintf "%s\n %s\n return session->ok;\n" - (abstract_result_type typ) call - | x -> - eprintf "%s" (Types.to_string x) ; - assert false - ) - -and abstract_result_handling_async classname msg_name param_count = - let call = - if param_count = 0 then - sprintf - "xen_call_(session, \"Async.%s.%s\", NULL, 0, &result_type, result);" - classname msg_name - else - sprintf "XEN_CALL_(\"Async.%s.%s\");" classname msg_name - in - sprintf - " abstract_type result_type = abstract_type_string;\n\n\ - \ *result = NULL;\n\ - \ %s\n\ - \ return session->ok;\n" - call - -and abstract_record_field classname prefix prefix_caps content = - match content with - | Field fr -> - let fn = fieldname fr.field_name in - sprintf - "{ .key = \"%s%s\",\n\ - \ .type = &%s,\n\ - \ .offset = offsetof(%s, %s%s) }" prefix_caps fr.field_name - (abstract_type true fr.ty) - (record_typename classname) - prefix fn - | Namespace (p, c) -> - joined ",\n " - (abstract_record_field classname - (prefix ^ fieldname p ^ "_") - (prefix_caps ^ p ^ "_") - ) - c - -and abstract_result_type typ = - let ab_typ = abstract_type false typ in - sprintf " abstract_type result_type = %s;" ab_typ - and abstract_type record = function | SecretString | String -> "abstract_type_string" @@ -575,87 +504,6 @@ and abstract_type record = function | Option n -> abstract_type record n -and get_deprecated_message message = - let deprecatedMessage = get_deprecated_info_message message in - if deprecatedMessage = "" then - sprintf "" - else - sprintf "/* " ^ deprecatedMessage ^ " */\n" - -and message_signature needed classname message = - let front = - { - param_type= Ref "session" - ; param_name= "session" - ; param_doc= "" - ; param_release= message.msg_release - ; param_default= None - } - :: - ( match message.msg_result with - | Some res -> - [ - { - param_type= fst res - ; param_name= "*result" - ; param_doc= "" - ; param_release= message.msg_release - ; param_default= None - } - ] - | None -> - [] - ) - in - let params = joined ", " (param needed) (front @ message.msg_params) in - sprintf "bool\n%s(%s)" (messagename classname message.msg_name) params - -and message_signature_async needed classname message = - let sessionParam = - { - param_type= Ref "session" - ; param_name= "session" - ; param_doc= "" - ; param_release= message.msg_release - ; param_default= None - } - in - let taskParam = - { - param_type= Ref "task" - ; param_name= "*result" - ; param_doc= "" - ; param_release= message.msg_release - ; param_default= None - } - in - let params = - joined ", " (param needed) (sessionParam :: taskParam :: message.msg_params) - in - sprintf "bool\n%s(%s)" (messagename_async classname message.msg_name) params - -and param needed p = - let t = p.param_type in - let n = p.param_name in - sprintf "%s%s" (c_type_of_ty needed false t) (paramname n) - -and hash_includes needed = - String.concat "\n" - (List.sort String.compare - (List.filter - (function s -> s <> "") - (List.map hash_include ("common" :: StringSet.elements needed)) - ) - ) - -and hash_include n = - if Astring.String.is_suffix ~affix:"internal" n then - sprintf "#include \"%s\"" (decl_filename n) - else if n = "session" then - "" - else - sprintf "#include <%s>" (decl_filename n) - and replace_dashes x = Astring.String.map (fun y -> match y with '-' -> '_' | _ -> y) x @@ -677,7 +525,9 @@ and render_enum x = `O [ ("enum_value", `String n) - ; ("enum_value_doc", `String c) + ; ( "enum_value_doc" + , `String (Helper.comment true ~indent:4 c) + ) ; ( "enum_value_upper" , `String (replace_dashes (String.uppercase_ascii n)) ) @@ -702,371 +552,159 @@ and render_enum x = | _ -> () -and write_map_decl name l r out_chan = - let print format = fprintf out_chan format in - let tn = typename name in - let protect = protector name in - let needed = ref StringSet.empty in - let alloc_com = - Helper.comment true (sprintf "Allocate a %s of the given size." tn) - in - - print_h_header out_chan protect ; - print - "\n\ - %s%s%s\n\n\n\ - typedef struct %s_contents\n\ - {\n\ - \ %skey;\n\ - \ %sval;\n\ - } %s_contents;\n\n\n\ - typedef struct %s\n\ - {\n\ - \ size_t size;\n\ - \ %s_contents contents[];\n\ - } %s;\n\n\ - %s\n\ - extern %s *\n\ - %s_alloc(size_t size);\n\n\ - %s\n\n" - (hash_include "common") (hash_include_enum l) (hash_include_enum r) tn - (c_type_of_ty needed false l) - (c_type_of_ty needed true r) - tn tn tn tn alloc_com tn tn - (decl_free tn "*map" true "map") ; - print_h_footer out_chan - -and write_map_impl name l r out_chan = - let print format = fprintf out_chan format in - let tn = typename name in - let l_free_impl = free_impl "map->contents[i].key" false l in - let r_free_impl = free_impl "map->contents[i].val" true r in - let needed = ref StringSet.empty in - find_needed'' needed l ; - find_needed'' needed r ; - needed := StringSet.add "internal" !needed ; - needed := StringSet.add name !needed ; - ( match r with - | Set String -> - needed := StringSet.add "string_set" !needed - | _ -> - () - ) ; - - print - "%s\n\n\n\ - %s\n\n\n\ - %s *\n\ - %s_alloc(size_t size)\n\ - {\n\ - \ %s *result = calloc(1, sizeof(%s) +\n\ - \ %s size * sizeof(struct %s_contents));\n\ - \ result->size = size;\n\ - \ return result;\n\ - }\n\n\n\ - void\n\ - %s_free(%s *map)\n\ - {\n" - Licence.bsd_two_clause (hash_includes !needed) tn tn tn tn - (String.make (String.length tn) ' ') - tn tn tn ; - - if String.compare l_free_impl "" != 0 || String.compare r_free_impl "" != 0 - then - print - " if (map == NULL)\n\ - \ {\n\ - \ return;\n\ - \ }\n\n\ - \ size_t n = map->size;\n\ - \ for (size_t i = 0; i < n; i++)\n\ - \ {\n\ - \ %s\n\ - \ %s\n\ - \ }\n\n" - l_free_impl r_free_impl ; - - print " free(map);\n}\n" ; - - match (l, r) with - | Enum (_, _), _ -> - gen_enum_map_abstract_type print l r - | _, Enum (_, _) -> - gen_enum_map_abstract_type print l r - | _ -> - () - -and gen_enum_map_abstract_type print l r = - let tn = mapname l r in - print - "\n\n\ - static const struct_member %s_struct_members[] =\n\ - \ {\n\ - \ { .type = &%s,\n\ - \ .offset = offsetof(xen_%s_contents, key) },\n\ - \ { .type = &%s,\n\ - \ .offset = offsetof(xen_%s_contents, val) },\n\ - \ };\n\n\ - const abstract_type %s_abstract_type_ =\n\ - \ {\n\ - \ .XEN_API_TYPE = MAP,\n\ - \ .struct_size = sizeof(%s_struct_members),\n\ - \ .member_count =\n\ - \ sizeof(%s_struct_members) / sizeof(struct_member),\n\ - \ .members = %s_struct_members\n\ - \ };\n" - tn (abstract_type false l) tn (abstract_type false r) tn tn tn tn tn - -and write_enum_map_internal_decl name l r out_chan = - let print format = fprintf out_chan format in - let protect = protector (sprintf "%s_internal" name) in - - print_h_header out_chan protect ; - print "\nextern const abstract_type %s_abstract_type_;\n\n" (mapname l r) ; - print_h_footer out_chan - -and hash_include_enum = function - | Enum (x, _) -> - "\n" ^ hash_include x - | _ -> - "" - -and gen_failure_h () = - let protect = protector "api_failure" in - let out_chan = - open_out (Filename.concat destdir "include/xen/api/xen_api_failure.h") +and render_enum_map l r = + let x = mapname l r in + let json = + `O + [ + ("map_upper", `String (String.uppercase_ascii x)) + ; ("map_lower", `String (String.lowercase_ascii x)) + ] in - Fun.protect - (fun () -> - print_h_header out_chan protect ; - gen_failure_enum out_chan ; - gen_failure_funcs out_chan ; - print_h_footer out_chan + render_file + ( "xen_enum_map_internal.h.mustache" + , sprintf "include/xen_%s_internal.h" (String.lowercase_ascii x) ) - ~finally:(fun () -> close_out out_chan) - -and gen_failure_enum out_chan = - let print format = fprintf out_chan format in - print "\nenum xen_api_failure\n{\n%s\n};\n\n\n" - (String.concat ",\n\n" (failure_enum_entries ())) - -and failure_enum_entries () = - let r = Hashtbl.fold failure_enum_entry Datamodel.errors [] in - let r = List.sort (fun (x, _) (y, _) -> String.compare y x) r in - let r = - failure_enum_entry "UNDEFINED" - { - err_doc= "Unknown to this version of the bindings." - ; err_params= [] - ; err_name= "UNDEFINED" - } - r + json templates_dir destdir + +and render_map_decl l r = + let headers = ref StringSet.empty in + let add_enum_header = function + | Enum (x, _) -> + headers := StringSet.add x !headers + | _ -> + () + in + add_enum_header l ; + add_enum_header r ; + let x = mapname l r in + let json = + `O + [ + ("key_type_lower", `String (c_type_of_ty headers false l)) + ; ("val_type_lower", `String (c_type_of_ty headers true r)) + ; ("map_upper", `String (String.uppercase_ascii x)) + ; ("map_lower", `String (String.lowercase_ascii x)) + ; ( "headers" + , `A + (List.map + (fun x -> `O [("header", `String x)]) + ("common" :: StringSet.elements !headers + |> List.map String.lowercase_ascii + |> List.sort String.compare + |> List.filter (fun x -> + not (Astring.String.is_suffix ~affix:"internal" x) + ) + ) + ) + ) + ] in - List.map (fun (_, y) -> y) (List.rev r) - -and failure_enum_entry name err acc = - ( name - , sprintf "%s\n %s" - (Helper.comment true ~indent:4 err.Datamodel_types.err_doc) - (failure_enum name) - ) - :: acc - -and gen_failure_funcs out_chan = - let print format = fprintf out_chan format in - print - "%s\n\ - extern const char *\n\ - xen_api_failure_to_string(enum xen_api_failure val);\n\n\n\ - %s\n\ - extern enum xen_api_failure\n\ - xen_api_failure_from_string(const char *str);\n\n" - (Helper.comment true - "Return the name corresponding to the given code. This string must not \ - be modified or freed." - ) - (Helper.comment true - "Return the correct code for the given string, or UNDEFINED if the \ - given string does not match a known code." - ) - -and gen_failure_c () = - let out_chan = open_out (Filename.concat destdir "src/xen_api_failure.c") in - let print format = fprintf out_chan format in - Fun.protect - (fun () -> - print - "%s\n\n\ - #include \"xen_internal.h\"\n\ - #include \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\ - const char *\n\ - xen_api_failure_to_string(enum xen_api_failure val)\n\ - {\n\ - \ return lookup_table[val];\n\ - }\n\n\n\ - extern enum xen_api_failure\n\ - xen_api_failure_from_string(const char *str)\n\ - {\n\ - \ return ENUM_LOOKUP(str, lookup_table);\n\ - }\n\n\n" - Licence.bsd_two_clause - (String.concat ",\n " (failure_lookup_entries ())) + if not (List.mem x !all_headers) then all_headers := x :: !all_headers ; + render_file + ( "map.h.mustache" + , sprintf "include/xen/api/xen_%s.h" (String.lowercase_ascii x) ) - ~finally:(fun () -> close_out out_chan) + json templates_dir destdir -and failure_lookup_entries () = - List.sort String.compare - (Hashtbl.fold failure_lookup_entry Datamodel.errors []) +and render_map_impl l r = + let x = mapname l r in + let headers = ref StringSet.empty in + headers := StringSet.add x !headers ; + find_needed headers l ; + find_needed headers r ; -and failure_lookup_entry name _ acc = sprintf "\"%s\"" name :: acc - -and failure_enum name = "XEN_API_FAILURE_" ^ String.uppercase_ascii name - -and write_impl {name= classname; contents; messages; _} out_chan = - let is_event = classname = "event" in - let print format = fprintf out_chan format in - let needed = ref StringSet.empty in - let tn = typename classname in - let record_tn = record_typename classname in - let record_opt_tn = record_opt_typename classname in - let msgs = - impl_messages needed classname - (List.filter - (fun x -> not (classname = "event" && x.msg_name = "from")) - messages - ) - in - let record_free_handle = - if classname = "event" then "" else " free(record->handle);\n" - in - let record_free_impls = - joined "\n " (record_free_impl "record->") contents - in - let filtered_record_fields = - let not_obj_uuid x = - match x with Field r when r.field_name = "obj_uuid" -> false | _ -> true - in - if is_event then List.filter not_obj_uuid contents else contents - in - let record_fields = - joined ",\n " - (abstract_record_field classname "" "") - filtered_record_fields + let l_free_impl = free_impl "map->contents[i].key" false l in + let r_free_impl = free_impl "map->contents[i].val" true r in + let is_enum_map = + match (l, r) with Enum (_, _), _ | _, Enum (_, _) -> true | _ -> false in - let needed = ref StringSet.empty in - find_needed needed messages ; - needed := StringSet.add "internal" !needed ; - needed := StringSet.add classname !needed ; - - let getAllRecordsExists = - List.exists (fun x -> x.msg_name = "get_all_records") messages + let json = + `O + [ + ("abstract_type_key", `String (abstract_type false l)) + ; ("abstract_type_val", `String (abstract_type false r)) + ; ("map_upper", `String (String.uppercase_ascii x)) + ; ("map_lower", `String (String.lowercase_ascii x)) + ; ( "headers" + , `A + (List.map + (fun x -> `O [("header", `String x)]) + ("common" :: StringSet.elements !headers + |> List.map String.lowercase_ascii + |> List.sort String.compare + |> List.filter (fun x -> + not (Astring.String.is_suffix ~affix:"internal" x) + ) + ) + ) + ) + ; ( "internal_headers" + , `A + (List.map + (fun x -> `O [("header", `String x)]) + ("internal" :: StringSet.elements !headers + |> List.map String.lowercase_ascii + |> List.sort String.compare + |> List.filter (fun x -> + Astring.String.is_suffix ~affix:"internal" x + ) + ) + ) + ) + ; ("can_free_key", `Bool (String.compare l_free_impl "" != 0)) + ; ("can_free_val", `Bool (String.compare r_free_impl "" != 0)) + ; ( "can_free" + , `Bool + (String.compare l_free_impl "" != 0 + || String.compare r_free_impl "" != 0 + ) + ) + ; ("free_key", `String l_free_impl) + ; ("free_val", `String r_free_impl) + ; ("enum_map", `Bool is_enum_map) + ] in - let mappingName = sprintf "%s_%s" tn record_tn in - - let free_block = - String.concat "\n" - (( if is_event then - [] - else - [sprintf "XEN_FREE(%s)" tn; sprintf "XEN_SET_ALLOC_FREE(%s)" tn] - ) - @ [ - sprintf "XEN_ALLOC(%s)" record_tn - ; sprintf "XEN_SET_ALLOC_FREE(%s)" record_tn - ] - @ - if is_event then - [] - else - [ - sprintf "XEN_ALLOC(%s)" record_opt_tn - ; sprintf "XEN_RECORD_OPT_FREE(%s)" tn - ; sprintf "XEN_SET_ALLOC_FREE(%s)" record_opt_tn - ] + if not (List.mem x !all_headers) then all_headers := x :: !all_headers ; + render_file + ("map.c.mustache", sprintf "src/xen_%s.c" (String.lowercase_ascii x)) + json templates_dir destdir + +and gen_failure () = + let errors = + Hashtbl.fold + (fun _ x acc -> + (x.Datamodel_types.err_name, x.Datamodel_types.err_doc) :: acc ) + Datamodel.errors [] in + let errors = List.sort (fun (x, _) (y, _) -> String.compare x y) errors in + let json = + `O + [ + ( "api_errors" + , `A + (List.map + (fun (x, y) -> + `O + [ + ("api_error", `String (String.uppercase_ascii x)) + ; ("api_error_doc", `String (Helper.comment true ~indent:4 y)) + ] + ) + errors + ) + ) + ] + in + render_file + ("xen_api_failure.h.mustache", "include/xen/api/xen_api_failure.h") + json templates_dir destdir ; + render_file + ("xen_api_failure.c.mustache", "src/xen_api_failure.c") + json templates_dir destdir - print "%s\n\n\n#include \n#include \n\n%s\n\n\n%s\n\n\n" - Licence.bsd_two_clause (hash_includes !needed) free_block ; - - print - "static const struct_member %s_struct_members[] =\n\ - \ {\n\ - \ %s\n\ - \ };\n\n\ - const abstract_type %s_abstract_type_ =\n\ - \ {\n\ - \ .XEN_API_TYPE = STRUCT,\n\ - \ .struct_size = sizeof(%s),\n\ - \ .member_count =\n\ - \ sizeof(%s_struct_members) / sizeof(struct_member),\n\ - \ .members = %s_struct_members\n\ - \ };\n\n\n" - record_tn record_fields record_tn record_tn record_tn record_tn ; - - print - "const abstract_type %s_set_abstract_type_ =\n\ - \ {\n\ - \ .XEN_API_TYPE = SET,\n\ - \ .child = &%s_abstract_type_\n\ - \ };\n\n\n" - record_tn record_tn ; - - if getAllRecordsExists then - print - "static const struct struct_member %s_members[] =\n\ - {\n\ - \ {\n\ - \ .type = &abstract_type_string,\n\ - \ .offset = offsetof(%s_map_contents, key)\n\ - \ },\n\ - \ {\n\ - \ .type = &%s_abstract_type_,\n\ - \ .offset = offsetof(%s_map_contents, val)\n\ - \ }\n\ - };\n\n\ - const abstract_type abstract_type_string_%s_map =\n\ - {\n\ - \ .XEN_API_TYPE = MAP,\n\ - \ .struct_size = sizeof(%s_map_contents),\n\ - \ .members = %s_members\n\ - };\n\n\n" - mappingName mappingName record_tn mappingName record_tn mappingName - mappingName ; - - print - "void\n\ - %s_free(%s *record)\n\ - {\n\ - \ if (record == NULL)\n\ - \ {\n\ - \ return;\n\ - \ }\n\ - %s %s\n\ - \ free(record);\n\ - }\n\n\n" - record_tn record_tn record_free_handle record_free_impls ; - - print "%s\n" msgs - -and find_needed needed messages = List.iter (find_needed' needed) messages - -and find_needed' needed message = - List.iter (fun p -> find_needed'' needed p.param_type) message.msg_params ; - match message.msg_result with - | Some (x, _) -> - find_needed'' needed x - | None -> - () - -and find_needed'' needed = function +and find_needed needed = function | SecretString | String | Int | Float | Bool | DateTime -> () | Enum (n, _) -> @@ -1091,13 +729,7 @@ and find_needed'' needed = function | Record n -> needed := StringSet.add n !needed | Option x -> - find_needed'' needed x - -and record_free_impl prefix = function - | Field fr -> - free_impl (prefix ^ fieldname fr.field_name) true fr.ty - | Namespace (p, c) -> - joined "\n " (record_free_impl (prefix ^ fieldname p ^ "_")) c + find_needed needed x and free_impl val_name record = function | SecretString | String -> @@ -1167,7 +799,7 @@ and c_type_of_ty needed record = function | Enum (name, _) as x -> needed := StringSet.add name !needed ; enums := TypeSet.add x !enums ; - c_type_of_enum name + sprintf "enum %s " (typename name) | Set (Ref name) -> needed := StringSet.add (name ^ "_decl") !needed ; if record then @@ -1220,23 +852,13 @@ and c_type_of_ty needed record = function | Option (Enum (name, _) as x) -> needed := StringSet.add name !needed ; enums := TypeSet.add x !enums ; - c_type_of_enum name ^ " *" + sprintf "enum %s *" (typename name) | Option n -> c_type_of_ty needed record n | x -> eprintf "%s" (Types.to_string x) ; assert false -and c_type_of_enum name = sprintf "enum %s " (typename name) - -and initialiser_of_ty = function - | SecretString | String | Ref _ | Set _ | Map _ | Record _ -> - " *result = NULL;\n" - | _ -> - "" - -and mapname l r = sprintf "%s_%s_map" (name_of_ty l) (name_of_ty r) - and name_of_ty = function | SecretString | String -> "string" @@ -1262,21 +884,7 @@ and name_of_ty = function eprintf "%s" (Types.to_string x) ; assert false -and decl_filename name = - let dir = - if Astring.String.is_suffix ~affix:"internal" name then "" else "xen/api/" - in - sprintf "%sxen_%s.h" dir (String.lowercase_ascii name) - -and predecl_filename name = - sprintf "xen/api/xen_%s_decl.h" (String.lowercase_ascii name) - -and internal_decl_filename name = - sprintf "xen_%s_internal.h" (String.lowercase_ascii name) - -and impl_filename name = sprintf "xen_%s.c" (String.lowercase_ascii name) - -and protector classname = sprintf "XEN_%s_H" (String.uppercase_ascii classname) +and mapname l r = sprintf "%s_%s_map" (name_of_ty l) (name_of_ty r) and typename classname = sprintf "xen_%s" (String.lowercase_ascii classname) @@ -1284,16 +892,6 @@ and record_typename classname = sprintf "%s_record" (typename classname) and record_opt_typename classname = sprintf "%s_record_opt" (typename classname) -and messagename classname name = - sprintf "xen_%s_%s" - (String.lowercase_ascii classname) - (String.lowercase_ascii name) - -and messagename_async classname name = - sprintf "xen_%s_%s_async" - (String.lowercase_ascii classname) - (String.lowercase_ascii name) - and keyword_map name = let keywords = [("class", "XEN_CLAZZ"); ("public", "pubblic")] in if List.mem_assoc name keywords then List.assoc name keywords else name @@ -1302,14 +900,6 @@ and paramname name = keyword_map (String.lowercase_ascii name) and fieldname name = keyword_map (String.lowercase_ascii name) -and print_h_header out_chan protect = - let print format = fprintf out_chan format in - print "%s\n\n" Licence.bsd_two_clause ; - print "#ifndef %s\n" protect ; - print "#define %s\n\n" protect - -and print_h_footer out_chan = fprintf out_chan "\n#endif\n" - and populate_version () = List.iter (fun x -> render_file x json_releases templates_dir destdir) @@ -1319,4 +909,4 @@ and populate_version () = ; ("xen_api_version.c.mustache", "src/xen_api_version.c") ] -let _ = main () ; populate_version () +let _ = main () ; gen_failure () ; populate_version () diff --git a/ocaml/sdk-gen/c/templates/Makefile.mustache b/ocaml/sdk-gen/c/templates/Makefile.mustache index 384ffcb174d..ac78e5ca1e6 100644 --- a/ocaml/sdk-gen/c/templates/Makefile.mustache +++ b/ocaml/sdk-gen/c/templates/Makefile.mustache @@ -29,7 +29,9 @@ DESTDIR=/usr/local -ifeq ($(CYGWIN), 1) +UNAME_S := $(shell uname -s) + +ifeq ($(findstring CYGWIN,$(UNAME_S)),CYGWIN) CYGWIN_LIBXML = -L/bin -lxml2-2 POS_FLAG = -U__STRICT_ANSI__ else @@ -80,7 +82,7 @@ install: build $(INSTALL_DATA) libxenserver.so.{{API_VERSION_MAJOR}}.{{API_VERSION_MINOR}} $(DESTDIR)/lib ln -sf libxenserver.so.{{API_VERSION_MAJOR}}.{{API_VERSION_MINOR}} $(DESTDIR)/lib/libxenserver.so.{{API_VERSION_MAJOR}} ln -sf libxenserver.so.{{API_VERSION_MAJOR}} $(DESTDIR)/lib/libxenserver.so -ifeq ($(CYGWIN), 1) +ifeq ($(findstring CYGWIN,$(UNAME_S)),CYGWIN) ln -sf libxenserver.so $(DESTDIR)/lib/libxenserver.dll endif $(INSTALL_DATA) libxenserver.a $(DESTDIR)/lib @@ -95,3 +97,4 @@ clean: .PHONY: clean build install .DEFAULT_GOAL := build + diff --git a/ocaml/sdk-gen/c/templates/class.c.mustache b/ocaml/sdk-gen/c/templates/class.c.mustache new file mode 100644 index 00000000000..55f6da267ae --- /dev/null +++ b/ocaml/sdk-gen/c/templates/class.c.mustache @@ -0,0 +1,192 @@ +/* + * 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 + +{{#internal_headers}} +#include "xen_{{header}}.h" +{{/internal_headers}} +{{#headers}} +#include +{{/headers}} + + +{{^is_event}} +XEN_FREE(xen_{{{class_lower}}}) +XEN_SET_ALLOC_FREE(xen_{{{class_lower}}}) +{{/is_event}} +XEN_ALLOC(xen_{{{class_lower}}}_record) +XEN_SET_ALLOC_FREE(xen_{{{class_lower}}}_record) +{{^is_event}} +XEN_ALLOC(xen_{{{class_lower}}}_record_opt) +XEN_RECORD_OPT_FREE(xen_{{{class_lower}}}) +XEN_SET_ALLOC_FREE(xen_{{{class_lower}}}_record_opt) +{{/is_event}} + + +static const struct_member xen_{{{class_lower}}}_record_struct_members[] = + { +{{#fields}} + { .key = "{{{field_name}}}", + .type = &{{{abstract_field_type}}}, + .offset = offsetof(xen_{{{class_lower}}}_record, {{{field_name_lower}}}) }{{^is_last}},{{/is_last}} +{{/fields}} + }; + + +const abstract_type xen_{{{class_lower}}}_record_abstract_type_ = + { + .XEN_API_TYPE = STRUCT, + .struct_size = sizeof(xen_{{{class_lower}}}_record), + .member_count = + sizeof(xen_{{{class_lower}}}_record_struct_members) / sizeof(struct_member), + .members = xen_{{{class_lower}}}_record_struct_members + }; + + +const abstract_type xen_{{{class_lower}}}_record_set_abstract_type_ = + { + .XEN_API_TYPE = SET, + .child = &xen_{{{class_lower}}}_record_abstract_type_ + }; +{{#has_all_records}} + + +static const struct struct_member xen_{{{class_lower}}}_xen_{{{class_lower}}}_record_members[] = +{ + { + .type = &abstract_type_string, + .offset = offsetof(xen_{{{class_lower}}}_xen_{{{class_lower}}}_record_map_contents, key) + }, + { + .type = &xen_{{{class_lower}}}_record_abstract_type_, + .offset = offsetof(xen_{{{class_lower}}}_xen_{{{class_lower}}}_record_map_contents, val) + } +}; + + +const abstract_type abstract_type_string_xen_{{{class_lower}}}_record_map = +{ + .XEN_API_TYPE = MAP, + .struct_size = sizeof(xen_{{{class_lower}}}_xen_{{{class_lower}}}_record_map_contents), + .members = xen_{{{class_lower}}}_xen_{{{class_lower}}}_record_members +}; +{{/has_all_records}} + + +void +xen_{{{class_lower}}}_record_free(xen_{{{class_lower}}}_record *record) +{ + if (record == NULL) + return; + +{{^is_event}} + free(record->handle); +{{/is_event}} +{{#fields}} +{{#can_free}} + {{{free_record_field}}} +{{/can_free}} +{{/fields}} + free(record); +} +{{#messages}} + + +bool +xen_{{{class_lower}}}_{{{msg_name_lower}}}(xen_session *session{{#sync_params}}, {{{param_type}}}{{{param_name}}}{{/sync_params}}) +{ +{{#has_params}} + abstract_value param_values[] = + { +{{#msg_params}} + { .type = &{{{abstract_param_type}}}, + .u.{{{abstract_member}}}_val = {{{abstract_member_conv}}} }{{^is_last}},{{/is_last}} +{{/msg_params}} + }; +{{/has_params}} +{{#has_result}} + + abstract_type result_type = {{{abstract_result_type}}}; +{{/has_result}} + +{{#init_result}} + *result = NULL; +{{/init_result}} +{{#has_result}} +{{#has_params}} + XEN_CALL_("{{{class_name}}}.{{{msg_name}}}"); +{{/has_params}} +{{^has_params}} + xen_call_(session, "{{{class_name}}}.{{{msg_name}}}", NULL, 0, &result_type, result); +{{/has_params}} +{{/has_result}} +{{^has_result}} + xen_call_(session, "{{{class_name}}}.{{{msg_name}}}", {{#has_params}}param_values{{/has_params}}{{^has_params}}NULL{{/has_params}}, {{param_count}}, NULL, NULL); +{{/has_result}} +{{#is_result_record}} + + if (session->ok) + (*result)->handle = xen_strdup_((*result)->uuid); + +{{/is_result_record}} + return session->ok; +} +{{#is_async}} + + +bool +xen_{{{class_lower}}}_{{{msg_name_lower}}}_async(xen_session *session{{#async_params}}, {{{param_type}}}{{{param_name}}}{{/async_params}}) +{ +{{#has_params}} + abstract_value param_values[] = + { +{{#msg_params}} + { .type = &{{{abstract_param_type}}}, + .u.{{{abstract_member}}}_val = {{{abstract_member_conv}}} }{{^is_last}},{{/is_last}} +{{/msg_params}} + }; +{{/has_params}} + + abstract_type result_type = abstract_type_string; + + *result = NULL; +{{#has_params}} + XEN_CALL_("Async.{{{class_name}}}.{{{msg_name}}}"); +{{/has_params}} +{{^has_params}} + xen_call_(session, "Async.{{{class_name}}}.{{{msg_name}}}", NULL, 0, &result_type, result); +{{/has_params}} + return session->ok; +} +{{/is_async}} +{{/messages}} + diff --git a/ocaml/sdk-gen/c/templates/class.h.mustache b/ocaml/sdk-gen/c/templates/class.h.mustache new file mode 100644 index 00000000000..98dd1f37446 --- /dev/null +++ b/ocaml/sdk-gen/c/templates/class.h.mustache @@ -0,0 +1,179 @@ +/* + * 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_{{{class_upper}}}_H +#define XEN_{{{class_upper}}}_H + +{{#headers}} +#include +{{/headers}} + + +{{{class_doc}}} + + +{{^is_event}} +/** + * Free the given xen_{{{class_lower}}}. The given handle must have been + * allocated by this library. + */ +extern void +xen_{{{class_lower}}}_free(xen_{{{class_lower}}} {{{class_lower}}}); + + +typedef struct xen_{{{class_lower}}}_set +{ + size_t size; + xen_{{{class_lower}}} *contents[]; +} xen_{{{class_lower}}}_set; + +/** + * Allocate a xen_{{{class_lower}}}_set of the given size. + */ +extern xen_{{{class_lower}}}_set * +xen_{{{class_lower}}}_set_alloc(size_t size); + +/** + * Free the given xen_{{{class_lower}}}_set. The given set must have been + * allocated by this library. + */ +extern void +xen_{{{class_lower}}}_set_free(xen_{{{class_lower}}}_set *set); + + +{{/is_event}} +typedef struct xen_{{{class_lower}}}_record +{ +{{^is_event}} + xen_{{{class_lower}}} handle; +{{/is_event}} +{{#fields}} + {{{field_type}}}{{{field_name_lower}}}; +{{/fields}} +} xen_{{{class_lower}}}_record; + +/** + * Allocate a xen_{{{class_lower}}}_record. + */ +extern xen_{{{class_lower}}}_record * +xen_{{{class_lower}}}_record_alloc(void); + +/** + * Free the given xen_{{{class_lower}}}_record, and all referenced values. + * The given record must have been allocated by this library. + */ +extern void +xen_{{{class_lower}}}_record_free(xen_{{{class_lower}}}_record *record); + + +{{^is_event}} +typedef struct xen_{{{class_lower}}}_record_opt +{ + bool is_record; + union + { + xen_{{{class_lower}}} handle; + xen_{{{class_lower}}}_record *record; + } u; +} xen_{{{class_lower}}}_record_opt; + +/** + * Allocate a xen_{{{class_lower}}}_record_opt. + */ +extern xen_{{{class_lower}}}_record_opt * +xen_{{{class_lower}}}_record_opt_alloc(void); + +/** + * Free the given xen_{{{class_lower}}}_record_opt, and all referenced values. + * The given record_opt must have been allocated by this library. + */ +extern void +xen_{{{class_lower}}}_record_opt_free(xen_{{{class_lower}}}_record_opt *record_opt); + + +{{/is_event}} +typedef struct xen_{{{class_lower}}}_record_set +{ + size_t size; + xen_{{{class_lower}}}_record *contents[]; +} xen_{{{class_lower}}}_record_set; + +/** + * Allocate a xen_{{{class_lower}}}_record_set of the given size. + */ +extern xen_{{{class_lower}}}_record_set * +xen_{{{class_lower}}}_record_set_alloc(size_t size); + +/** + * Free the given xen_{{{class_lower}}}_record_set, and all referenced values. + * The given set must have been allocated by this library. + */ +extern void +xen_{{{class_lower}}}_record_set_free(xen_{{{class_lower}}}_record_set *set); + + +{{^is_event}} +typedef struct xen_{{{class_lower}}}_record_opt_set +{ + size_t size; + xen_{{{class_lower}}}_record_opt *contents[]; +} xen_{{{class_lower}}}_record_opt_set; + +/** + * Allocate a xen_{{{class_lower}}}_record_opt_set of the given size. + */ +extern xen_{{{class_lower}}}_record_opt_set * +xen_{{{class_lower}}}_record_opt_set_alloc(size_t size); + +/** + * Free the given xen_{{{class_lower}}}_record_opt_set, and all referenced + * values. The given set must have been allocated by this library. + */ +extern void +xen_{{{class_lower}}}_record_opt_set_free(xen_{{{class_lower}}}_record_opt_set *set); + + +{{/is_event}} +{{#messages}} +{{{msg_doc}}} +extern bool +xen_{{{class_lower}}}_{{{msg_name_lower}}}(xen_session *session{{#sync_params}}, {{{param_type}}}{{{param_name}}}{{/sync_params}}); + + +{{#is_async}} +{{{msg_doc}}} +extern bool +xen_{{{class_lower}}}_{{{msg_name_lower}}}_async(xen_session *session{{#async_params}}, {{{param_type}}}{{{param_name}}}{{/async_params}}); + + +{{/is_async}} +{{/messages}} +#endif + diff --git a/ocaml/sdk-gen/c/templates/class_decl.h.mustache b/ocaml/sdk-gen/c/templates/class_decl.h.mustache new file mode 100644 index 00000000000..521d3d49d40 --- /dev/null +++ b/ocaml/sdk-gen/c/templates/class_decl.h.mustache @@ -0,0 +1,47 @@ +/* + * 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_{{{class_upper}}}_DECL_H +#define XEN_{{{class_upper}}}_DECL_H + +{{^is_event}} +typedef void *xen_{{{class_lower}}}; + +struct xen_{{{class_lower}}}_set; +{{/is_event}} +struct xen_{{{class_lower}}}_record; +struct xen_{{{class_lower}}}_record_set; +{{^is_event}} +struct xen_{{{class_lower}}}_record_opt; +struct xen_{{{class_lower}}}_record_opt_set; +{{/is_event}} + +#endif + diff --git a/ocaml/sdk-gen/c/templates/map.c.mustache b/ocaml/sdk-gen/c/templates/map.c.mustache new file mode 100644 index 00000000000..0b944b35ad3 --- /dev/null +++ b/ocaml/sdk-gen/c/templates/map.c.mustache @@ -0,0 +1,92 @@ +/* + * 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. + */ + + +{{#internal_headers}} +#include "xen_{{{header}}}.h" +{{/internal_headers}} +{{#headers}} +#include +{{/headers}} + + +xen_{{{map_lower}}} * +xen_{{{map_lower}}}_alloc(size_t size) +{ + xen_{{{map_lower}}} *result = + calloc(1, sizeof(xen_{{{map_lower}}}) + + size * sizeof(struct xen_{{{map_lower}}}_contents)); + result->size = size; + return result; +} + + +void +xen_{{{map_lower}}}_free(xen_{{{map_lower}}} *map) +{ +{{#can_free}} + if (map == NULL) + return; + + size_t n = map->size; + for (size_t i = 0; i < n; i++) + { +{{#can_free_key}} + {{{free_key}}} +{{/can_free_key}} +{{#can_free_val}} + {{{free_val}}} +{{/can_free_val}} + } + +{{/can_free}} + free(map); +} +{{#enum_map}} + + +static const struct_member {{{map_lower}}}_struct_members[] = + { + { .type = &{{{abstract_type_key}}}, + .offset = offsetof(xen_{{{map_lower}}}_contents, key) }, + { .type = &{{{abstract_type_val}}}, + .offset = offsetof(xen_{{{map_lower}}}_contents, val) }, + }; + + +const abstract_type {{{map_lower}}}_abstract_type_ = + { + .XEN_API_TYPE = MAP, + .struct_size = sizeof({{{map_lower}}}_struct_members), + .member_count = + sizeof({{{map_lower}}}_struct_members) / sizeof(struct_member), + .members = {{{map_lower}}}_struct_members + }; +{{/enum_map}} + diff --git a/ocaml/sdk-gen/c/templates/map.h.mustache b/ocaml/sdk-gen/c/templates/map.h.mustache new file mode 100644 index 00000000000..aa7c96bf512 --- /dev/null +++ b/ocaml/sdk-gen/c/templates/map.h.mustache @@ -0,0 +1,68 @@ +/* + * 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_{{{map_upper}}}_H +#define XEN_{{{map_upper}}}_H + + +{{#headers}} +#include +{{/headers}} + + +typedef struct xen_{{{map_lower}}}_contents +{ + {{{key_type_lower}}}key; + {{{val_type_lower}}}val; +} xen_{{{map_lower}}}_contents; + + +typedef struct xen_{{{map_lower}}} +{ + size_t size; + xen_{{{map_lower}}}_contents contents[]; +} xen_{{{map_lower}}}; + +/** + * Allocate a xen_{{{map_lower}}} of the given size. + */ +extern xen_{{{map_lower}}} * +xen_{{{map_lower}}}_alloc(size_t size); + +/** + * Free the given xen_{{{map_lower}}} + * and all referenced values. The map must have been allocated by this library. + */ +extern void +xen_{{{map_lower}}}_free(xen_{{{map_lower}}} *map); + + +#endif + diff --git a/ocaml/sdk-gen/c/templates/xen_all.h.mustache b/ocaml/sdk-gen/c/templates/xen_all.h.mustache index 9d9bef9143e..fb86a54f4ef 100644 --- a/ocaml/sdk-gen/c/templates/xen_all.h.mustache +++ b/ocaml/sdk-gen/c/templates/xen_all.h.mustache @@ -27,7 +27,6 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* This file is autogenerated */ #ifndef XEN_API_XEN_ALL_H #define XEN_API_XEN_ALL_H @@ -37,9 +36,10 @@ #include #include {{#api_headers}} -#include <{{api_header}}> +#include {{/api_headers}} #include #include #endif + diff --git a/ocaml/sdk-gen/c/templates/xen_api_failure.c.mustache b/ocaml/sdk-gen/c/templates/xen_api_failure.c.mustache new file mode 100644 index 00000000000..f35926bfce1 --- /dev/null +++ b/ocaml/sdk-gen/c/templates/xen_api_failure.c.mustache @@ -0,0 +1,58 @@ +/* + * 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 "xen_internal.h" +#include + + +/* + * Maintain this in the same order as the enum declaration! + */ +static const char *lookup_table[] = +{ +{{#api_errors}} + "{{api_error}}", +{{/api_errors}} +}; + + +const char * +xen_api_failure_to_string(enum xen_api_failure val) +{ + return lookup_table[val]; +} + + +extern enum xen_api_failure +xen_api_failure_from_string(const char *str) +{ + return ENUM_LOOKUP(str, lookup_table); +} + diff --git a/ocaml/sdk-gen/c/templates/xen_api_failure.h.mustache b/ocaml/sdk-gen/c/templates/xen_api_failure.h.mustache new file mode 100644 index 00000000000..3094d7a51ea --- /dev/null +++ b/ocaml/sdk-gen/c/templates/xen_api_failure.h.mustache @@ -0,0 +1,66 @@ +/* + * 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_API_FAILURE_H +#define XEN_API_FAILURE_H + + +enum xen_api_failure +{ +{{#api_errors}} +{{{api_error_doc}}} + XEN_API_FAILURE_{{api_error}}, + +{{/api_errors}} + /** + * Unknown to this SDK version. + */ + XEN_API_FAILURE_UNDEFINED +}; + + +/** + * Return the name corresponding to the given code. This string must + * not be modified or freed. + */ +extern const char * +xen_api_failure_to_string(enum xen_api_failure val); + + +/** + * Return the correct code for the given string, or UNDEFINED if the + * given string does not match a known code. + */ +extern enum xen_api_failure +xen_api_failure_from_string(const char *str); + + +#endif + diff --git a/ocaml/sdk-gen/c/templates/xen_api_version.c.mustache b/ocaml/sdk-gen/c/templates/xen_api_version.c.mustache index 0a13575d334..94b0c894b47 100644 --- a/ocaml/sdk-gen/c/templates/xen_api_version.c.mustache +++ b/ocaml/sdk-gen/c/templates/xen_api_version.c.mustache @@ -27,6 +27,7 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include "xen/api/xen_api_version.h" const char * @@ -53,3 +54,4 @@ xen_api_version_from_int(int64_t major_version, int64_t minor_version) {{/releases}} return xen_api_unknown_version; } + diff --git a/ocaml/sdk-gen/c/templates/xen_api_version.h.mustache b/ocaml/sdk-gen/c/templates/xen_api_version.h.mustache index 5f55ec79291..09115486aa6 100644 --- a/ocaml/sdk-gen/c/templates/xen_api_version.h.mustache +++ b/ocaml/sdk-gen/c/templates/xen_api_version.h.mustache @@ -27,6 +27,7 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ + #ifndef XEN_API_VERSION_H #define XEN_API_VERSION_H @@ -48,3 +49,4 @@ extern xen_api_version xen_api_version_from_int(int64_t major_version, int64_t minor_version); #endif + diff --git a/ocaml/sdk-gen/c/templates/xen_enum.c.mustache b/ocaml/sdk-gen/c/templates/xen_enum.c.mustache index 421c9015a6f..90b1d200868 100644 --- a/ocaml/sdk-gen/c/templates/xen_enum.c.mustache +++ b/ocaml/sdk-gen/c/templates/xen_enum.c.mustache @@ -96,3 +96,4 @@ const abstract_type xen_{{{enum_name}}}_set_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 index 824179cf2d3..3a944a71438 100644 --- a/ocaml/sdk-gen/c/templates/xen_enum.h.mustache +++ b/ocaml/sdk-gen/c/templates/xen_enum.h.mustache @@ -38,14 +38,12 @@ enum xen_{{{enum_name}}} { {{#enum_values}} - /** - * {{{enum_value_doc}}} - */ +{{{enum_value_doc}}} XEN_{{{enum_name_upper}}}_{{{enum_value_upper}}}, {{/enum_values}} /** - * Unknown to this version of the bindings. + * Unknown to this SDK version. */ XEN_{{{enum_name_upper}}}_UNDEFINED }; @@ -64,8 +62,8 @@ 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. + * 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); @@ -89,3 +87,4 @@ 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 index b9731686edb..f3945be9738 100644 --- a/ocaml/sdk-gen/c/templates/xen_enum_internal.h.mustache +++ b/ocaml/sdk-gen/c/templates/xen_enum_internal.h.mustache @@ -28,10 +28,9 @@ */ - /* * Declarations of the abstract types used during demarshalling of enum - * xen_{{{enum_name}}}. Internal to this library -- do not use from outside. + * xen_{{{enum_name}}}. */ @@ -43,9 +42,8 @@ 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/c/templates/xen_enum_map_internal.h.mustache b/ocaml/sdk-gen/c/templates/xen_enum_map_internal.h.mustache new file mode 100644 index 00000000000..6d595ad16fc --- /dev/null +++ b/ocaml/sdk-gen/c/templates/xen_enum_map_internal.h.mustache @@ -0,0 +1,39 @@ +/* + * 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_{{{map_upper}}}_INTERNAL_H +#define XEN_{{{map_upper}}}_INTERNAL_H + + +extern const abstract_type {{{map_lower}}}_abstract_type_; + + +#endif + diff --git a/ocaml/sdk-gen/c/templates/xen_internal.mustache b/ocaml/sdk-gen/c/templates/xen_internal.mustache index 934ae5047e0..621617511ce 100644 --- a/ocaml/sdk-gen/c/templates/xen_internal.mustache +++ b/ocaml/sdk-gen/c/templates/xen_internal.mustache @@ -27,6 +27,7 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ + #ifndef XEN_INTERNAL_H #define XEN_INTERNAL_H @@ -208,3 +209,4 @@ void type__ ## _record_opt_free(type__ ## _record_opt *opt) { \ #endif +