summaryrefslogtreecommitdiff
path: root/lib/dialyzer/src/dialyzer_cl_parse.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dialyzer/src/dialyzer_cl_parse.erl')
-rw-r--r--lib/dialyzer/src/dialyzer_cl_parse.erl153
1 files changed, 100 insertions, 53 deletions
diff --git a/lib/dialyzer/src/dialyzer_cl_parse.erl b/lib/dialyzer/src/dialyzer_cl_parse.erl
index 9a522e906a..f80eb81ac6 100644
--- a/lib/dialyzer/src/dialyzer_cl_parse.erl
+++ b/lib/dialyzer/src/dialyzer_cl_parse.erl
@@ -2,7 +2,7 @@
%%-----------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. 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
@@ -20,8 +20,8 @@
-module(dialyzer_cl_parse).
--export([start/0]).
--export([collect_args/1]). % used also by typer_options.erl
+-export([start/0, get_lib_dir/1]).
+-export([collect_args/1]). % used also by typer
-include("dialyzer.hrl").
@@ -30,9 +30,11 @@
-type dial_cl_parse_ret() :: {'check_init', #options{}}
| {'plt_info', #options{}}
| {'cl', #options{}}
- | {{'gui', 'gs' | 'wx'}, #options{}}
+ | {{'gui', 'gs' | 'wx'}, #options{}}
| {'error', string()}.
+-type deep_string() :: string() | [deep_string()].
+
%%-----------------------------------------------------------------------
-spec start() -> dial_cl_parse_ret().
@@ -53,7 +55,7 @@ cl(["--add_to_plt"|T]) ->
put(dialyzer_options_analysis_type, plt_add),
cl(T);
cl(["--apps"|T]) ->
- T1 = get_lib_dir(T, []),
+ T1 = get_lib_dir(T),
{Args, T2} = collect_args(T1),
append_var(dialyzer_options_files_rec, Args),
cl(T2);
@@ -80,7 +82,7 @@ cl(["--get_warnings"|T]) ->
put(dialyzer_options_get_warnings, true),
cl(T);
cl(["-D"|_]) ->
- error("No defines specified after -D");
+ cl_error("No defines specified after -D");
cl(["-D"++Define|T]) ->
Def = re:split(Define, "=", [{return, list}]),
append_defines(Def),
@@ -90,7 +92,7 @@ cl(["-h"|_]) ->
cl(["--help"|_]) ->
help_message();
cl(["-I"]) ->
- error("no include directory specified after -I");
+ cl_error("no include directory specified after -I");
cl(["-I", Dir|T]) ->
append_include(Dir),
cl(T);
@@ -111,14 +113,14 @@ cl(["--com"++_|T]) ->
NewTail = command_line(T),
cl(NewTail);
cl(["--output"]) ->
- error("No outfile specified");
+ cl_error("No outfile specified");
cl(["-o"]) ->
- error("No outfile specified");
+ cl_error("No outfile specified");
cl(["--output",Output|T]) ->
put(dialyzer_output, Output),
cl(T);
cl(["--output_plt"]) ->
- error("No outfile specified for --output_plt");
+ cl_error("No outfile specified for --output_plt");
cl(["--output_plt",Output|T]) ->
put(dialyzer_output_plt, Output),
cl(T);
@@ -131,16 +133,25 @@ cl(["-o"++Output|T]) ->
cl(["--raw"|T]) ->
put(dialyzer_output_format, raw),
cl(T);
+cl(["--fullpath"|T]) ->
+ put(dialyzer_filename_opt, fullpath),
+ cl(T);
cl(["-pa", Path|T]) ->
case code:add_patha(Path) of
true -> cl(T);
- {error, _} -> error("Bad directory for -pa: "++Path)
+ {error, _} -> cl_error("Bad directory for -pa: " ++ Path)
end;
-cl(["--plt", PLT|T]) ->
- put(dialyzer_init_plt, PLT),
- cl(T);
cl(["--plt"]) ->
error("No plt specified for --plt");
+cl(["--plt", PLT|T]) ->
+ put(dialyzer_init_plts, [PLT]),
+ cl(T);
+cl(["--plts"]) ->
+ error("No plts specified for --plts");
+cl(["--plts"|T]) ->
+ {PLTs, NewT} = get_plts(T, []),
+ put(dialyzer_init_plts, PLTs),
+ cl(NewT);
cl(["-q"|T]) ->
put(dialyzer_options_report_mode, quiet),
cl(T);
@@ -163,14 +174,14 @@ cl(["--verbose"|T]) ->
put(dialyzer_options_report_mode, verbose),
cl(T);
cl(["-W"|_]) ->
- error("-W given without warning");
+ cl_error("-W given without warning");
cl(["-Whelp"|_]) ->
help_warnings();
cl(["-W"++Warn|T]) ->
append_var(dialyzer_warnings, [list_to_atom(Warn)]),
cl(T);
cl(["--dump_callgraph"]) ->
- error("No outfile specified for --dump_callgraph");
+ cl_error("No outfile specified for --dump_callgraph");
cl(["--dump_callgraph", File|T]) ->
put(dialyzer_callgraph_file, File),
cl(T);
@@ -186,7 +197,7 @@ cl([H|_] = L) ->
NewTail = command_line(L),
cl(NewTail);
false ->
- error("Unknown option: " ++ H)
+ cl_error("Unknown option: " ++ H)
end;
cl([]) ->
{RetTag, Opts} =
@@ -205,7 +216,7 @@ cl([]) ->
end
end,
case dialyzer_options:build(Opts) of
- {error, Msg} -> error(Msg);
+ {error, Msg} -> cl_error(Msg);
OptsRecord -> {RetTag, OptsRecord}
end.
@@ -221,7 +232,9 @@ command_line(T0) ->
end,
T.
-error(Str) ->
+-spec cl_error(deep_string()) -> no_return().
+
+cl_error(Str) ->
Msg = lists:flatten(Str),
throw({dialyzer_cl_parse_error, Msg}).
@@ -235,6 +248,7 @@ init() ->
put(dialyzer_options_defines, DefaultOpts#options.defines),
put(dialyzer_options_files, DefaultOpts#options.files),
put(dialyzer_output_format, formatted),
+ put(dialyzer_filename_opt, basename),
put(dialyzer_options_check_plt, DefaultOpts#options.check_plt),
ok.
@@ -273,6 +287,7 @@ cl_options() ->
{files_rec, get(dialyzer_options_files_rec)},
{output_file, get(dialyzer_output)},
{output_format, get(dialyzer_output_format)},
+ {filename_opt, get(dialyzer_filename_opt)},
{analysis_type, get(dialyzer_options_analysis_type)},
{get_warnings, get(dialyzer_options_get_warnings)},
{callgraph_file, get(dialyzer_callgraph_file)}
@@ -282,7 +297,7 @@ common_options() ->
[{defines, get(dialyzer_options_defines)},
{from, get(dialyzer_options_from)},
{include_dirs, get(dialyzer_include)},
- {init_plt, get(dialyzer_init_plt)},
+ {plts, get(dialyzer_init_plts)},
{output_plt, get(dialyzer_output_plt)},
{report_mode, get(dialyzer_options_report_mode)},
{use_spec, get(dialyzer_options_use_contracts)},
@@ -291,6 +306,11 @@ common_options() ->
%%-----------------------------------------------------------------------
+-spec get_lib_dir([string()]) -> [string()].
+
+get_lib_dir(Apps) ->
+ get_lib_dir(Apps, []).
+
get_lib_dir([H|T], Acc) ->
NewElem =
case code:lib_dir(list_to_atom(H)) of
@@ -307,30 +327,42 @@ get_lib_dir([], Acc) ->
%%-----------------------------------------------------------------------
+get_plts(["--"|T], Acc) -> {lists:reverse(Acc), T};
+get_plts(["-"++_Opt = H|T], Acc) -> {lists:reverse(Acc), [H|T]};
+get_plts([H|T], Acc) -> get_plts(T, [H|Acc]);
+get_plts([], Acc) -> {lists:reverse(Acc), []}.
+
+%%-----------------------------------------------------------------------
+
+-spec help_warnings() -> no_return().
+
help_warnings() ->
S = warning_options_msg(),
io:put_chars(S),
erlang:halt(?RET_NOTHING_SUSPICIOUS).
+-spec help_message() -> no_return().
+
help_message() ->
S = "Usage: dialyzer [--help] [--version] [--shell] [--quiet] [--verbose]
- [-pa dir]* [--plt plt] [-Ddefine]* [-I include_dir]*
- [--output_plt file] [-Wwarn]* [--src] [--gui | --wx]
- [files_or_dirs] [-r dirs] [--apps applications] [-o outfile]
+ [-pa dir]* [--plt plt] [--plts plt*] [-Ddefine]*
+ [-I include_dir]* [--output_plt file] [-Wwarn]*
+ [--src] [--gui | --wx] [files_or_dirs] [-r dirs]
+ [--apps applications] [-o outfile]
[--build_plt] [--add_to_plt] [--remove_from_plt]
[--check_plt] [--no_check_plt] [--plt_info] [--get_warnings]
- [--no_native]
+ [--no_native] [--fullpath]
Options:
files_or_dirs (for backwards compatibility also as: -c files_or_dirs)
Use Dialyzer from the command line to detect defects in the
specified files or directories containing .erl or .beam files,
- depending on the type of the analysis
+ depending on the type of the analysis.
-r dirs
Same as the previous but the specified directories are searched
recursively for subdirectories containing .erl or .beam files in
- them, depending on the type of analysis
+ them, depending on the type of analysis.
--apps applications
- Option typically used when building or modifying a PLT as in:
+ Option typically used when building or modifying a plt as in:
dialyzer --build_plt --apps erts kernel stdlib mnesia ...
to conveniently refer to library applications corresponding to the
Erlang/OTP installation. However, the option is general and can also
@@ -339,75 +371,90 @@ Options:
dialyzer --apps inets ssl ./ebin ../other_lib/ebin/my_module.beam
-o outfile (or --output outfile)
When using Dialyzer from the command line, send the analysis
- results to the specified \"outfile\" rather than to stdout
+ results to the specified outfile rather than to stdout.
--raw
When using Dialyzer from the command line, output the raw analysis
results (Erlang terms) instead of the formatted result.
The raw format is easier to post-process (for instance, to filter
- warnings or to output HTML pages)
+ warnings or to output HTML pages).
--src
Override the default, which is to analyze BEAM files, and
- analyze starting from Erlang source code instead
+ analyze starting from Erlang source code instead.
-Dname (or -Dname=value)
- When analyzing from source, pass the define to Dialyzer (**)
+ When analyzing from source, pass the define to Dialyzer. (**)
-I include_dir
- When analyzing from source, pass the include_dir to Dialyzer (**)
+ When analyzing from source, pass the include_dir to Dialyzer. (**)
-pa dir
Include dir in the path for Erlang (useful when analyzing files
- that have '-include_lib()' directives)
+ that have '-include_lib()' directives).
--output_plt file
- Store the plt at the specified file after building it
+ Store the plt at the specified file after building it.
--plt plt
Use the specified plt as the initial plt (if the plt was built
- during setup the files will be checked for consistency)
+ during setup the files will be checked for consistency).
+ --plts plt*
+ Merge the specified plts to create the initial plt -- requires
+ that the plts are disjoint (i.e., do not have any module
+ appearing in more than one plt).
+ The plts are created in the usual way:
+ dialyzer --build_plt --output_plt plt_1 files_to_include
+ ...
+ dialyzer --build_plt --output_plt plt_n files_to_include
+ and then can be used in either of the following ways:
+ dialyzer files_to_analyze --plts plt_1 ... plt_n
+ or:
+ dialyzer --plts plt_1 ... plt_n -- files_to_analyze
+ (Note the -- delimiter in the second case)
-Wwarn
A family of options which selectively turn on/off warnings
- (for help on the names of warnings use dialyzer -Whelp)
+ (for help on the names of warnings use dialyzer -Whelp).
--shell
- Do not disable the Erlang shell while running the GUI
+ Do not disable the Erlang shell while running the GUI.
--version (or -v)
- Prints the Dialyzer version and some more information and exits
+ Print the Dialyzer version and some more information and exit.
--help (or -h)
- Prints this message and exits
+ Print this message and exit.
--quiet (or -q)
- Makes Dialyzer a bit more quiet
+ Make Dialyzer a bit more quiet.
--verbose
- Makes Dialyzer a bit more verbose
+ Make Dialyzer a bit more verbose.
--build_plt
The analysis starts from an empty plt and creates a new one from the
files specified with -c and -r. Only works for beam files.
- Use --plt or --output_plt to override the default plt location.
+ Use --plt(s) or --output_plt to override the default plt location.
--add_to_plt
The plt is extended to also include the files specified with -c and -r.
- Use --plt to specify wich plt to start from, and --output_plt to
- specify where to put the plt. Note that the analysis might include
- files from the plt if they depend on the new files.
+ Use --plt(s) to specify which plt to start from, and --output_plt to
+ specify where to put the plt. Note that the analysis might include
+ files from the plt if they depend on the new files.
This option only works with beam files.
--remove_from_plt
The information from the files specified with -c and -r is removed
from the plt. Note that this may cause a re-analysis of the remaining
dependent files.
--check_plt
- Checks the plt for consistency and rebuilds it if it is not up-to-date.
+ Check the plt for consistency and rebuild it if it is not up-to-date.
Actually, this option is of rare use as it is on by default.
--no_check_plt (or -n)
Skip the plt check when running Dialyzer. Useful when working with
installed plts that never change.
--plt_info
- Makes Dialyzer print information about the plt and then quit. The plt
- can be specified with --plt.
+ Make Dialyzer print information about the plt and then quit. The plt
+ can be specified with --plt(s).
--get_warnings
- Makes Dialyzer emit warnings even when manipulating the plt. Only
- emits warnings for files that are actually analyzed.
+ Make Dialyzer emit warnings even when manipulating the plt. Warnings
+ are only emitted for files that are actually analyzed.
--dump_callgraph file
Dump the call graph into the specified file whose format is determined
by the file name extension. Supported extensions are: raw, dot, and ps.
If something else is used as file name extension, default format '.raw'
will be used.
--no_native (or -nn)
- Bypass the native code compilation of some key files that dialyzer
+ Bypass the native code compilation of some key files that Dialyzer
heuristically performs when dialyzing many files; this avoids the
compilation time but it may result in (much) longer analysis time.
+ --fullpath
+ Display the full path names of files for which warnings are emitted.
--gui
Use the gs-based GUI.
--wx
@@ -455,13 +502,13 @@ warning_options_msg() ->
Include warnings about behaviour callbacks which drift from the published
recommended interfaces.
-Wunderspecs ***
- Warn about underspecified functions
+ Warn about underspecified functions
(those whose -spec is strictly more allowing than the success typing).
The following options are also available but their use is not recommended:
(they are mostly for Dialyzer developers and internal debugging)
-Woverspecs ***
- Warn about overspecified functions
+ Warn about overspecified functions
(those whose -spec is strictly less allowing than the success typing).
-Wspecdiffs ***
Warn when the -spec is different than the success typing.