suggested patch: file:script()

Ulf Wiger <>
Mon Feb 24 19:29:34 CET 2003


I've attached a diff to file.erl in kernel-2.8.1 that adds
the following functions for evaluating scripts (and being
able to capture a return value -- something file:eval/1 will
not let you do.)

/Uffe

script(File) ->
  {ok, ReturnValue} | {error, Reason}

   evaluates the expressions in File. Returns the result of
   the last expression. The expressions can create bindings
   to be reused in following expressions, just like in the
   Erlang shell.

script(File, Bindings) ->
  {ok, ReturnValue} | {error, Reason}

   Like script/1, but with predefined bindings. Use the
   functions in erl_eval.erl to manage bindings.

path_script(Path, File [, Bindings]) ->
   {ok, ReturnValue, Fullname} | {error, Reason}

   Analogous to path_eval/2, but for script/[2,3] above.

Example, using two "script" files:

eval1.txt:
----------
Cwd = fun() ->
	      {ok,D} = file:get_cwd(),
	      D
      end,
[{cwd, Cwd()}].

eval2.txt:  (assuming that the variable Var is bound)
----------
Cwd = fun() ->
	      {ok,D} = file:get_cwd(),
	      D
      end,
[{var, Var},
 {cwd, Cwd()}].



erl -boot start_clean -pa ../ebin -nostick
Erlang (BEAM) emulator version 5.2.3.1 [hipe] [threads:0]

Eshell V5.2.3.1  (abort with ^G)
1> file:script("eval1.txt").
{ok,[{cwd,"/home/etxuwig/work/erlang/open_source/contribs/mine/not_ready/builder-0.5/src"}]}
2> file:script("eval2.txt").
{error,[{7,file,{{unbound,'Var'},[{erl_eval,expr,3}]}},
        {error,undefined_script}]}
3>
file:script("eval2.txt",erl_eval:add_binding('Var',the_value,erl_eval:new_bindings())).
{ok,[{var,the_value},

{cwd,"/home/etxuwig/work/erlang/open_source/contribs/mine/not_ready/builder-0.5/src"}]}
4>

-- 
Ulf Wiger, Senior Specialist,
   / / /   Architecture & Design of Carrier-Class Software
  / / /    Strategic Product & System Management
 / / /     Ericsson AB, Connectivity and Control Nodes
-------------- next part --------------
44d43
< -export([script/1, script/2, path_script/2, path_script/3]).
833c832
< 	    R = eval_stream(Fd, ignore, erl_eval:new_bindings()),
---
> 	    R = eval_stream(Fd, erl_eval:new_bindings()),
843c842
< 	    case eval_stream(Fd, ignore, erl_eval:new_bindings()) of
---
> 	    case eval_stream(Fd, erl_eval:new_bindings()) of
855,891d853
< script(File) ->
<     script(File, erl_eval:new_bindings()).
< 
< script(File, Bs) ->
<     case open(File, [read]) of
< 	{ok, Fd} ->
< 	    R = case eval_stream(Fd, return, Bs) of
< 		    {ok, Result} ->
< 			Result;
< 		    Error1 ->
< 			Error1
< 		end,
< 	    close(Fd),
< 	    R;
< 	Error ->
< 	    Error
<     end.
< 
< path_script(Path, File) ->
<     path_script(Path, File, erl_eval:new_bindings()).
< 
< path_script(Path, File, Bs) ->
<     case path_open(Path, File, [read]) of
< 	{ok,Fd,Full} ->
< 	    case eval_stream(Fd, return, Bs) of
< 		{error,E} ->
< 		    close(Fd),
< 		    {error,E};
< 		{ok, R} ->
< 		    close(Fd),
< 		    {R,Full}
< 	    end;
< 	Error ->
< 	    Error
<     end.
<     
< 
961,962c923,927
< eval_stream(Fd, Handling, Bs) ->
<     eval_stream(Fd, Handling, undefined, [], Bs).
---
> eval_stream(Fd, Bs) ->
>     case eval_stream(Fd, [], Bs) of
> 	[] -> ok;
> 	[Error1 | _] -> {error,Error1}
>     end.
964,965c929,930
< eval_stream(Fd, Handling, Last, E, Bs) ->
<     eval_stream(io:parse_erl_exprs(Fd, ''), Fd, Handling, Last, E, Bs).
---
> eval_stream(Fd, E, Bs) ->
>     eval_stream(io:parse_erl_exprs(Fd, ''), Fd, E, Bs).
967,968c932
< 
< eval_stream({ok,Form,EndLine}, Fd, Handling, Last, E, Bs0) ->
---
> eval_stream({ok,Form,EndLine}, Fd, E, Bs0) ->
971c935
< 	    eval_stream(Fd, Handling, {V}, E, Bs);
---
> 	    eval_stream(Fd, E, Bs);
973c937
< 	    eval_stream(Fd, Handling, Last, [{EndLine,?MODULE,Reason}|E], Bs0)
---
> 	    eval_stream(Fd, [{EndLine,?MODULE,Reason}|E], Bs0)
975,987c939,942
< eval_stream({error,What,EndLine}, Fd, H, L, E, Bs) ->
<     eval_stream(Fd, H, L, [What | E], Bs);
< eval_stream({eof,EndLine}, Fd, H, Last, E, Bs) ->
<     case {H, Last, E} of
< 	{return, {Val}, []} ->
< 	    {ok, Val};
< 	{return, undefined, E} ->
< 	    {error, lists:reverse([{error, undefined_script}|E])};
< 	{ignore, _, []} ->
< 	    ok;
< 	{_, _, [_|_] = E} ->
< 	    {error, lists:reverse(E)}
<     end.
---
> eval_stream({error,What,EndLine}, Fd, E, Bs) ->
>     eval_stream(Fd, [What | E], Bs);
> eval_stream({eof,EndLine}, Fd, E, Bs) ->
>     lists:reverse(E).


More information about the erlang-patches mailing list