Allow passing an explicit "file system" for included files to the compiler
This commit is contained in:
@@ -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
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user