aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diameter/src/base/diameter_info.erl
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2014-03-29 18:34:38 +0100
committerAnders Svensson <[email protected]>2014-03-29 19:20:45 +0100
commit5ca206af45b3195233991dfe820e9fb636800a33 (patch)
treecad0095bc906fd4e7aa6272e98fd017a2b91469b /lib/diameter/src/base/diameter_info.erl
parentc23b242d0d634d10b03412c19768d381906578ab (diff)
downloadotp-5ca206af45b3195233991dfe820e9fb636800a33.tar.gz
otp-5ca206af45b3195233991dfe820e9fb636800a33.tar.bz2
otp-5ca206af45b3195233991dfe820e9fb636800a33.zip
Move info modules into own subdirectory
Possibly overkill for two modules but it mirrors their different treatment by the makefile.
Diffstat (limited to 'lib/diameter/src/base/diameter_info.erl')
-rw-r--r--lib/diameter/src/base/diameter_info.erl869
1 files changed, 0 insertions, 869 deletions
diff --git a/lib/diameter/src/base/diameter_info.erl b/lib/diameter/src/base/diameter_info.erl
deleted file mode 100644
index 10972f3231..0000000000
--- a/lib/diameter/src/base/diameter_info.erl
+++ /dev/null
@@ -1,869 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2010-2014. 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%
-%%
-
-%%
-%% Generic functions for formatting table listings and more. Used by
-%% diameter_dbg.
-%%
-
--module(diameter_info).
-
--export([usage/1,
- format/1,
- format/2,
- format/3,
- format/4,
- table/2,
- tables/1,
- tables/2,
- split/2,
- split/3,
- tab2list/1,
- modules/1,
- versions/1,
- version_info/1,
- attrs/2,
- compiled/1,
- procs/1,
- latest/1,
- list/1]).
-
-%% Support for rolling your own.
--export([sep/0,
- sep/1,
- widest/1,
- p/1,
- p/3]).
-
--compile({no_auto_import,[max/2]}).
-
--export([collect/2]).
-
--define(LONG_TIMEOUT, 30000).
--define(VALUES(Rec), tl(tuple_to_list(Rec))).
-
-%%% ----------------------------------------------------------
-%%% # usage(String)
-%%% ----------------------------------------------------------
-
-usage(Usage) ->
- sep($+),
- io:format("+ ~p~n", [?MODULE]),
- io:format("~n~s~n~n", [compact(Usage)]),
- sep($+).
-
-%%%
-%%% The function format/3, for pretty-printing tables, comes in
-%%% several flavours.
-%%%
-
-%%% ----------------------------------------------------------
-%%% # format(TableName, Fields, SplitFun)
-%%%
-%%% Input: TableName = atom() name of table.
-%%%
-%%% Fields = List of field names for the records maintained
-%%% in the specified table. Can be empty, in which
-%%% case entries are listed unadorned of field names
-%%% and SplitFun is unused.
-%%% | Integer, equivalent to a list with this many '' atoms.
-%%% | Arity 1 fun mapping a table entry to a Fields list
-%%% or a tuple {Fields, Values} of lists of the same
-%%% length.
-%%%
-%%% If Fields is a list then its length must be the same
-%%% as or one less than the size of the tuples contained
-%%% in the table. (The values printed then being those
-%%% in the tuple or record in question.)
-%%%
-%%% SplitFun = Arity 3 fun applied as
-%%%
-%%% SplitFun(TableName, Fields, Values)
-%%%
-%%% in order to obtain a tuple
-%%%
-%%% {Field, RestFields, Value, RestValues}
-%%%
-%%% for which Field/Value will be formatted on
-%%% STDOUT. (This is to allow a value to be
-%%% transformed before being output by returning a
-%%% new value and/or replacing the remainder of
-%%% the list.) The returned lists must have the
-%%% same length and Field here is an atom, '' causing
-%%% a value to be listed unadorned of the field name.
-%%%
-%%% Field can also be list of field names, in
-%%% which case Value must be a record of the
-%%% corresponding type.
-%%%
-%%% | Arity 2 fun applied as SplitFun(Fields, Values).
-%%%
-%%% Output: Count | undefined
-%%%
-%%% Count = Number of entries output.
-%%%
-%%% Description: Pretty-print records in a named table.
-%%% ----------------------------------------------------------
-
-format(Table, Fields, SFun)
- when is_atom(Table), is_function(SFun, 2) ->
- ft(ets:info(Table), Table, SFun, Fields);
-
-format(Table, Fields, SFun)
- when is_atom(Table), is_function(SFun, 3) ->
- format(Table, Fields, fun(Fs,Vs) -> SFun(Table, Fs, Vs) end);
-
-%%% ----------------------------------------------------------
-%%% # format(Recs, Fields, SplitFun)
-%%%
-%%% Input: Recs = list of records/tuples
-%%% Fields = As for format(Table, Fields, SplitFun), a table
-%%% entry there being a member of Recs.
-%%% SplitFun = Arity 3 fun applied as above but with the TableName
-%%% replaced by the first element of the records in
-%%% question.
-%%% | Arity 2 fun as for format/3.
-%%%
-%%% Output: length(Recs)
-%%%
-%%% Description: Pretty print records/tuples.
-%%% ----------------------------------------------------------
-
-format(Recs, Fields, SFun)
- when is_list(Recs), is_function(SFun, 3) ->
- lists:foldl(fun(R,A) -> f(recsplit(SFun, R), 0, Fields, R, A) end,
- 0,
- Recs);
-
-format(Recs, Fields, SFun)
- when is_list(Recs), is_function(SFun, 2) ->
- lists:foldl(fun(R,A) -> f(SFun, 0, Fields, R, A) end,
- 0,
- Recs);
-
-%%% ----------------------------------------------------------
-%%% # format(Tables, SplitFun, CollectFun)
-%%%
-%%% Input: Tables = list of {TableName, Fields}.
-%%% SplitFun = As for format(Table, Fields, SplitFun).
-%%% CollectFun = arity 1 fun mapping a table name to a list
-%%% of elements. A non-list can be returned to indicate
-%%% that the table in question doesn't exist.
-%%%
-%%% Output: Number of entries output.
-%%%
-%%% Description: Pretty-print records in a named tables as collected
-%%% from known nodes. Each table listing is preceeded by
-%%% a banner.
-%%% ----------------------------------------------------------
-
-format(Tables, SFun, CFun)
- when is_list(Tables), is_function(CFun, 1) ->
- format_remote(Tables,
- SFun,
- rpc:multicall(nodes(known),
- ?MODULE,
- collect,
- [CFun, lists:map(fun({T,_}) -> T end, Tables)],
- ?LONG_TIMEOUT));
-
-%%% ----------------------------------------------------------
-%%% # format(LocalTables, RemoteTables, SplitFun, CollectFun)
-%%% # format(LocalTables, RemoteTables, SplitFun)
-%%%
-%%% Input: LocalTables = list of {TableName, Fields}.
-%%% | list of {TableName, Recs, Fields}
-%%% RemoteTable = list of {TableName, Fields}.
-%%% SplitFun, CollectFun = As for format(Table, CollectFun, SplitFun).
-%%%
-%%% Output: Number of entries output.
-%%%
-%%% Description: Pretty-print records in a named tables as collected
-%%% from local and remote nodes. Each table listing is
-%%% preceeded by a banner.
-%%% ----------------------------------------------------------
-
-format(Local, Remote, SFun) ->
- format(Local, Remote, SFun, fun tab2list/1).
-
-format(Local, Remote, SFun, CFun)
- when is_list(Local), is_list(Remote), is_function(CFun, 1) ->
- format_local(Local, SFun) + format(Remote, SFun, CFun).
-
-%%% ----------------------------------------------------------
-%%% # format(Tables, SplitFun)
-%%% ----------------------------------------------------------
-
-format(Tables, SFun)
- when is_list(Tables), (is_function(SFun, 2) or is_function(SFun, 3)) ->
- format(Tables, SFun, fun tab2list/1);
-
-format(Tables, CFun)
- when is_list(Tables), is_function(CFun, 1) ->
- format(Tables, fun split/2, CFun).
-
-%%% ----------------------------------------------------------
-%%% # format(Table|Tables)
-%%% ----------------------------------------------------------
-
-format(Table)
- when is_atom(Table) ->
- format(Table, [], fun split/2);
-
-format(Tables)
- when is_list(Tables) ->
- format(Tables, fun split/2, fun tab2list/1).
-
-%%% ----------------------------------------------------------
-%%% # split(TableName, Fields, Values)
-%%%
-%%% Description: format/3 SplitFun that does nothing special.
-%%% ----------------------------------------------------------
-
-split([F|FT], [V|VT]) ->
- {F, FT, V, VT}.
-
-split(_, Fs, Vs) ->
- split(Fs, Vs).
-
-%%% ----------------------------------------------------------
-%%% # tab2list(TableName)
-%%%
-%%% Description: format/4 CollectFun that extracts records from an
-%%% existing ets table.
-%%% ----------------------------------------------------------
-
-tab2list(Table) ->
- case ets:info(Table) of
- undefined = No ->
- No;
- _ ->
- ets:tab2list(Table)
- end.
-
-list(Table) ->
- l(tab2list(Table)).
-
-l(undefined = No) ->
- No;
-l(List)
- when is_list(List) ->
- io:format("~p~n", [List]),
- length(List).
-
-%%% ----------------------------------------------------------
-%%% # table(TableName, Fields)
-%%% ----------------------------------------------------------
-
-table(Table, Fields) ->
- format(Table, Fields, fun split/2).
-
-%%% ----------------------------------------------------------
-%%% # tables(LocalTables, RemoteTables)
-%%% ----------------------------------------------------------
-
-tables(Local, Remote) ->
- format(Local, Remote, fun split/2).
-
-%%% ----------------------------------------------------------
-%%% # tables(Tables)
-%%% ----------------------------------------------------------
-
-tables(Tables) ->
- format(Tables, fun split/2).
-
-%%% ----------------------------------------------------------
-%%% # modules(Prefix|Prefixes)
-%%%
-%%% Input: Prefix = atom()
-%%%
-%%% Description: Return the list of all loaded modules with the
-%%% specified prefix.
-%%% ----------------------------------------------------------
-
-modules(Prefix)
- when is_atom(Prefix) ->
- lists:sort(mods(Prefix));
-
-modules(Prefixes)
- when is_list(Prefixes) ->
- lists:sort(lists:flatmap(fun modules/1, Prefixes)).
-
-mods(Prefix) ->
- P = atom_to_list(Prefix),
- lists:filter(fun(M) ->
- lists:prefix(P, atom_to_list(M))
- end,
- erlang:loaded()).
-
-%%% ----------------------------------------------------------
-%%% # versions(Modules|Prefix)
-%%%
-%%% Output: Number of modules listed.
-%%%
-%%% Description: List the versions of the specified modules.
-%%% ----------------------------------------------------------
-
-versions(Modules) ->
- {SysInfo, OsInfo, ModInfo} = version_info(Modules),
- sep(),
- print_sys_info(SysInfo),
- sep(),
- print_os_info(OsInfo),
- sep(),
- print_mod_info(ModInfo),
- sep().
-
-%%% ----------------------------------------------------------
-%%% # attrs(Modules|Prefix, Attr|FormatFun)
-%%%
-%%% Output: Number of modules listed.
-%%%
-%%% Description: List an attribute from module_info.
-%%% ----------------------------------------------------------
-
-attrs(Modules, Attr)
- when is_atom(Attr) ->
- attrs(Modules, fun(W,M) -> attr(W, M, Attr, fun attr/1) end);
-
-attrs(Modules, Fun)
- when is_list(Modules) ->
- sep(),
- W = 2 + widest(Modules),
- N = lists:foldl(fun(M,A) -> Fun(W,M), A+1 end, 0, Modules),
- sep(),
- N;
-
-attrs(Prefix, Fun) ->
- attrs(modules(Prefix), Fun).
-
-%% attr/1
-
-attr(T) when is_atom(T) ->
- atom_to_list(T);
-attr(N) when is_integer(N) ->
- integer_to_list(N);
-attr(V) ->
- case is_list(V) andalso lists:all(fun is_char/1, V) of
- true -> %% string
- V;
- false ->
- io_lib:format("~p", [V])
- end.
-
-is_char(C) ->
- 0 =< C andalso C < 256.
-
-%% attr/4
-
-attr(Width, Mod, Attr, VFun) ->
- io:format(": ~*s~s~n", [-Width, Mod, attr(Mod, Attr, VFun)]).
-
-attr(Mod, Attr, VFun) ->
- Key = key(Attr),
- try
- VFun(val(Attr, keyfetch(Attr, Mod:module_info(Key))))
- catch
- _:_ ->
- "-"
- end.
-
-attr(Mod, Attr) ->
- attr(Mod, Attr, fun attr/1).
-
-key(time) -> compile;
-key(_) -> attributes.
-
-val(time, {_,_,_,_,_,_} = T) ->
- lists:flatten(io_lib:format("~p-~2..0B-~2..0B ~2..0B:~2..0B:~2..0B",
- tuple_to_list(T)));
-val(_, [V]) ->
- V.
-
-%%% ----------------------------------------------------------
-%%% # compiled(Modules|Prefix)
-%%%
-%%% Output: Number of modules listed.
-%%%
-%%% Description: List the compile times of the specified modules.
-%%% ----------------------------------------------------------
-
-compiled(Modules)
- when is_list(Modules) ->
- attrs(Modules, fun compiled/2);
-
-compiled(Prefix) ->
- compiled(modules(Prefix)).
-
-compiled(Width, Mod) ->
- io:format(": ~*s~19s ~s~n", [-Width,
- Mod,
- attr(Mod, time),
- opt(attr(Mod, date))]).
-
-opt("-") ->
- "";
-opt(D) ->
- "(" ++ D ++ ")".
-
-%%% ----------------------------------------------------------
-%%% # procs(Pred|Prefix|Prefixes|Pid|Pids)
-%%%
-%%% Input: Pred = arity 2 fun returning true|false when applied to a
-%%% pid and its process info.
-%%%
-%%% Output: Number of processes listed.
-%%%
-%%% Description: List process info for all local processes that test
-%%% true with the specified predicate. With the prefix
-%%% form, those processes that are either currently
-%%% executing in, started executing in, or have a
-%%% registered name with a specified prefix are listed.
-%%% With the pid forms, only those process that are local
-%%% are listed and those that are dead list only the pid
-%%% itself.
-%%% ----------------------------------------------------------
-
-procs(Pred)
- when is_function(Pred, 2) ->
- procs(Pred, erlang:processes());
-
-procs([]) ->
- 0;
-
-procs(Prefix)
- when is_atom(Prefix) ->
- procs(fun(_,I) -> info(fun pre1/2, I, atom_to_list(Prefix)) end);
-
-procs(Prefixes)
- when is_atom(hd(Prefixes)) ->
- procs(fun(_,I) -> info(fun pre/2, I, Prefixes) end);
-
-procs(Pid)
- when is_pid(Pid) ->
- procs(fun true2/2, [Pid]);
-
-procs(Pids)
- when is_list(Pids) ->
- procs(fun true2/2, Pids).
-
-true2(_,_) ->
- true.
-
-%% procs/2
-
-procs(Pred, Pids) ->
- Procs = lists:foldl(fun(P,A) ->
- procs_acc(Pred, P, catch process_info(P), A)
- end,
- [],
- Pids),
- sep(0 < length(Procs)),
- lists:foldl(fun(T,N) -> p(T), sep(), N+1 end, 0, Procs).
-
-procs_acc(_, Pid, undefined, Acc) -> %% dead
- [[{pid, Pid}] | Acc];
-procs_acc(Pred, Pid, Info, Acc)
- when is_list(Info) ->
- p_acc(Pred(Pid, Info), Pid, Info, Acc);
-procs_acc(_, _, _, Acc) ->
- Acc.
-
-p_acc(true, Pid, Info, Acc) ->
- [[{pid, Pid} | Info] | Acc];
-p_acc(false, _, _, Acc) ->
- Acc.
-
-%% info/3
-
-info(Pred, Info, T) ->
- lists:any(fun(I) -> i(Pred, I, T) end, Info).
-
-i(Pred, {K, {M,_,_}}, T)
- when K == current_function;
- K == initial_call ->
- Pred(M,T);
-i(Pred, {registered_name, N}, T) ->
- Pred(N,T);
-i(_,_,_) ->
- false.
-
-pre1(A, Pre) ->
- lists:prefix(Pre, atom_to_list(A)).
-
-pre(A, Prefixes) ->
- lists:any(fun(P) -> pre1(A, atom_to_list(P)) end, Prefixes).
-
-%%% ----------------------------------------------------------
-%%% # latest(Modules|Prefix)
-%%%
-%%% Output: {Mod, {Y,M,D,HH,MM,SS}, Version}
-%%%
-%%% Description: Return the compile time of the most recently compiled
-%%% module from the specified non-empty list. The modules
-%%% are assumed to exist.
-%%% ----------------------------------------------------------
-
-latest(Prefix)
- when is_atom(Prefix) ->
- latest(modules(Prefix));
-
-latest([_|_] = Modules) ->
- {Mod, T}
- = hd(lists:sort(fun latest/2, lists:map(fun compile_time/1, Modules))),
- {Mod, T, app_vsn(Mod)}.
-
-app_vsn(Mod) ->
- keyfetch(app_vsn, Mod:module_info(attributes)).
-
-compile_time(Mod) ->
- T = keyfetch(time, Mod:module_info(compile)),
- {Mod, T}.
-
-latest({_,T1},{_,T2}) ->
- T1 > T2.
-
-%%% ----------------------------------------------------------
-%%% version_info(Modules|Prefix)
-%%%
-%%% Output: {SysInfo, OSInfo, [ModInfo]}
-%%%
-%%% SysInfo = {Arch, Vers}
-%%% OSInfo = {Vers, {Fam, Name}}
-%%% ModInfo = {Vsn, AppVsn, Time, CompilerVsn}
-%%% ----------------------------------------------------------
-
-version_info(Prefix)
- when is_atom(Prefix) ->
- version_info(modules(Prefix));
-
-version_info(Mods)
- when is_list(Mods) ->
- {sys_info(), os_info(), [{M, mod_version_info(M)} || M <- Mods]}.
-
-mod_version_info(Mod) ->
- try
- Info = Mod:module_info(),
- [[Vsn], AppVsn] = get_values(attributes, [vsn, app_vsn], Info),
- [Ver, Time] = get_values(compile, [version, time], Info),
- [Vsn, AppVsn, Ver, Time]
- catch
- _:_ ->
- []
- end.
-
-get_values(Attr, Keys, Info) ->
- As = proplists:get_value(Attr, Info),
- [proplists:get_value(K, As, "?") || K <- Keys].
-
-sys_info() ->
- [A,V] = [chomp(erlang:system_info(K)) || K <- [system_architecture,
- system_version]],
- {A,V}.
-
-os_info() ->
- {os:version(), os:type()}.
-
-chomp(S) ->
- string:strip(S, right, $\n).
-
-print_sys_info({Arch, Ver}) ->
- io:format("System info:~n"
- " architecture : ~s~n"
- " version : ~s~n",
- [Arch, Ver]).
-
-print_os_info({Vsn, {Fam, Name}}) ->
- io:format("OS info:~n"
- " family : ~s ~s~n"
- " version : ~s~n",
- [str(Fam), bkt(str(Name)), vsn(Vsn)]).
-
-print_mod_info(Mods) ->
- io:format("Module info:~n", []),
- lists:foreach(fun print_mod/1, Mods).
-
-print_mod({Mod, []}) ->
- io:format(" ~w:~n", [Mod]);
-print_mod({Mod, [Vsn, AppVsn, Ver, {Year, Month, Day, Hour, Min, Sec}]}) ->
- Time = io_lib:format("~w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w",
- [Year, Month, Day, Hour, Min, Sec]),
- io:format(" ~w:~n"
- " vsn : ~s~n"
- " app_vsn : ~s~n"
- " compiled : ~s~n"
- " compiler : ~s~n",
- [Mod, str(Vsn), str(AppVsn), Time, Ver]).
-
-str(A)
- when is_atom(A) ->
- atom_to_list(A);
-str(S)
- when is_list(S) ->
- S;
-str(T) ->
- io_lib:format("~p", [T]).
-
-bkt("" = S) ->
- S;
-bkt(S) ->
- [$[, S, $]].
-
-vsn(T) when is_tuple(T) ->
- case [[$., integer_to_list(N)] || N <- tuple_to_list(T)] of
- [[$.,S] | Rest] ->
- [S | Rest];
- [] = S ->
- S
- end;
-vsn(T) ->
- str(T).
-
-%%% ----------------------------------------------------------
-%%% ----------------------------------------------------------
-
-%% p/1
-
-p(Info) ->
- W = 2 + widest([K || {K,_} <- Info]),
- lists:foreach(fun({K,V}) -> p(W,K,V) end, Info).
-
-p(Width, Key, Value) ->
- io:format(": ~*s: ~p~n", [-Width, Key, Value]).
-
-%% sep/[01]
-
-sep() ->
- sep($#).
-
-sep(true) ->
- sep();
-sep(false) ->
- ok;
-
-sep(Ch) ->
- io:format("~c~65c~n", [Ch, $-]).
-
-%% widest/1
-
-widest(List) ->
- lists:foldl(fun widest/2, 0, List).
-
-widest(T, Max)
- when is_atom(T) ->
- widest(atom_to_list(T), Max);
-
-widest(T, Max)
- when is_integer(T) ->
- widest(integer_to_list(T), Max);
-
-widest(T, Max)
- when is_list(T) -> %% string
- max(length(T), Max).
-
-pt(T) ->
- io:format(": ~p~n", [T]).
-
-recsplit(SFun, Rec) ->
- fun(Fs,Vs) -> SFun(element(1, Rec), Fs, Vs) end.
-
-max(A, B) ->
- if A > B -> A; true -> B end.
-
-keyfetch(Key, List) ->
- {Key,V} = lists:keyfind(Key, 1, List),
- V.
-
-%% ft/4
-
-ft(undefined = No, _, _, _) ->
- No;
-
-ft(_, Table, SFun, Fields) ->
- ets:foldl(fun(R,A) ->
- f(SFun, 0, Fields, R, A)
- end,
- 0,
- Table).
-
-%% f/5
-
-f(SFun, Width, Fields, Rec, Count) ->
- ff(SFun, Width, fields(Fields, Rec), Rec, Count).
-
-ff(SFun, Width, Fields, Rec, Count) ->
- sep(0 == Count),
- f(SFun, Width, Fields, Rec),
- sep(),
- Count+1.
-
-fields(N, _)
- when is_integer(N), N >= 0 ->
- lists:duplicate(N, ''); %% list values unadorned
-fields(Fields, R)
- when is_function(Fields, 1) ->
- fields(Fields(R), R);
-fields({Fields, Values} = T, _)
- when length(Fields) == length(Values) ->
- T;
-fields(Fields, _)
- when is_list(Fields) ->
- Fields. %% list field/value pairs, or tuples if []
-
-%% f/4
-
-%% Empty fields list: just print the entry.
-f(_, _, [], Rec)
- when is_tuple(Rec) ->
- pt(Rec);
-
-%% Otherwise list field names/values.
-f(SFun, Width, {Fields, Values}, _) ->
- f(SFun, Width, Fields, Values);
-
-f(SFun, Width, Fields, Rec)
- when is_tuple(Rec) ->
- f(SFun, Width, Fields, values(Fields, Rec));
-
-f(_, _, [], []) ->
- ok;
-
-f(SFun, Width, [HF | _] = Fields, Values) ->
- {F, FT, V, VT} = SFun(Fields, Values),
- if is_list(F) -> %% V is a record
- break($>, HF),
- f(SFun, Width, F, values(F,V)),
- break($<, HF),
- f(SFun, Width, FT, VT);
- F == '' -> %% no field name: just list value
- pt(V),
- f(SFun, Width, FT, VT);
- true -> %% list field/value.
- W = max(Width, 1 + widest(Fields)),
- p(W, F, V),
- f(SFun, W, FT, VT)
- end.
-
-values(Fields, Rec)
- when length(Fields) == size(Rec) - 1 ->
- ?VALUES(Rec);
-values(Fields, T)
- when length(Fields) == size(T) ->
- tuple_to_list(T).
-
-%% format_local/2
-
-format_local(Tables, SFun) ->
- lists:foldl(fun(T,A) -> fl(SFun, T, A) end, 0, Tables).
-
-fl(SFun, {Table, Recs, Fields}, Count) ->
- sep(),
- io:format("# ~p~n", [Table]),
- N = fmt(Recs, Fields, SFun),
- sep(0 == N),
- Count + N;
-
-fl(SFun, {Table, Fields}, Count) ->
- fl(SFun, {Table, Table, Fields}, Count).
-
-%% fmt/3
-
-fmt(T, Fields, SFun) ->
- case format(T, Fields, SFun) of
- undefined ->
- 0;
- N ->
- N
- end.
-
-%% break/2
-
-break(C, T) ->
- io:format("~c ~p~n", [C, T]).
-
-%% collect/2
-%%
-%% Output: {[{TableName, Recs}, ...], node()}
-
-collect(CFun, TableNames) ->
- {lists:foldl(fun(N,A) -> c(CFun, N, A) end, [], TableNames), node()}.
-
-c(CFun, TableName, Acc) ->
- case CFun(TableName) of
- Recs when is_list(Recs) ->
- [{TableName, Recs} | Acc];
- _ ->
- Acc
- end.
-
-%% format_remote/3
-
-format_remote(Tables, SFun, {Replies, BadNodes}) ->
- N = lists:foldl(fun(T,A) -> fr(Tables, SFun, T, A) end,
- 0,
- Replies),
- sep(0 == N andalso [] /= BadNodes),
- lists:foreach(fun(Node) -> io:format("# no reply from ~p~n", [Node]) end,
- BadNodes),
- sep([] /= BadNodes),
- N.
-
-fr(Tables, SFun, {List, Node}, Count)
- when is_list(List) -> %% guard against {badrpc, Reason}
- lists:foldl(fun({T,Recs}, C) -> fr(Tables, SFun, Node, T, Recs,C) end,
- Count,
- List);
-fr(_, _, _, Count) ->
- Count.
-
-fr(Tables, SFun, Node, Table, Recs, Count) ->
- Fields = keyfetch(Table, Tables),
- sep(),
- io:format("# ~p@~p~n", [Table, Node]),
- N = format(Recs, Fields, tblsplit(SFun, Table)),
- sep(0 == N),
- Count + N.
-
-tblsplit(SFun, Table)
- when is_function(SFun, 3) ->
- fun(Fs,Vs) -> SFun(Table, Fs, Vs) end;
-tblsplit(SFun, _)
- when is_function(SFun, 2) ->
- SFun.
-
-%% compact/1
-%%
-%% Strip whitespace from both ends of a string.
-
-compact(Str) ->
- compact(Str, true).
-
-compact([Ch|Rest], B)
- when Ch == $\n;
- Ch == $ ;
- Ch == $\t;
- Ch == $\v;
- Ch == $\r ->
- compact(Rest, B);
-
-compact(Str, false) ->
- Str;
-
-compact(Str, true) ->
- lists:reverse(compact(lists:reverse(Str), false)).