common/mlstdutils: Drop our implementations of functions now in OCaml 4.01.

We reimplemented some functions which can now be found in the OCaml
stdlib since 4.01 (or earlier).  The functions I have dropped are:

 - String.map
 - |>
 - iteri  (replaced by List.iteri)
 - mapi   (replaced by List.mapi)

Note that our definition of iteri was slightly wrong: the type of the
function parameter was too wide, allowing (int -> 'a -> 'b) instead of
(int -> 'a -> unit).

I also added this new function to the Std_utils.String module as an
export from stdlib String:

 - String.iteri

Thanks: Pino Toscano
This commit is contained in:
Richard W.M. Jones
2017-10-05 10:07:11 +01:00
parent a702858664
commit 457bdb4e2f
26 changed files with 39 additions and 73 deletions

View File

@@ -110,7 +110,7 @@ let main () =
printf "command line:";
List.iter (printf " %s") (Array.to_list Sys.argv);
print_newline ();
iteri (
List.iteri (
fun i (source, fingerprint) ->
printf "source[%d] = (%S, %S)\n" i source fingerprint
) cmdline.sources
@@ -576,7 +576,7 @@ let main () =
| `Convert -> printf "qemu-img convert"
in
iteri (
List.iteri (
fun i (itags, task, otags) ->
printf "%d: itags:" i;
print_tags itags;

View File

@@ -81,14 +81,6 @@ end
module String = struct
include String
let map f s =
let len = String.length s in
let b = Bytes.create len in
for i = 0 to len-1 do
Bytes.unsafe_set b i (f (unsafe_get s i))
done;
Bytes.to_string b
let lowercase_ascii s = map Char.lowercase_ascii s
let uppercase_ascii s = map Char.uppercase_ascii s
@@ -493,8 +485,6 @@ and _wrap_find_next_break i len str =
and output_spaces chan n = for i = 0 to n-1 do output_char chan ' ' done
let (|>) x f = f x
(* Drop elements from a list while a predicate is true. *)
let rec dropwhile f = function
| [] -> []
@@ -520,21 +510,6 @@ let rec find_map f = function
| Some y -> y
| None -> find_map f xs
let iteri f xs =
let rec loop i = function
| [] -> ()
| x :: xs -> f i x; loop (i+1) xs
in
loop 0 xs
let rec mapi i f =
function
| [] -> []
| a::l ->
let r = f i a in
r :: mapi (i + 1) f l
let mapi f l = mapi 0 f l
let rec combine3 xs ys zs =
match xs, ys, zs with
| [], [], [] -> []

View File

@@ -62,6 +62,8 @@ module String : sig
val index : string -> char -> int
val index_from : string -> int -> char -> int
val iter : (char -> unit) -> string -> unit
val iteri : (int -> char -> unit) -> string -> unit
val map : (char -> char) -> string -> string
val length : string -> int
val make : int -> char -> string
val rcontains_from : string -> int -> char -> bool
@@ -70,8 +72,6 @@ module String : sig
val sub : string -> int -> int -> string
val unsafe_get : string -> int -> char
val map : (char -> char) -> string -> string
val lowercase_ascii : string -> string
val uppercase_ascii : string -> string
val capitalize_ascii : string -> string
@@ -195,10 +195,6 @@ val wrap : ?chan:out_channel -> ?indent:int -> string -> unit
val output_spaces : out_channel -> int -> unit
(** Write [n] spaces to [out_channel]. *)
val (|>) : 'a -> ('a -> 'b) -> 'b
(** Added in OCaml 4.01, we can remove our definition when we
can assume this minimum version of OCaml. *)
val dropwhile : ('a -> bool) -> 'a list -> 'a list
(** [dropwhile f xs] drops leading elements from [xs] until
[f] returns false. *)
@@ -215,11 +211,6 @@ val find_map : ('a -> 'b option) -> 'a list -> 'b
(** [find_map f xs] applies [f] to each element of [xs] until
[f x] returns [Some y]. It returns [y]. If we exhaust the
list then this raises [Not_found]. *)
val iteri : (int -> 'a -> 'b) -> 'a list -> unit
(** [iteri f xs] calls [f i x] for each element, with [i] counting from [0]. *)
val mapi : (int -> 'a -> 'b) -> 'a list -> 'b list
(** [mapi f xs] calls [f i x] for each element, with [i] counting from [0],
forming the return values from [f] into another list. *)
val combine3 : 'a list -> 'b list -> 'c list -> ('a * 'b * 'c) list
(** Like {!List.combine} but for triples. All lists must be the same length. *)

View File

@@ -276,7 +276,7 @@ let external_command ?(echo_cmd = true) cmd =
let rec run_commands ?(echo_cmd = true) cmds =
let res = Array.make (List.length cmds) 0 in
let pids =
mapi (
List.mapi (
fun i (args, stdout_chan, stderr_chan) ->
let run_res = do_run args ?stdout_chan ?stderr_chan in
match run_res with

View File

@@ -990,7 +990,7 @@ let main () =
[ csum_tool; fn ], Some outfd, None
) checksums in
let res = run_commands cmds in
iteri (
List.iteri (
fun i code ->
if code <> 0 then (
let args, _, _ = List.nth cmds i in

View File

@@ -497,7 +497,7 @@ copy_table (char * const * argv)
pr " CAMLlocal2 (rv, v);\n";
pr "\n";
pr " rv = caml_alloc (%d, 0);\n" (List.length cols);
iteri (
List.iteri (
fun i col ->
(match col with
| name, FString ->
@@ -774,7 +774,7 @@ copy_table (char * const * argv)
name;
pr "{\n";
pr " return guestfs_int_ocaml_%s (argv[0]" name;
iteri (fun i _ -> pr ", argv[%d]" (i+1)) (List.tl params);
List.iteri (fun i _ -> pr ", argv[%d]" (i+1)) (List.tl params);
pr ");\n";
pr "}\n";
pr "\n"

View File

@@ -648,7 +648,7 @@ extern GUESTFS_DLL_PUBLIC void *guestfs_next_private (guestfs_h *g, const char *
pr "#define GUESTFS_HAVE_%s 1\n" (String.uppercase_ascii shortname);
if optargs <> [] then (
iteri (
List.iteri (
fun i argt ->
let uc_shortname = String.uppercase_ascii shortname in
let n = name_of_optargt argt in
@@ -677,7 +677,7 @@ extern GUESTFS_DLL_PUBLIC void *guestfs_next_private (guestfs_h *g, const char *
pr "\n";
pr "struct guestfs_%s_argv {\n" shortname;
pr " uint64_t bitmask;\n";
iteri (
List.iteri (
fun i argt ->
let c_type =
match argt with

View File

@@ -48,7 +48,7 @@ let generate_daemon_actions_h () =
function
| { style = _, _, [] } -> ()
| { name = shortname; style = _, _, (_::_ as optargs) } ->
iteri (
List.iteri (
fun i arg ->
let uc_shortname = String.uppercase_ascii shortname in
let n = name_of_optargt arg in
@@ -535,7 +535,7 @@ let generate_daemon_caml_stubs () =
pr " return NULL;\n";
pr " }\n";
pr "\n";
iteri (
List.iteri (
fun i ->
pr " v = Field (retv, %d);\n" i;
function

View File

@@ -288,7 +288,7 @@ instead of erl_interface.
pr "{\n";
pr " ETERM *t[%d];\n" (List.length cols);
pr "\n";
iteri (
List.iteri (
fun i col ->
(match col with
| name, FString ->
@@ -358,7 +358,7 @@ instead of erl_interface.
pr "run_%s (ETERM *args_tuple)\n" name;
pr "{\n";
iteri (
List.iteri (
fun i ->
function
| String (_, n) ->

View File

@@ -44,6 +44,6 @@ let events = [
"warning"; (* warnings from the library *)
]
let events = mapi (fun i name -> name, 1 lsl i) events
let events = List.mapi (fun i name -> name, 1 lsl i) events
let all_events_bitmask = (1 lsl List.length events) - 1

View File

@@ -1165,7 +1165,7 @@ $VG guestfish \\
let vg_count = ref 0 in
iteri (
List.iteri (
fun i (name, _, _, _) ->
let params = [name] in
let params =

View File

@@ -330,7 +330,7 @@ public class GuestFS {
pr " /* Unpack optional args. */\n";
pr " Object _optobj;\n";
pr " long _optargs_bitmask = 0;\n";
iteri (
List.iteri (
fun i argt ->
let t, boxed_t, convert, n, default =
match argt with

View File

@@ -493,7 +493,7 @@ guestfs_int_lua_delete_event_callback (lua_State *L)
pr " \"%s\");\n" name;
pr "\n";
iteri (
List.iteri (
fun i ->
let i = i+2 in (* Lua indexes from 1(!), plus the handle. *)
function

View File

@@ -353,7 +353,7 @@ PREINIT:
pr ", ...";
pr ")\n";
pr " guestfs_h *g;\n";
iteri (
List.iteri (
fun i ->
function
| String (_, n) ->

View File

@@ -873,7 +873,7 @@ class GuestFS(object):
* at the end.
*)
let lines =
mapi (
List.mapi (
fun lineno line ->
if line = "" && lineno <> endpos then
""

View File

@@ -240,7 +240,7 @@ and generate_ruby_c actions () =
pr " if (argc < %d || argc > %d)\n" nr_args (nr_args+1);
pr " rb_raise (rb_eArgError, \"expecting %d or %d arguments\");\n" nr_args (nr_args+1);
pr "\n";
iteri (
List.iteri (
fun i arg ->
pr " volatile VALUE %sv = argv[%d];\n" (name_of_argt arg) i
) args;

View File

@@ -99,7 +99,7 @@ let rec generate_c_api_tests () =
let test_names =
List.map (
fun { name; optional; tests } ->
mapi (generate_one_test name optional) tests
List.mapi (generate_one_test name optional) tests
) (actions |> sort) in
let test_names = List.concat test_names in
@@ -274,7 +274,7 @@ and generate_test_perform name i test_name test =
| TestResult (seq, expr) ->
pr " /* TestResult for %s (%d) */\n" name i;
let n = List.length seq in
iteri (
List.iteri (
fun i cmd ->
let ret = if i = n-1 then "ret" else sprintf "ret%d" (n-i-1) in
generate_test_command_call ~ret test_name cmd
@@ -430,12 +430,12 @@ and generate_test_command_call ?(expect_error = false) ?(do_return = true) ?test
pr " const char *const %s[1] = { NULL };\n" sym
| StringList (_, _), arg, sym ->
let strs = String.nsplit " " arg in
iteri (
List.iteri (
fun i str ->
pr " const char *%s_%d = \"%s\";\n" sym i (c_quote str);
) strs;
pr " const char *const %s[] = {\n" sym;
iteri (
List.iteri (
fun i _ -> pr " %s_%d,\n" sym i
) strs;
pr " NULL\n";
@@ -478,12 +478,12 @@ and generate_test_command_call ?(expect_error = false) ?(do_return = true) ?test
pr " const char *const %s[1] = { NULL };\n" n; true
| OStringList n, arg ->
let strs = String.nsplit " " arg in
iteri (
List.iteri (
fun i str ->
pr " const char *%s_%d = \"%s\";\n" n i (c_quote str);
) strs;
pr " const char *const %s[] = {\n" n;
iteri (
List.iteri (
fun i _ -> pr " %s_%d,\n" n i
) strs;
pr " NULL\n";

View File

@@ -921,7 +921,7 @@ let convert (g : G.guestfs) inspect source output rcaps =
| IDE -> ide_block_prefix in
let map =
mapi (
List.mapi (
fun i disk ->
let block_prefix_before_conversion =
match disk.s_controller with
@@ -945,7 +945,7 @@ let convert (g : G.guestfs) inspect source output rcaps =
* although the guest uses xvdX natively.
*)
let map = map @
mapi (
List.mapi (
fun i disk ->
"xvd" ^ drive_name i, block_prefix_after_conversion ^ drive_name i
) source.s_disks in

View File

@@ -174,7 +174,7 @@ read the man page virt-v2v-copy-to-local(1).
(* Copy the disks. *)
let n = List.length disks in
iteri (
List.iteri (
fun i (remote_disk, local_disk, sslverify, cookie) ->
message (f_"Copying remote disk %d/%d to %s")
(i+1) n local_disk;

View File

@@ -478,7 +478,7 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
with Not_found -> assert false in
(* Iterate over the disks, adding them to the OVF document. *)
iteri (
List.iteri (
fun i ({ target_overlay = ov } as t, image_uuid, vol_uuid) ->
(* This sets the boot order to boot the first disk first. This
* isn't generally correct. We should copy over the boot order
@@ -604,7 +604,7 @@ and add_networks nics guestcaps ovf =
with Not_found -> assert false in
(* Iterate over the NICs, adding them to the OVF document. *)
iteri (
List.iteri (
fun i { s_mac = mac; s_vnet_type = vnet_type;
s_vnet = vnet; s_vnet_orig = vnet_orig } ->
let dev = sprintf "eth%d" i in

View File

@@ -118,7 +118,7 @@ and find_hdds vmx vmx_filename
let hdds = List.map (fun (_, _, source) -> source) hdds in
(* Set the s_disk_id field to an incrementing number. *)
let hdds = mapi (fun i source -> { source with s_disk_id = i }) hdds in
let hdds = List.mapi (fun i source -> { source with s_disk_id = i }) hdds in
hdds

View File

@@ -121,7 +121,7 @@ and choose_root root_choice g = function
printf "\n***\n";
printf (f_"Dual- or multi-boot operating system detected. Choose the root filesystem\nthat contains the main operating system from the list below:\n");
printf "\n";
iteri (
List.iteri (
fun i root ->
let prod = g#inspect_get_product_name root in
match prod with

View File

@@ -144,7 +144,7 @@ object
* will be called "guestname-disk2" etc. The manual strongly
* hints you should import the data disks to Cinder.
*)
iteri (
List.iteri (
fun i { target_file; target_format } ->
let name =
if i == 0 then source.s_name

View File

@@ -164,7 +164,7 @@ object
| Virtio_net -> "virtio-net-pci"
| E1000 -> "e1000"
| RTL8139 -> "rtl8139" in
iteri (
List.iteri (
fun i nic ->
arg_list "-netdev" ["user"; "id=net" ^ string_of_int i];
arg_list "-device" [net_bus;

View File

@@ -37,7 +37,7 @@ let rec target_bus_assignment source targets guestcaps =
| Virtio_blk -> virtio_blk_bus
| Virtio_SCSI -> scsi_bus
| IDE -> ide_bus in
iteri (
List.iteri (
fun i t ->
let t = BusSlotTarget t in
insert bus i t

View File

@@ -282,7 +282,7 @@ and check_host_free_space () =
(* Create a qcow2 v3 overlay to protect the source image(s). *)
and create_overlays src_disks =
message (f_"Creating an overlay to protect the source from being modified");
mapi (
List.mapi (
fun i ({ s_qemu_uri = qemu_uri; s_format = format } as source) ->
let overlay_file =
Filename.temp_file ~temp_dir:overlay_dir "v2vovl" ".qcow2" in
@@ -664,7 +664,7 @@ and copy_targets cmdline targets input output =
)
);
let nr_disks = List.length targets in
mapi (
List.mapi (
fun i t ->
message (f_"Copying disk %d/%d to %s (%s)")
(i+1) nr_disks t.target_file t.target_format;