File: dialyze.escript

package info (click to toggle)
wings3d 2.4.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 14,404 kB
  • sloc: erlang: 132,169; ansic: 3,779; lisp: 1,434; sh: 805; makefile: 794; cpp: 244; xml: 50
file content (112 lines) | stat: -rwxr-xr-x 3,718 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env escript
%% -*- erlang -*-

main(Args) ->
    argparse:run(Args, cli(), #{progname => "dialyze"}).

cli() ->
    #{
      arguments => [ #{name => verbose, long => "-verbose", short => $v, type => boolean} ],
      handler => fun(Args) -> dialyze(Args) end
     }.

dialyze(Opts) ->
    Verbose = maps:get(verbose, Opts, false),
    CacheDir = filename:basedir(user_cache, "erlang"),
    IpltFile = filename:join(CacheDir, "wings.dialyzer_iplt"),
    Verbose andalso io:format("Using cache at: ~p~n", [IpltFile]),
    os:putenv("DIALYZER_IPLT", IpltFile),
    Analyze = [core, plugins, tools],
    Dirs = lists:flatmap(
             fun(core) ->
                     [filename:join(wings_dir(), "ebin")];
                (plugins) ->
                     get_plugin_dirs();
                (tools) ->
                     [filename:join(wings_dir(), "intl_tools")]
             end, Analyze),

    CL = filename:join([wings_dir(),"_deps", "cl", "ebin"]),

    Verbose andalso io:format("Analyzing files in: ~p~n", [Dirs]),
    Apps = [erts, kernel, stdlib, wx, xmerl, CL, tools],
    AppDirs = get_lib_dir(Apps),

    DOpts = [{files_rec,AppDirs ++ Dirs},
             {warning_files_rec, Dirs},
             {warnings, [no_improper_lists]},
             {analysis_type, incremental},
             {report_mode, if Verbose -> verbose; true -> normal end},
             {metrics_file, filename:join(CacheDir, "wings_dialyzer.metrics")}
            ],

    Res = dialyzer:run(DOpts),
    case dialyze_res(Res) of
        0 when Verbose -> io:format("No errors or warnings~n",[]);
        0 -> ok;
        N -> io:format("Found ~w errors or warnings~n", [N]),
             erlang:halt(1)
    end.

dialyze_res(Ws) ->
    File = dump_file(),
    file:write_file(File, term_to_binary(Ws)),
    diana().

diana() ->
    {ok,B} = file:read_file(dump_file()),
    case binary_to_term(B) of
	Ws when is_list(Ws) ->
	    diana_1(lists:keysort(2, Ws), 0)
    end.

diana_1([W|Ws], N) ->
    io:format("~s", [dialyzer:format_warning(W)]),
    diana_1(Ws, N+1);
diana_1([], N) -> N.

dump_file() ->
    filename:join(filename:basedir(user_cache, "erlang"), "wings_dialyzer_warnings.raw").

get_plugin_dirs() ->
    PluginDir = filename:join(wings_dir(), "plugins"),
    {ok, PluginDirs} = file:list_dir(PluginDir),
    lists:filtermap(fun(Dir0) ->
                            Dir = filename:join(PluginDir, Dir0),
                            Pattern = filename:join(Dir, "*.beam"),
                            filelib:is_dir(Dir) andalso
                                filelib:wildcard(Pattern) /= [] andalso
                                {true, Dir}
                    end, PluginDirs).

get_lib_dir(Apps) ->
    get_lib_dir(Apps, []).

get_lib_dir([H|T], Acc) ->
    NewElem =
        case code:lib_dir(H) of
            {error, bad_name} -> H;
            LibDir when H =:= erts -> % hack for including erts in an un-installed system
                EbinDir = filename:join([LibDir,"ebin"]),
                case file:read_file_info(EbinDir) of
                    {error,enoent} ->
                        filename:join([LibDir,"preloaded","ebin"]);
                    _ ->
                        EbinDir
                end;
            LibDir -> filename:join(LibDir,"ebin")
        end,
    get_lib_dir(T, [NewElem|Acc]);
get_lib_dir([], Acc) ->
    lists:reverse(Acc).

wings_dir() ->
    case code:lib_dir(wings) of
        {error, bad_name} ->
            WhoAmI = filename:absname(escript:script_name()),
            WingsTop = filename:dirname(filename:dirname(WhoAmI)),
            %% io:format("NAME: ~p => ~p~n", [WhoAmI, WingsTop]),
            WingsTop;
        Dir ->
            Dir
    end.