ltlcross, autcross: add --quiet/-q option
* bin/autcross.cc, bin/ltlcross.cc: Implement it. * doc/org/autcross.org, doc/org/ltlcross.org, NEWS: Document it. * doc/org/spot.css: Add colors for Makefile snippets. * tests/core/autcross4.test, tests/core/ltlcross3.test, tests/core/ltlcrossce.test: Add test cases.
This commit is contained in:
parent
6a71438268
commit
6f37ff8ed0
9 changed files with 275 additions and 58 deletions
|
|
@ -113,10 +113,12 @@ static const argp_option options[] =
|
|||
"all available optimizations (slow, default)", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Output options:", -15 },
|
||||
{ "quiet", 'q', nullptr, 0,
|
||||
"suppress all normal output in absence of errors", 0 },
|
||||
{ "save-bogus", OPT_BOGUS, "[>>]FILENAME", 0,
|
||||
"save formulas for which problems were detected in FILENAME", -1 },
|
||||
"save formulas for which problems were detected in FILENAME", 0 },
|
||||
{ "verbose", OPT_VERBOSE, nullptr, 0,
|
||||
"print what is being done, for debugging", -1 },
|
||||
"print what is being done, for debugging", 0 },
|
||||
{ nullptr, 0, nullptr, 0,
|
||||
"If an output FILENAME is prefixed with '>>', it is open "
|
||||
"in append mode instead of being truncated.", -14 },
|
||||
|
|
@ -135,6 +137,7 @@ const struct argp_child children[] =
|
|||
};
|
||||
|
||||
static bool verbose = false;
|
||||
static bool quiet = false;
|
||||
static bool ignore_exec_fail = false;
|
||||
static unsigned ignored_exec_fail = 0;
|
||||
static bool fail_on_timeout = false;
|
||||
|
|
@ -155,6 +158,10 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
case 'F':
|
||||
jobs.emplace_back(arg, true);
|
||||
break;
|
||||
case 'q':
|
||||
quiet = true;
|
||||
verbose = false;
|
||||
break;
|
||||
case OPT_BOGUS:
|
||||
{
|
||||
bogus_output = new output_file(arg);
|
||||
|
|
@ -196,6 +203,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
break;
|
||||
case OPT_VERBOSE:
|
||||
verbose = true;
|
||||
quiet = false;
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (arg[0] == '-' && !arg[1])
|
||||
|
|
@ -385,7 +393,12 @@ namespace
|
|||
format(command, tools[tool_num].cmd);
|
||||
|
||||
std::string cmd = command.str();
|
||||
std::cerr << "Running [" << l << tool_num << "]: " << cmd << '\n';
|
||||
auto disp_cmd = [&]() {
|
||||
std::cerr << "Running [" << l << tool_num
|
||||
<< "]: " << cmd << '\n';
|
||||
};
|
||||
if (!quiet)
|
||||
disp_cmd();
|
||||
spot::process_timer timer;
|
||||
timer.start();
|
||||
int es = exec_with_timeout(cmd.c_str());
|
||||
|
|
@ -397,12 +410,15 @@ namespace
|
|||
{
|
||||
if (fail_on_timeout)
|
||||
{
|
||||
if (quiet)
|
||||
disp_cmd();
|
||||
global_error() << "error: timeout during execution of command\n";
|
||||
end_error();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "warning: timeout during execution of command\n";
|
||||
if (!quiet)
|
||||
std::cerr << "warning: timeout during execution of command\n";
|
||||
++timeout_count;
|
||||
}
|
||||
status_str = "timeout";
|
||||
|
|
@ -411,6 +427,8 @@ namespace
|
|||
}
|
||||
else if (WIFSIGNALED(es))
|
||||
{
|
||||
if (quiet)
|
||||
disp_cmd();
|
||||
status_str = "signal";
|
||||
problem = true;
|
||||
es = WTERMSIG(es);
|
||||
|
|
@ -424,6 +442,8 @@ namespace
|
|||
status_str = "exit code";
|
||||
if (!ignore_exec_fail)
|
||||
{
|
||||
if (quiet)
|
||||
disp_cmd();
|
||||
problem = true;
|
||||
global_error() << "error: execution returned exit code "
|
||||
<< es << ".\n";
|
||||
|
|
@ -432,8 +452,9 @@ namespace
|
|||
else
|
||||
{
|
||||
problem = false;
|
||||
std::cerr << "warning: execution returned exit code "
|
||||
<< es << ".\n";
|
||||
if (!quiet)
|
||||
std::cerr << "warning: execution returned exit code "
|
||||
<< es << ".\n";
|
||||
++ignored_exec_fail;
|
||||
}
|
||||
}
|
||||
|
|
@ -448,6 +469,8 @@ namespace
|
|||
opt_parse);
|
||||
if (!aut->errors.empty())
|
||||
{
|
||||
if (quiet)
|
||||
disp_cmd();
|
||||
status_str = "parse error";
|
||||
problem = true;
|
||||
es = -1;
|
||||
|
|
@ -459,6 +482,8 @@ namespace
|
|||
}
|
||||
else if (aut->aborted)
|
||||
{
|
||||
if (quiet)
|
||||
disp_cmd();
|
||||
status_str = "aborted";
|
||||
problem = true;
|
||||
es = -1;
|
||||
|
|
@ -508,9 +533,10 @@ namespace
|
|||
if (aut_i->num_sets() + aut_j->num_sets() >
|
||||
spot::acc_cond::mark_t::max_accsets())
|
||||
{
|
||||
std::cerr << "info: building " << autname(i)
|
||||
<< '*' << autname(j, true)
|
||||
<< " requires more acceptance sets than supported\n";
|
||||
if (!quiet)
|
||||
std::cerr << "info: building " << autname(i)
|
||||
<< '*' << autname(j, true)
|
||||
<< " requires more acceptance sets than supported\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -573,14 +599,21 @@ namespace
|
|||
|
||||
input_statistics.push_back(in_statistics());
|
||||
|
||||
std::cerr << bold << source << reset_color;
|
||||
input_statistics[round_num].input_source = std::move(source);
|
||||
if (auto name = input->get_named_prop<std::string>("automaton-name"))
|
||||
{
|
||||
std::cerr << '\t' << *name;
|
||||
input_statistics[round_num].input_name = *name;
|
||||
}
|
||||
std::cerr << '\n';
|
||||
input_statistics[round_num].input_name = *name;
|
||||
|
||||
auto disp_src = [&]() {
|
||||
std::cerr << bold
|
||||
<< input_statistics[round_num].input_source
|
||||
<< reset_color;
|
||||
if (!input_statistics[round_num].input_name.empty())
|
||||
std::cerr << '\t'
|
||||
<< input_statistics[round_num].input_name;
|
||||
std::cerr << '\n';
|
||||
};
|
||||
if (!quiet)
|
||||
disp_src();
|
||||
input_statistics[round_num].input.set(input);
|
||||
|
||||
int problems = 0;
|
||||
|
|
@ -606,7 +639,6 @@ namespace
|
|||
problems += prob;
|
||||
}
|
||||
spot::cleanup_tmpfiles();
|
||||
++round_num;
|
||||
output_statistics.push_back(std::move(stats));
|
||||
|
||||
if (verbose)
|
||||
|
|
@ -622,7 +654,9 @@ namespace
|
|||
|
||||
if (!no_checks)
|
||||
{
|
||||
std::cerr << "Performing sanity checks and gathering statistics...\n";
|
||||
if (!quiet)
|
||||
std::cerr
|
||||
<< "Performing sanity checks and gathering statistics...\n";
|
||||
{
|
||||
bool print_first = true;
|
||||
for (unsigned i = 0; i < mi; ++i)
|
||||
|
|
@ -709,15 +743,23 @@ namespace
|
|||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Gathering statistics...\n";
|
||||
if (!quiet)
|
||||
std::cerr << "Gathering statistics...\n";
|
||||
}
|
||||
|
||||
|
||||
if (problems && bogus_output)
|
||||
print_hoa(bogus_output->ostream(), input) << std::endl;
|
||||
|
||||
std::cerr << '\n';
|
||||
if (problems && quiet)
|
||||
{
|
||||
std::cerr << "input automaton was ";
|
||||
disp_src();
|
||||
}
|
||||
if (!quiet || problems)
|
||||
std::cerr << '\n';
|
||||
|
||||
++round_num;
|
||||
// Shall we stop processing now?
|
||||
abort_run = global_error_flag && stop_on_error;
|
||||
return problems;
|
||||
|
|
@ -794,7 +836,7 @@ main(int argc, char** argv)
|
|||
{
|
||||
error(2, 0, "no automaton to translate");
|
||||
}
|
||||
else
|
||||
else if (!quiet)
|
||||
{
|
||||
if (global_error_flag)
|
||||
{
|
||||
|
|
|
|||
111
bin/ltlcross.cc
111
bin/ltlcross.cc
|
|
@ -176,6 +176,8 @@ static const argp_option options[] =
|
|||
{ "grind", OPT_GRIND, "[>>]FILENAME", 0,
|
||||
"for each formula for which a problem was detected, write a simpler " \
|
||||
"formula that fails on the same test in FILENAME", 0 },
|
||||
{ "quiet", 'q', nullptr, 0,
|
||||
"suppress all normal output in absence of error", 0 },
|
||||
{ "save-bogus", OPT_BOGUS, "[>>]FILENAME", 0,
|
||||
"save formulas for which problems were detected in FILENAME", 0 },
|
||||
{ "verbose", OPT_VERBOSE, nullptr, 0,
|
||||
|
|
@ -220,6 +222,7 @@ static const char* bogus_output_filename = nullptr;
|
|||
static output_file* bogus_output = nullptr;
|
||||
static output_file* grind_output = nullptr;
|
||||
static bool verbose = false;
|
||||
static bool quiet = false;
|
||||
static bool ignore_exec_fail = false;
|
||||
static unsigned ignored_exec_fail = 0;
|
||||
static bool fail_on_timeout = false;
|
||||
|
|
@ -452,6 +455,10 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
error(2, 0, "Options --determinize-max-edges and "
|
||||
"--determinize are incompatible.");
|
||||
break;
|
||||
case 'q':
|
||||
verbose = false;
|
||||
quiet = true;
|
||||
break;
|
||||
case OPT_DET_MAX_EDGES:
|
||||
max_det_edges_given = true;
|
||||
max_det_states = to_pos_int(arg, "--determinize-max-edges");
|
||||
|
|
@ -544,6 +551,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
break;
|
||||
case OPT_VERBOSE:
|
||||
verbose = true;
|
||||
quiet = false;
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
|
|
@ -571,7 +579,12 @@ namespace
|
|||
format(command, tools[translator_num].cmd);
|
||||
|
||||
std::string cmd = command.str();
|
||||
std::cerr << "Running [" << l << translator_num << "]: " << cmd << '\n';
|
||||
auto disp_cmd = [&]() {
|
||||
std::cerr << "Running [" << l << translator_num
|
||||
<< "]: " << cmd << '\n';
|
||||
};
|
||||
if (!quiet)
|
||||
disp_cmd();
|
||||
spot::process_timer timer;
|
||||
timer.start();
|
||||
int es = exec_with_timeout(cmd.c_str());
|
||||
|
|
@ -583,12 +596,15 @@ namespace
|
|||
{
|
||||
if (fail_on_timeout)
|
||||
{
|
||||
if (quiet)
|
||||
disp_cmd();
|
||||
global_error() << "error: timeout during execution of command\n";
|
||||
end_error();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "warning: timeout during execution of command\n";
|
||||
if (!quiet)
|
||||
std::cerr << "warning: timeout during execution of command\n";
|
||||
++timeout_count;
|
||||
}
|
||||
status_str = "timeout";
|
||||
|
|
@ -597,6 +613,8 @@ namespace
|
|||
}
|
||||
else if (WIFSIGNALED(es))
|
||||
{
|
||||
if (quiet)
|
||||
disp_cmd();
|
||||
status_str = "signal";
|
||||
problem = true;
|
||||
es = WTERMSIG(es);
|
||||
|
|
@ -610,6 +628,8 @@ namespace
|
|||
status_str = "exit code";
|
||||
if (!ignore_exec_fail)
|
||||
{
|
||||
if (quiet)
|
||||
disp_cmd();
|
||||
problem = true;
|
||||
global_error() << "error: execution returned exit code "
|
||||
<< es << ".\n";
|
||||
|
|
@ -618,8 +638,9 @@ namespace
|
|||
else
|
||||
{
|
||||
problem = false;
|
||||
std::cerr << "warning: execution returned exit code "
|
||||
<< es << ".\n";
|
||||
if (!quiet)
|
||||
std::cerr << "warning: execution returned exit code "
|
||||
<< es << ".\n";
|
||||
++ignored_exec_fail;
|
||||
}
|
||||
}
|
||||
|
|
@ -634,6 +655,8 @@ namespace
|
|||
opt_parse);
|
||||
if (!aut->errors.empty())
|
||||
{
|
||||
if (quiet)
|
||||
disp_cmd();
|
||||
status_str = "parse error";
|
||||
problem = true;
|
||||
es = -1;
|
||||
|
|
@ -645,6 +668,8 @@ namespace
|
|||
}
|
||||
else if (aut->aborted)
|
||||
{
|
||||
if (quiet)
|
||||
disp_cmd();
|
||||
status_str = "aborted";
|
||||
problem = true;
|
||||
es = -1;
|
||||
|
|
@ -735,16 +760,19 @@ namespace
|
|||
// complemented, or the --verbose option is used,
|
||||
if (!verbose && (icomp || jcomp))
|
||||
return false;
|
||||
std::cerr << "info: building ";
|
||||
if (icomp)
|
||||
std::cerr << "Comp(N" << i << ')';
|
||||
else
|
||||
std::cerr << 'P' << i;
|
||||
if (jcomp)
|
||||
std::cerr << "*Comp(P" << j << ')';
|
||||
else
|
||||
std::cerr << "*N" << j;
|
||||
std::cerr << " requires more acceptance sets than supported\n";
|
||||
if (!quiet)
|
||||
{
|
||||
std::cerr << "info: building ";
|
||||
if (icomp)
|
||||
std::cerr << "Comp(N" << i << ')';
|
||||
else
|
||||
std::cerr << 'P' << i;
|
||||
if (jcomp)
|
||||
std::cerr << "*Comp(P" << j << ')';
|
||||
else
|
||||
std::cerr << "*N" << j;
|
||||
std::cerr << " requires more acceptance sets than supported\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -931,16 +959,18 @@ namespace
|
|||
unsigned mutation_max;
|
||||
while (res)
|
||||
{
|
||||
std::cerr << "Trying to find a bogus mutation of " << bold
|
||||
<< bogus << reset_color << "...\n";
|
||||
if (!quiet)
|
||||
std::cerr << "Trying to find a bogus mutation of " << bold
|
||||
<< bogus << reset_color << "...\n";
|
||||
mutations = mutate(f);
|
||||
mutation_count = 1;
|
||||
mutation_max = mutations.size();
|
||||
res = 0;
|
||||
for (auto g: mutations)
|
||||
{
|
||||
std::cerr << "Mutation " << mutation_count << '/'
|
||||
<< mutation_max << ": ";
|
||||
if (!quiet)
|
||||
std::cerr << "Mutation " << mutation_count << '/'
|
||||
<< mutation_max << ": ";
|
||||
f = g;
|
||||
res = process_formula(g);
|
||||
if (res)
|
||||
|
|
@ -957,9 +987,10 @@ namespace
|
|||
bogus_output->ostream() << bogus << std::endl;
|
||||
}
|
||||
}
|
||||
std::cerr << "Smallest bogus mutation found for "
|
||||
<< bold << input << reset_color << " is "
|
||||
<< bold << bogus << reset_color << ".\n\n";
|
||||
if (!quiet)
|
||||
std::cerr << "Smallest bogus mutation found for "
|
||||
<< bold << input << reset_color << " is "
|
||||
<< bold << bogus << reset_color << ".\n\n";
|
||||
grind_output->ostream() << bogus << std::endl;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -1014,23 +1045,27 @@ namespace
|
|||
// Call formula() before printing anything else, in case it
|
||||
// complains.
|
||||
std::string fstr = runner.formula();
|
||||
if (filename)
|
||||
std::cerr << filename << ':';
|
||||
if (linenum)
|
||||
std::cerr << linenum << ':';
|
||||
if (filename || linenum)
|
||||
std::cerr << ' ';
|
||||
std::cerr << bold << fstr << reset_color << '\n';
|
||||
if (!quiet)
|
||||
{
|
||||
if (filename)
|
||||
std::cerr << filename << ':';
|
||||
if (linenum)
|
||||
std::cerr << linenum << ':';
|
||||
if (filename || linenum)
|
||||
std::cerr << ' ';
|
||||
std::cerr << bold << fstr << reset_color << '\n';
|
||||
}
|
||||
|
||||
// Make sure we do not translate the same formula twice.
|
||||
if (!allow_dups)
|
||||
{
|
||||
if (!unique_set.insert(f).second)
|
||||
{
|
||||
std::cerr
|
||||
<< ("warning: This formula or its negation has already"
|
||||
" been checked.\n Use --allow-dups if it "
|
||||
"should not be ignored.\n\n");
|
||||
if (!quiet)
|
||||
std::cerr
|
||||
<< ("warning: This formula or its negation has already"
|
||||
" been checked.\n Use --allow-dups if it "
|
||||
"should not be ignored.\n\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1134,7 +1169,9 @@ namespace
|
|||
|
||||
if (!no_checks)
|
||||
{
|
||||
std::cerr << "Performing sanity checks and gathering statistics...\n";
|
||||
if (!quiet)
|
||||
std::cerr
|
||||
<< "Performing sanity checks and gathering statistics...\n";
|
||||
|
||||
// If we have reference tools, pick the smallest of their
|
||||
// automata for positive and negative references.
|
||||
|
|
@ -1564,7 +1601,11 @@ namespace
|
|||
delete pos_map[i];
|
||||
++seed;
|
||||
}
|
||||
std::cerr << '\n';
|
||||
if (problems && quiet)
|
||||
std::cerr << "input formula was "
|
||||
<< bold << fstr << reset_color << "\n\n";
|
||||
if (!quiet)
|
||||
std::cerr << '\n';
|
||||
delete ap;
|
||||
|
||||
// Shall we stop processing formulas now?
|
||||
|
|
@ -1685,7 +1726,7 @@ main(int argc, char** argv)
|
|||
{
|
||||
error(2, 0, "no formula to translate");
|
||||
}
|
||||
else
|
||||
else if (!quiet)
|
||||
{
|
||||
if (global_error_flag)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue