ltlcross: Add a --color option.
* src/bin/ltlcross.cc: Add a --color option. * NEWS: Mention it.
This commit is contained in:
parent
35129e5a5a
commit
5b0bf8ef09
2 changed files with 88 additions and 19 deletions
3
NEWS
3
NEWS
|
|
@ -3,6 +3,9 @@ New in spot 1.1.4a (not relased)
|
||||||
* All the parsers implemented in Spot now use the same type
|
* All the parsers implemented in Spot now use the same type
|
||||||
to store locations.
|
to store locations.
|
||||||
|
|
||||||
|
* ltlcross has a new option --color to color its output. It is enabled
|
||||||
|
by default when the output is a terminal.
|
||||||
|
|
||||||
* Cleanup of exported symbols
|
* Cleanup of exported symbols
|
||||||
|
|
||||||
All symbols in the library now have hidden visibility on ELF systems.
|
All symbols in the library now have hidden visibility on ELF systems.
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "gethrxtime.h"
|
#include "gethrxtime.h"
|
||||||
|
#include "argmatch.h"
|
||||||
|
|
||||||
#include "common_setup.hh"
|
#include "common_setup.hh"
|
||||||
#include "common_cout.hh"
|
#include "common_cout.hh"
|
||||||
|
|
@ -85,6 +86,7 @@ Exit status:\n\
|
||||||
#define OPT_STOP_ERR 7
|
#define OPT_STOP_ERR 7
|
||||||
#define OPT_SEED 8
|
#define OPT_SEED 8
|
||||||
#define OPT_PRODUCTS 9
|
#define OPT_PRODUCTS 9
|
||||||
|
#define OPT_COLOR 10
|
||||||
|
|
||||||
static const argp_option options[] =
|
static const argp_option options[] =
|
||||||
{
|
{
|
||||||
|
|
@ -138,6 +140,10 @@ static const argp_option options[] =
|
||||||
"output statistics as CSV in FILENAME or on standard output", 0 },
|
"output statistics as CSV in FILENAME or on standard output", 0 },
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
{ 0, 0, 0, 0, "Miscellaneous options:", -1 },
|
{ 0, 0, 0, 0, "Miscellaneous options:", -1 },
|
||||||
|
{ "color", OPT_COLOR, "WHEN", OPTION_ARG_OPTIONAL,
|
||||||
|
"colorize output; WHEN can be 'never', 'always' (the default if "
|
||||||
|
"--color is used without argument), or "
|
||||||
|
"'auto' (the default if --color is not used)", 0 },
|
||||||
{ 0, 0, 0, 0, 0, 0 }
|
{ 0, 0, 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -148,6 +154,28 @@ const struct argp_child children[] =
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum color_type { color_never, color_always, color_if_tty };
|
||||||
|
|
||||||
|
static char const *const color_args[] =
|
||||||
|
{
|
||||||
|
"always", "yes", "force",
|
||||||
|
"never", "no", "none",
|
||||||
|
"auto", "tty", "if-tty", 0
|
||||||
|
};
|
||||||
|
static color_type const color_types[] =
|
||||||
|
{
|
||||||
|
color_always, color_always, color_always,
|
||||||
|
color_never, color_never, color_never,
|
||||||
|
color_if_tty, color_if_tty, color_if_tty
|
||||||
|
};
|
||||||
|
ARGMATCH_VERIFY(color_args, color_types);
|
||||||
|
|
||||||
|
color_type color_opt = color_if_tty;
|
||||||
|
const char* bright_red = "\033[01;31m";
|
||||||
|
const char* bright_white = "\033[01;37m";
|
||||||
|
const char* reset_color = "\033[m";
|
||||||
|
|
||||||
unsigned states = 200;
|
unsigned states = 200;
|
||||||
float density = 0.1;
|
float density = 0.1;
|
||||||
unsigned timeout = 0;
|
unsigned timeout = 0;
|
||||||
|
|
@ -167,9 +195,19 @@ static std::ostream&
|
||||||
global_error()
|
global_error()
|
||||||
{
|
{
|
||||||
global_error_flag = true;
|
global_error_flag = true;
|
||||||
|
if (color_opt)
|
||||||
|
std::cerr << bright_red;
|
||||||
return std::cerr;
|
return std::cerr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
end_error()
|
||||||
|
{
|
||||||
|
if (color_opt)
|
||||||
|
std::cerr << reset_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct statistics
|
struct statistics
|
||||||
{
|
{
|
||||||
statistics()
|
statistics()
|
||||||
|
|
@ -334,6 +372,14 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
<< "on your platform" << std::endl;
|
<< "on your platform" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
case OPT_COLOR:
|
||||||
|
{
|
||||||
|
if (arg)
|
||||||
|
color_opt = XARGMATCH("--color", arg, color_args, color_types);
|
||||||
|
else
|
||||||
|
color_opt = color_always;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case OPT_CSV:
|
case OPT_CSV:
|
||||||
want_stats = true;
|
want_stats = true;
|
||||||
csv_output = arg ? arg : "-";
|
csv_output = arg ? arg : "-";
|
||||||
|
|
@ -658,11 +704,13 @@ namespace
|
||||||
{
|
{
|
||||||
global_error() << "error: execution terminated by signal "
|
global_error() << "error: execution terminated by signal "
|
||||||
<< WTERMSIG(es) << ".\n";
|
<< WTERMSIG(es) << ".\n";
|
||||||
|
end_error();
|
||||||
}
|
}
|
||||||
else if (WIFEXITED(es) && WEXITSTATUS(es) != 0)
|
else if (WIFEXITED(es) && WEXITSTATUS(es) != 0)
|
||||||
{
|
{
|
||||||
global_error() << "error: execution returned exit code "
|
global_error() << "error: execution returned exit code "
|
||||||
<< WEXITSTATUS(es) << ".\n";
|
<< WEXITSTATUS(es) << ".\n";
|
||||||
|
end_error();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -677,6 +725,7 @@ namespace
|
||||||
std::ostream& err = global_error();
|
std::ostream& err = global_error();
|
||||||
err << "error: failed to parse the produced neverclaim.\n";
|
err << "error: failed to parse the produced neverclaim.\n";
|
||||||
spot::format_neverclaim_parse_errors(err, output, pel);
|
spot::format_neverclaim_parse_errors(err, output, pel);
|
||||||
|
end_error();
|
||||||
delete res;
|
delete res;
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -690,15 +739,18 @@ namespace
|
||||||
{
|
{
|
||||||
global_error() << "Cannot open " << output.val()
|
global_error() << "Cannot open " << output.val()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
global_error_flag = true;
|
end_error();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = spot::lbtt_parse(f, error, &dict);
|
res = spot::lbtt_parse(f, error, &dict);
|
||||||
if (!res)
|
if (!res)
|
||||||
|
{
|
||||||
global_error() << ("error: failed to parse output in "
|
global_error() << ("error: failed to parse output in "
|
||||||
"LBTT format: ")
|
"LBTT format: ")
|
||||||
<< error << std::endl;
|
<< error << std::endl;
|
||||||
|
end_error();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -808,6 +860,7 @@ namespace
|
||||||
err << "state-space #" << p << "/" << products << "\n";
|
err << "state-space #" << p << "/" << products << "\n";
|
||||||
else
|
else
|
||||||
err << "the state-space\n";
|
err << "the state-space\n";
|
||||||
|
end_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -905,7 +958,11 @@ namespace
|
||||||
std::cerr << linenum << ":";
|
std::cerr << linenum << ":";
|
||||||
if (filename || linenum)
|
if (filename || linenum)
|
||||||
std::cerr << " ";
|
std::cerr << " ";
|
||||||
|
if (color_opt)
|
||||||
|
std::cerr << bright_white;
|
||||||
std::cerr << fstr << "\n";
|
std::cerr << fstr << "\n";
|
||||||
|
if (color_opt)
|
||||||
|
std::cerr << reset_color;
|
||||||
|
|
||||||
// Make sure we do not translate the same formula twice.
|
// Make sure we do not translate the same formula twice.
|
||||||
if (!allow_dups)
|
if (!allow_dups)
|
||||||
|
|
@ -987,8 +1044,11 @@ namespace
|
||||||
spot::tgba_product* prod =
|
spot::tgba_product* prod =
|
||||||
new spot::tgba_product(pos[i], neg[j]);
|
new spot::tgba_product(pos[i], neg[j]);
|
||||||
if (!is_empty(prod))
|
if (!is_empty(prod))
|
||||||
|
{
|
||||||
global_error() << "error: P" << i << "*N" << j
|
global_error() << "error: P" << i << "*N" << j
|
||||||
<< " is nonempty\n";
|
<< " is nonempty\n";
|
||||||
|
end_error();
|
||||||
|
}
|
||||||
delete prod;
|
delete prod;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1065,13 +1125,15 @@ namespace
|
||||||
if (pos_map[i] && neg_map[i] &&
|
if (pos_map[i] && neg_map[i] &&
|
||||||
!(consistency_check(pos_map[i], neg_map[i], statespace)))
|
!(consistency_check(pos_map[i], neg_map[i], statespace)))
|
||||||
{
|
{
|
||||||
global_error() << "error: inconsistency between P" << i
|
std::ostream& err = global_error();
|
||||||
|
err << "error: inconsistency between P" << i
|
||||||
<< " and N" << i;
|
<< " and N" << i;
|
||||||
if (products > 1)
|
if (products > 1)
|
||||||
global_error() << " for state-space #" << p
|
err << " for state-space #" << p
|
||||||
<< "/" << products << "\n";
|
<< "/" << products << "\n";
|
||||||
else
|
else
|
||||||
global_error() << "\n";
|
err << "\n";
|
||||||
|
end_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1230,6 +1292,9 @@ main(int argc, char** argv)
|
||||||
error(2, 0, "No translator to run? Run '%s --help' for usage.",
|
error(2, 0, "No translator to run? Run '%s --help' for usage.",
|
||||||
program_name);
|
program_name);
|
||||||
|
|
||||||
|
if (color_opt == color_if_tty)
|
||||||
|
color_opt = isatty(STDERR_FILENO) ? color_always : color_never;
|
||||||
|
|
||||||
setup_sig_handler();
|
setup_sig_handler();
|
||||||
|
|
||||||
processor p;
|
processor p;
|
||||||
|
|
@ -1244,16 +1309,17 @@ main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (global_error_flag)
|
if (global_error_flag)
|
||||||
{
|
{
|
||||||
std::cerr
|
std::ostream& err = global_error();
|
||||||
<< ("error: some error was detected during the above runs,\n"
|
err << ("error: some error was detected during the above runs,\n"
|
||||||
" please search for 'error:' messages in the above "
|
" please search for 'error:' messages in the above "
|
||||||
"trace.")
|
"trace.")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
if (timeout_count == 1)
|
if (timeout_count == 1)
|
||||||
std::cerr << "Additionally, 1 timeout occurred." << std::endl;
|
err << "Additionally, 1 timeout occurred." << std::endl;
|
||||||
else if (timeout_count > 1)
|
else if (timeout_count > 1)
|
||||||
std::cerr << "Additionally, "
|
err << "Additionally, "
|
||||||
<< timeout_count << " timeouts occurred." << std::endl;
|
<< timeout_count << " timeouts occurred." << std::endl;
|
||||||
|
end_error();
|
||||||
}
|
}
|
||||||
else if (timeout_count == 0)
|
else if (timeout_count == 0)
|
||||||
std::cerr << "No problem detected." << std::endl;
|
std::cerr << "No problem detected." << std::endl;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue