]> xenbits.xensource.com Git - xenclient/toolstack.git/commitdiff
Fix rpc codegen to output code by endpoints.
authorPrashanth Mundkur <prashanth.mundkur@citrix.com>
Thu, 28 May 2009 05:26:11 +0000 (22:26 -0700)
committerPrashanth Mundkur <prashanth.mundkur@citrix.com>
Thu, 28 May 2009 05:26:11 +0000 (22:26 -0700)
gen/rpc/codegen.ml
gen/rpc/gen_rpc.ml
gen/rpc/rpc_decl.ml
gen/rpc/syntax.ml
gen/rpc/syntax_json_conv.ml
gen/rpc/tests/OMakefile
gen/rpc/tests/rpc_defns.json
gen/rpc/tests/test_rpc.ml

index 4dd63011bcb7120898067b75f17db1e95647079b..cfb22ce547a299b295bc6aeaad82d81d6729b2bd 100644 (file)
@@ -273,34 +273,34 @@ let open_output fn =
        let ff = formatter_of_out_channel oc in
        oc, ff
 
-let generate_server spec fn =
+let generate_server ff spec s =
+       Server.start_server ff s;
+       let rpc_list, notif_list = get_sorted_rpcs_by_server spec s in
+       let sig_name = Server.gen_dispatch_struct ff s rpc_list notif_list in
+       Server.gen_rpc_dispatch ff Var_env.new_env s sig_name rpc_list;
+       Server.gen_notification_dispatch ff Var_env.new_env s sig_name notif_list;
+       Server.gen_dispatch ff sig_name;
+       Server.end_server ff;
+       fprintf ff "@\n@?"
+
+let generate_client ff spec c =
+       let rpc_list = get_rpcs_by_server spec c in
+       let rpcid_maker = Client.start_maker ff c in
+       List.iter (Client.generate_rpc ff Var_env.new_env rpcid_maker c) rpc_list;
+       Client.end_maker ff
+
+let generate_endpoint spec e fn =
        let oc, ff = open_output fn in
        generate_header ff;
        generate_opens ff spec;
        List.iter (fun s ->
-                       Server.start_server ff s;
-                       let rpc_list, notif_list = get_sorted_rpcs_by_server spec s in
-                       let sig_name = Server.gen_dispatch_struct ff s rpc_list notif_list in
-                       Server.gen_rpc_dispatch ff Var_env.new_env s sig_name rpc_list;
-                       Server.gen_notification_dispatch ff Var_env.new_env s sig_name notif_list;
-                       Server.gen_dispatch ff sig_name;
-                       Server.end_server ff;
-                       fprintf ff "@\n@?"
-                 ) (get_servers spec);
-       close_out oc
-
-let generate_client spec fn =
-       let oc, ff = open_output fn in
-       generate_header ff;
-       generate_opens ff spec;
-       List.iter (fun s ->
-                       let rpc_list = get_rpcs_by_server spec s in
-                       let rpcid_maker = Client.start_maker ff s in
-                       List.iter (Client.generate_rpc ff Var_env.new_env rpcid_maker s) rpc_list;
-                       Client.end_maker ff
-                 ) (get_servers spec);
-       close_out oc
-
-let generate spec cfn sfn =
-       generate_client spec cfn;
-       generate_server spec sfn
+                       generate_server ff spec s
+                 ) (get_matching_servers spec e.endpoint_servers);
+       List.iter (fun c ->
+                       generate_client ff spec c
+                 ) (get_matching_servers spec e.endpoint_clients)
+
+let generate spec endpoints =
+       List.iter (fun (ep, outf) ->
+                       generate_endpoint spec ep outf
+                 ) endpoints
index a1d18d024be74a7d0a8235470746692ad54726c1..9551fbc9bf6699eba2ad331743d390a506b3223f 100644 (file)
@@ -20,21 +20,26 @@ let make_default_output_filename f suffix =
   let stem = Filename.chop_extension base in
         Filename.concat dir (stem ^ suffix)
 
+exception Invalid_endpoint_option of string
 let parse_args () =
        let input = ref "" in
-       let client = ref "" in
-       let server = ref "" in
+       let endpoints = ref [] in
+       let add_ep_output s =
+               try
+                       let colon = String.index s ':' in
+                       let len = String.length s in
+                       let ep = String.sub s 0 colon in
+                       let epfile = String.sub s (colon+1) (len - colon - 1) in
+                       endpoints := (ep, epfile) :: !endpoints
+               with _ -> raise (Invalid_endpoint_option s) in
        let options = [ ("-i", Arg.Set_string input, " input file");
-                       ("-c", Arg.Set_string client, " client interface");
-                       ("-s", Arg.Set_string server, " server interface")
+                       ("-o", Arg.String add_ep_output, " endpoint:output_file");
                      ] in
        let usage = Printf.sprintf "Usage: %s [options]" Sys.argv.(0) in
        let errmsg s = Printf.eprintf "%s\n" s; Arg.usage (Arg.align options) usage; exit 1 in
        Arg.parse (Arg.align options) (fun s -> input := s) usage;
        if !input = "" then errmsg "Unspecified input file!";
-       if !client = "" then client := make_default_output_filename !input "_client.ml";
-       if !server = "" then server := make_default_output_filename !input "_server.ml";
-       !input, !client, !server
+       !input, !endpoints
 
 let read_whole_file ic =
        let buf = Buffer.create 2048 in
@@ -73,6 +78,7 @@ let parse_file f =
 
 exception Unknown_rpc_decl of int * Json.t
 exception Invalid_rpc_decl of int * (* type *) string * (* msg *) string
+exception Undefined_endpoint of string
 
 let print_exception e =
        let msg =
@@ -85,6 +91,8 @@ let print_exception e =
                        Printf.sprintf "Rpc declaration #%d is of unknown type." i
                | Invalid_rpc_decl (i, n, m) ->
                        Printf.sprintf "Error parsing decl %d for %s: %s" i n m
+               | Undefined_endpoint e ->
+                       Printf.sprintf "Endpoint \"%s\" not found in input file." e
                | Sys_error s ->
                        Printf.sprintf "%s" s
                | e ->
@@ -105,16 +113,24 @@ let process_jdecl (i, j) =
        else if (Json_conv.is_object_field_present obj "rpc_type") then
                try Rpc_decl.Rpc_rpc (rpc_of_json j)
                with Json_conv.Json_conv_error err -> raise (Invalid_rpc_decl (i, "rpc", (Json_conv.string_of_error err)))
+       else if (Json_conv.is_object_field_present obj "endpoint_name") then
+               try Rpc_decl.Rpc_endpoint (endpoint_of_json j)
+               with Json_conv.Json_conv_error err -> raise (Invalid_rpc_decl (i, "endpoint", (Json_conv.string_of_error err)))
        else
                raise (Unknown_rpc_decl (i, j))
 
 let _ =
-       let input, client, server = parse_args () in
+       let input, endpoints = parse_args () in
        try
                let jdecls = parse_file input in
                let decls = List.map process_jdecl jdecls in
                let spec = Rpc_decl.spec_with_decls decls in
-               Codegen.generate spec client server;
+               let gen = List.map (fun (n, outf) ->
+                                       let e = try Rpc_decl.get_endpoint_by_name spec n
+                                               with Not_found -> raise (Undefined_endpoint n)
+                                       in e, outf
+                                  ) endpoints in
+               Codegen.generate spec gen;
                exit 0
        with e ->
                print_exception e;
index 10a10174efc21b531783d361fc5c2fc3c53af92e..cba39185136aa91ac7fb4c38ef80d6ed804985d7 100644 (file)
@@ -19,23 +19,26 @@ type decl =
        | Rpc_use of use
        | Rpc_server of server
        | Rpc_rpc of rpc
+       | Rpc_endpoint of endpoint
 
-type elem = Server | RPC
+type elem = Server | RPC | Endpoint
 
-let elem_name = function Server -> "server" | RPC -> "rpc"
+let elem_name = function Server -> "server" | RPC -> "rpc" | Endpoint -> "endpoint"
 
 type spec =
 {
        uses: string list;
        servers: server list;
        rpcs: rpc list;
+       endpoints: endpoint list;
 }
 
 let init_spec =
 {
        uses = [];
        servers = [];
-       rpcs = []
+       rpcs = [];
+       endpoints = [];
 }
 
 let get_rpcs_by_server spec server =
@@ -51,6 +54,12 @@ let get_sorted_rpcs_by_server spec server =
                               ) ([], []) rpcs
        in rlist, nlist
 
+let get_matching_servers spec names =
+       List.filter (fun s -> List.mem s.server_name names) spec.servers
+
+let get_endpoint_by_name spec name =
+       List.find (fun e -> e.endpoint_name = name) spec.endpoints
+
 exception Multiple_decl of elem * string
 exception Unknown_ref of elem * string
 exception Unknown_RPC_type of string
@@ -62,6 +71,7 @@ let present spec elem name =
                match elem with
                | Server -> ignore (List.find (fun s -> s.server_name = name) spec.servers); true
                | RPC    -> ignore (List.find (fun r -> (r.rpc_server ^ "." ^ r.rpc_request.request_name) = name) spec.rpcs); true
+               | Endpoint -> ignore (List.find (fun e -> e.endpoint_name = name) spec.endpoints); true
        with Not_found -> false
 
 let check_new spec elem name =
@@ -99,10 +109,19 @@ let add_rpc spec r =
        | s -> raise (Unknown_RPC_type s));
        { spec with rpcs = r :: spec.rpcs }
 
+let add_endpoint spec e =
+       check_new spec Endpoint e.endpoint_name;
+       List.iter (fun s -> check_existing spec Server s) e.endpoint_servers;
+       List.iter (fun c -> check_existing spec Server c) e.endpoint_clients;
+       { spec with endpoints = e :: spec.endpoints }
+
+let get_endpoints spec = List.rev spec.endpoints
+
 let add_decl spec = function 
        | Rpc_use u -> add_use spec u
        | Rpc_server s -> add_server spec s
        | Rpc_rpc r -> add_rpc spec r
+       | Rpc_endpoint e -> add_endpoint spec e
 
 let error_message e =
        match e with
index ad5224997878e6a20e8048e1cff7c67e442ebc75..2f9bf4dda386dd0d9fe7adc5763197ec285dc365 100644 (file)
@@ -61,3 +61,9 @@ type rpc =
        rpc_response: response option;
 }
 
+type endpoint =
+{
+       endpoint_name: string;
+       endpoint_servers: string list;
+       endpoint_clients: string list;
+}
index f08a9d071eb890b2f877a261bcb6a7d119bc54c1..b50378b70bd85cf1f0aff2b5d7317eb6405c5984 100644 (file)
@@ -212,3 +212,44 @@ let rec rpc_of_json j =
                 ) in
         { rpc_type = str; rpc_server = str_1; rpc_doc = str_2; rpc_version = str_3; rpc_deprecated = opt; rpc_label_arguments = opt_1; rpc_request = request; rpc_response = opt_2 }
 
+let rec endpoint_to_json o =
+        (match o with
+        | { endpoint_name = str; endpoint_servers = lst; endpoint_clients = lst_1 } ->
+                let j_str =
+                        Json_conv.string_to_json str in
+                let j_lst =
+                        let lst_jlist = List.map
+                                (fun str_1 ->
+                                        Json_conv.string_to_json str_1
+                                ) lst in
+                        Json.Array (Array.of_list lst_jlist) in
+                let j_lst_1 =
+                        let lst_1_jlist = List.map
+                                (fun str_1 ->
+                                        Json_conv.string_to_json str_1
+                                ) lst_1 in
+                        Json.Array (Array.of_list lst_1_jlist) in
+                Json.Object [| ("endpoint_name", j_str); ("endpoint_servers", j_lst); ("endpoint_clients", j_lst_1) |]
+        )
+
+let rec endpoint_of_json j =
+        let j_ftable = Json_conv.get_object_table j in
+        let endpoint_name_f = Json_conv.get_object_field j_ftable "endpoint_name" in
+        let str =
+                Json_conv.string_of_json endpoint_name_f in
+        let endpoint_servers_f = Json_conv.get_object_field j_ftable "endpoint_servers" in
+        let lst =
+                let endpoint_servers_f_oarray = Array.map
+                        (fun str_1 ->
+                                Json_conv.string_of_json str_1
+                        ) (Json_conv.get_array endpoint_servers_f) in
+                Array.to_list endpoint_servers_f_oarray in
+        let endpoint_clients_f = Json_conv.get_object_field j_ftable "endpoint_clients" in
+        let lst_1 =
+                let endpoint_clients_f_oarray = Array.map
+                        (fun str_1 ->
+                                Json_conv.string_of_json str_1
+                        ) (Json_conv.get_array endpoint_clients_f) in
+                Array.to_list endpoint_clients_f_oarray in
+        { endpoint_name = str; endpoint_servers = lst; endpoint_clients = lst_1 }
+
index fed949d445e1f4559d987638d225542fc121ff75..258b09887173a9bde77dec8d6960777401207958 100644 (file)
@@ -1,16 +1,16 @@
 rpc_types_json_conv.ml: rpc_types.ml $(JSON_CONV)
        $(JSON_GEN_CONV_DIR)/$(JSON_CONV_PROG) -i $< -o $@
 
-rpc_defns_client.ml rpc_defns_server.ml: rpc_defns.json $(GEN_RPC)
-       $(JSON_GEN_RPC_DIR)/$(GEN_RPC_PROG) $<
+rpc_one.ml rpc_two.ml: rpc_defns.json $(GEN_RPC)
+       $(JSON_GEN_RPC_DIR)/$(GEN_RPC_PROG)  -o 'one:rpc_one.ml' -o 'two:rpc_two.ml' $<
 
 OCAMLFLAGS += -I $(JSON_LIB_DIR) -I $(JSON_RPC_LIB_DIR)
 
 RPC_TEST_FILES[] =
        rpc_types
        rpc_types_json_conv
-       rpc_defns_client
-       rpc_defns_server
+       rpc_one
+       rpc_two
        test_rpc
 
 
index 1e9d1fd2a45d32a35ab11874651ee0a0088aa8c3..6ba66687968f10c2df5079aed37c33006f4e8bf1 100644 (file)
@@ -24,7 +24,7 @@
                                      }
                  },
 
-  "rpc_deprecated": "string",
+  "rpc_deprecated": "some notes",
   "rpc_label_arguments": false
 }
 
@@ -51,7 +51,7 @@
                                      }
                  },
 
-  "rpc_deprecated": "string",
+  "rpc_deprecated": "some notes",
   "rpc_label_arguments": false
 }
 
 
   "rpc_label_arguments": true
 }
+
+{ "endpoint_name": "one",
+  "endpoint_servers": [ "server" ],
+  "endpoint_clients": [ "server1" ]
+}
+
+{ "endpoint_name": "two",
+  "endpoint_servers": [ "server1" ],
+  "endpoint_clients": [ "server" ]
+}
index 378e66a1dccc41856e3f41c26e9e451f7fb14bfb..e38b490343a05ff5807d218b093359c0167f7c2f 100644 (file)
@@ -1,7 +1,7 @@
 open Rpc_types
 open Rpc_types_json_conv
-open Rpc_defns_server
-open Rpc_defns_client
+open Rpc_one
+open Rpc_two
 
 (* First, implement the Json-rpc id generator. *)
 module I : Jsonrpc.Rpc_id_generator = struct