Packages

otpbp

4.76.2
7.18.0 7.16.1 7.15.0 7.14.0 7.13.0 7.12.0 7.11.0 7.10.2 7.9.3 7.9.2 7.9.1 7.8.7 7.8.6 7.8.5 7.8.4 7.7.1 7.7.0 7.6.3 7.6.2 7.6.1 7.6.0 7.5.1 7.5.0 7.4.0 7.3.4 7.3.3 7.3.2 7.3.1 7.3.0 7.2.0 7.1.1 7.1.0 7.0.4 7.0.3 7.0.2 7.0.1 6.26.0 6.25.0 6.24.0 6.23.0 6.22.2 6.21.3 6.21.2 6.21.1 6.20.2 6.19.1 6.19.0 6.18.3 6.18.2 6.18.1 6.18.0 6.17.1 6.17.0 6.16.0 6.15.4 6.15.3 6.15.2 6.15.1 6.15.0 6.14.0 6.13.5 6.13.4 6.13.3 6.13.2 6.13.1 6.13.0 6.12.0 6.11.2 6.11.1 6.10.0 6.9.2 6.9.1 6.9.0 6.8.0 6.7.1 6.7.0 6.6.4 6.6.3 6.6.2 6.6.1 6.6.0 6.5.0 6.4.0 6.3.3 6.3.2 6.3.1 6.3.0 6.2.1 6.2.0 6.1.0 6.0.0 5.39.0 5.38.0 5.37.0 5.36.0 5.35.2 5.34.3 5.34.2 5.34.1 5.33.1 5.32.1 5.32.0 5.31.3 5.31.2 5.31.1 5.31.0 5.30.1 5.30.0 5.29.0 5.28.4 5.28.3 5.28.2 5.28.1 5.28.0 5.27.0 5.26.5 5.26.4 5.26.3 5.26.2 5.26.1 5.26.0 5.25.0 5.24.2 5.24.1 5.23.0 5.22.2 5.22.1 5.22.0 5.21.0 5.20.1 5.20.0 5.19.4 5.19.3 5.19.2 5.19.1 5.19.0 5.18.0 5.17.0 5.16.3 5.16.1 5.16.0 5.15.1 5.15.0 5.14.0 5.13.1 5.13.0 5.12.1 5.12.0 5.11.2 5.11.1 5.10.1 5.10.0 5.9.0 5.8.0 5.7.0 5.6.1 5.6.0 5.5.0 5.4.2 5.4.1 5.4.0 5.3.0 5.2.2 5.2.1 5.2.0 5.1.2 5.1.1 4.79.0 4.78.0 4.77.0 4.76.2 4.75.3 4.75.2 4.75.1 4.74.0 4.73.1 4.73.0 4.72.3 4.72.2 4.72.1 4.72.0 4.71.1 4.71.0 4.70.0 4.69.4 4.69.3 4.69.2 4.69.1 4.69.0 4.68.0 4.67.5 4.67.4 4.67.3 4.67.2 4.67.0 4.66.0 4.65.2 4.65.1 4.64.0 4.63.2 4.63.1 4.63.0 4.62.0 4.61.1 4.61.0 4.60.4 4.60.3 4.60.2 4.60.1 4.60.0 4.59.0 4.58.0 4.57.2 4.57.1 4.57.0 4.56.2 4.56.1 4.56.0 4.55.0 4.54.0 4.53.0 4.52.1 4.52.0 4.51.3 4.51.2 4.51.0 4.50.0 4.49.3 4.49.2

OTP backports

Current section

Files

Jump to
otpbp src otpbp_c.erl
Raw

src/otpbp_c.erl

-module(otpbp_c).
-compile([{parse_transform, otpbp_pt}]).
-ifndef(HAVE_c__lm_0).
% OTP 20.0
-export([lm/0]).
-endif.
-ifndef(HAVE_c__c_3).
% OTP 20.0
-export([c/3]).
-endif.
-ifndef(HAVE_c__erlangrc_1).
% OTP 21.0
-export([erlangrc/1]).
-endif.
-ifndef(HAVE_c__h_1).
% OTP 23.0
-export([h/1]).
-endif.
-ifndef(HAVE_c__h_2).
% OTP 23.0
-export([h/2]).
-endif.
-ifndef(HAVE_c__h_3).
% OTP 23.0
-export([h/3]).
-endif.
-ifndef(HAVE_c__hcb_1).
% OTP 23.0
-export([hcb/1]).
-endif.
-ifndef(HAVE_c__hcb_2).
% OTP 23.0
-export([hcb/2]).
-endif.
-ifndef(HAVE_c__hcb_3).
% OTP 23.0
-export([hcb/3]).
-endif.
-ifndef(HAVE_c__ht_1).
% OTP 23.0
-export([ht/1]).
-endif.
-ifndef(HAVE_c__ht_2).
% OTP 23.0
-export([ht/2]).
-endif.
-ifndef(HAVE_c__ht_3).
% OTP 23.0
-export([ht/3]).
-endif.
-ifndef(HAVE_c__lm_0).
lm() -> lists:map(fun c:l/1, c:mm()).
-endif.
-ifndef(HAVE_c__erlangrc_1).
erlangrc([Home|_] = Paths) when is_list(Home) ->
case file:path_eval(Paths, ".erlang") of
{error, {Line, _Mod, _Term} = E} = Error ->
error_logger:error_msg("file:path_eval(~tp,.erlang): error on line ~p: ~ts~n",
[Paths, Line, file:format_error(E)]),
Error;
{error, E} = Error when E =/= enoent ->
error_logger:error_msg("file:path_eval(~tp,.erlang): ~ts~n", [Paths, file:format_error(E)]),
Error;
Other -> Other
end.
-endif.
-ifndef(HAVE_c__c_3).
c(Module, Options, Filter) when is_atom(Module) ->
case find_beam(Module) of
BeamFile when is_list(BeamFile) ->
case compile_info(Module, BeamFile) of
Info when is_list(Info) ->
case find_source(BeamFile, Info) of
SrcFile when is_list(SrcFile) -> c(SrcFile, Options, Filter, BeamFile, Info);
Error -> Error
end;
Error -> Error
end;
Error -> {error, Error}
end.
-compile({inline, c/5}).
c(SrcFile, Options, Filter, BeamFile, Info) ->
io:fwrite("Recompiling ~ts\n", [SrcFile]),
%% Note that it's possible that because of options such as 'to_asm',
%% the compiler might not actually write a new beam file at all
Backup = BeamFile ++ ".bak",
case file:rename(BeamFile, Backup) of
Status when Status =:= ok; Status =:= {error, enoent} ->
case compile_and_load(SrcFile,
%% Filter old options; also remove options that will be replaced.
%% Write new beam over old beam unless other outdir is specified.
Options ++ [{outdir, filename:dirname(BeamFile)}] ++
case lists:keyfind(options, 1, Info) of
{_, Opts} -> [O || O <- Opts, not is_outdir_opt(O) andalso Filter(O)];
false -> []
end) of
{ok, _} = Result ->
Status =:= ok andalso file:delete(Backup),
Result;
Error ->
Status =:= ok andalso file:rename(Backup, BeamFile),
Error
end;
Error -> Error
end.
is_outdir_opt({outdir, _}) -> true;
is_outdir_opt(_) -> false.
-compile({inline, find_beam/1}).
find_beam(Module) ->
case code:which(Module) of
[_|_] = Beam ->
case module_loaded(Module) of
false -> Beam; % code:which/1 found this in the path
true ->
case filelib:is_file(Beam) of
true -> Beam;
false -> code:where_is_file(atom_to_list(Module) ++ code:objfile_extension()) % file moved?
end
end;
Other when Other =:= ""; Other =:= cover_compiled ->
%% module is loaded but not compiled directly from source
code:where_is_file(atom_to_list(Module) ++ code:objfile_extension());
Error -> Error
end.
-compile({inline, compile_info/2}).
compile_info(Module, Beam) ->
case module_loaded(Module) of
true ->
%% getting the compile info for a loaded module should normally
%% work, but return an empty info list if it fails
try
erlang:get_module_info(Module, compile)
catch
_:_ -> []
end;
false ->
case beam_lib:chunks(Beam, [compile_info]) of
{ok, {_Module, [{compile_info, Info}]}} -> Info;
Error -> Error
end
end.
-compile({inline, find_source/2}).
find_source(BeamFile, Info) ->
case lists:keyfind(source, 1, Info) of
{_, SrcFile} ->
case filelib:is_file(SrcFile) of
true -> SrcFile;
false -> find_source(BeamFile)
end;
_ -> find_source(BeamFile)
end.
find_source(BeamFile) ->
case filelib:find_source(BeamFile) of
{ok, SrcFile} -> SrcFile;
_ -> {error, no_source}
end.
compile_and_load(File, Opts0) when is_list(Opts0) ->
{[Opt|_], Opts1} = lists:partition(fun is_outdir_opt/1, Opts0 ++ [{outdir, "."}]),
Opts = [report_errors, report_warnings|ensure_from(filename:extension(File), [Opt|Opts1])],
case compile:file(File, Opts) of
{ok, Mod} -> purge_and_load(Mod, File, Opts); % Listing file.
{ok, Mod, _Ws} -> purge_and_load(Mod, File, Opts); % Warnings maybe turned on.
Other -> Other % Errors go here
end;
compile_and_load(File, Opt) -> compile_and_load(File, [Opt]).
-compile({inline, ensure_from/2}).
ensure_from(Suffix, Opts0) ->
case lists:partition(fun(O) -> O =:= from_core orelse O =:= from_asm end,
if
Suffix =:= ".core" -> Opts0 ++ [from_core];
Suffix =:= ".S" -> Opts0 ++ [from_asm];
true -> Opts0
end) of
{[Opt|_], Opts} -> [Opt|Opts];
{[], Opts} -> Opts
end.
purge_and_load(Mod, File, Opts) ->
case compile:output_generated(Opts) of
true ->
Base = filename:basename(File, src_suffix(Opts)),
case atom_to_list(Mod) of
Base ->
code:purge(Mod),
%% Note that load_abs() adds the object file suffix
case code:load_abs(filename:join(outdir(Opts), Base), Mod) of
{error, _} = Error -> Error;
_ -> {ok, Mod}
end;
_OtherMod ->
io:fwrite("** Module name '~s' does not match file name '~tp' **~n", [Mod, File]),
{error, badfile}
end;
false -> io:put_chars("** Warning: No object file created - nothing loaded **\n")
end.
src_suffix([from_core|_]) -> ".core";
src_suffix([from_asm|_]) -> ".S";
src_suffix([_|Opts]) -> src_suffix(Opts);
src_suffix([]) -> ".erl".
outdir([{outdir, D}|_]) -> D;
outdir([_|Rest]) -> outdir(Rest);
outdir([]) -> ".".
-endif.
-ifndef(HAVE_c__h_1).
h(M) when is_atom(M) -> {error, missing}.
-endif.
-ifndef(HAVE_c__h_2).
h(M, F) when is_atom(M), is_atom(F) -> {error, missing}.
-endif.
-ifndef(HAVE_c__h_3).
h(M, F, A) when is_atom(M), is_atom(F), is_integer(A) -> {error, missing}.
-endif.
-ifndef(HAVE_c__hcb_1).
hcb(M) when is_atom(M) -> {error, missing}.
-endif.
-ifndef(HAVE_c__hcb_2).
hcb(M, F) when is_atom(M), is_atom(F) -> {error, missing}.
-endif.
-ifndef(HAVE_c__hcb_3).
hcb(M, F, A) when is_atom(M), is_atom(F), is_integer(A) -> {error, missing}.
-endif.
-ifndef(HAVE_c__ht_1).
ht(M) when is_atom(M) -> {error, missing}.
-endif.
-ifndef(HAVE_c__ht_2).
ht(M, F) when is_atom(M), is_atom(F) -> {error, missing}.
-endif.
-ifndef(HAVE_c__ht_3).
ht(M, F, A) when is_atom(M), is_atom(F), is_integer(A) -> {error, missing}.
-endif.