diff --git a/src/cbor/containers_cbor.ml b/src/cbor/containers_cbor.ml index 62f0e003a..f70f4c6cb 100644 --- a/src/cbor/containers_cbor.ml +++ b/src/cbor/containers_cbor.ml @@ -45,7 +45,7 @@ let to_string_diagnostic (self : t) : string = Format.asprintf "@[%a@]" pp_diagnostic self (* we use funtions from Bytes *) -[@@@ifge 4.08] +[@@@if ge 4.08] exception Indefinite diff --git a/src/cbor/containers_cbor.mli b/src/cbor/containers_cbor.mli index fe3537f74..e0eb9e7e1 100644 --- a/src/cbor/containers_cbor.mli +++ b/src/cbor/containers_cbor.mli @@ -28,7 +28,7 @@ val pp_diagnostic : t CCFormat.printer val to_string_diagnostic : t -> string (* we use funtions from Bytes *) -[@@@ifge 4.08] +[@@@if ge 4.08] val encode : ?buf:Buffer.t -> t -> string val decode : string -> (t, string) result diff --git a/src/cbor/tests/t_appendix_a.ml b/src/cbor/tests/t_appendix_a.ml index aef954f55..2db3c22aa 100644 --- a/src/cbor/tests/t_appendix_a.ml +++ b/src/cbor/tests/t_appendix_a.ml @@ -1,6 +1,6 @@ let verbose = try Sys.getenv "VERBOSE" = "1" with _ -> false -[@@@ifge 4.08] +[@@@if ge 4.08] module J = Yojson.Safe module Fmt = CCFormat diff --git a/src/core/CCArray.ml b/src/core/CCArray.ml index 2c3386427..f850214fc 100644 --- a/src/core/CCArray.ml +++ b/src/core/CCArray.ml @@ -13,11 +13,11 @@ type 'a printer = Format.formatter -> 'a -> unit open CCShims_ -[@@@ifge 4.8] +[@@@if ge 4.8] include Array -[@@@elifge 4.6] +[@@@elif ge 4.6] include Array @@ -542,7 +542,7 @@ module Infix = struct let ( -- ) = ( -- ) let ( --^ ) = ( --^ ) - [@@@ifge 4.8] + [@@@if ge 4.8] type 'a t = 'a array diff --git a/src/core/CCArray.mli b/src/core/CCArray.mli index de08d819a..548847b97 100644 --- a/src/core/CCArray.mli +++ b/src/core/CCArray.mli @@ -14,13 +14,13 @@ type 'a printer = Format.formatter -> 'a -> unit (** {2 Arrays} *) -[@@@ifge 4.8] +[@@@if ge 4.8] include module type of Array (** @inline {{: https://caml.inria.fr/pub/docs/manual-ocaml/libref/Array.html} Documentation for the standard Array module}*) -[@@@elifge 4.6] +[@@@elif ge 4.6] include module type of Array (** @inline @@ -333,7 +333,7 @@ module Infix : sig (** [x --^ y] creates an array containing integers in the range [x .. y]. Right bound excluded. @since 0.17 *) - [@@@ifge 4.8] + [@@@if ge 4.8] include CCShims_syntax.LET with type 'a t := 'a array (** Let operators on OCaml >= 4.08.0, nothing otherwise diff --git a/src/core/CCArrayLabels.mli b/src/core/CCArrayLabels.mli index e9b2c649a..9df417067 100644 --- a/src/core/CCArrayLabels.mli +++ b/src/core/CCArrayLabels.mli @@ -14,13 +14,13 @@ type 'a printer = Format.formatter -> 'a -> unit (** {2 Arrays} *) -[@@@ifge 4.8] +[@@@if ge 4.8] include module type of ArrayLabels with module Floatarray = Array.Floatarray (** @inline {{: https://caml.inria.fr/pub/docs/manual-ocaml/libref/Array.html} Documentation for the standard Array module}*) -[@@@elifge 4.6] +[@@@elif ge 4.6] include module type of ArrayLabels with module Floatarray = Array.Floatarray (** @inline @@ -347,7 +347,7 @@ module Infix : sig (** [x --^ y] creates an array containing integers in the range [x .. y]. Right bound excluded. @since 0.17 *) - [@@@ifge 4.8] + [@@@if ge 4.8] include CCShims_syntax.LET with type 'a t := 'a array (** Let operators on OCaml >= 4.08.0, nothing otherwise diff --git a/src/core/CCAtomic.ml b/src/core/CCAtomic.ml index 3c60ba347..70777da99 100644 --- a/src/core/CCAtomic.ml +++ b/src/core/CCAtomic.ml @@ -1,4 +1,4 @@ -[@@@ifge 4.12] +[@@@if ge 4.12] include Atomic diff --git a/src/core/CCFormat.ml b/src/core/CCFormat.ml index 6c047cec9..7ec0ce382 100644 --- a/src/core/CCFormat.ml +++ b/src/core/CCFormat.ml @@ -301,7 +301,7 @@ let mark_close_style st : string = else "" -[@@@ifge 4.8] +[@@@if ge 4.8] type stag += Style of ANSI_codes.style list diff --git a/src/core/CCFormat.mli b/src/core/CCFormat.mli index a5bc11edd..98d76e3dd 100644 --- a/src/core/CCFormat.mli +++ b/src/core/CCFormat.mli @@ -334,7 +334,7 @@ module ANSI_codes : sig is a very shiny style. *) end -[@@@ifge 4.8] +[@@@if ge 4.8] val styling : ANSI_codes.style list -> 'a printer -> 'a printer (** [styling st p] is the same printer as [p], except it locally sets diff --git a/src/core/CCFun.ml b/src/core/CCFun.ml index 04459c2d6..8b3cae045 100644 --- a/src/core/CCFun.ml +++ b/src/core/CCFun.ml @@ -9,7 +9,7 @@ let opaque_identity x = x include Sys include CCShims_.Stdlib -[@@@ifge 4.8] +[@@@if ge 4.8] include Fun diff --git a/src/core/CCFun.mli b/src/core/CCFun.mli index 0308aa5e1..10f0d28d5 100644 --- a/src/core/CCFun.mli +++ b/src/core/CCFun.mli @@ -2,7 +2,7 @@ (** Basic operations on Functions *) -[@@@ifge 4.8] +[@@@if ge 4.8] include module type of Fun (** @inline *) diff --git a/src/core/CCInt.ml b/src/core/CCInt.ml index d391d0eb2..bbfafa253 100644 --- a/src/core/CCInt.ml +++ b/src/core/CCInt.ml @@ -1,12 +1,12 @@ (* This file is free software, part of containers. See file "license" for more details. *) -[@@@ifge 4.07] +[@@@if ge 4.07] [@@@else_] module Stdlib = Pervasives [@@@endif] -[@@@ifge 4.08] +[@@@if ge 4.08] include Int diff --git a/src/core/CCInt.mli b/src/core/CCInt.mli index 537a26c90..e1d199f27 100644 --- a/src/core/CCInt.mli +++ b/src/core/CCInt.mli @@ -2,7 +2,7 @@ (** Basic Int functions *) -[@@@ifge 4.08] +[@@@if ge 4.08] include module type of Int (** @inline diff --git a/src/core/CCList.ml b/src/core/CCList.ml index e54cb3fb1..59cbc4c78 100644 --- a/src/core/CCList.ml +++ b/src/core/CCList.ml @@ -48,7 +48,7 @@ let rec assq_opt x = function (* end of backport *) -[@@@ifge 4.8] +[@@@if ge 4.8] include List @@ -1470,7 +1470,7 @@ module Infix = struct let ( -- ) = ( -- ) let ( --^ ) = ( --^ ) - [@@@ifge 4.8] + [@@@if ge 4.8] let ( let+ ) = ( >|= ) let ( let* ) = ( >>= ) diff --git a/src/core/CCList.mli b/src/core/CCList.mli index 056a182d8..14cbe52c7 100644 --- a/src/core/CCList.mli +++ b/src/core/CCList.mli @@ -10,7 +10,7 @@ type 'a gen = unit -> 'a option type 'a printer = Format.formatter -> 'a -> unit type 'a random_gen = Random.State.t -> 'a -[@@@ifge 4.8] +[@@@if ge 4.8] include module type of List with type 'a t := 'a list (** @inline @@ -983,7 +983,7 @@ module Infix : sig (** [i --^ j] is the infix alias for [range']. Second bound [j] excluded. @since 0.17 *) - [@@@ifge 4.08] + [@@@if ge 4.08] include CCShims_syntax.LET with type 'a t := 'a t (** @inline *) diff --git a/src/core/CCOption.ml b/src/core/CCOption.ml index 0f9824056..635a933b0 100644 --- a/src/core/CCOption.ml +++ b/src/core/CCOption.ml @@ -177,7 +177,7 @@ module Infix = struct let ( <$> ) = map let ( <+> ) = ( <+> ) - [@@@ifge 4.8] + [@@@if ge 4.8] let ( let+ ) = ( >|= ) let ( let* ) = ( >>= ) diff --git a/src/core/CCOption.mli b/src/core/CCOption.mli index 1e5357766..df2d0c8c5 100644 --- a/src/core/CCOption.mli +++ b/src/core/CCOption.mli @@ -171,7 +171,7 @@ module Infix : sig val ( <+> ) : 'a t -> 'a t -> 'a t (** [o1 <+> o2] is [o1] if [o1] is [Some _], [o2] if [o1] is [None]. *) - [@@@ifge 4.08] + [@@@if ge 4.08] include CCShims_syntax.LET with type 'a t := 'a t (** Let operators on OCaml >= 4.08.0, nothing otherwise diff --git a/src/core/CCParse.ml b/src/core/CCParse.ml index fdb43481a..812995629 100644 --- a/src/core/CCParse.ml +++ b/src/core/CCParse.ml @@ -251,7 +251,7 @@ module Infix = struct let ( ||| ) = both let[@inline] ( ) p msg = set_error_message msg p - [@@@ifge 4.8] + [@@@if ge 4.8] let ( let+ ) = ( >|= ) let ( let* ) = ( >>= ) diff --git a/src/core/CCParse.mli b/src/core/CCParse.mli index fdbdc9e8a..93b1d24b3 100644 --- a/src/core/CCParse.mli +++ b/src/core/CCParse.mli @@ -667,7 +667,7 @@ module Infix : sig [a ||| b] parses [a], then [b], then returns the pair of their results. @since 3.6 *) - [@@@ifge 4.08] + [@@@if ge 4.08] include CCShims_syntax.LET with type 'a t := 'a t (** Let operators on OCaml >= 4.08.0, nothing otherwise diff --git a/src/core/CCRandom.ml b/src/core/CCRandom.ml index 5a6b5862b..14dd0c02a 100644 --- a/src/core/CCRandom.ml +++ b/src/core/CCRandom.ml @@ -178,7 +178,7 @@ let fix ?(sub1 = []) ?(sub2 = []) ?(subn = []) ~base fuel st = let pure x _st = x let ( <*> ) f g st = f st (g st) -[@@@ifge 4.8] +[@@@if ge 4.8] let ( let+ ) = ( >|= ) let ( let* ) = ( >>= ) diff --git a/src/core/CCRandom.mli b/src/core/CCRandom.mli index d2149495e..485911642 100644 --- a/src/core/CCRandom.mli +++ b/src/core/CCRandom.mli @@ -152,7 +152,7 @@ val fix : val pure : 'a -> 'a t val ( <*> ) : ('a -> 'b) t -> 'a t -> 'b t -[@@@ifge 4.08] +[@@@if ge 4.08] include CCShims_syntax.LET with type 'a t := 'a t (** Let operators on OCaml >= 4.08.0, nothing otherwise diff --git a/src/core/CCResult.ml b/src/core/CCResult.ml index 33e23b5ab..1591f67f8 100644 --- a/src/core/CCResult.ml +++ b/src/core/CCResult.ml @@ -269,7 +269,7 @@ module Infix = struct let ( >>= ) e f = flat_map f e let ( <*> ) = ( <*> ) - [@@@ifge 4.8] + [@@@if ge 4.8] let ( let+ ) = ( >|= ) let ( let* ) = ( >>= ) diff --git a/src/core/CCResult.mli b/src/core/CCResult.mli index e71eb6259..508a0f7b8 100644 --- a/src/core/CCResult.mli +++ b/src/core/CCResult.mli @@ -191,7 +191,7 @@ module Infix : sig [Ok (a b)]. Otherwise, it fails, and the error of [a] is chosen over the error of [b] if both fail. *) - [@@@ifge 4.08] + [@@@if ge 4.08] val ( let+ ) : ('a, 'e) t -> ('a -> 'b) -> ('b, 'e) t (** @since 2.8 *) diff --git a/src/core/CCShims_.ml b/src/core/CCShims_.ml index 7e4ca0f42..2958e6666 100644 --- a/src/core/CCShims_.ml +++ b/src/core/CCShims_.ml @@ -1,4 +1,4 @@ -[@@@ifge 4.07] +[@@@if ge 4.07] module Stdlib = Stdlib diff --git a/src/core/CCShims_syntax.mli b/src/core/CCShims_syntax.mli index d975819c7..847c1aeab 100644 --- a/src/core/CCShims_syntax.mli +++ b/src/core/CCShims_syntax.mli @@ -1,4 +1,4 @@ -[@@@ifge 4.8] +[@@@if ge 4.8] (** Let operators on OCaml >= 4.08.0, nothing otherwise @since 2.8 diff --git a/src/core/CCString.ml b/src/core/CCString.ml index c41b76566..8b74c6d3b 100644 --- a/src/core/CCString.ml +++ b/src/core/CCString.ml @@ -388,7 +388,7 @@ module Split = struct let right ~by s = try Some (right_exn ~by s) with Not_found -> None end -[@@@ifge 4.04] +[@@@if ge 4.04] [@@@else_] let split_on_char c s : _ list = diff --git a/src/core/CCUnit.ml b/src/core/CCUnit.ml index 1e7cf14ce..dd9e5ae91 100644 --- a/src/core/CCUnit.ml +++ b/src/core/CCUnit.ml @@ -1,4 +1,4 @@ -[@@@ifge 4.08] +[@@@if ge 4.08] include Unit diff --git a/src/core/CCVector.ml b/src/core/CCVector.ml index c0996ffb8..2e602cfd1 100644 --- a/src/core/CCVector.ml +++ b/src/core/CCVector.ml @@ -666,7 +666,7 @@ let pp ?(pp_start = fun _ () -> ()) ?(pp_stop = fun _ () -> ()) v; pp_stop fmt () -[@@@ifge 4.8] +[@@@if ge 4.8] let ( let+ ) = ( >|= ) let ( let* ) = ( >>= ) diff --git a/src/core/CCVector.mli b/src/core/CCVector.mli index 0d639bff1..82a7808d3 100644 --- a/src/core/CCVector.mli +++ b/src/core/CCVector.mli @@ -397,7 +397,7 @@ val pp : By defaults [pp_start] and [pp_stop] does nothing and [pp_sep] defaults to (fun out -> Format.fprintf out ",@ "). *) -[@@@ifge 4.08] +[@@@if ge 4.08] val ( let+ ) : ('a, 'e) t -> ('a -> 'b) -> ('b, 'e) t (** @since 2.8 *) diff --git a/src/core/cpp/cpp.ml b/src/core/cpp/cpp.ml index 8ce5e5297..025dc59d7 100644 --- a/src/core/cpp/cpp.ml +++ b/src/core/cpp/cpp.ml @@ -1,13 +1,16 @@ module C = Configurator.V1 -type op = Le | Ge +type conf = { os_type: string; major: int; minor: int } +type comp = Le | Ge +type condition = Version of comp * int * int | Os_type of string type line = - | If of op * int * int - | Elseif of op * int * int + | If of condition + | Elseif of condition | Else | Endif | Raw of string + | Eol | Eof let prefix ~pre s = @@ -26,81 +29,132 @@ let prefix ~pre s = check 0 ) -let eval ~major ~minor op i j = - match op with - | Le -> (major, minor) <= (i, j) - | Ge -> (major, minor) >= (i, j) +let get_tag_from_opt s pos = + let rec get_start pos = + let p = String.index_from s pos '[' in + if p > String.length s - 5 then + raise_notrace Not_found + else if s.[p + 1] = '@' && s.[p + 2] = '@' && s.[p + 3] = '@' then + p + else + get_start (p + 1) + in + try + let start = get_start pos in + Some (get_start pos, String.index_from s (start + 4) ']') + with Not_found -> None + +let split_trim s c = + try + let p = String.index s c in + ( String.trim (String.sub s 0 p), + String.trim (String.sub s (p + 1) (String.length s - p - 1)) ) + with Not_found -> s, "" -let preproc_lines ~file ~major ~minor (ic : in_channel) : unit = +let eval ~conf = function + | Os_type ty -> conf.os_type = ty + | Version (op, i, j) -> + (match op with + | Le -> (conf.major, conf.minor) <= (i, j) + | Ge -> (conf.major, conf.minor) >= (i, j)) + +let preproc_lines ~file ~conf (ic : in_channel) : unit = let pos = ref 0 in let fail msg = failwith (Printf.sprintf "at line %d in '%s': %s" !pos file msg) in let pp_pos () = Printf.printf "#%d %S\n" !pos file in - let parse_line () : line = - match input_line ic with - | exception End_of_file -> Eof - | line -> - let line' = String.trim line in - incr pos; - if line' <> "" && line'.[0] = '[' then - if prefix line' ~pre:"[@@@ifle" then - Scanf.sscanf line' "[@@@ifle %d.%d]" (fun x y -> If (Le, x, y)) - else if prefix line' ~pre:"[@@@ifge" then - Scanf.sscanf line' "[@@@ifge %d.%d]" (fun x y -> If (Ge, x, y)) - else if prefix line' ~pre:"[@@@elifle" then - Scanf.sscanf line' "[@@@elifle %d.%d]" (fun x y -> Elseif (Le, x, y)) - else if prefix line' ~pre:"[@@@elifge" then - Scanf.sscanf line' "[@@@elifge %d.%d]" (fun x y -> Elseif (Ge, x, y)) - else if line' = "[@@@else_]" then - Else - else if line' = "[@@@endif]" then - Endif - else - Raw line + let parse_condition condition = + flush_all (); + match split_trim condition ' ' with + | "le", value -> Scanf.sscanf value "%d.%d" (fun x y -> Version (Le, x, y)) + | "ge", value -> Scanf.sscanf value "%d.%d" (fun x y -> Version (Ge, x, y)) + | "os", value -> Os_type (String.lowercase_ascii value) + | _ -> failwith (Printf.sprintf "Syntax error condition: %s" condition) + in + + let rec parse_from line pos = + match get_tag_from_opt line pos with + | None -> [ Raw (String.sub line pos (String.length line - pos)); Eol ] + | Some (s, e) -> + let tag = String.sub line (s + 4) (e - s - 4) |> String.trim in + flush_all (); + let op, rest = split_trim tag ' ' in + let next_token = + match op with + | "if" -> If (parse_condition rest) + | "elif" -> Elseif (parse_condition rest) + | "else_" -> Else + | "endif" -> Endif + | _ -> Raw (String.sub line s (e - s + 1)) + in + if s = 0 && s = String.length line then + [ next_token ] else - Raw line + next_token :: parse_from line (e + 1) + in + + let parse_line () : line list = + match input_line ic with + | exception End_of_file -> [ Eof ] + | line -> parse_from line 0 + in + + let get_next = + let q = Queue.create () in + fun () -> + try Queue.pop q + with Queue.Empty -> + List.iter (fun x -> Queue.push x q) (parse_line ()); + Queue.pop q in (* entry point *) let rec top () = - match parse_line () with + match get_next () with | Eof -> () - | If (op, i, j) -> - if eval ~major ~minor op i j then ( + | If condition -> + if eval ~conf condition then ( pp_pos (); cat_block () ) else skip_block ~elseok:true () | Raw s -> - print_endline s; + print_string s; + top () + | Eol -> + print_newline (); top () | Elseif _ | Else | Endif -> fail "unexpected elseif|else|endif" (* current block is the valid one *) and cat_block () = - match parse_line () with + match get_next () with | Eof -> fail "unexpected EOF" | If _ -> fail "nested if not supported" | Raw s -> - print_endline s; + print_string s; + cat_block () + | Eol -> + print_newline (); cat_block () | Endif -> + flush_all (); pp_pos (); top () | Elseif _ | Else -> skip_block ~elseok:false () (* skip current block. @param elseok if true, we should evaluate "elseif" *) and skip_block ~elseok () = - match parse_line () with + match get_next () with | Eof -> fail "unexpected EOF" | If _ -> fail "nested if not supported" - | Raw _ -> skip_block ~elseok () + | Raw _ | Eol -> skip_block ~elseok () | Endif -> pp_pos (); top () - | Elseif (op, i, j) -> - if elseok && eval ~major ~minor op i j then ( + | Elseif condition -> + if elseok && eval ~conf condition then ( pp_pos (); cat_block () ) else @@ -120,9 +174,10 @@ let () = let c = C.create "main" in let version = C.ocaml_config_var_exn c "version" in let major, minor = Scanf.sscanf version "%u.%u" (fun maj min -> maj, min) in + let os_type = String.lowercase_ascii (C.ocaml_config_var_exn c "os_type") in let ic = open_in file in - preproc_lines ~file ~major ~minor ic; + preproc_lines ~file ~conf:{ os_type; major; minor } ic; Printf.printf "(* file preprocessed in %.3fs *)\n" (Unix.gettimeofday () -. t0); () diff --git a/src/monomorphic/CCMonomorphic.ml b/src/monomorphic/CCMonomorphic.ml index cb5873bec..e25de0f16 100644 --- a/src/monomorphic/CCMonomorphic.ml +++ b/src/monomorphic/CCMonomorphic.ml @@ -1,6 +1,6 @@ (* This file is free software, part of containers. See file "license" for more details. *) -[@@@ifge 4.07] +[@@@if ge 4.07] [@@@else_] module Stdlib = Pervasives diff --git a/src/testlib/containers_testlib.ml b/src/testlib/containers_testlib.ml index 63a7264fd..9898ae831 100644 --- a/src/testlib/containers_testlib.ml +++ b/src/testlib/containers_testlib.ml @@ -31,7 +31,7 @@ module Test = struct in Printf.sprintf "(test :file '%s'%s :n %d)" self.__FILE__ what self.n - [@@@ifge 4.08] + [@@@if ge 4.08] let get_state (r : _ QCheck.TestResult.t) : _ QCheck.TestResult.state = QCheck.TestResult.get_state r diff --git a/src/threads/CCPool.ml b/src/threads/CCPool.ml index e438bd79e..112c6fb92 100644 --- a/src/threads/CCPool.ml +++ b/src/threads/CCPool.ml @@ -519,7 +519,7 @@ module Make (P : PARAM) = struct let ( >|= ) a f = map f a let ( <*> ) = app - [@@@ifge 4.8] + [@@@if ge 4.8] let ( let+ ) = ( >|= ) let ( let* ) = ( >>= ) diff --git a/src/threads/CCPool.mli b/src/threads/CCPool.mli index 248440110..95e0b06e5 100644 --- a/src/threads/CCPool.mli +++ b/src/threads/CCPool.mli @@ -147,7 +147,7 @@ module Make (P : PARAM) : sig val ( >|= ) : 'a t -> ('a -> 'b) -> 'b t val ( <*> ) : ('a -> 'b) t -> 'a t -> 'b t - [@@@ifge 4.08] + [@@@if ge 4.08] include CCShims_syntax.LET with type 'a t := 'a t (** Let operators on OCaml >= 4.08.0, nothing otherwise diff --git a/tests/core/t_cbor.ml b/tests/core/t_cbor.ml index c33bd494c..21f966953 100644 --- a/tests/core/t_cbor.ml +++ b/tests/core/t_cbor.ml @@ -1,7 +1,7 @@ include (val Containers_testlib.make ~__FILE__ ()) module Cbor = Containers_cbor -[@@@ifge 4.08] +[@@@if ge 4.08] let gen_c : Cbor.t Q.Gen.t = let open Q.Gen in diff --git a/tests/core/t_format.ml b/tests/core/t_format.ml index c343a9c01..6e644c8b5 100644 --- a/tests/core/t_format.ml +++ b/tests/core/t_format.ml @@ -45,7 +45,7 @@ t @@ fun () -> assert_equal ~printer:CCFun.id "coucou\n" (Buffer.contents buf2); true;; -[@@@ifge 4.8] +[@@@if ge 4.8] t @@ fun () -> set_color_default true;