From 9585922659a072fdd82d897e4b150ef0818259d3 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 21 Aug 2017 00:20:18 +0200 Subject: [PATCH] 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 --- src/buddies/src/bd/bdInit.cc | 2 +- src/buddies/src/bd/strmxor.cc | 11 +++++----- src/tl/tlCommandLineParser.cc | 40 +++++++++++++++-------------------- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/buddies/src/bd/bdInit.cc b/src/buddies/src/bd/bdInit.cc index 3f1486f7f..a2b660c3d 100644 --- a/src/buddies/src/bd/bdInit.cc +++ b/src/buddies/src/bd/bdInit.cc @@ -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; diff --git a/src/buddies/src/bd/strmxor.cc b/src/buddies/src/bd/strmxor.cc index 6a87e6cc4..43ad0185f 100644 --- a/src/buddies/src/bd/strmxor.cc +++ b/src/buddies/src/bd/strmxor.cc @@ -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 " diff --git a/src/tl/tlCommandLineParser.cc b/src/tl/tlCommandLineParser.cc index b92f68366..6bdc20f38 100644 --- a/src/tl/tlCommandLineParser.cc +++ b/src/tl/tlCommandLineParser.cc @@ -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::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 {