Some enhancements in the command line parser

* Cancel exceptions are handled properly and -h does
  no longer produce an error
* Help text is more readable now
* Some typos fixed
This commit is contained in:
Matthias Koefferlein 2017-08-21 00:20:18 +02:00
parent f013f1541e
commit 9585922659
3 changed files with 24 additions and 29 deletions

View File

@ -53,7 +53,7 @@ int _main_impl (int (*delegate) (int, char *[]), int argc, char *argv[])
init ();
return (*delegate) (argc, argv);
} catch (tl::CancelException & /*ex*/) {
return 1;
return 0;
} catch (std::exception &ex) {
tl::error << ex.what ();
return 1;

View File

@ -62,23 +62,24 @@ BD_PUBLIC int strmxor (int argc, char *argv[])
"This argument is optional. If not given, the exit status alone will indicate whether the layouts "
"are identical or not."
)
<< tl::arg ("-ta|--top-a=name", &top_a, "Specifies the cell to take as top cell from the first layout",
<< tl::arg ("-ta|--top-a=name", &top_a, "Specifies the top cell for the first layout",
"Use this option to take a specific cell as the top cell from the first layout. All "
"cells not called directly or indirectly from this cell are ignored. If you use this option, "
"--top-b must be specified too and can be different from the first layout's top cell."
)
<< tl::arg ("-tb|--top-b=name", &top_b, "Specifies the cell to take as top cell from the second layout",
<< tl::arg ("-tb|--top-b=name", &top_b, "Specifies the top cell for the second layout",
"See --top-a for details."
)
<< tl::arg ("-s|--silent", &silent, "Silent mode",
"In silent mode, no summary is printed, but the exit code indicates whether "
"the layouts are the same (0) or differences exist (> 0)."
)
<< tl::arg ("-l|--layer-details", &dont_summarize_missing_layers, "Output details about differences for missing layers",
<< tl::arg ("-l|--layer-details", &dont_summarize_missing_layers, "Treats missing layers as empty",
"With this option, missing layers are treated as \"empty\" and the whole layer of the other "
"layout is output. Without this option, a message is printed for missing layers instead."
"layout is output. Without this option, a message is printed for missing layers instead and the "
"layer from the other layout is ignored."
)
<< tl::arg ("-t|--tolerance=values", &tolerances, "Specifies tolerances for the geometry compare",
<< tl::arg ("-t|--tolerances=values", &tolerances, "Specifies tolerances for the geometry compare",
"This option can take multiple tolerance values. The values are given in micrometer units and "
"are separated by a comma. If a tolerance is given, XOR differences are "
"only reported when they are larger than the tolerance value. Tolerance values must be given in "

View File

@ -111,6 +111,12 @@ ArgBase::option_desc () const
}
res += "--" + m_option.long_option;
}
if (! m_option.name.empty ()) {
if (! res.empty ()) {
res += "=";
}
res += m_option.name;
}
return res;
}
@ -352,7 +358,7 @@ struct NameCompare
void
CommandLineOptions::produce_help (const std::string &program_name, bool advanced)
{
int columns = 80;
int columns = 70;
tl::info << "Usage:" << tl::endl;
tl::info << " " << program_name << " [options]" << tl::noendl;
@ -374,14 +380,9 @@ CommandLineOptions::produce_help (const std::string &program_name, bool advanced
print_string_formatted (" ", columns, m_brief);
tl::info << tl::endl;
unsigned int short_option_width = 0;
unsigned int long_option_width = 0;
unsigned int name_width = 0;
unsigned int arg_width = 0;
for (std::vector<ArgBase *>::const_iterator a = sorted_args.begin (); a != sorted_args.end (); ++a) {
name_width = std::max (name_width, (unsigned int) (*a)->option ().name.size ());
short_option_width = std::max (short_option_width, (unsigned int) (*a)->option ().short_option.size ());
long_option_width = std::max (long_option_width, (unsigned int) (*a)->option ().long_option.size ());
arg_width = std::max (arg_width, (unsigned int) (*a)->option_desc ().size ());
}
tl::info << "Arguments:" << tl::endl;
@ -390,15 +391,15 @@ CommandLineOptions::produce_help (const std::string &program_name, bool advanced
if ((*a)->is_option ()) {
continue;
}
std::string n = "<" + (*a)->option ().name + ">";
std::string n = "<" + (*a)->option_desc () + ">";
if ((*a)->option ().optional) {
n += " (optional)";
}
tl::info << " " << pad_string (name_width + 13, n) << (*a)->brief_doc ();
tl::info << " " << pad_string (arg_width + 4, n) << (*a)->brief_doc ();
tl::info << "";
if (! (*a)->long_doc ().empty ()) {
print_string_formatted (" ", columns, (*a)->long_doc ());
print_string_formatted (" ", columns, (*a)->long_doc ());
tl::info << "";
}
}
@ -413,12 +414,6 @@ CommandLineOptions::produce_help (const std::string &program_name, bool advanced
tl::info << tl::endl << " List of options:" << tl::endl;
std::string header = pad_string (short_option_width + 5, "Short") + " "
+ pad_string (long_option_width + 5, "Long") + " "
+ pad_string (name_width + 3, "Value") + " " + "Description";
tl::info << " " << header << tl::endl;
std::string prev_group;
bool hidden = false;
@ -436,7 +431,6 @@ CommandLineOptions::produce_help (const std::string &program_name, bool advanced
if ((*a)->option ().group != prev_group) {
prev_group = (*a)->option ().group;
tl::info << tl::endl << " " << prev_group << ":" << tl::endl;
tl::info << " " << header << tl::endl;
}
std::string name;
@ -448,14 +442,12 @@ CommandLineOptions::produce_help (const std::string &program_name, bool advanced
}
tl::info << " "
<< pad_string (short_option_width + 5, (*a)->option ().short_option.empty () ? "" : "-" + (*a)->option ().short_option) << " "
<< pad_string (long_option_width + 5, (*a)->option ().long_option.empty () ? "" : "--" + (*a)->option ().long_option) << " "
<< pad_string (name_width + 3, name) << " "
<< pad_string (arg_width + 4, (*a)->option_desc ())
<< (*a)->brief_doc ();
tl::info << "";
if (! (*a)->long_doc ().empty ()) {
print_string_formatted (" ", columns, (*a)->long_doc ());
print_string_formatted (" ", columns, (*a)->long_doc ());
tl::info << "";
}
@ -584,9 +576,11 @@ CommandLineOptions::parse (int argc, char *argv[])
// Execute the action if there is one
arg->action (this);
} catch (tl::CancelException &) {
throw;
} catch (tl::Exception &ex) {
std::string msg = "Parser error ";
std::string msg = "Error ";
if (i == argc) {
msg += "at end of argument list";
} else {