<commit_before>%% -*- erlang-indent-level: 2 -*-

-module(concuerror_options).

-export([parse_cl/1, finalize/1]).

-export_type([options/0]).

%%%-----------------------------------------------------------------------------

-include("concuerror.hrl").

-type options() :: proplists:proplist().

%%%-----------------------------------------------------------------------------

-define(MINIMUM_TIMEOUT, 1000).
-define(DEFAULT_VERBOSITY, ?linfo).
-define(DEFAULT_PRINT_DEPTH, 20).

%%%-----------------------------------------------------------------------------

-spec parse_cl([string()]) ->
                  {'ok', options()} | {'exit', concuerror:exit_status()}.

parse_cl(CommandLineArgs) ->
  try
    parse_cl_aux(CommandLineArgs)
  catch
    throw:opt_error -> {exit, fail}
  end.

parse_cl_aux([]) ->
  {ok, [help]};
parse_cl_aux(CommandLineArgs) ->
  case getopt:parse(getopt_spec(), CommandLineArgs) of
    {ok, {Options, OtherArgs}} ->
      case OtherArgs =:= [] of
        true -> ok;
        false ->
          Msg = "Unknown argument(s)/option(s): ~s",
          opt_error(Msg, [string:join(OtherArgs, " ")])
      end,
      {ok, Options};
    {error, Error} ->
      case Error of
        {missing_option_arg, help} ->
          cl_usage(basic),
          {exit, ok};
        {missing_option_arg, Option} ->
          opt_error("no argument given for '--~s'", [Option]);
        _Other ->
          opt_error(getopt:format_error([], Error))
      end
  end.

%%%-----------------------------------------------------------------------------

getopt_spec() ->
  getopt_spec(options()).

getopt_spec(Options) ->
  %% Option's long name is the same as the inner representation atom for
  %% consistency.
  [case Option of
     {Key, _Keywords, Short, Type, Help} ->
       {Key, Short, atom_to_list(Key), Type, Help};
     {Key, _Keywords, Short, Type, Help, _Long} ->
       {Key, Short, atom_to_list(Key), Type, Help}
   end || Option <- Options].

-define(OPTION_KEY, 1).
-define(OPTION_KEYWORDS, 2).
-define(OPTION_SHORT, 3).
-define(OPTION_GETOPT_DEFAULT, 4).
-define(OPTION_GETOPT_SHORT_HELP, 5).
-define(OPTION_GETOPT_LONG_HELP, 6).

-define(DEFAULT_OUTPUT, "concuerror_report.txt").

options(Keyword) ->
  [T || T <- options(), lists:member(Keyword, element(?OPTION_KEYWORDS, T))].

options() ->
  [{module, [basic, input], $m, atom,
    "Module containing the test function",
    "Concuerror begins exploration from a test function located in the module"
    " specified by this option."}
  ,{test, [basic, input], $t, {atom, test},
    "Test function",
    "This must be a 0-arity function located in the module specified by '-m'."
    " Concuerror will start the test by spawning a process that calls this"
    " function."}
  ,{output, [basic, output], $o, {string, ?DEFAULT_OUTPUT},
    "Output file",
    "This is where Concuerror writes the results of the analysis."}
  ,{quiet, [basic, console], $q, undefined,
    "Do not write anything to stderr",
    "Shorthand for '--verbosity 0'."}
  ,{verbosity, [basic, console, advanced], $v, integer,
    io_lib:format("Sets the verbosity level (0-~w). [default: ~w]",
                  [?MAX_VERBOSITY, ?DEFAULT_VERBOSITY]),
    "Verbosity decides what is shown on stderr. Messages up to info are"
    " always also shown in the output file. The available levels are the"
    " following:~n~n"
    "0 <quiet> Nothing is printed (equivalent to -q)~n"
    "1 <error> Critical, resulting in early termination~n"
    "2 <warn>  Non-critical, notifying about weak support for a feature or~n"
    "           the use of an option that alters the output~n"
    "3 <tip>   Notifying of a suggested refactoring or option to make~n"
    "           testing more efficient~n"
    "4 <info>  Normal operation messages, can be ignored~n"
    "5 <time>  Timing messages~n"
    "6 <debug> Used only during debugging~n"
    "7 <trace> Everything else"
   }
  ,{graph, [output, visual], undefined, string,
    "Produce a DOT graph in the specified file",
    "The DOT graph can be converted to an image with 'dot -Tsvg -o graph.svg"
    " <graph>"}
  ,{symbolic_names, [output, visual, erlang], $s, {boolean, true},<commit_msg>Use long version of options in help texts<commit_after>%% -*- erlang-indent-level: 2 -*-

-module(concuerror_options).

-export([parse_cl/1, finalize/1]).

-export_type([options/0]).

%%%-----------------------------------------------------------------------------

-include("concuerror.hrl").

-type options() :: proplists:proplist().

%%%-----------------------------------------------------------------------------

-define(MINIMUM_TIMEOUT, 1000).
-define(DEFAULT_VERBOSITY, ?linfo).
-define(DEFAULT_PRINT_DEPTH, 20).

%%%-----------------------------------------------------------------------------

-spec parse_cl([string()]) ->
                  {'ok', options()} | {'exit', concuerror:exit_status()}.

parse_cl(CommandLineArgs) ->
  try
    parse_cl_aux(CommandLineArgs)
  catch
    throw:opt_error -> {exit, fail}
  end.

parse_cl_aux([]) ->
  {ok, [help]};
parse_cl_aux(CommandLineArgs) ->
  case getopt:parse(getopt_spec(), CommandLineArgs) of
    {ok, {Options, OtherArgs}} ->
      case OtherArgs =:= [] of
        true -> ok;
        false ->
          Msg = "Unknown argument(s)/option(s): ~s",
          opt_error(Msg, [string:join(OtherArgs, " ")])
      end,
      {ok, Options};
    {error, Error} ->
      case Error of
        {missing_option_arg, help} ->
          cl_usage(basic),
          {exit, ok};
        {missing_option_arg, Option} ->
          opt_error("no argument given for '--~s'", [Option]);
        _Other ->
          opt_error(getopt:format_error([], Error))
      end
  end.

%%%-----------------------------------------------------------------------------

getopt_spec() ->
  getopt_spec(options()).

getopt_spec(Options) ->
  %% Option's long name is the same as the inner representation atom for
  %% consistency.
  [case Option of
     {Key, _Keywords, Short, Type, Help} ->
       {Key, Short, atom_to_list(Key), Type, Help};
     {Key, _Keywords, Short, Type, Help, _Long} ->
       {Key, Short, atom_to_list(Key), Type, Help}
   end || Option <- Options].

-define(OPTION_KEY, 1).
-define(OPTION_KEYWORDS, 2).
-define(OPTION_SHORT, 3).
-define(OPTION_GETOPT_DEFAULT, 4).
-define(OPTION_GETOPT_SHORT_HELP, 5).
-define(OPTION_GETOPT_LONG_HELP, 6).

-define(DEFAULT_OUTPUT, "concuerror_report.txt").

options(Keyword) ->
  [T || T <- options(), lists:member(Keyword, element(?OPTION_KEYWORDS, T))].

options() ->
  [{module, [basic, input], $m, atom,
    "Module containing the test function",
    "Concuerror begins exploration from a test function located in the module"
    " specified by this option."}
  ,{test, [basic, input], $t, {atom, test},
    "Test function",
    "This must be a 0-arity function located in the module specified by"
    " '--module'. Concuerror will start the test by spawning a process that"
    " calls this function."}
  ,{output, [basic, output], $o, {string, ?DEFAULT_OUTPUT},
    "Output file",
    "This is where Concuerror writes the results of the analysis."}
  ,{quiet, [basic, console], $q, undefined,
    "Do not write anything to stderr",
    "Shorthand for '--verbosity 0'."}
  ,{verbosity, [basic, console, advanced], $v, integer,
    io_lib:format("Sets the verbosity level (0-~w). [default: ~w]",
                  [?MAX_VERBOSITY, ?DEFAULT_VERBOSITY]),
    "Verbosity decides what is shown on stderr. Messages up to info are"
    " always also shown in the output file. The available levels are the"
    " following:~n~n"
    "0 <quiet> Nothing is printed (equivalent to '--quiet')~n"
    "1 <error> Critical, resulting in early termination~n"
    "2 <warn>  Non-critical, notifying about weak support for a feature or~n"
    "           the use of an option that alters the output~n"
    "3 <tip>   Notifying of a suggested refactoring or option to make~n"
    "           testing more efficient~n"
    "4 <info>  Normal operation messages, can be ignored~n"
    "5 <time>  Timing messages~n"
    "6 <debug> Used only during debugging~n"
    "7 <trace> Everything else"
   }
  ,{graph, [output, visual], undefined, string,
    "Produce a DOT graph in the specified file",
    "The DOT graph can be converted to an image with 'dot -Tsvg -o graph.svg"
    " <graph>"}
  ,{symbolic_names, [output, visual, erlang], $s, {boolean, true},
{'fraction_non_alphanumeric': 0.21096444285884172, 'fraction_numerical': 0.006421691045308598, 'mean_word_length': 2.4048582995951415, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6244277', 'n_tokens_mistral': 2663, 'n_tokens_neox': 2587, 'n_words': 772}