Simplify String_with_vars

Make it expand only to Value.t since the string only version wasn't really used.
Variable expansions are now Value.t list. Which also gives the flexibility for a
value to expand to a collection of more than 1 value.

Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
This commit is contained in:
Rudi Grinberg 2018-06-05 23:42:32 +07:00
parent bab65e989d
commit 589943df60
13 changed files with 237 additions and 395 deletions

View File

@ -270,13 +270,12 @@ module Unresolved = struct
| Search s -> Ok (f s)) | Search s -> Ok (f s))
end end
let var_expansion_to_prog_and_args dir exp : Unresolved.Program.t * string list = let prog_and_args_of_values p ~dir =
let module P = Unresolved.Program in match p with
match (exp : Var_expansion.t) with | [] -> (Unresolved.Program.Search "", [])
| Paths (x::xs) -> (This x, Var_expansion.to_strings dir (Paths xs)) | Value.Path p :: xs -> (This p, Value.to_strings ~dir xs)
| Strings (s::xs) -> ( P.of_string ~dir s | String s :: xs ->
, Var_expansion.to_strings dir (Strings xs)) (Unresolved.Program.of_string ~dir s, Value.to_strings ~dir xs)
| Paths [] | Strings [] -> (Search "", [])
module SW = String_with_vars module SW = String_with_vars
@ -315,43 +314,33 @@ module Unexpanded = struct
include Past include Past
module E = struct module E = struct
let expand ~generic ~special ~map ~dir ~allow_multivalue ~f = function let expand ~dir ~mode ~f ~l ~r =
| Left x -> map x Either.map ~l
| Right template -> ~r:(fun s -> r (String_with_vars.expand s ~dir ~f ~mode) ~dir)
match
Var_expansion.Expand.expand dir template ~f ~allow_multivalue
with
| Expansion e -> special dir e
| String s -> generic dir s
[@@inlined always]
let string ~dir ~f x = let string =
expand ~dir ~f x expand ~mode:Single
~allow_multivalue:false ~l:(fun x -> x)
~generic:(fun _dir x -> x) ~r:Value.to_string
~special:Var_expansion.to_string
~map:(fun x -> x)
let strings ~dir ~f x = let strings =
expand ~dir ~f x expand ~mode:Many
~allow_multivalue:true ~l:(fun x -> [x])
~generic:(fun _dir x -> [x]) ~r:Value.to_strings
~special:Var_expansion.to_strings
~map:(fun x -> [x])
let path ~dir ~f x = let path e =
expand ~dir ~f x let error_loc =
~allow_multivalue:false match e with
~generic:Var_expansion.path_of_string | Left _ -> None
~special:Var_expansion.to_path | Right r -> Some (String_with_vars.loc r) in
~map:(fun x -> x) expand ~mode:Single
~l:(fun x -> x)
~r:Value.(to_path ?error_loc) e
let prog_and_args ~dir ~f x = let prog_and_args =
expand ~dir ~f x expand ~mode:Many
~allow_multivalue:true ~l:(fun x -> (x, []))
~generic:(fun _dir s -> (Program.of_string ~dir s, [])) ~r:prog_and_args_of_values
~special:var_expansion_to_prog_and_args
~map:(fun x -> (x, []))
end end
let rec expand t ~dir ~map_exe ~f : Unresolved.t = let rec expand t ~dir ~map_exe ~f : Unresolved.t =
@ -414,37 +403,17 @@ module Unexpanded = struct
end end
module E = struct module E = struct
let expand ~generic ~special ~dir ~allow_multivalue ~f template = let expand ~dir ~mode ~f ~map x =
match match String_with_vars.partial_expand ~mode ~dir ~f x with
Var_expansion.Expand.partial_expand dir template ~allow_multivalue ~f | Expanded e -> Left (map e ~dir)
with
| Expansion e -> Left (special dir e)
| String s -> Left (generic dir s)
| Unexpanded x -> Right x | Unexpanded x -> Right x
let string ~dir ~f x = let string = expand ~mode:Single ~map:(Value.to_string)
expand ~dir ~f x let strings = expand ~mode:Many ~map:(Value.to_strings)
~allow_multivalue:false let path x =
~generic:(fun _dir x -> x) let error_loc = String_with_vars.loc x in
~special:Var_expansion.to_string expand ~mode:Single ~map:(Value.to_path ~error_loc) x
let prog_and_args = expand ~mode:Many ~map:(prog_and_args_of_values)
let strings ~dir ~f x =
expand ~dir ~f x
~allow_multivalue:true
~generic:(fun _dir x -> [x])
~special:Var_expansion.to_strings
let path ~dir ~f x =
expand ~dir ~f x
~allow_multivalue:false
~generic:Var_expansion.path_of_string
~special:Var_expansion.to_path
let prog_and_args ~dir ~f x =
expand ~dir ~f x
~allow_multivalue:true
~generic:(fun dir s -> (Unresolved.Program.of_string ~dir s, []))
~special:var_expansion_to_prog_and_args
end end
let rec partial_expand t ~dir ~map_exe ~f : Partial.t = let rec partial_expand t ~dir ~map_exe ~f : Partial.t =

View File

@ -82,7 +82,7 @@ module Unexpanded : sig
: t : t
-> dir:Path.t -> dir:Path.t
-> map_exe:(Path.t -> Path.t) -> map_exe:(Path.t -> Path.t)
-> f:(Loc.t -> String.t -> Var_expansion.t option) -> f:(Loc.t -> String.t -> Value.t list option)
-> Unresolved.t -> Unresolved.t
end end
@ -90,7 +90,7 @@ module Unexpanded : sig
: t : t
-> dir:Path.t -> dir:Path.t
-> map_exe:(Path.t -> Path.t) -> map_exe:(Path.t -> Path.t)
-> f:(Loc.t -> string -> Var_expansion.t option) -> f:(Loc.t -> string -> Value.t list option)
-> Partial.t -> Partial.t
end end

View File

@ -187,7 +187,7 @@ include Sub_system.Register_end_point(
in in
let extra_vars = let extra_vars =
String.Map.singleton "library-name" (Var_expansion.Strings [lib.name]) String.Map.singleton "library-name" ([Value.String lib.name])
in in
let runner_libs = let runner_libs =
@ -209,7 +209,7 @@ include Sub_system.Register_end_point(
let target = Path.relative inline_test_dir main_module_filename in let target = Path.relative inline_test_dir main_module_filename in
let source_modules = Module.Name.Map.values source_modules in let source_modules = Module.Name.Map.values source_modules in
let files ml_kind = let files ml_kind =
Var_expansion.Paths ( Value.paths (
List.filter_map source_modules ~f:(fun m -> List.filter_map source_modules ~f:(fun m ->
Module.file m ~dir ml_kind)) Module.file m ~dir ml_kind))
in in

View File

@ -1,3 +1,8 @@
type ('a, 'b) t = type ('a, 'b) t =
| Left of 'a | Left of 'a
| Right of 'b | Right of 'b
let map t ~l ~r =
match t with
| Left x -> l x
| Right x -> r x

View File

@ -3,3 +3,5 @@
type ('a, 'b) t = type ('a, 'b) t =
| Left of 'a | Left of 'a
| Right of 'b | Right of 'b
val map : ('a, 'b) t -> l:('a -> 'c) -> r:('b -> 'c) -> 'c

View File

@ -104,137 +104,103 @@ let string_of_var syntax v =
| Parens -> sprintf "$(%s)" v | Parens -> sprintf "$(%s)" v
| Braces -> sprintf "${%s}" v | Braces -> sprintf "${%s}" v
module type EXPANSION = sig
type t
val length : t -> int
val is_multivalued : t -> bool
type context
val to_string : context -> t -> string
end
let concat_rev = function let concat_rev = function
| [] -> "" | [] -> ""
| [s] -> s | [s] -> s
| l -> String.concat (List.rev l) ~sep:"" | l -> String.concat (List.rev l) ~sep:""
module Expand = struct module Mode = struct
module Full = struct type 'a t =
type nonrec 'a t = | Single : Value.t t
| Expansion of 'a | Many : Value.t list t
| String of string
end let string
module Partial = struct : type a. a t -> string -> a
type nonrec 'a t = = fun t s ->
| Expansion of 'a match t with
| String of string | Single -> Value.String s
| Unexpanded of t | Many -> [Value.String s]
end
let value
: type a. a t -> Value.t list -> a option
= fun t s ->
match t, s with
| Many, s -> Some s
| Single, [s] -> Some s
| Single, _ -> None
end end
module type Expand_intf = sig module Partial = struct
type context type nonrec 'a t =
type expansion | Expanded of 'a
| Unexpanded of t
val expand
: context
-> t
-> allow_multivalue:bool
-> f:(Loc.t -> string -> expansion option)
-> expansion Expand.Full.t
val partial_expand
: context
-> t
-> allow_multivalue:bool
-> f:(Loc.t -> string -> expansion option)
-> expansion Expand.Partial.t
end end
module Expand_to(V: EXPANSION) = struct let invalid_multivalue syntax ~var t x =
type expansion = V.t Loc.fail t.loc "Variable %s expands to %d values, \
type context = V.context however a single value is expected here. \
Please quote this atom."
(string_of_var syntax var) (List.length x)
let check_valid_multivalue syntax ~var t x = let expand t ~mode ~dir ~f =
if not t.quoted && V.is_multivalued x then match t.items with
Loc.fail t.loc "Variable %s expands to %d values, \ | [Var (syntax, v)] when not t.quoted ->
however a single value is expected here. \ (* Unquoted single var *)
Please quote this atom." begin match f t.loc v with
(string_of_var syntax var) (V.length x) | Some e ->
begin match Mode.value mode e with
| None -> invalid_multivalue syntax ~var:v t e
| Some s -> s
end
| None -> Mode.string mode (string_of_var syntax v)
end
| _ ->
Mode.string mode (
List.concat_map t.items ~f:(function
| Text s -> [s]
| Var (syntax, v) ->
begin match f t.loc v, t.quoted with
| Some ([] | _::_::_ as e) , false ->
invalid_multivalue syntax ~var:v t e
| Some ([_] as t), false
| Some t, true -> Value.to_strings ~dir t
| None, _ -> [string_of_var syntax v]
end)
|> String.concat ~sep:"")
let expand ctx t ~allow_multivalue ~f = let partial_expand t ~mode ~dir ~f =
match t.items with let commit_text acc_text acc =
| [Var (syntax, v)] when not t.quoted -> let s = concat_rev acc_text in
(* Unquoted single var *) if s = "" then acc else Text s :: acc
(match f t.loc v with in
| Some e -> let rec loop acc_text acc items =
if not allow_multivalue then match items with
check_valid_multivalue syntax ~var:v t e; | [] ->
Expand.Full.Expansion e begin match acc with
| None -> Expand.Full.String (string_of_var syntax v)) | [] -> Partial.Expanded (Mode.string mode (concat_rev acc_text))
| _ -> | _ -> Unexpanded { t with items = List.rev (commit_text acc_text acc) }
Expand.Full.String ( end
List.map t.items ~f:(function | Text s :: items -> loop (s :: acc_text) acc items
| Text s -> s | Var (syntax, v) as it :: items ->
| Var (syntax, v) -> begin match f t.loc v with
match f t.loc v with | Some (([] | _::_) as e) when not t.quoted ->
| Some x -> invalid_multivalue syntax ~var:v t e
check_valid_multivalue syntax ~var:v t x; | Some t ->
V.to_string ctx x loop (List.rev_append (Value.to_strings ~dir t) acc_text) acc items
| None -> string_of_var syntax v) | None -> loop [] (it :: commit_text acc_text acc) items
|> String.concat ~sep:"") end
in
let partial_expand ctx t ~allow_multivalue ~f = match t.items with
let commit_text acc_text acc = | [Var (syntax, v)] when not t.quoted ->
let s = concat_rev acc_text in (* Unquoted single var *)
if s = "" then acc else Text s :: acc begin match f t.loc v with
in | Some e -> Partial.Expanded (
let rec loop acc_text acc items = match Mode.value mode e with
match items with | None -> invalid_multivalue syntax ~var:v t e
| [] -> begin | Some s -> s)
match acc with | None -> Unexpanded t
| [] -> Expand.Partial.String (concat_rev acc_text) end
| _ -> Unexpanded { t with items = List.rev (commit_text acc_text acc) } | _ -> loop [] [] t.items
end
| Text s :: items -> loop (s :: acc_text) acc items
| Var (syntax, v) as it :: items ->
match f t.loc v with
| None -> loop [] (it :: commit_text acc_text acc) items
| Some x ->
check_valid_multivalue syntax ~var:v t x;
loop (V.to_string ctx x :: acc_text) acc items
in
match t.items with
| [Var (syntax, v)] when not t.quoted ->
(* Unquoted single var *)
(match f t.loc v with
| Some e ->
if not allow_multivalue then
check_valid_multivalue syntax ~var:v t e;
Expand.Partial.Expansion e
| None -> Expand.Partial.Unexpanded t)
| _ -> loop [] [] t.items
end
module String_expansion = struct
type t = string
let length _ = 1
let is_multivalued _ = false
type context = unit
let to_string () (s: string) = s
end
module S = Expand_to(String_expansion)
let expand t ~f =
match S.expand () t ~allow_multivalue:true ~f with
| Expand.Full.String s
| Expansion s -> s
let partial_expand t ~f =
match S.partial_expand () t ~allow_multivalue:true ~f with
| Expand.Partial.Expansion s -> Left s
| String s -> Left s
| Unexpanded s -> Right s
let to_string t = let to_string t =
match t.items with match t.items with

View File

@ -45,81 +45,28 @@ val iter : t -> f:(Loc.t -> string -> unit) -> unit
val is_var : t -> name:string -> bool val is_var : t -> name:string -> bool
module type EXPANSION = sig module Mode : sig
type t type 'a t =
(** The value to which variables are expanded. *) | Single : Value.t t
| Many : Value.t list t
val length : t -> int
val is_multivalued : t -> bool
(** Report whether the value is a multivalued one (such as for
example ${@}) which much be in quoted strings to be concatenated
to text or other variables. *)
type context
(** Context needed to expand values of type [t] to strings. *)
val to_string : context -> t -> string
(** When needing to expand with text portions or if the
string-with-vars is quoted, the value is converted to a string
using [to_string]. *)
end end
module Expand : sig module Partial : sig
module Full : sig type nonrec 'a t =
type nonrec 'a t = | Expanded of 'a
| Expansion of 'a | Unexpanded of t
| String of string
end
module Partial : sig
type nonrec 'a t =
| Expansion of 'a
| String of string
| Unexpanded of t
end
end end
module type Expand_intf = sig
type context
type expansion
val expand
: context
-> t
-> allow_multivalue:bool
-> f:(Loc.t -> string -> expansion option)
-> expansion Expand.Full.t
(** [expand t ~f] return [t] where all variables have been expanded
using [f]. If [f loc var] return [Some x], the variable [var] is
replaced by [x]; otherwise, the variable is inserted using the syntax
it was originally defined with: ${..} or $(..) *)
val partial_expand
: context
-> t
-> allow_multivalue:bool
-> f:(Loc.t -> string -> expansion option)
-> expansion Expand.Partial.t
(** [partial_expand t ~f] is like [expand_generic] where all
variables that could be expanded (i.e., those for which [f]
returns [Some _]) are. If all the variables of [t] were
expanded, a string is returned. If [f] returns [None] on at
least a variable of [t], it returns a string-with-vars. *)
end
module Expand_to(V : EXPANSION) : Expand_intf
with type expansion = V.t and type context = V.context
val expand val expand
: t : t
-> f:(Loc.t -> string -> string option) -> mode:'a Mode.t
-> string -> dir:Path.t
(** Specialized version [Expand_to.expand] that returns a string (so -> f:(Loc.t -> string -> Value.t list option)
variables are assumed to expand to a single value). *) -> 'a
val partial_expand val partial_expand
: t : t
-> f:(Loc.t -> string -> string option) -> mode:'a Mode.t
-> (string, t) Either.t -> dir:Path.t
(** [partial_expand] is a specialized version of -> f:(Loc.t -> string -> Value.t list option)
[Expand_to.partial_expand] that returns a string. *) -> 'a Partial.t

View File

@ -45,7 +45,7 @@ type t =
; artifacts : Artifacts.t ; artifacts : Artifacts.t
; stanzas_to_consider_for_install : Installable.t list ; stanzas_to_consider_for_install : Installable.t list
; cxx_flags : string list ; cxx_flags : string list
; vars : Var_expansion.t String.Map.t ; vars : Value.t list String.Map.t
; chdir : (Action.t, Action.t) Build.t ; chdir : (Action.t, Action.t) Build.t
; host : t option ; host : t option
; libs_by_package : (Package.t * Lib.Set.t) Package.Name.Map.t ; libs_by_package : (Package.t * Lib.Set.t) Package.Name.Map.t
@ -87,17 +87,24 @@ let find_scope_by_name t name = Scope.DB.find_by_name t.scopes name
let expand_var_no_root t var = String.Map.find t.vars var let expand_var_no_root t var = String.Map.find t.vars var
let (expand_vars, expand_vars_path) = let (expand_vars, expand_vars_path) =
let make expander t ~scope ~dir ?(extra_vars=String.Map.empty) s = let expand t ~scope ~dir ?(extra_vars=String.Map.empty) s =
expander ~dir s ~f:(fun _loc -> function String_with_vars.expand ~mode:Single ~dir s ~f:(fun _loc -> function
| "ROOT" -> Some (Var_expansion.Paths [t.context.build_dir]) | "ROOT" -> Some [Value.Path t.context.build_dir]
| "SCOPE_ROOT" -> Some (Paths [Scope.root scope]) | "SCOPE_ROOT" -> Some [Value.Path (Scope.root scope)]
| var -> | var ->
(match expand_var_no_root t var with (match expand_var_no_root t var with
| Some _ as x -> x | Some _ as x -> x
| None -> String.Map.find extra_vars var)) in | None -> String.Map.find extra_vars var))
( make Var_expansion.Single.string in
, make Var_expansion.Single.path let expand_vars t ~scope ~dir ?extra_vars s =
) expand t ~scope ~dir ?extra_vars s
|> Value.to_string ~dir
in
let expand_vars_path t ~scope ~dir ?extra_vars s =
expand t ~scope ~dir ?extra_vars s
|> Value.to_path ~error_loc:(String_with_vars.loc s) ~dir
in
(expand_vars, expand_vars_path)
let expand_and_eval_set t ~scope ~dir ?extra_vars set ~standard = let expand_and_eval_set t ~scope ~dir ?extra_vars set ~standard =
let open Build.O in let open Build.O in
@ -272,18 +279,17 @@ let create
| None -> Path.relative context.ocaml_bin "ocamlopt" | None -> Path.relative context.ocaml_bin "ocamlopt"
| Some p -> p | Some p -> p
in in
let open Var_expansion in let string s = [Value.String s] in
let path p = [Value.Path p] in
let make = let make =
match Bin.make with match Bin.make with
| None -> Strings ["make"] | None -> string "make"
| Some p -> Paths [p] | Some p -> path p
in in
let cflags = context.ocamlc_cflags in let cflags = context.ocamlc_cflags in
let strings l = Strings l in let strings = Value.strings in
let string s = Strings [s] in
let path p = Paths [p] in
let vars = let vars =
[ "-verbose" , Strings ([] (*"-verbose";*)) [ "-verbose" , []
; "CPP" , strings (context.c_compiler :: cflags @ ["-E"]) ; "CPP" , strings (context.c_compiler :: cflags @ ["-E"])
; "PA_CPP" , strings (context.c_compiler :: cflags ; "PA_CPP" , strings (context.c_compiler :: cflags
@ ["-undef"; "-traditional"; @ ["-undef"; "-traditional";
@ -586,7 +592,7 @@ module Action = struct
; (* Static deps from ${...} variables. For instance ${exe:...} *) ; (* Static deps from ${...} variables. For instance ${exe:...} *)
mutable sdeps : Path.Set.t mutable sdeps : Path.Set.t
; (* Dynamic deps from ${...} variables. For instance ${read:...} *) ; (* Dynamic deps from ${...} variables. For instance ${read:...} *)
mutable ddeps : (unit, Var_expansion.t) Build.t String.Map.t mutable ddeps : (unit, Value.t list) Build.t String.Map.t
} }
let add_lib_dep acc lib kind = let add_lib_dep acc lib kind =
@ -600,8 +606,8 @@ module Action = struct
acc.ddeps <- String.Map.add acc.ddeps key dep; acc.ddeps <- String.Map.add acc.ddeps key dep;
None None
let path_exp path = Var_expansion.Paths [path] let path_exp path = [Value.Path path]
let str_exp path = Var_expansion.Strings [path] let str_exp str = [Value.String str]
let map_exe sctx = let map_exe sctx =
match sctx.host with match sctx.host with
@ -628,7 +634,6 @@ module Action = struct
; ddeps = String.Map.empty ; ddeps = String.Map.empty
} }
in in
let open Var_expansion in
let expand loc key var = function let expand loc key var = function
| Some ("exe" , s) -> Some (path_exp (map_exe (Path.relative dir s))) | Some ("exe" , s) -> Some (path_exp (map_exe (Path.relative dir s)))
| Some ("path" , s) -> Some (path_exp (Path.relative dir s) ) | Some ("path" , s) -> Some (path_exp (Path.relative dir s) )
@ -681,8 +686,8 @@ module Action = struct
| Some p -> | Some p ->
let x = let x =
Pkg_version.read sctx p >>^ function Pkg_version.read sctx p >>^ function
| None -> Strings [""] | None -> [Value.String ""]
| Some s -> Strings [s] | Some s -> [String s]
in in
add_ddep acc ~key x add_ddep acc ~key x
| None -> | None ->
@ -694,7 +699,7 @@ module Action = struct
let path = Path.relative dir s in let path = Path.relative dir s in
let data = let data =
Build.contents path Build.contents path
>>^ fun s -> Strings [s] >>^ fun s -> [Value.String s]
in in
add_ddep acc ~key data add_ddep acc ~key data
end end
@ -702,7 +707,7 @@ module Action = struct
let path = Path.relative dir s in let path = Path.relative dir s in
let data = let data =
Build.lines_of path Build.lines_of path
>>^ fun l -> Strings l >>^ Value.strings
in in
add_ddep acc ~key data add_ddep acc ~key data
end end
@ -710,7 +715,7 @@ module Action = struct
let path = Path.relative dir s in let path = Path.relative dir s in
let data = let data =
Build.strings path Build.strings path
>>^ fun l -> Strings l >>^ Value.strings
in in
add_ddep acc ~key data add_ddep acc ~key data
end end
@ -732,7 +737,7 @@ module Action = struct
match targets_written_by_user with match targets_written_by_user with
| Infer -> Loc.fail loc "You cannot use ${@} with inferred rules." | Infer -> Loc.fail loc "You cannot use ${@} with inferred rules."
| Alias -> Loc.fail loc "You cannot use ${@} in aliases." | Alias -> Loc.fail loc "You cannot use ${@} in aliases."
| Static l -> Some (Paths l) | Static l -> Some (Value.paths l)
end end
| _ -> | _ ->
match String.lsplit2 var ~on:':' with match String.lsplit2 var ~on:':' with
@ -740,16 +745,15 @@ module Action = struct
Some (path_exp (Path.relative dir s)) Some (path_exp (Path.relative dir s))
| x -> | x ->
let exp = expand loc key var x in let exp = expand loc key var x in
(match exp with Option.iter exp ~f:(fun vs ->
| Some (Paths ps) -> acc.sdeps <-
acc.sdeps <- Path.Set.union (Path.Set.of_list ps) acc.sdeps Path.Set.union (Path.Set.of_list (Value.paths_only vs)) acc.sdeps;
| _ -> ()); );
exp) exp)
in in
(t, acc) (t, acc)
let expand_step2 ~dir ~dynamic_expansions ~deps_written_by_user ~map_exe t = let expand_step2 ~dir ~dynamic_expansions ~deps_written_by_user ~map_exe t =
let open Var_expansion in
U.Partial.expand t ~dir ~map_exe ~f:(fun loc key -> U.Partial.expand t ~dir ~map_exe ~f:(fun loc key ->
match String.Map.find dynamic_expansions key with match String.Map.find dynamic_expansions key with
| Some _ as opt -> opt | Some _ as opt -> opt
@ -762,10 +766,10 @@ module Action = struct
| [] -> | [] ->
Loc.warn loc "Variable '<' used with no explicit \ Loc.warn loc "Variable '<' used with no explicit \
dependencies@."; dependencies@.";
Strings [""] [Value.String ""]
| dep :: _ -> | dep :: _ ->
Paths [dep]) [Path dep])
| "^" -> Some (Paths deps_written_by_user) | "^" -> Some (Value.paths deps_written_by_user)
| _ -> None) | _ -> None)
let run sctx ~loc ?(extra_vars=String.Map.empty) let run sctx ~loc ?(extra_vars=String.Map.empty)

View File

@ -82,7 +82,7 @@ val expand_vars
: t : t
-> scope:Scope.t -> scope:Scope.t
-> dir:Path.t -> dir:Path.t
-> ?extra_vars:Var_expansion.t String.Map.t -> ?extra_vars:Value.t list String.Map.t
-> String_with_vars.t -> String_with_vars.t
-> string -> string
@ -90,7 +90,7 @@ val expand_vars_path
: t : t
-> scope:Scope.t -> scope:Scope.t
-> dir:Path.t -> dir:Path.t
-> ?extra_vars:Var_expansion.t String.Map.t -> ?extra_vars:Value.t list String.Map.t
-> String_with_vars.t -> String_with_vars.t
-> Path.t -> Path.t
@ -98,7 +98,7 @@ val expand_and_eval_set
: t : t
-> scope:Scope.t -> scope:Scope.t
-> dir:Path.t -> dir:Path.t
-> ?extra_vars:Var_expansion.t String.Map.t -> ?extra_vars:Value.t list String.Map.t
-> Ordered_set_lang.Unexpanded.t -> Ordered_set_lang.Unexpanded.t
-> standard:(unit, string list) Build.t -> standard:(unit, string list) Build.t
-> (unit, string list) Build.t -> (unit, string list) Build.t
@ -232,7 +232,7 @@ module Action : sig
val run val run
: t : t
-> loc:Loc.t -> loc:Loc.t
-> ?extra_vars:Var_expansion.t String.Map.t -> ?extra_vars:Value.t list String.Map.t
-> Action.Unexpanded.t -> Action.Unexpanded.t
-> dir:Path.t -> dir:Path.t
-> dep_kind:Build.lib_dep_kind -> dep_kind:Build.lib_dep_kind

27
src/value.ml Normal file
View File

@ -0,0 +1,27 @@
open Stdune
type t =
| String of string
| Path of Path.t
let string_of_path ~dir p = Path.reach ~from:dir p
let to_string t ~dir =
match t with
| String s -> s
| Path p -> string_of_path ~dir p
let to_strings t ~dir = List.map t ~f:(to_string ~dir)
let to_path ?error_loc t ~dir =
match t with
| String s -> Path.relative ?error_loc dir s
| Path p -> p
let strings = List.map ~f:(fun x -> String x)
let paths = List.map ~f:(fun x -> Path x)
let paths_only =
List.filter_map ~f:(function
| String _ -> None
| Path p -> Some p)

17
src/value.mli Normal file
View File

@ -0,0 +1,17 @@
open Stdune
type t =
| String of string
| Path of Path.t
val to_string : t -> dir:Path.t -> string
val to_strings : t list -> dir:Path.t -> string list
val to_path : ?error_loc:Loc.t -> t -> dir:Path.t -> Path.t
val strings : string list -> t list
val paths : Path.t list -> t list
val paths_only : t list -> Path.t list

View File

@ -1,61 +0,0 @@
open Stdune
module T = struct
type t =
| Paths of Path.t list
| Strings of string list
let length = function
| Paths x -> List.length x
| Strings x -> List.length x
let is_multivalued = function
| Paths [_] -> false
| Strings [_] -> false
| _ -> true
type context = Path.t (* For String_with_vars.Expand_to *)
let concat = function
| [s] -> s
| l -> String.concat ~sep:" " l
let string_of_path ~dir p = Path.reach ~from:dir p
let to_string (dir: context) = function
| Strings l -> concat l
| Paths l -> concat (List.map l ~f:(string_of_path ~dir))
end
include T
module Expand = String_with_vars.Expand_to(T)
let path_of_string dir s = Path.relative dir s
let to_strings dir = function
| Strings l -> l
| Paths l -> List.map l ~f:(string_of_path ~dir)
let to_path dir = function
| Strings l -> path_of_string dir (concat l)
| Paths [p] -> p
| Paths l ->
path_of_string dir (concat (List.map l ~f:(string_of_path ~dir)))
module Single = struct
let path ~dir sw ~f =
let relative = Path.relative ~error_loc:(String_with_vars.loc sw) in
match Expand.expand dir sw ~allow_multivalue:false ~f with
| String s
| Expansion (Strings [s]) -> relative dir s
| Expansion (Paths [s]) -> Path.append dir s
| _ -> assert false (* multivalues aren't allowed *)
let string ~dir sw ~f =
match Expand.expand dir sw ~allow_multivalue:false ~f with
| String s
| Expansion (Strings [s]) -> s
| Expansion (Paths [s]) -> string_of_path ~dir s
| _ -> assert false (* multivalues aren't allowed *)
end

View File

@ -1,34 +0,0 @@
open Stdune
type t =
| Paths of Path.t list
| Strings of string list
val to_string : Path.t -> t -> string
(** [to_string dir v] convert the variable expansion to a string.
If it is a path, the corresponding string will be relative to
[dir]. *)
val path_of_string : Path.t -> string -> Path.t
val to_strings : Path.t -> t -> string list
val to_path : Path.t -> t -> Path.t
module Expand : String_with_vars.Expand_intf
with type expansion = t and type context = Path.t
(** Specialized expansion that produce only a single value *)
module Single : sig
val path
: dir:Path.t
-> String_with_vars.t
-> f:(Loc.t -> string -> t option)
-> Path.t
val string
: dir:Path.t
-> String_with_vars.t
-> f:(Loc.t -> string -> t option)
-> string
end