Allow passing an explicit "file system" for included files to the compiler

This commit is contained in:
Ulf Norell
2019-02-08 14:05:29 +01:00
parent 0b86cdc318
commit aa6d56ce9b
3 changed files with 38 additions and 27 deletions
+7 -8
View File
@@ -28,8 +28,8 @@
| pp_icode
| pp_assembler
| pp_bytecode
| {include_path, [string()]}
| {allow_include, boolean()}
| {include, {file_system, [string()]} |
{explicit_files, #{string() => binary()}}}
| {src_file, string()}.
-type options() :: [option()].
@@ -49,12 +49,13 @@ version() ->
-spec file(string()) -> {ok, map()} | {error, binary()}.
file(Filename) ->
Dir = filename:dirname(Filename),
file(Filename, [{include_path, [Dir]}]).
{ok, Cwd} = file:get_cwd(),
file(Filename, [{include, {file_system, [Cwd, Dir]}}]).
-spec file(string(), options()) -> {ok, map()} | {error, binary()}.
file(File, Options) ->
case read_contract(File) of
{ok, Bin} -> from_string(Bin, [{src_file, File}, {allow_include, true} | Options]);
{ok, Bin} -> from_string(Bin, [{src_file, File} | Options]);
{error, Error} ->
ErrorString = [File,": ",file:format_error(Error)],
{error, join_errors("File errors", [ErrorString], fun(E) -> E end)}
@@ -288,10 +289,8 @@ parse(Text, Options) ->
ErrorString = io_lib:format("Ambiguous ~p", [As]),
parse_error(Pos, ErrorString);
%% Include error
{error, {Pos, include_not_allowed}} ->
parse_error(Pos, "includes not allowed in this context");
{error, {Pos, include_error}} ->
parse_error(Pos, "could not find include file")
{error, {Pos, {include_error, File}}} ->
parse_error(Pos, io_lib:format("could not find include file '~s'", [File]))
end.
parse_error(Pos, ErrorString) ->
+13 -9
View File
@@ -483,9 +483,8 @@ expand_includes(AST, Opts) ->
expand_includes([], Acc, _Opts) ->
{ok, lists:reverse(Acc)};
expand_includes([{include, S = {string, _, File}} | AST], Acc, Opts) ->
AllowInc = proplists:get_value(allow_include, Opts, false),
case read_file(File, Opts) of
{ok, Bin} when AllowInc ->
{ok, Bin} ->
Opts1 = lists:keystore(src_file, 1, Opts, {src_file, File}),
case string(binary_to_list(Bin), Opts1) of
{ok, AST1} ->
@@ -493,17 +492,22 @@ expand_includes([{include, S = {string, _, File}} | AST], Acc, Opts) ->
Err = {error, _} ->
Err
end;
{ok, _} ->
{error, {get_pos(S), include_not_allowed}};
{error, _} ->
{error, {get_pos(S), include_error}}
{error, {get_pos(S), {include_error, File}}}
end;
expand_includes([E | AST], Acc, Opts) ->
expand_includes(AST, [E | Acc], Opts).
read_file(File, Opts) ->
CandidateNames = [File] ++ [ filename:join(Dir, File)
|| Dir <- proplists:get_value(include_path, Opts, []) ],
lists:foldr(fun(F, {error, _}) -> file:read_file(F);
(_F, OK) -> OK end, {error, not_found}, CandidateNames).
case proplists:get_value(include, Opts, {explicit_files, #{}}) of
{file_system, Paths} ->
CandidateNames = [ filename:join(Dir, File) || Dir <- Paths ],
lists:foldr(fun(F, {error, _}) -> file:read_file(F);
(_F, OK) -> OK end, {error, not_found}, CandidateNames);
{explicit_files, Files} ->
case maps:get(binary_to_list(File), Files, not_found) of
not_found -> {error, not_found};
Src -> {ok, Src}
end
end.