diff --git a/base64.opam b/base64.opam index d48794e..07ce173 100644 --- a/base64.opam +++ b/base64.opam @@ -17,7 +17,8 @@ representation. It is specified in RFC 4648. depends: [ "ocaml" {>="4.03.0"} "base-bytes" - "dune" {>= "1.0.1"} + "dune-configurator" + "dune" {>= "2.0"} "bos" {with-test} "rresult" {with-test} "alcotest" {with-test} diff --git a/config/.config.ml.swp b/config/.config.ml.swp new file mode 100644 index 0000000..ab78414 Binary files /dev/null and b/config/.config.ml.swp differ diff --git a/config/config.ml b/config/config.ml new file mode 100644 index 0000000..8ea3416 --- /dev/null +++ b/config/config.ml @@ -0,0 +1,48 @@ +module Config = Configurator.V1 + +let pre407 = {ocaml|external unsafe_set_uint16 : bytes -> int -> int -> unit = "%caml_string_set16u" [@@noalloc]|ocaml} +let standard = {ocaml|external unsafe_set_uint16 : bytes -> int -> int -> unit = "%caml_bytes_set16u" [@@noalloc]|ocaml} + +type t = + { major : int + ; minor : int + ; patch : int option + ; extra : string option } + +let v ?patch ?extra major minor = { major; minor; patch; extra; } + +let parse s = + try Scanf.sscanf s "%d.%d.%d+%s" (fun major minor patch extra -> v ~patch ~extra major minor) + with End_of_file | Scanf.Scan_failure _ -> + ( try Scanf.sscanf s "%d.%d+%s" (fun major minor extra -> v ~extra major minor) + with End_of_file | Scanf.Scan_failure _ -> + ( try Scanf.sscanf s "%d.%d.%d" (fun major minor patch -> v ~patch major minor) + with End_of_file | Scanf.Scan_failure _ -> + Scanf.sscanf s "%d.%d" (fun major minor -> v major minor) ) ) + +let ( >|= ) x f = match x with + | Some x -> Some (f x ) + | None -> None + +let ocaml_cp ~src ~dst = + let ic = open_in src in + let oc = open_out dst in + let bf = Bytes.create 0x1000 in + let rec go () = match input ic bf 0 (Bytes.length bf) with + | 0 -> () + | len -> output oc bf 0 len ; go () + | exception End_of_file -> () in + go () ; close_in ic ; close_out oc +;; + +let () = + Config.main ~name:"config-base64" @@ fun t -> + match Config.ocaml_config_var t "version" >|= parse with + | Some version -> + let dst = "unsafe.ml" in + + if (version.major, version.minor) >= (4, 7) + then ocaml_cp ~src:"unsafe_stable.ml" ~dst + else ocaml_cp ~src:"unsafe_pre407.ml" ~dst + | None -> Config.die "OCaml version is not available" + | exception exn -> Config.die "Got an exception: %s" (Printexc.to_string exn) diff --git a/config/dune b/config/dune new file mode 100644 index 0000000..852874e --- /dev/null +++ b/config/dune @@ -0,0 +1,3 @@ +(executable + (name config) + (libraries dune-configurator)) diff --git a/src/base64.ml b/src/base64.ml index 7ce84a3..6fcda60 100644 --- a/src/base64.ml +++ b/src/base64.ml @@ -32,8 +32,8 @@ let (//) x y = let unsafe_get_uint8 t off = Char.code (String.unsafe_get t off) let unsafe_set_uint8 t off v = Bytes.unsafe_set t off (Char.chr v) +let unsafe_set_uint16 = Unsafe.unsafe_set_uint16 -external unsafe_set_uint16 : bytes -> int -> int -> unit = "%caml_string_set16u" [@@noalloc] external unsafe_get_uint16 : string -> int -> int = "%caml_string_get16u" [@@noalloc] external swap16 : int -> int = "%bswap16" [@@noalloc] diff --git a/src/dune b/src/dune index bf4a9bb..04a9b33 100644 --- a/src/dune +++ b/src/dune @@ -1,11 +1,16 @@ (library (name base64) - (modules base64) + (modules unsafe base64) (public_name base64) (libraries bytes)) +(rule + (targets unsafe.ml) + (deps (:config ../config/config.exe) unsafe_pre407.ml unsafe_stable.ml) + (action (run %{config}))) + (library (name base64_rfc2045) (modules base64_rfc2045) (public_name base64.rfc2045) - (libraries bytes)) \ No newline at end of file + (libraries bytes)) diff --git a/src/unsafe_pre407.ml b/src/unsafe_pre407.ml new file mode 100644 index 0000000..86d3db9 --- /dev/null +++ b/src/unsafe_pre407.ml @@ -0,0 +1 @@ +external unsafe_set_uint16 : bytes -> int -> int -> unit = "%caml_string_set16u" [@@noalloc] diff --git a/src/unsafe_stable.ml b/src/unsafe_stable.ml new file mode 100644 index 0000000..01b2db4 --- /dev/null +++ b/src/unsafe_stable.ml @@ -0,0 +1 @@ +external unsafe_set_uint16 : bytes -> int -> int -> unit = "%caml_bytes_set16u" [@@noalloc]