/* KLayout Layout Viewer Copyright (C) 2006-2025 Matthias Koefferlein This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "tlCommandLineParser.h" #include "tlUnitTest.h" TEST(1) { std::string a; int b = 0; bool c = false; double d = 1; bool e = false; std::string f; tl::CommandLineOptions cmd; cmd << tl::arg ("a", &a, "") << tl::arg ("?b", &b, "") << tl::arg ("-c", &c, "") << tl::arg ("!-cc", &c, "") << tl::arg ("--plong|-p", &d, "") << tl::arg ("--elong", &e, "") << tl::arg ("-f|--flong=value", &f, ""); { const char *argv[] = { "x", "y" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (a, "y"); EXPECT_EQ (b, 0); { const char *argv[] = { "x", "z", "17" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (a, "z"); EXPECT_EQ (b, 17); b = 0; { const char *argv[] = { "x", "u", "-c" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (a, "u"); EXPECT_EQ (b, 0); EXPECT_EQ (c, true); b = 0; c = true; { const char *argv[] = { "x", "u", "-cc" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (a, "u"); EXPECT_EQ (b, 0); EXPECT_EQ (c, false); b = 0; c = true; { const char *argv[] = { "x", "u", "-cc=false" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (a, "u"); EXPECT_EQ (b, 0); EXPECT_EQ (c, true); b = 0; c = true; { const char *argv[] = { "x", "u", "-cc=true" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (a, "u"); EXPECT_EQ (b, 0); EXPECT_EQ (c, false); { const char *argv[] = { "x", "u", "-c", "-cc" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (c, false); b = 0; c = false; { const char *argv[] = { "x", "u", "-c", "-p=21" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (a, "u"); EXPECT_EQ (b, 0); EXPECT_EQ (c, true); EXPECT_EQ (d, 21); b = 0; c = false; { const char *argv[] = { "x", "u", "-p", "22", "-c" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (a, "u"); EXPECT_EQ (b, 0); EXPECT_EQ (c, true); EXPECT_EQ (d, 22); e = false; { const char *argv[] = { "x", "u", "--plong", "23" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (a, "u"); EXPECT_EQ (d, 23); EXPECT_EQ (e, false); { const char *argv[] = { "x", "u", "--plong=24", "--elong" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (a, "u"); EXPECT_EQ (d, 24); EXPECT_EQ (e, true); { const char *argv[] = { "x", "u", "-c", "-f=foo" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (a, "u"); EXPECT_EQ (f, "foo"); { const char *argv[] = { "x", "u", "--flong", "bar" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (a, "u"); EXPECT_EQ (f, "bar"); } struct Values { Values () { b = 0; d = 1; c = e = false; } void set_a (const std::string &x) { a = x; } void set_b (int x) { b = x; } void set_c (bool x) { c = x; } void set_d (const double &x) { d = x; } void set_e (bool x) { e = x; } void set_f (std::string x) { f = x; } std::string a; int b; bool c; double d; bool e; std::string f; }; TEST(2) { Values v; tl::CommandLineOptions cmd; cmd << tl::arg ("a", &v, &Values::set_a, "") << tl::arg ("?b", &v, &Values::set_b, "") << tl::arg ("-c", &v, &Values::set_c, "") << tl::arg ("!-cc", &v, &Values::set_c, "") << tl::arg ("--plong|-p", &v, &Values::set_d, "") << tl::arg ("--elong", &v, &Values::set_e, "") << tl::arg ("-f|--flong=value", &v, &Values::set_f, ""); { const char *argv[] = { "x", "y" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (v.a, "y"); EXPECT_EQ (v.b, 0); { const char *argv[] = { "x", "z", "17" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (v.a, "z"); EXPECT_EQ (v.b, 17); v.b = 0; { const char *argv[] = { "x", "u", "-c" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (v.a, "u"); EXPECT_EQ (v.b, 0); EXPECT_EQ (v.c, true); v.b = 0; v.c = true; { const char *argv[] = { "x", "u", "-cc" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (v.a, "u"); EXPECT_EQ (v.b, 0); EXPECT_EQ (v.c, false); { const char *argv[] = { "x", "u", "-c", "-cc" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (v.c, false); v.b = 0; v.c = false; { const char *argv[] = { "x", "u", "-c", "-p=21" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (v.a, "u"); EXPECT_EQ (v.b, 0); EXPECT_EQ (v.c, true); EXPECT_EQ (v.d, 21); v.b = 0; v.c = false; { const char *argv[] = { "x", "u", "-p", "22", "-c" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (v.a, "u"); EXPECT_EQ (v.b, 0); EXPECT_EQ (v.c, true); EXPECT_EQ (v.d, 22); v.e = false; { const char *argv[] = { "x", "u", "--plong", "23" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (v.a, "u"); EXPECT_EQ (v.d, 23); EXPECT_EQ (v.e, false); { const char *argv[] = { "x", "u", "--plong=24", "--elong" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (v.a, "u"); EXPECT_EQ (v.d, 24); EXPECT_EQ (v.e, true); { const char *argv[] = { "x", "u", "-c", "-f=foo" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (v.a, "u"); EXPECT_EQ (v.f, "foo"); { const char *argv[] = { "x", "u", "--flong", "bar" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (v.a, "u"); EXPECT_EQ (v.f, "bar"); } // Array arguments TEST(3) { std::vector a; std::vector b; tl::CommandLineOptions cmd; cmd << tl::arg ("a", &a, "") << tl::arg ("-b", &b, ""); { const char *argv[] = { "x", "r,u,v" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (int (a.size ()), 3); EXPECT_EQ (a[0], "r"); EXPECT_EQ (a[1], "u"); EXPECT_EQ (a[2], "v"); EXPECT_EQ (b.empty (), true); a.clear (); { const char *argv[] = { "x", "\"r,u\",v" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (int (a.size ()), 2); EXPECT_EQ (a[0], "r,u"); EXPECT_EQ (a[1], "v"); EXPECT_EQ (b.empty (), true); a.clear (); { const char *argv[] = { "x", "'\"'", "-b=1,5,-13" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (int (a.size ()), 1); EXPECT_EQ (a[0], "\""); EXPECT_EQ (int (b.size ()), 3); EXPECT_EQ (b[0], 1); EXPECT_EQ (b[1], 5); EXPECT_EQ (b[2], -13); a.clear (); b.clear (); { const char *argv[] = { "x", "", "-b", "-13,21" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (int (a.size ()), 0); EXPECT_EQ (int (b.size ()), 2); EXPECT_EQ (b[0], -13); EXPECT_EQ (b[1], 21); } // Repeated array arguments TEST(4) { std::vector a; std::vector b; tl::CommandLineOptions cmd; cmd << tl::arg ("*-a|--along", &a, "") << tl::arg ("*-b|--blong", &b, ""); { const char *argv[] = { "x", "-a", "r,u,v" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) argv); } EXPECT_EQ (int (a.size ()), 1); EXPECT_EQ (a[0], "r,u,v"); EXPECT_EQ (b.empty (), true); a.clear (); b.clear (); { const char *argv[] = { "x", "-b", "1", "-a=r", "-a", "u", "--along=v", "--blong=2" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) 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 b; std::vector c; tl::CommandLineOptions cmd; cmd << tl::arg ("a", &a, "") << tl::arg ("b", &b, "") << tl::arg ("?*c", &c, ""); { const char *argv[] = { "x", "y", "r,u,v" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) 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 (); { const char *argv[] = { "x", "y", "r,u,v", "a,b", "c", "d" }; cmd.parse (sizeof (argv) / sizeof (argv[0]), (char **) 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"); }