mirror of https://github.com/KLayout/klayout.git
Equipped strmclip with the new command line parser
Plus: added repeated arguments (in addition to the array arguments that have been there before).
This commit is contained in:
parent
e54cadef99
commit
681c255e50
|
|
@ -229,20 +229,25 @@ void GenericReaderOptions::set_dbu (double dbu)
|
|||
}
|
||||
|
||||
void
|
||||
GenericReaderOptions::configure (db::LoadLayoutOptions &load_options)
|
||||
GenericReaderOptions::configure (db::LoadLayoutOptions &load_options) const
|
||||
{
|
||||
m_common_reader_options.layer_map = m_layer_map;
|
||||
m_common_reader_options.create_other_layers = m_create_other_layers;
|
||||
m_dxf_reader_options.layer_map = m_layer_map;
|
||||
m_dxf_reader_options.create_other_layers = m_create_other_layers;
|
||||
m_cif_reader_options.layer_map = m_layer_map;
|
||||
m_cif_reader_options.create_other_layers = m_create_other_layers;
|
||||
db::CommonReaderOptions common_reader_options = m_common_reader_options;
|
||||
common_reader_options.layer_map = m_layer_map;
|
||||
common_reader_options.create_other_layers = m_create_other_layers;
|
||||
|
||||
load_options.set_options (m_common_reader_options);
|
||||
db::DXFReaderOptions dxf_reader_options = m_dxf_reader_options;
|
||||
dxf_reader_options.layer_map = m_layer_map;
|
||||
dxf_reader_options.create_other_layers = m_create_other_layers;
|
||||
|
||||
db::CIFReaderOptions cif_reader_options = m_cif_reader_options;
|
||||
cif_reader_options.layer_map = m_layer_map;
|
||||
cif_reader_options.create_other_layers = m_create_other_layers;
|
||||
|
||||
load_options.set_options (common_reader_options);
|
||||
load_options.set_options (m_gds2_reader_options);
|
||||
load_options.set_options (m_oasis_reader_options);
|
||||
load_options.set_options (m_cif_reader_options);
|
||||
load_options.set_options (m_dxf_reader_options);
|
||||
load_options.set_options (cif_reader_options);
|
||||
load_options.set_options (dxf_reader_options);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ public:
|
|||
/**
|
||||
* @brief Configures the reader options object with the options stored in this object
|
||||
*/
|
||||
void configure (db::LoadLayoutOptions &load_options);
|
||||
void configure (db::LoadLayoutOptions &load_options) const;
|
||||
|
||||
/**
|
||||
* @brief Sets the option prefix for the short option name
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
|
|||
"given factor."
|
||||
);
|
||||
|
||||
if (format == gds2_format_name || format == gds2text_format_name || format == oasis_format_name) {
|
||||
if (format.empty () || format == gds2_format_name || format == gds2text_format_name || format == oasis_format_name) {
|
||||
cmd << tl::arg (group +
|
||||
"-od|--dbu-out=dbu", &m_dbu, "Uses the specified database unit",
|
||||
"Specifies the database unit to save the layout in. The database unit is given "
|
||||
|
|
@ -68,7 +68,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
|
|||
"If given, empty cells won't be written. See --keep-instances for more options."
|
||||
);
|
||||
|
||||
if (format == gds2_format_name || format == gds2text_format_name) {
|
||||
if (format.empty () || format == gds2_format_name || format == gds2text_format_name) {
|
||||
cmd << tl::arg (group +
|
||||
"#--keep-instances", &m_keep_instances, "Keeps instances of dropped cells",
|
||||
"If given, instances of dropped cell's won't be removed. Hence, ghost cells are "
|
||||
|
|
@ -79,7 +79,7 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
|
|||
);
|
||||
}
|
||||
|
||||
if (format == gds2_format_name || format == gds2text_format_name || format == oasis_format_name) {
|
||||
if (format.empty () || format == gds2_format_name || format == gds2text_format_name || format == oasis_format_name) {
|
||||
cmd << tl::arg (group +
|
||||
"#--write-context-info", &m_write_context_info, "Writes context information",
|
||||
"Include context information for PCell instances and other information in a format-specific "
|
||||
|
|
@ -289,7 +289,7 @@ static void get_selected_cells (tl::Extractor &ex, const db::Layout &layout, std
|
|||
}
|
||||
|
||||
void
|
||||
GenericWriterOptions::configure (db::SaveLayoutOptions &save_options, const db::Layout &layout)
|
||||
GenericWriterOptions::configure (db::SaveLayoutOptions &save_options, const db::Layout &layout) const
|
||||
{
|
||||
save_options.set_scale_factor (m_scale_factor);
|
||||
save_options.set_dbu (m_dbu);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ public:
|
|||
* The format string gives a hint about the target format. Certain options will be
|
||||
* suppressed if they are known to be unavailable for the given format.
|
||||
*/
|
||||
void add_options (tl::CommandLineOptions &cmd, const std::string &format);
|
||||
void add_options (tl::CommandLineOptions &cmd, const std::string &format = std::string ());
|
||||
|
||||
/**
|
||||
* @brief Adds the generic options to the command line parser object for the GDS2 format
|
||||
|
|
@ -100,7 +100,7 @@ public:
|
|||
* @brief Configures the writer options object with the options stored in this object
|
||||
* The layout is required in order to derive the cell and layer ID's.
|
||||
*/
|
||||
void configure (db::SaveLayoutOptions &save_options, const db::Layout &layout);
|
||||
void configure (db::SaveLayoutOptions &save_options, const db::Layout &layout) const;
|
||||
|
||||
private:
|
||||
double m_scale_factor;
|
||||
|
|
|
|||
|
|
@ -20,42 +20,62 @@
|
|||
|
||||
*/
|
||||
|
||||
#include "bdInit.h"
|
||||
#include "bdReaderOptions.h"
|
||||
#include "bdWriterOptions.h"
|
||||
#include "dbClip.h"
|
||||
#include "dbLayout.h"
|
||||
#include "dbGDS2Writer.h"
|
||||
#include "dbOASISWriter.h"
|
||||
#include "dbReader.h"
|
||||
#include "tlLog.h"
|
||||
#include "tlCommandLineParser.h"
|
||||
|
||||
|
||||
struct ClipData
|
||||
{
|
||||
ClipData ()
|
||||
: file_in (), file_out (), clip_layer (),
|
||||
oasis (false), gzip (false)
|
||||
: file_in (), file_out (), clip_layer ()
|
||||
{ }
|
||||
|
||||
bd::GenericReaderOptions reader_options;
|
||||
bd::GenericWriterOptions writer_options;
|
||||
std::string file_in;
|
||||
std::string file_out;
|
||||
db::LayerProperties clip_layer;
|
||||
bool oasis;
|
||||
bool gzip;
|
||||
std::vector <db::DBox> clip_boxes;
|
||||
std::string result;
|
||||
std::string top;
|
||||
|
||||
void add_box (const std::string &spec)
|
||||
{
|
||||
tl::Extractor ex (spec.c_str ());
|
||||
double l = 0.0, b = 0.0, r = 0.0, t = 0.0;
|
||||
ex >> l >> "," >> b >> "," >> r >> "," >> t >> tl::Extractor::end ();
|
||||
clip_boxes.push_back (db::DBox (l, b, r, t));
|
||||
}
|
||||
|
||||
void set_clip_layer (const std::string &spec)
|
||||
{
|
||||
tl::Extractor ex (spec.c_str ());
|
||||
clip_layer = db::LayerProperties ();
|
||||
clip_layer.read (ex);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void clip (const ClipData &data)
|
||||
{
|
||||
db::Manager m;
|
||||
db::Layout layout (&m);
|
||||
db::Layout target_layout (&m);
|
||||
db::Layout layout;
|
||||
db::Layout target_layout;
|
||||
|
||||
{
|
||||
db::LoadLayoutOptions load_options;
|
||||
data.reader_options.configure (load_options);
|
||||
|
||||
tl::InputStream stream (data.file_in);
|
||||
db::Reader reader (stream);
|
||||
reader.read (layout);
|
||||
reader.read (layout, load_options);
|
||||
}
|
||||
|
||||
// create the layers in the target layout as well
|
||||
|
|
@ -135,123 +155,61 @@ void clip (const ClipData &data)
|
|||
}
|
||||
|
||||
// write the layout
|
||||
tl::OutputStreamBase *out_file = 0;
|
||||
try {
|
||||
|
||||
tl::OutputStream stream (data.file_out, data.gzip ? tl::OutputStream::OM_Zlib : tl::OutputStream::OM_Plain);
|
||||
db::SaveLayoutOptions save_options;
|
||||
save_options.set_format_from_filename (data.file_out);
|
||||
data.writer_options.configure (save_options, target_layout);
|
||||
|
||||
if (data.oasis) {
|
||||
db::OASISWriter writer;
|
||||
writer.write (target_layout, stream, db::SaveLayoutOptions ());
|
||||
} else {
|
||||
db::GDS2Writer writer;
|
||||
writer.write (target_layout, stream, db::SaveLayoutOptions ());
|
||||
}
|
||||
|
||||
delete out_file;
|
||||
|
||||
} catch (...) {
|
||||
if (out_file) {
|
||||
delete out_file;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
tl::OutputStream stream (data.file_out);
|
||||
db::Writer writer (save_options);
|
||||
writer.write (target_layout, stream);
|
||||
}
|
||||
|
||||
void print_syntax ()
|
||||
BD_MAIN_FUNC
|
||||
{
|
||||
printf ("Syntax: strmclip [<options>] <infile> <outfile>\n");
|
||||
printf ("\n");
|
||||
printf ("Options are:\n");
|
||||
printf (" -l 'l/d' take clip regions from layer l, datatype d\n");
|
||||
printf (" -o produce oasis output\n");
|
||||
printf (" -g produce gds output\n");
|
||||
printf (" -z gzip output\n");
|
||||
printf (" -t 'cell' use this cell from input (default: determine top cell automatically)\n");
|
||||
printf (" -x 'name' use this cell as top cell in output\n");
|
||||
printf (" -r 'l,b,r,t' explicitly specify a clip rectangle (can be present multiple times)\n");
|
||||
}
|
||||
ClipData data;
|
||||
|
||||
int
|
||||
main (int argc, char *argv [])
|
||||
{
|
||||
try {
|
||||
bd::init ();
|
||||
|
||||
ClipData data;
|
||||
tl::CommandLineOptions cmd;
|
||||
data.reader_options.add_options (cmd);
|
||||
data.writer_options.add_options (cmd);
|
||||
|
||||
for (int n = 1; n < argc; ++n) {
|
||||
cmd << tl::arg ("input", &data.file_in, "The input file",
|
||||
"The input file can be any supported format. It can be gzip compressed and will "
|
||||
"be uncompressed automatically in this case."
|
||||
)
|
||||
<< tl::arg ("output", &data.file_out, "The output file",
|
||||
"The output format is determined from the suffix of the file. If the suffix indicates "
|
||||
"gzip compression, the file will be compressed on output. Examples for recognized suffixes are "
|
||||
"\".oas\", \".gds.gz\", \".dxf\" or \"gds2\"."
|
||||
)
|
||||
<< tl::arg ("-l|--clip-layer=spec", &data, &ClipData::set_clip_layer, "Specifies a layer to take the clip regions from",
|
||||
"If this option is given, the clip rectangles are taken from the given layer."
|
||||
"The layer specification is of the \"layer/datatype\" form or a plain layer name if named layers "
|
||||
"are available."
|
||||
)
|
||||
<< tl::arg ("-t|--top-in=cellname", &data.top, "Specifies the top cell for input",
|
||||
"If this option is given, it specifies the cell to use as top cell from the input."
|
||||
)
|
||||
<< tl::arg ("-x|--top-out=cellname", &data.result, "Specifies the top cell for output",
|
||||
"If given, this name will be used as the top cell name in the output file. "
|
||||
"By default the output's top cell will be \"CLIPPED_\" plus the input's top cell name."
|
||||
)
|
||||
<< tl::arg ("*-r|--clip-box=l,b,r,t", &data, &ClipData::add_box, "Specifies a clip box",
|
||||
"This option specifies the box to clip in micrometer units. The box is given "
|
||||
"by left, bottom, right and top coordinates. This option can be used multiple times "
|
||||
"to produce a clip covering more than one rectangle."
|
||||
)
|
||||
;
|
||||
|
||||
if (std::string (argv [n]) == "-h") {
|
||||
print_syntax ();
|
||||
return 0;
|
||||
} else if (std::string (argv [n]) == "-o") {
|
||||
data.oasis = true;
|
||||
} else if (std::string (argv [n]) == "-g") {
|
||||
data.oasis = false;
|
||||
} else if (std::string (argv [n]) == "-z") {
|
||||
data.gzip = true;
|
||||
} else if (std::string (argv [n]) == "-x") {
|
||||
if (n < argc + 1) {
|
||||
++n;
|
||||
data.result = argv [n];
|
||||
}
|
||||
} else if (std::string (argv [n]) == "-t") {
|
||||
if (n < argc + 1) {
|
||||
++n;
|
||||
data.top = argv [n];
|
||||
}
|
||||
} else if (std::string (argv [n]) == "-r") {
|
||||
if (n < argc + 1) {
|
||||
++n;
|
||||
tl::Extractor ex (argv [n]);
|
||||
double l = 0.0, b = 0.0, r = 0.0, t = 0.0;
|
||||
ex.read (l); ex.expect (",");
|
||||
ex.read (b); ex.expect (",");
|
||||
ex.read (r); ex.expect (",");
|
||||
ex.read (t); ex.expect_end ();
|
||||
data.clip_boxes.push_back (db::DBox (l, b, r, t));
|
||||
}
|
||||
} else if (std::string (argv [n]) == "-l") {
|
||||
if (n < argc + 1) {
|
||||
++n;
|
||||
tl::Extractor ex (argv[n]);
|
||||
db::LayerProperties lp;
|
||||
lp.read (ex);
|
||||
data.clip_layer = lp;
|
||||
}
|
||||
} else if (argv [n][0] == '-') {
|
||||
print_syntax ();
|
||||
throw tl::Exception ("Unknown option: " + std::string (argv [n]));
|
||||
} else if (data.file_in.empty ()) {
|
||||
data.file_in = argv [n];
|
||||
} else if (data.file_out.empty ()) {
|
||||
data.file_out = argv [n];
|
||||
} else {
|
||||
print_syntax ();
|
||||
throw tl::Exception ("Superfluous command element: " + std::string (argv [n]));
|
||||
}
|
||||
cmd.brief ("This program will produce clips from an input layout and writes them to another layout");
|
||||
|
||||
}
|
||||
cmd.parse (argc, argv);
|
||||
|
||||
if (data.file_in.empty () || data.file_out.empty ()) {
|
||||
print_syntax ();
|
||||
throw tl::Exception ("Input or output file name missing");
|
||||
}
|
||||
|
||||
clip (data);
|
||||
|
||||
} catch (std::exception &ex) {
|
||||
tl::error << ex.what ();
|
||||
return 1;
|
||||
} catch (tl::Exception &ex) {
|
||||
tl::error << ex.msg ();
|
||||
return 1;
|
||||
} catch (...) {
|
||||
tl::error << "unspecific error";
|
||||
return 1;
|
||||
}
|
||||
clip (data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BD_MAIN
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ namespace tl
|
|||
// ArgBase implementation
|
||||
|
||||
ArgBase::ParsedOption::ParsedOption (const std::string &option)
|
||||
: optional (false), inverted (false), advanced (false), non_advanced (false)
|
||||
: optional (false), inverted (false), advanced (false), non_advanced (false), repeated (false)
|
||||
{
|
||||
tl::Extractor ex (option.c_str ());
|
||||
|
||||
|
|
@ -42,6 +42,12 @@ ArgBase::ParsedOption::ParsedOption (const std::string &option)
|
|||
advanced = true;
|
||||
} else if (ex.test ("/")) {
|
||||
non_advanced = true;
|
||||
} else if (ex.test ("*")) {
|
||||
repeated = true;
|
||||
} else if (ex.test ("!")) {
|
||||
inverted = true;
|
||||
} else if (ex.test ("?")) {
|
||||
optional = true;
|
||||
} else if (ex.test ("[")) {
|
||||
const char *t = ex.get ();
|
||||
while (! ex.at_end () && *ex != ']') {
|
||||
|
|
@ -55,10 +61,6 @@ ArgBase::ParsedOption::ParsedOption (const std::string &option)
|
|||
|
||||
}
|
||||
|
||||
if (ex.test ("!")) {
|
||||
inverted = true;
|
||||
}
|
||||
|
||||
while (! ex.at_end ()) {
|
||||
if (ex.test ("--")) {
|
||||
optional = true;
|
||||
|
|
@ -73,7 +75,6 @@ ArgBase::ParsedOption::ParsedOption (const std::string &option)
|
|||
ex.read_word (name);
|
||||
}
|
||||
} else {
|
||||
optional = ex.test ("?");
|
||||
ex.read_word (name);
|
||||
}
|
||||
ex.test("|");
|
||||
|
|
@ -523,13 +524,20 @@ CommandLineOptions::parse (int argc, char *argv[])
|
|||
throw tl::Exception (tl::to_string (QObject::tr ("Unknown command line component %1 - no further plain argument expected (use -h for help)").arg (tl::to_qstring (arg_as_utf8))));
|
||||
}
|
||||
|
||||
arg = *next_plain_arg++;
|
||||
arg = *next_plain_arg;
|
||||
if (! arg->option ().repeated) {
|
||||
++next_plain_arg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (arg->wants_value ()) {
|
||||
if (! arg->is_option ()) {
|
||||
|
||||
if (! arg->is_option () || ex.test ("=")) {
|
||||
arg->take_value (ex);
|
||||
|
||||
} else if (arg->wants_value ()) {
|
||||
|
||||
if (ex.test ("=")) {
|
||||
arg->take_value (ex);
|
||||
} else {
|
||||
|
||||
|
|
@ -557,7 +565,7 @@ CommandLineOptions::parse (int argc, char *argv[])
|
|||
|
||||
}
|
||||
|
||||
// Exection the action if there is one
|
||||
// Execute the action if there is one
|
||||
arg->action (this);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public:
|
|||
*/
|
||||
ParsedOption (const std::string &option);
|
||||
|
||||
bool optional, inverted, advanced, non_advanced;
|
||||
bool optional, inverted, advanced, non_advanced, repeated;
|
||||
std::string long_option, short_option, name;
|
||||
std::string group;
|
||||
};
|
||||
|
|
@ -80,7 +80,11 @@ public:
|
|||
* "-o|--long-option=value" - A short/long option with a value
|
||||
* "[group]..." - List the option under this group (group = group title)
|
||||
* "#..." - Advanced option - listed with --help-all only
|
||||
* "/..." - Non-ddvanced option - listed with -h|--help only
|
||||
* "/..." - Non-advanced option - listed with -h|--help only
|
||||
* "*..." - Multiple occurances allowed - values needs to be
|
||||
* an array and values are accumulated. Without *, the
|
||||
* value string is evaluated to a comma-separated list.
|
||||
* "*" means one occurance at least unless combined with "?".
|
||||
*/
|
||||
ArgBase (const std::string &option, const std::string &brief_doc, const std::string &long_doc);
|
||||
|
||||
|
|
@ -187,6 +191,11 @@ inline void extract (tl::Extractor &ex, std::string &t, bool for_list = false)
|
|||
ex.read (t, ",");
|
||||
} else {
|
||||
t = ex.get ();
|
||||
// TODO: there should be a tl::Extractor method either to
|
||||
// read all remaining text or to move the pointer to the end.
|
||||
while (! ex.at_end ()) {
|
||||
++ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -194,12 +203,14 @@ inline void extract (tl::Extractor &ex, std::string &t, bool for_list = false)
|
|||
* @brief A specialization for a list of any type (vector)
|
||||
*/
|
||||
template <class T>
|
||||
inline void extract (tl::Extractor &ex, std::vector<T> &t, bool /*for_list*/ = false)
|
||||
inline void extract (tl::Extractor &ex, std::vector<T> &t, bool for_list = false)
|
||||
{
|
||||
while (! ex.at_end ()) {
|
||||
t.push_back (T ());
|
||||
extract (ex, t.back (), true);
|
||||
ex.test (",");
|
||||
extract (ex, t.back (), for_list);
|
||||
if (for_list) {
|
||||
ex.test (",");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -276,7 +287,7 @@ public:
|
|||
|
||||
virtual void take_value (tl::Extractor &ex)
|
||||
{
|
||||
extract (ex, *mp_value);
|
||||
extract (ex, *mp_value, !option ().repeated);
|
||||
}
|
||||
|
||||
virtual void mark_present (bool inverted)
|
||||
|
|
@ -316,7 +327,7 @@ public:
|
|||
{
|
||||
typedef typename type_without_const_ref<T>::inner_type inner_type;
|
||||
inner_type t = inner_type ();
|
||||
extract (ex, t);
|
||||
extract (ex, t, !option ().repeated);
|
||||
(mp_object->*mp_setter) (t);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -266,6 +266,7 @@ TEST(2)
|
|||
EXPECT_EQ (v.f, "bar");
|
||||
}
|
||||
|
||||
// Array arguments
|
||||
TEST(3)
|
||||
{
|
||||
std::vector<std::string> a;
|
||||
|
|
@ -318,3 +319,78 @@ TEST(3)
|
|||
EXPECT_EQ (b[0], -13);
|
||||
EXPECT_EQ (b[1], 21);
|
||||
}
|
||||
|
||||
// Repeated array arguments
|
||||
TEST(4)
|
||||
{
|
||||
std::vector<std::string> a;
|
||||
std::vector<int> b;
|
||||
|
||||
tl::CommandLineOptions cmd;
|
||||
cmd << tl::arg ("*-a|--along", &a, "")
|
||||
<< tl::arg ("*-b|--blong", &b, "");
|
||||
|
||||
{
|
||||
char *argv[] = { "x", "-a", "r,u,v" };
|
||||
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
|
||||
}
|
||||
EXPECT_EQ (int (a.size ()), 1);
|
||||
EXPECT_EQ (a[0], "r,u,v");
|
||||
EXPECT_EQ (b.empty (), true);
|
||||
|
||||
a.clear ();
|
||||
b.clear ();
|
||||
{
|
||||
char *argv[] = { "x", "-b", "1", "-a=r", "-a", "u", "--along=v", "--blong=2" };
|
||||
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
|
||||
}
|
||||
EXPECT_EQ (int (a.size ()), 3);
|
||||
EXPECT_EQ (int (b.size ()), 2);
|
||||
EXPECT_EQ (a[0], "r");
|
||||
EXPECT_EQ (a[1], "u");
|
||||
EXPECT_EQ (a[2], "v");
|
||||
EXPECT_EQ (b[0], 1);
|
||||
EXPECT_EQ (b[1], 2);
|
||||
}
|
||||
|
||||
// Repeated and non-repeated plain arguments
|
||||
TEST(5)
|
||||
{
|
||||
std::string a;
|
||||
std::vector<std::string> b;
|
||||
std::vector<std::string> c;
|
||||
|
||||
tl::CommandLineOptions cmd;
|
||||
cmd << tl::arg ("a", &a, "")
|
||||
<< tl::arg ("b", &b, "")
|
||||
<< tl::arg ("?*c", &c, "");
|
||||
|
||||
{
|
||||
char *argv[] = { "x", "y", "r,u,v" };
|
||||
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
|
||||
}
|
||||
EXPECT_EQ (int (b.size ()), 3);
|
||||
EXPECT_EQ (int (c.size ()), 0);
|
||||
EXPECT_EQ (a, "y");
|
||||
EXPECT_EQ (b[0], "r");
|
||||
EXPECT_EQ (b[1], "u");
|
||||
EXPECT_EQ (b[2], "v");
|
||||
|
||||
a.clear ();
|
||||
b.clear ();
|
||||
c.clear ();
|
||||
|
||||
{
|
||||
char *argv[] = { "x", "y", "r,u,v", "a,b", "c", "d" };
|
||||
cmd.parse (sizeof (argv) / sizeof (argv[0]), argv);
|
||||
}
|
||||
EXPECT_EQ (int (b.size ()), 3);
|
||||
EXPECT_EQ (int (c.size ()), 3);
|
||||
EXPECT_EQ (a, "y");
|
||||
EXPECT_EQ (b[0], "r");
|
||||
EXPECT_EQ (b[1], "u");
|
||||
EXPECT_EQ (b[2], "v");
|
||||
EXPECT_EQ (c[0], "a,b");
|
||||
EXPECT_EQ (c[1], "c");
|
||||
EXPECT_EQ (c[2], "d");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue