%% Copyright (c) 2008-2024 Robert Virding %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %%% File : lfe_init.erl %%% Author : Robert Virding %%% Purpose : Lisp Flavoured Erlang init module. %%% The calls needed to start user/user_drv have changed from OTP %%% 26. In the release after 26 the module user no longer exists and %%% user_drv has a different interface. Note that this is sort of %%% documented but these modules are not included in the standard %%% Erlang documentation. %%% %%% We are basically called when we want to run the shell or no shell %%% at all, for running scripts we use lfescript instead of lfe. %%% %%% Note that we are very basic here and a much of the work is done in %%% the lfe start script, e.g. doing -lfe_eval and -erl_eval. -module(lfe_init_new). -export([start/0,do_evals/1]). -include("lfe.hrl"). %% Exit status. -define(OK_STATUS, 0). -define(ERROR_STATUS, 127). %% Default repl to use when none is given. -define(DEFAULT_REPL, lfe_repl). %% Start LFE running a script or the shell depending on arguments. start() -> OTPRelease = erlang:system_info(otp_release), %% Find out which repl/shell we want to use. Repl = case init:get_argument(repl) of {ok, [[R|_]]} -> list_to_atom(R); _ -> ?DEFAULT_REPL end, %% Check if we are to run the repl/shell or not and if so run it. case init:get_argument(noshell) of {ok, [[]]} -> %Only match straight -noshell if OTPRelease >= "26" -> %% The new way 26 and later) user_drv:start(#{initial_shell => noshell}); true -> %% The old way before 26. user:start() end; _ -> %Otherwise run a shell if OTPRelease >= "26" -> %% The new way 26 and later. user_drv:start(#{initial_shell => {Repl,start,[]}}); true -> %% The old way before 26. user_drv:start(['tty_sl -c -e',{Repl,start,[]}]) end end, ok. do_evals(Evals) -> foreach(fun do_eval/1, Evals). do_eval(EvalString) -> case lfe_io:read_string(EvalString) of {ok, Exprs} -> lfe_eval:exprs(Exprs); {error, E} -> error(E) end. %% Implement our own lists functions to get around stacktrace printing %% problems. %% foldl(F, Accu, [Hd|Tail]) -> %% foldl(F, F(Hd, Accu), Tail); %% foldl(F, Accu, []) when is_function(F, 2) -> Accu. foreach(F, [Hd | Tail]) -> F(Hd), foreach(F, Tail); foreach(F, []) when is_function(F, 1) -> ok.