support ${..} in :include

This commit is contained in:
Rudi Grinberg 2017-08-23 16:56:32 -04:00
parent 001daa62d0
commit 7c6f3e6dd6
3 changed files with 28 additions and 26 deletions

View File

@ -9,7 +9,7 @@ module Ast = struct
| Special : Loc.t * string -> ('a, _) t
| Union : ('a, 'b) t list -> ('a, 'b) t
| Diff : ('a, 'b) t * ('a, 'b) t -> ('a, 'b) t
| Include : string -> ('a, unexpanded) t
| Include : String_with_vars.t -> ('a, unexpanded) t
end
type t = (string, Ast.expanded) Ast.t
@ -83,7 +83,7 @@ module Unexpanded = struct
match t with
| Element s -> Element s
| Union [Special (_, "include"); Element fn] ->
Include (Sexp.Of_sexp.string fn)
Include (String_with_vars.t fn)
| Union [Special (loc, "include"); _]
| Special (loc, "include") ->
Loc.fail loc "(:include expects a single element (do you need to quote the filename?)"
@ -99,14 +99,14 @@ module Unexpanded = struct
let append = append
let files t =
let files t ~f =
let rec loop acc (t : t) =
let open Ast in
match t with
| Element _
| Special _ -> acc
| Include fn ->
String_set.add fn acc
String_set.add (f fn) acc
| Union l ->
List.fold_left l ~init:acc ~f:loop
| Diff (l, r) ->
@ -117,11 +117,13 @@ module Unexpanded = struct
let rec expand (t : t) ~files_contents ~f : (string, Ast.expanded) Ast.t =
let open Ast in
match t with
| Element s -> Element (f s)
| Element s -> Element (f (String_with_vars.t s))
| Special (l, s) -> Special (l, s)
| Include fn ->
parse_general (String_map.find_exn fn files_contents ~string_of_key:(sprintf "%S")
~desc:(fun _ -> "<filename to s-expression>")) ~f
parse_general (
String_map.find_exn (f fn) files_contents ~string_of_key:(sprintf "%S")
~desc:(fun _ -> "<filename to s-expression>")
) ~f:(fun s -> f (String_with_vars.t s))
| Union l ->
Union (List.map l ~f:(expand ~files_contents ~f))
| Diff (l, r) ->

View File

@ -23,10 +23,10 @@ module Unexpanded : sig
val append : t -> t -> t
(** List of files needed to expand this set *)
val files : t -> String_set.t
val files : t -> f:(String_with_vars.t -> string) -> String_set.t
(** Expand [t] using with the given file contents. [file_contents] is a map from
filenames to their parsed contents. Every [(:include fn)] in [t] is replaced by
[Map.find files_contents fn]. Every element is converted to a string using [f]. *)
val expand : t -> files_contents:Sexp.Ast.t String_map.t -> f:(Sexp.Ast.t -> string) -> expanded
val expand : t -> files_contents:Sexp.Ast.t String_map.t -> f:(String_with_vars.t -> string) -> expanded
end with type expanded := t

View File

@ -902,8 +902,8 @@ end
let expand_and_eval_set t ~scope ~dir set ~standard =
let open Build.O in
let f sexp = expand_vars t ~scope ~dir (String_with_vars.t sexp) in
match Ordered_set_lang.Unexpanded.files set |> String_set.elements with
let f = expand_vars t ~scope ~dir in
match Ordered_set_lang.Unexpanded.files set ~f |> String_set.elements with
| [] ->
let set = Ordered_set_lang.Unexpanded.expand set ~files_contents:String_map.empty ~f in
Build.return (Ordered_set_lang.eval_with_standard set ~standard)