diff options
Diffstat (limited to 'lib/tools/test/cover_SUITE_data/d.erl')
-rw-r--r-- | lib/tools/test/cover_SUITE_data/d.erl | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/lib/tools/test/cover_SUITE_data/d.erl b/lib/tools/test/cover_SUITE_data/d.erl new file mode 100644 index 0000000000..696e27e49b --- /dev/null +++ b/lib/tools/test/cover_SUITE_data/d.erl @@ -0,0 +1,156 @@ +-module(d). + +-export([start/0, stop/0]). +-export([store/2, store/3, move/2, + location/1, who_are_at/1, who_are_older/1, + size/0]). +-export([init/0]). % spawn + +-record(person, {name, age, location, moved=false}). + +%%%---------------------------------------------------------------------- +%%% User interface functions +%%%---------------------------------------------------------------------- + +%%% start() -> pid() +start() -> + spawn(?MODULE, init, []). + +%%% stop() +stop() -> + arne ! stop. + +%%% store(Name, Location) -> +%%% store(Name, Age, Location) -> ok | {error,Reason} +%%% Name = Location = atom() +%%% Age = integer() +%%% Reason = not_started | no_response | {internal_error,term()} +store(Name, Location) -> + store(Name, ?AGE, Location). +store(Name, Age, Location) when atom(Name), integer(Age), atom(Location) -> + send({store, Name, Age, Location}). + +%%% move(OldLocation, NewLocation) -> Names | {error,Reason} +%%% OldLocation = NewLocation = atom() +%%% Names = [Name] +%%% Name = atom() +%%% Reason = not_started | no_response | {internal_error,term()} +move(OldLocation, NewLocation) -> + send({move, OldLocation, NewLocation}). + +%%% location(Name) -> Location | no_such_person | {error,Reason} +%%% Name = atom() +%%% Reason = not_started | no_response | {internal_error,term()} +location(Name) when atom(Name) -> + send({location, Name}). + +%%% who_are_at(Location) -> Names | {error,Reason} +%%% Location = atom() +%%% Names = [Name] +%%% Name = atom() +%%% Reason = not_started | no_response | {internal_error,term()} +who_are_at(Location) when atom(Location) -> + send({who_are_at, Location}). + +%%% who_are_older(Age) -> Names | {error,Reason} +%%% Age = integer() +%%% Names = [Name] +%%% Name = atom() +%%% Reason = not_started | no_response | {internal_error,term()} +who_are_older(Age) when integer(Age) -> + send({who_are_older, Age}). + +%%% size() -> N | {error,Reason} +%%% N = integer() +%%% Reason = not_started | no_response | {internal_error,term()} +size() -> + send(size). + +%%%---------------------------------------------------------------------- +%%% Main loop +%%%---------------------------------------------------------------------- +send(Request) -> + Pid = whereis(arne), + if + Pid==undefined -> + {error, not_started}; + true -> + send(Pid, Request) + end. +send(Pid, Request) -> + Pid ! {request, self(), Request}, + receive + {reply, Reply} -> + Reply + after + 1000 -> + {error, no_response} + end. + +init() -> + register(arne, self()), + loop([]). + +loop(Db) -> + receive + stop -> + true; + {request, From, Request} -> + case catch handle(Request, Db) of + {reply, Reply, NewDb} -> + From ! {reply, Reply}, + loop(NewDb); + {'EXIT', Reason} -> + From ! {reply, {error, {internal_error, Reason}}}, + loop(Db) + end + end. + +%%%---------------------------------------------------------------------- +%%% DB functionality +%%%---------------------------------------------------------------------- +handle({store, Name, Age, Location}, Db) -> + {reply, ok, [#person{name=Name, age=Age, location=Location} | Db]}; +handle({move, OldLocation, NewLocation}, Db) -> + {Names, NewDb} = move(OldLocation, NewLocation, Db, [], []), + {reply, Names, NewDb}; +handle({location, Name}, Db) -> + case lists:keysearch(Name, #person.name, Db) of + {value, #person{location=Location}} when atom(Location) -> + {reply, Location, Db}; + false -> + {reply, no_such_name, Db} + end; +handle({who_are_at, Location}, Db) -> + Result = lists:foldl(fun(Person, Names) -> + case Person#person.location of + Location -> + [Person#person.name | Names]; + _OtherLocation -> + Names + end + end, + [], + Db), + {reply, Result, Db}; +handle({who_are_older, Old}, Db) -> + Result = [Name || {person,Name,Age,Location} <- Db, + Age>Old], + {reply, Result, Db}; +handle(size, Db) -> + Result = count(Db, 0), {reply, Result, Db}. + +count([H|T], N) -> + count(T, N+1); +count([], N) -> + N. + +move(OldLoc, NewLoc, [#person{location=OldLoc} = Person|T], Db, Names) -> + NewPerson = Person#person{location=NewLoc, + moved=true}, + NewNames = [Person#person.name|Names], + move(OldLoc, NewLoc, T, [NewPerson|Db], NewNames); +move(OldLoc, NewLoc, [Person|T], Db, Names) -> + move(OldLoc, NewLoc, T, [Person|Db], Names); +move(OldLoc, NewLoc, [], Db, Names) -> + {lists:reverse(Names), lists:reverse(Db)}. |