aboutsummaryrefslogtreecommitdiffstats
path: root/lib/test_server/src/things/verify.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/test_server/src/things/verify.erl')
-rw-r--r--lib/test_server/src/things/verify.erl199
1 files changed, 199 insertions, 0 deletions
diff --git a/lib/test_server/src/things/verify.erl b/lib/test_server/src/things/verify.erl
new file mode 100644
index 0000000000..eac20c013e
--- /dev/null
+++ b/lib/test_server/src/things/verify.erl
@@ -0,0 +1,199 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(verify).
+
+-export([dir/0, dir/1]).
+
+%% usage verify:dir()
+%% or verify:dir(Dir)
+%%
+%% runs tests on all files with the extension ".t1"
+%% creates an error log file verify.log in the directory where the
+%% tests were run
+
+-import(lists, [reverse/1, foldl/3, map/2]).
+
+dir() ->
+ dir(".").
+
+dir(Dir) ->
+ case file:list_dir(Dir) of
+ {ok, Files} ->
+ VFiles = collect_vers(Files, []),
+ VFiles1 = map(fun(F) -> Dir ++ "/" ++ F end, VFiles),
+ Nerrs = foldl(fun(F, Sum) ->
+ case file(F) of
+ {file,_,had,N,errors} ->
+ Sum + N;
+ no_errors ->
+ Sum;
+ Other ->
+ Sum + 1
+ end
+ end, 0, VFiles1),
+ case Nerrs of
+ 0 -> no_errors;
+ _ -> {dir,Dir,had,Nerrs,errors}
+ end;
+ _ ->
+ {error, cannot,list_dir, Dir}
+ end.
+
+collect_vers([H|T], L) ->
+ case reverse(H) of
+ [$1,$t,$.|T1] -> collect_vers(T, [reverse(T1)|L]);
+ _ -> collect_vers(T, L)
+ end;
+collect_vers([], L) ->
+ L.
+
+file(File) ->
+ case file:open(File ++ ".t1", read) of
+ {ok, S} ->
+ io:format("Verifying: ~s\n", [File]),
+ ErrFile = File ++ ".errs",
+ {ok, E} = file:open(ErrFile, write),
+ Bind0 = erl_eval:new_bindings(),
+ NErrs = do(S, {E, File, Bind0, 0}, 1),
+ file:close(S),
+ file:close(E),
+ case NErrs of
+ 0 ->
+ file:delete(ErrFile),
+ no_errors;
+ _ ->
+ {file,File,had,NErrs,errors}
+ end;
+ _ ->
+ error_in_opening_file
+ end.
+
+do(S, Env, Line) ->
+ R = io:scan_erl_exprs(S, '', Line),
+ do1(R, S, Env).
+
+do1({eof,_}, _, {_,_,_,NErrs}) ->
+ NErrs;
+do1({ok,Toks,Next}, S, Env0) ->
+ E1 = handle_toks(Toks, Next, Env0),
+ do(S, E1, Next);
+do1({error, {Line,Mod,Args}, Next}, S, E) ->
+ io:format("*** ~w ~p~n", [Line,Mod:format_error(Args)]),
+ E1 = add_error(E),
+ do(S, E1, Next).
+
+add_error({Stream, File, Bindings, N}) -> {Stream, File, Bindings, N+1}.
+
+handle_toks(Toks, Line, Env0) ->
+ %% io:format("Toks:~p\n", [Toks]).
+ case erl_parse:parse_exprs(Toks) of
+ {ok, Exprs} ->
+ %% io:format("Got:~p\n", [Exprs]),
+ eval(Exprs, Line, Env0);
+ {error, {LineNo, Mod, What}} ->
+ Str = apply(Mod, format_error, [What]),
+ io:format("*** Line:~w ***~s\n", [LineNo, Str]),
+ add_error(Env0);
+ Parse_error ->
+ io:format("Parse Error:~p\n",[Parse_error]),
+ add_error(Env0)
+ end.
+
+forget([{var,_,Name}], B0) -> erl_eval:del_binding(Name, B0);
+forget([], _) -> erl_eval:new_bindings().
+
+eval([{call,_,{atom,_,f}, Args}], _, {Stream, Bind0, Errs}) ->
+ Bind1 = forget(Args, Bind0),
+ {Stream, Bind1, Errs};
+eval(Exprs, Line, {Stream, File, Bind0, NErrs}) ->
+ %% io:format("Bindings >> ~p\n", [Bind0]),
+ %% io:format("Exprs >> ~p\n", [Exprs]),
+ case catch erl_eval:exprs(Exprs, Bind0) of
+ {'EXIT', Reason} ->
+ out_both(Stream, "----------------------------------~n", []),
+ out_both(Stream, "File:~s Error in:~s~n", [File, pp(Exprs)]),
+ print_bindings(Stream, Exprs, Bind0),
+ print_lhs(Stream, Exprs),
+ out_both(Stream, '*** Rhs evaluated to:~p~n',[rhs(Exprs, Bind0)]),
+ {Stream, File, Bind0, NErrs+1};
+ {value, _, Bind1} ->
+ {Stream, File, Bind1, NErrs}
+ end.
+
+pp([H]) -> erl_pp:expr(H);
+pp([H|T]) -> [erl_pp:expr(H),$,|pp(T)];
+pp([]) -> [].
+
+print_bindings(E, Form, Bindings) ->
+ case varsin(Form) of
+ [] ->
+ true;
+ Vars ->
+ print_vars(E, Vars, Bindings)
+ end.
+
+print_vars(E, [Var|T], Bindings) ->
+ case erl_eval:binding(Var, Bindings) of
+ {value, Val} ->
+ out_both(E, '~s = ~p\n',[Var, Val]);
+ unbound ->
+ out_both(E, '~s *is unbound*\n', [Var])
+ end,
+ print_vars(E, T, Bindings);
+print_vars(_, [], _) ->
+ true.
+
+
+out_both(E, Format, Data) ->
+ io:format(Format, Data),
+ io:format(E, Format, Data).
+
+print_lhs(E, [{match, _, Lhs, Rhs}]) ->
+ %% io:format(">>>> here:~w\n",[Lhs]),
+ out_both(E, '*** Lhs was:~s\n',[erl_pp:expr(Lhs)]);
+print_lhs(E, _) ->
+ out_both(E, '** UNDEFINED **', []).
+
+
+rhs([{match, _, Lhs, Rhs}], Bindings) ->
+ case catch erl_eval:exprs([Rhs], Bindings) of
+ {value, Val, _} -> Val;
+ Other -> undefined()
+ end;
+rhs(_, _) ->
+ undefined().
+
+varsin(X) -> varsin(X, []).
+
+varsin({var,_,'_'}, L) ->
+ L;
+varsin({var,_,V}, L) ->
+ case lists:member(V, L) of
+ true -> L;
+ false -> [V|L]
+ end;
+varsin([H|T], L) ->
+ varsin(T, varsin(H, L));
+varsin(T, L) when tuple(T) ->
+ varsin(tuple_to_list(T), L);
+varsin(_, L) ->
+ L.
+
+undefined() ->
+ '** UNDEFINED **'.