diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/ctor.cc | 59 | ||||
-rw-r--r-- | test/execute_test.cc | 65 | ||||
-rw-r--r-- | test/source_type_test.cc | 41 | ||||
-rw-r--r-- | test/suite/ctor_files/ctor.cc.bar | 18 | ||||
-rw-r--r-- | test/suite/ctor_files/ctor.cc.base | 19 | ||||
-rw-r--r-- | test/suite/ctor_files/ctor.cc.multi | 18 | ||||
-rwxr-xr-x | test/suite/test.sh | 32 | ||||
-rw-r--r-- | test/tasks_test.cc | 12 | ||||
-rw-r--r-- | test/testprog.cc | 49 | ||||
-rw-r--r-- | test/tmpfile.h | 48 | ||||
-rw-r--r-- | test/tools_test.cc | 945 |
11 files changed, 1231 insertions, 75 deletions
diff --git a/test/ctor.cc b/test/ctor.cc index c24ded7..ccf1c31 100644 --- a/test/ctor.cc +++ b/test/ctor.cc @@ -1,25 +1,41 @@ // -*- c++ -*- // Distributed under the BSD 2-Clause License. // See accompanying file LICENSE for details. -#include <libctor.h> +#include <ctor.h> namespace { -BuildConfigurations ctorTestConfigs(const Settings& settings) +ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) { return { { - .type = TargetType::UnitTest, + .type = ctor::target_type::unit_test, + .system = ctor::output_system::build, + .target = "testprog", + .sources = { + "testprog.cc", + }, + .flags = { + .cxxflags = { + "-std=c++20", "-O3", "-Wall", "-Werror", + }, + }, + }, + { + .type = ctor::target_type::unit_test, + .system = ctor::output_system::build, .target = "execute_test", .sources = { "execute_test.cc", "testmain.cc", "../src/execute.cc", + "../src/util.cc", }, + .depends = { "testprog", }, .flags = { .cxxflags = { - "-std=c++20", "-O3", "-s", "-Wall", "-Werror", + "-std=c++20", "-O3", "-Wall", "-Werror", "-I../src", "-Iuunit", "-DOUTPUT=\"execute\"", }, @@ -27,7 +43,8 @@ BuildConfigurations ctorTestConfigs(const Settings& settings) }, }, { - .type = TargetType::UnitTest, + .type = ctor::target_type::unit_test, + .system = ctor::output_system::build, .target = "tasks_test", .sources = { "tasks_test.cc", @@ -36,7 +53,7 @@ BuildConfigurations ctorTestConfigs(const Settings& settings) .depends = { "libctor_nomain.a" }, .flags = { .cxxflags = { - "-std=c++20", "-O3", "-s", "-Wall", "-Werror", + "-std=c++20", "-O3", "-Wall", "-Werror", "-I../src", "-Iuunit", "-DOUTPUT=\"tasks\"", }, @@ -44,7 +61,8 @@ BuildConfigurations ctorTestConfigs(const Settings& settings) }, }, { - .type = TargetType::UnitTest, + .type = ctor::target_type::unit_test, + .system = ctor::output_system::build, .target = "source_type_test", .sources = { "source_type_test.cc", @@ -53,7 +71,7 @@ BuildConfigurations ctorTestConfigs(const Settings& settings) .depends = { "libctor_nomain.a" }, .flags = { .cxxflags = { - "-std=c++20", "-O3", "-s", "-Wall", "-Werror", + "-std=c++20", "-O3", "-Wall", "-Werror", "-I../src", "-Iuunit", "-DOUTPUT=\"source_type\"", }, @@ -61,7 +79,27 @@ BuildConfigurations ctorTestConfigs(const Settings& settings) }, }, { - .type = TargetType::UnitTestLib, + .type = ctor::target_type::unit_test, + .system = ctor::output_system::build, + .target = "tools_test", + .sources = { + "tools_test.cc", + "testmain.cc", + "../src/util.cc", + "../src/tools.cc", + }, + //.depends = { "libctor_nomain.a" }, + .flags = { + .cxxflags = { + "-std=c++20", "-O3", "-Wall", "-Werror", + "-I../src", "-Iuunit", + "-DOUTPUT=\"tools\"", + }, + }, + }, + { + .type = ctor::target_type::unit_test_library, + .system = ctor::output_system::build, .target = "libctor_nomain.a", .sources = { "../src/build.cc", @@ -75,12 +113,13 @@ BuildConfigurations ctorTestConfigs(const Settings& settings) "../src/task_fn.cc", "../src/task_ld.cc", "../src/task_so.cc", + "../src/tools.cc", "../src/util.cc", "../src/externals_manual.cc", }, .flags = { .cxxflags = { - "-std=c++20", "-O3", "-s", "-Wall", "-Werror", + "-std=c++20", "-O3", "-Wall", "-Werror", "-I../src", }, .ldflags = { "-pthread" }, diff --git a/test/execute_test.cc b/test/execute_test.cc index 9da18dc..03b3c2a 100644 --- a/test/execute_test.cc +++ b/test/execute_test.cc @@ -1,6 +1,14 @@ #include <uunit.h> +#include <fstream> +#include <map> +#include <set> + #include <execute.h> +#include <util.h> + +#include "paths.h" +#include "tmpfile.h" class ExecuteTest : public uUnit @@ -8,14 +16,61 @@ class ExecuteTest public: ExecuteTest() { - uTEST(ExecuteTest::runit); + uTEST(ExecuteTest::return_value); + uTEST(ExecuteTest::env); + } + + void return_value() + { + auto cur_path = std::filesystem::path(paths::argv_0).parent_path(); + std::vector<std::string> paths{{cur_path.string()}}; + auto cmd = locate("testprog", paths); + uASSERT(!cmd.empty()); + + uASSERT_EQUAL(0, execute(cmd, {"retval", "0"}, {}, false)); + uASSERT_EQUAL(1, execute(cmd, {"retval", "1"}, {}, false)); + uASSERT_EQUAL(1, execute("no-such-binary", {}, {}, false)); } - void runit() + void env() { - uASSERT_EQUAL(0, execute("/bin/true", {}, false)); - uASSERT_EQUAL(1, execute("/bin/false", {}, false)); - uASSERT_EQUAL(1, execute("no-such-binary", {}, false)); + auto cur_path = std::filesystem::path(paths::argv_0).parent_path(); + std::vector<std::string> paths{{cur_path.string()}}; + auto cmd = locate("testprog", paths); + uASSERT(!cmd.empty()); + + tmp_file tmp; + + std::map<std::string, std::string> env; + + // New env vars + env["foo"] = "bar"; + env["bar"] = "42"; + + // Overwrite the exiting LANG var + env["LANG"] = "foo"; + + uASSERT_EQUAL(0, execute(cmd, {"envdump", tmp.get()}, env, false)); + + std::set<std::string> vars; + { + std::ifstream infile(tmp.get()); + std::string line; + while (std::getline(infile, line)) + { + vars.insert(line); + } + } + + // Check the two explicitly set vars + uASSERT(vars.find("foo=bar") != vars.end()); + uASSERT(vars.find("bar=42") != vars.end()); + + // Check the one that should have overwritten the existing one (probably LANG=en_US.UTF-8 or something) + uASSERT(vars.find("LANG=foo") != vars.end()); + + // Check that other vars are also there (ie. the env wasn't cleared on entry) + uASSERT(vars.size() > 3); } }; diff --git a/test/source_type_test.cc b/test/source_type_test.cc index ed7e783..288f1e5 100644 --- a/test/source_type_test.cc +++ b/test/source_type_test.cc @@ -1,37 +1,40 @@ -#include <uunit.h> - -#include <libctor.h> +#include <ctor.h> #include <task_cc.h> -std::ostream& operator<<(std::ostream& stream, const Language& lang) +std::ostream& operator<<(std::ostream& stream, const ctor::language& lang); + +#include <uunit.h> + +std::ostream& operator<<(std::ostream& stream, const ctor::language& lang) { switch(lang) { - case Language::Auto: - stream << "Language::Auto"; + case ctor::language::automatic: + stream << "ctor::language::automatic"; break; - case Language::C: - stream << "Language::C"; + case ctor::language::c: + stream << "ctor::language::c"; break; - case Language::Cpp: - stream << "Language::Cpp"; + case ctor::language::cpp: + stream << "ctor::language::cpp"; break; - case Language::Asm: - stream << "Language::Asm"; + case ctor::language::assembler: + stream << "ctor::language::assembler"; break; } return stream; } + class TestableTaskCC : public TaskCC { public: - TestableTaskCC(const Source& source) + TestableTaskCC(const ctor::source& source) : TaskCC({}, {}, "build", source) {} - Language language() const + ctor::language language() const { return source_language; } @@ -50,22 +53,22 @@ public: { { // c++ TestableTaskCC task("hello.cc"); - uASSERT_EQUAL(Language::Cpp, task.language()); + uASSERT_EQUAL(ctor::language::cpp, task.language()); } { // c TestableTaskCC task("hello.c"); - uASSERT_EQUAL(Language::C, task.language()); + uASSERT_EQUAL(ctor::language::c, task.language()); } { // asm TestableTaskCC task("hello.s"); - uASSERT_EQUAL(Language::Asm, task.language()); + uASSERT_EQUAL(ctor::language::assembler, task.language()); } { // custom/explicit language - TestableTaskCC task( {"hello.foo", Language::Asm} ); - uASSERT_EQUAL(Language::Asm, task.language()); + TestableTaskCC task( {"hello.foo", ctor::language::assembler} ); + uASSERT_EQUAL(ctor::language::assembler, task.language()); } // Note: Failure state will result in exit(1) so cannot be tested diff --git a/test/suite/ctor_files/ctor.cc.bar b/test/suite/ctor_files/ctor.cc.bar index 92456cb..218f9cc 100644 --- a/test/suite/ctor_files/ctor.cc.bar +++ b/test/suite/ctor_files/ctor.cc.bar @@ -1,12 +1,12 @@ // -*- c++ -*- // Distributed under the BSD 2-Clause License. // See accompanying file LICENSE for details. -#include <libctor.h> +#include <ctor.h> //#include "config.h" namespace { -BuildConfigurations ctorConfigs() +ctor::build_configurations ctorConfigs(const ctor::settings& settings) { return { @@ -30,17 +30,19 @@ BuildConfigurations ctorConfigs() }; } -ExternalConfigurations ctorExtConfigs() +ctor::external_configurations ctorExtConfigs(const ctor::settings& settings) { return { { .name = "bar", - .flags = { - .cxxflags = { "-D_A_", "-DBAR"}, - .cflags = { "-D_B_" }, - .ldflags = { "-D_C_" }, - .asmflags = { "-D_D_" }, + .external = ctor::external_manual{ + .flags = { + .cflags = { "-D_B_" }, + .cxxflags = { "-D_A_", "-DBAR"}, + .ldflags = { "-D_C_" }, + .asmflags = { "-D_D_" }, + }, }, // Creates --with-foo-prefix arg to configure which will be used for // -L and -I flags. diff --git a/test/suite/ctor_files/ctor.cc.base b/test/suite/ctor_files/ctor.cc.base index 6c60513..eab39c4 100644 --- a/test/suite/ctor_files/ctor.cc.base +++ b/test/suite/ctor_files/ctor.cc.base @@ -1,12 +1,12 @@ // -*- c++ -*- // Distributed under the BSD 2-Clause License. // See accompanying file LICENSE for details. -#include <libctor.h> +#include <ctor.h> //#include "config.h" namespace { -BuildConfigurations ctorConfigs() +ctor::build_configurations ctorConfigs(const ctor::settings& settings) { return { @@ -30,17 +30,20 @@ BuildConfigurations ctorConfigs() }; } -ExternalConfigurations ctorExtConfigs() +ctor::external_configurations ctorExtConfigs(const ctor::settings& settings) { return { { .name = "bar", - .flags = { - .cxxflags = { "-D_A_", "-DFOO"}, - .cflags = { "-D_B_" }, - .ldflags = { "-D_C_" }, - .asmflags = { "-D_D_" }, + .external = ctor::external_manual + { + .flags = { + .cflags = { "-D_B_" }, + .cxxflags = { "-D_A_", "-DFOO"}, + .ldflags = { "-D_C_" }, + .asmflags = { "-D_D_" }, + }, }, // Creates --with-foo-prefix arg to configure which will be used for // -L and -I flags. diff --git a/test/suite/ctor_files/ctor.cc.multi b/test/suite/ctor_files/ctor.cc.multi index 9db2517..2b88afe 100644 --- a/test/suite/ctor_files/ctor.cc.multi +++ b/test/suite/ctor_files/ctor.cc.multi @@ -1,14 +1,14 @@ // -*- c++ -*- // Distributed under the BSD 2-Clause License. // See accompanying file LICENSE for details. -#include <libctor.h> +#include <ctor.h> //#include "config.h" #include "foobar.h" namespace { -BuildConfigurations ctorConfigs() +ctor::build_configurations ctorConfigs(const ctor::settings& settings) { return { @@ -32,17 +32,19 @@ BuildConfigurations ctorConfigs() }; } -ExternalConfigurations ctorExtConfigs() +ctor::external_configurations ctorExtConfigs(const ctor::settings& settings) { return { { .name = "bar", - .flags = { - .cxxflags = { "-D_A_", "-DFOO"}, - .cflags = { "-D_B_" }, - .ldflags = { "-D_C_" }, - .asmflags = { "-D_D_" }, + .external = ctor::external_manual{ + .flags = { + .cflags = { "-D_B_" }, + .cxxflags = { "-D_A_", "-DFOO"}, + .ldflags = { "-D_C_" }, + .asmflags = { "-D_D_" }, + }, }, // Creates --with-foo-prefix arg to configure which will be used for // -L and -I flags. diff --git a/test/suite/test.sh b/test/suite/test.sh index c980154..c112351 100755 --- a/test/suite/test.sh +++ b/test/suite/test.sh @@ -1,4 +1,9 @@ #!/bin/bash +: ${CXX:=g++} +: ${CTORDIR:=../../build} +: ${BUILDDIR:=build} + +CXX=$(which $CXX) function fail { @@ -13,21 +18,22 @@ function ctor } # Wipe the board -rm -Rf build +rm -Rf ${BUILDDIR} rm -f configuration.cc rm -f ctor +echo "** ctor_files/ctor.cc.base" cp ctor_files/ctor.cc.base ctor.cc # Compile bootstrap binary -g++ -pthread -std=c++20 -L../../build -lctor -I../../src ctor.cc -o ctor || fail ${LINENO} +$CXX -pthread -std=c++20 -L${CTORDIR} -lctor -I../../src ctor.cc -o ctor || fail ${LINENO} # No build files should have been created yet -[ -d build ] && fail ${LINENO} +[ -d ${BUILDDIR} ] && fail ${LINENO} # capture md5 sum of ctor binary before configure is called MD5=`md5sum ctor` -ctor configure --ctor-includedir ../../src --ctor-libdir ../../build +ctor configure --ctor-includedir ../../src --ctor-libdir=${CTORDIR} --build-dir=${BUILDDIR} # ctor should be rebuilt at this point, so md5 sum should have changed (echo $MD5 | md5sum --status -c) && fail ${LINENO} @@ -36,7 +42,7 @@ ctor configure --ctor-includedir ../../src --ctor-libdir ../../build [ ! -f configuration.cc ] && fail ${LINENO} # Shouldn't compile anything yet - only configure -[ -f build/hello-hello_cc.o ] && fail ${LINENO} +[ -f ${BUILDDIR}/hello-hello_cc.o ] && fail ${LINENO} MD5=`md5sum ctor` @@ -44,12 +50,12 @@ MD5=`md5sum ctor` ctor -v # Compiled object should now exist -[ ! -f build/hello-hello_cc.o ] && fail ${LINENO} +[ ! -f ${BUILDDIR}/hello-hello_cc.o ] && fail ${LINENO} # ctor should not have been rebuilt, so md5 sum should be the same (echo $MD5 | md5sum --status -c) || fail ${LINENO} -MOD1=`stat -c %Y build/hello-hello_cc.o` +MOD1=`stat -c %Y ${BUILDDIR}/hello-hello_cc.o` touch hello.cc sleep 1.1 @@ -57,10 +63,11 @@ sleep 1.1 ctor -v # Object file should have been recompiled -MOD2=`stat -c %Y build/hello-hello_cc.o` +MOD2=`stat -c %Y ${BUILDDIR}/hello-hello_cc.o` [[ $MOD1 == $MOD2 ]] && fail ${LINENO} # Replacve -DFOO with -DBAR in foo external.cxxflags +echo "** ctor_files/ctor.cc.bar" cp ctor_files/ctor.cc.bar ctor.cc MD5C=`md5sum configuration.cc` @@ -71,22 +78,23 @@ sleep 1.1 # Run normally to reconfigure, rebuild ctor and rebuild hello.cc ctor -v -MOD2=`stat -c %Y build/hello-hello_cc.o` +MOD2=`stat -c %Y ${BUILDDIR}/hello-hello_cc.o` [[ $MOD1 == $MOD2 ]] && fail ${LINENO} (echo $MD5C | md5sum --status -c) && fail ${LINENO} (echo $MD5 | md5sum --status -c) && fail ${LINENO} +echo "** ctor_files/ctor.cc.multi" cp ctor_files/ctor.cc.multi ctor.cc MD5C=`md5sum configuration.cc` MD5=`md5sum ctor` -MOD1=`stat -c %Y build/hello-hello_cc.o` +MOD1=`stat -c %Y ${BUILDDIR}/hello-hello_cc.o` sleep 1.1 # Run normally to reconfigure, rebuild ctor and rebuild hello.cc ctor -v -MOD2=`stat -c %Y build/hello-hello_cc.o` +MOD2=`stat -c %Y ${BUILDDIR}/hello-hello_cc.o` [[ $MOD1 == $MOD2 ]] && fail ${LINENO} (echo $MD5C | md5sum --status -c) && fail ${LINENO} (echo $MD5 | md5sum --status -c) && fail ${LINENO} @@ -102,3 +110,5 @@ ctor -v MOD2=`stat -c %Y ctor` [[ $MOD1 == $MOD2 ]] && fail ${LINENO} + +exit 0 diff --git a/test/tasks_test.cc b/test/tasks_test.cc index 2e0ffc7..5f1db26 100644 --- a/test/tasks_test.cc +++ b/test/tasks_test.cc @@ -1,11 +1,11 @@ #include <uunit.h> -#include <libctor.h> +#include <ctor.h> #include <tasks.h> namespace { -BuildConfigurations ctorTestConfigs1(const Settings&) +ctor::build_configurations ctorTestConfigs1(const ctor::settings&) { return { @@ -19,7 +19,7 @@ BuildConfigurations ctorTestConfigs1(const Settings&) }; } -BuildConfigurations ctorTestConfigs2(const Settings&) +ctor::build_configurations ctorTestConfigs2(const ctor::settings&) { return { @@ -91,7 +91,7 @@ public: void getTargets_test() { using namespace std::string_literals; - Settings settings{}; + ctor::settings settings{}; const auto& targets = getTargets(settings); uASSERT_EQUAL(4u, targets.size()); @@ -109,7 +109,7 @@ public: void getTasks_test() { using namespace std::string_literals; - Settings settings{ .builddir = "foo" }; + ctor::settings settings{ .builddir = "foo" }; { auto tasks = getTasks(settings); uASSERT_EQUAL(6u, tasks.size()); @@ -139,7 +139,7 @@ public: void getNextTask_test() { using namespace std::string_literals; - Settings settings{}; + ctor::settings settings{}; { // Zero (Empty) std::set<std::shared_ptr<Task>> allTasks; diff --git a/test/testprog.cc b/test/testprog.cc new file mode 100644 index 0000000..dbfb665 --- /dev/null +++ b/test/testprog.cc @@ -0,0 +1,49 @@ +#include <iostream> +#include <fstream> +#include <string> + +extern const char **environ; // see 'man environ' + +int main(int argc, const char* argv[]) +{ + if(argc < 2) + { + return 0; + } + + std::string cmd = argv[1]; + + if(cmd == "envdump") + { + if(argc < 3) + { + return 0; + } + std::ofstream ostrm(argv[2], std::ios::binary); + for(auto current = environ; *current; ++current) + { + ostrm << (*current) << "\n"; + } + } + + if(cmd == "retval") + { + if(argc < 3) + { + return 0; + } + return std::stoi(argv[2]); + } + + if(cmd == "abort") + { + abort(); + } + + if(cmd == "throw") + { + throw "ouch"; + } + + return 0; +} diff --git a/test/tmpfile.h b/test/tmpfile.h new file mode 100644 index 0000000..5d114d0 --- /dev/null +++ b/test/tmpfile.h @@ -0,0 +1,48 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#pragma once + +#include <cstdlib> +#include <unistd.h> + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#endif + +struct tmp_file +{ + tmp_file(const std::string& data = {}) + { + int fd; +#ifdef _WIN32 + char templ[] = "ctor_tmp_file-XXXXXX"; // buffer for filename + _mktemp_s(templ, sizeof(templ)); + fd = open(templ, O_CREAT | O_RDWR); +#else + char templ[] = "/tmp/ctor_tmp_file-XXXXXX"; // buffer for filename + fd = mkstemp(templ); +#endif + filename = templ; + auto sz = write(fd, data.data(), data.size()); + (void)sz; + close(fd); + } + + ~tmp_file() + { + unlink(filename.data()); + } + + const std::string& get() const + { + return filename; + } + +private: + std::string filename; +}; diff --git a/test/tools_test.cc b/test/tools_test.cc new file mode 100644 index 0000000..a428ea1 --- /dev/null +++ b/test/tools_test.cc @@ -0,0 +1,945 @@ +#include <vector> +#include <string> +#include <ostream> +#include <initializer_list> +#include <cassert> + +#include <tools.h> + +std::ostream& operator<<(std::ostream& stream, const ctor::toolchain& toolchain) +{ + switch(toolchain) + { + case ctor::toolchain::none: + stream << "ctor::toolchain::none"; + break; + case ctor::toolchain::any: + stream << "ctor::toolchain::any"; + break; + case ctor::toolchain::gcc: + stream << "ctor::toolchain::gcc"; + break; + case ctor::toolchain::clang: + stream << "ctor::toolchain::clang"; + break; + } + return stream; +} + +std::ostream& operator<<(std::ostream& stream, const std::vector<std::string>& vs) +{ + bool first{true}; + stream << "{ "; + for(const auto& v : vs) + { + if(!first) + { + stream << ", "; + } + stream << "'" << v << "'"; + first = false; + } + stream << " }"; + + return stream; +} + +std::ostream& operator<<(std::ostream& stream, const ctor::c_flag& flag) +{ + stream << "{" << flag.opt << ", \"" << flag.arg << "\", " << flag.toolchain << "}"; + return stream; +} + +std::ostream& operator<<(std::ostream& stream, const ctor::cxx_flag& flag) +{ + stream << "{" << flag.opt << ", \"" << flag.arg << "\", " << flag.toolchain << "}"; + return stream; +} + +std::ostream& operator<<(std::ostream& stream, const ctor::ld_flag& flag) +{ + stream << "{" << flag.opt << ", \"" << flag.arg << "\", " << flag.toolchain << "}"; + return stream; +} + +std::ostream& operator<<(std::ostream& stream, const ctor::ar_flag& flag) +{ + stream << "{" << flag.opt << ", \"" << flag.arg << "\", " << flag.toolchain << "}"; + return stream; +} + +std::ostream& operator<<(std::ostream& stream, const ctor::asm_flag& flag) +{ + stream << "{" << flag.opt << ", \"" << flag.arg << "\", " << flag.toolchain << "}"; + return stream; +} + +bool operator!=(const ctor::c_flag& a, const ctor::c_flag& b) +{ + return + a.opt != b.opt || + a.arg != b.arg || + a.toolchain != b.toolchain; +} + +bool operator!=(const ctor::cxx_flag& a, const ctor::cxx_flag& b) +{ + return + a.opt != b.opt || + a.arg != b.arg || + a.toolchain != b.toolchain; +} +bool operator!=(const ctor::ld_flag& a, const ctor::ld_flag& b) +{ + return + a.opt != b.opt || + a.arg != b.arg || + a.toolchain != b.toolchain; +} + +bool operator!=(const ctor::ar_flag& a, const ctor::ar_flag& b) +{ + return + a.opt != b.opt || + a.arg != b.arg || + a.toolchain != b.toolchain; +} +bool operator!=(const ctor::asm_flag& a, const ctor::asm_flag& b) +{ + return + a.opt != b.opt || + a.arg != b.arg || + a.toolchain != b.toolchain; +} + +#include <uunit.h> + +namespace { +std::string conf_host_cxx{}; +std::string conf_build_cxx{}; +} + +const ctor::configuration& ctor::get_configuration() +{ + static ctor::configuration cfg; + return cfg; +} + +const std::string& ctor::configuration::get(const std::string& key, const std::string& defval) const +{ + if(key == ctor::cfg::host_cxx) + { + return conf_host_cxx; + } + + if(key == ctor::cfg::build_cxx) + { + return conf_build_cxx; + } + + assert(false); // bad key + + static std::string res{}; + return res; +} + +class ToolsTest + : public uUnit +{ +public: + ToolsTest() + { + uTEST(ToolsTest::getToolChain_test); + + uTEST(ToolsTest::getOption_toolchain_c_test); + uTEST(ToolsTest::getOption_toolchain_cxx_test); + uTEST(ToolsTest::getOption_toolchain_ld_test); + uTEST(ToolsTest::getOption_toolchain_ar_test); + uTEST(ToolsTest::getOption_toolchain_asm_test); + + uTEST(ToolsTest::getOption_str_c_test); + uTEST(ToolsTest::getOption_str_cxx_test); + uTEST(ToolsTest::getOption_str_ld_test); + uTEST(ToolsTest::getOption_str_ar_test); + uTEST(ToolsTest::getOption_str_asm_test); + + uTEST(ToolsTest::to_strings_c_test); + uTEST(ToolsTest::to_strings_cxx_test); + uTEST(ToolsTest::to_strings_ld_test); + uTEST(ToolsTest::to_strings_ar_test); + uTEST(ToolsTest::to_strings_asm_test); + } + + void getToolChain_test() + { + // + // gcc + // + uASSERT_EQUAL(ctor::toolchain::gcc, getToolChain("/usr/bin/gcc")); + uASSERT_EQUAL(ctor::toolchain::gcc, getToolChain("/usr/bin/gcc-10")); + uASSERT_EQUAL(ctor::toolchain::gcc, getToolChain("/usr/bin/x86_64-pc-linux-gnu-g++-9.3.0")); + + uASSERT_EQUAL(ctor::toolchain::gcc, getToolChain("/usr/bin/g++")); + uASSERT_EQUAL(ctor::toolchain::gcc, getToolChain("/usr/bin/g++-10")); + uASSERT_EQUAL(ctor::toolchain::gcc, getToolChain("/usr/bin/x86_64-pc-linux-gnu-g++-9.3.0")); + + // + // clang + // + uASSERT_EQUAL(ctor::toolchain::clang, getToolChain("/usr/bin/clang")); + uASSERT_EQUAL(ctor::toolchain::clang, getToolChain("/usr/bin/clang-16")); + uASSERT_EQUAL(ctor::toolchain::clang, getToolChain("/usr/lib/llvm/16/bin/i686-pc-linux-gnu-clang-16")); + + uASSERT_EQUAL(ctor::toolchain::clang, getToolChain("/usr/bin/clang++")); + uASSERT_EQUAL(ctor::toolchain::clang, getToolChain("/usr/bin/clang++-16")); + uASSERT_EQUAL(ctor::toolchain::clang, getToolChain("/usr/lib/llvm/16/bin/i686-pc-linux-gnu-clang++-16")); + } + + + void getOption_toolchain_c_test() + { + std::vector<std::string> exp; + std::vector<std::string> act; + + // + // gcc + // + exp = { "-o", "foo" }; + act = c_option(ctor::toolchain::gcc, ctor::c_opt::output, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-g" }; + act = c_option(ctor::toolchain::gcc, ctor::c_opt::debug); + uASSERT_EQUAL(exp, act); + + exp = { "-Wall" }; + act = c_option(ctor::toolchain::gcc, ctor::c_opt::warn_all); + uASSERT_EQUAL(exp, act); + + exp = { "-Werror" }; + act = c_option(ctor::toolchain::gcc, ctor::c_opt::warnings_as_errors); + uASSERT_EQUAL(exp, act); + + exp = { "-MMD" }; + act = c_option(ctor::toolchain::gcc, ctor::c_opt::generate_dep_tree); + uASSERT_EQUAL(exp, act); + + exp = { "-c" }; + act = c_option(ctor::toolchain::gcc, ctor::c_opt::no_link); + uASSERT_EQUAL(exp, act); + + exp = { "-Ifoo" }; + act = c_option(ctor::toolchain::gcc, ctor::c_opt::include_path, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-std=foo" }; + act = c_option(ctor::toolchain::gcc, ctor::c_opt::c_std, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-Ofoo" }; + act = c_option(ctor::toolchain::gcc, ctor::c_opt::optimization, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-fPIC" }; + act = c_option(ctor::toolchain::gcc, ctor::c_opt::position_independent_code); + uASSERT_EQUAL(exp, act); + + exp = { "-fPIE" }; + act = c_option(ctor::toolchain::gcc, ctor::c_opt::position_independent_executable); + uASSERT_EQUAL(exp, act); + + exp = { "-foo" }; + act = c_option(ctor::toolchain::gcc, ctor::c_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + + // + // clang + // + exp = { "-o", "foo" }; + act = c_option(ctor::toolchain::clang, ctor::c_opt::output, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-g" }; + act = c_option(ctor::toolchain::clang, ctor::c_opt::debug); + uASSERT_EQUAL(exp, act); + + exp = { "-Wall" }; + act = c_option(ctor::toolchain::clang, ctor::c_opt::warn_all); + uASSERT_EQUAL(exp, act); + + exp = { "-Werror" }; + act = c_option(ctor::toolchain::clang, ctor::c_opt::warnings_as_errors); + uASSERT_EQUAL(exp, act); + + exp = { "-MMD" }; + act = c_option(ctor::toolchain::clang, ctor::c_opt::generate_dep_tree); + uASSERT_EQUAL(exp, act); + + exp = { "-c" }; + act = c_option(ctor::toolchain::clang, ctor::c_opt::no_link); + uASSERT_EQUAL(exp, act); + + exp = { "-Ifoo" }; + act = c_option(ctor::toolchain::clang, ctor::c_opt::include_path, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-std=foo" }; + act = c_option(ctor::toolchain::clang, ctor::c_opt::c_std, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-Ofoo" }; + act = c_option(ctor::toolchain::clang, ctor::c_opt::optimization, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-fPIC" }; + act = c_option(ctor::toolchain::clang, ctor::c_opt::position_independent_code); + uASSERT_EQUAL(exp, act); + + exp = { "-fPIE" }; + act = c_option(ctor::toolchain::clang, ctor::c_opt::position_independent_executable); + uASSERT_EQUAL(exp, act); + + exp = { "-foo" }; + act = c_option(ctor::toolchain::clang, ctor::c_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + + // + // any + // + exp = { "{ctor::c_opt::output, \"foo\"}" }; + act = c_option(ctor::toolchain::any, ctor::c_opt::output, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::c_opt::debug}" }; + act = c_option(ctor::toolchain::any, ctor::c_opt::debug); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::c_opt::warn_all}" }; + act = c_option(ctor::toolchain::any, ctor::c_opt::warn_all); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::c_opt::warnings_as_errors}" }; + act = c_option(ctor::toolchain::any, ctor::c_opt::warnings_as_errors); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::c_opt::generate_dep_tree}" }; + act = c_option(ctor::toolchain::any, ctor::c_opt::generate_dep_tree); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::c_opt::no_link}" }; + act = c_option(ctor::toolchain::any, ctor::c_opt::no_link); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::c_opt::include_path, \"foo\"}" }; + act = c_option(ctor::toolchain::any, ctor::c_opt::include_path, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::c_opt::c_std, \"foo\"}" }; + act = c_option(ctor::toolchain::any, ctor::c_opt::c_std, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::c_opt::optimization, \"foo\"}" }; + act = c_option(ctor::toolchain::any, ctor::c_opt::optimization, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::c_opt::position_independent_code}" }; + act = c_option(ctor::toolchain::any, ctor::c_opt::position_independent_code); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::c_opt::position_independent_executable}" }; + act = c_option(ctor::toolchain::any, ctor::c_opt::position_independent_executable); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::c_opt::custom, \"-foo\"}" }; + act = c_option(ctor::toolchain::any, ctor::c_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + } + + void getOption_toolchain_cxx_test() + { + std::vector<std::string> exp; + std::vector<std::string> act; + + // + // gcc + // + exp = { "-o", "foo" }; + act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::output, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-g" }; + act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::debug); + uASSERT_EQUAL(exp, act); + + exp = { "-Wall" }; + act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::warn_all); + uASSERT_EQUAL(exp, act); + + exp = { "-Werror" }; + act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::warnings_as_errors); + uASSERT_EQUAL(exp, act); + + exp = { "-MMD" }; + act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::generate_dep_tree); + uASSERT_EQUAL(exp, act); + + exp = { "-c" }; + act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::no_link); + uASSERT_EQUAL(exp, act); + + exp = { "-Ifoo" }; + act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::include_path, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-std=foo" }; + act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::cpp_std, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-Ofoo" }; + act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::optimization, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-fPIC" }; + act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::position_independent_code); + uASSERT_EQUAL(exp, act); + + exp = { "-fPIE" }; + act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::position_independent_executable); + uASSERT_EQUAL(exp, act); + + exp = { "-foo" }; + act = cxx_option(ctor::toolchain::gcc, ctor::cxx_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + + // + // clang + // + exp = { "-o", "foo" }; + act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::output, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-g" }; + act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::debug); + uASSERT_EQUAL(exp, act); + + exp = { "-Wall" }; + act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::warn_all); + uASSERT_EQUAL(exp, act); + + exp = { "-Werror" }; + act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::warnings_as_errors); + uASSERT_EQUAL(exp, act); + + exp = { "-MMD" }; + act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::generate_dep_tree); + uASSERT_EQUAL(exp, act); + + exp = { "-c" }; + act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::no_link); + uASSERT_EQUAL(exp, act); + + exp = { "-Ifoo" }; + act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::include_path, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-std=foo" }; + act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::cpp_std, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-Ofoo" }; + act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::optimization, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-fPIC" }; + act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::position_independent_code); + uASSERT_EQUAL(exp, act); + + exp = { "-fPIE" }; + act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::position_independent_executable); + uASSERT_EQUAL(exp, act); + + exp = { "-foo" }; + act = cxx_option(ctor::toolchain::clang, ctor::cxx_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + + // + // any + // + exp = { "{ctor::cxx_opt::output, \"foo\"}" }; + act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::output, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::cxx_opt::debug}" }; + act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::debug); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::cxx_opt::warn_all}" }; + act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::warn_all); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::cxx_opt::warnings_as_errors}" }; + act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::warnings_as_errors); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::cxx_opt::generate_dep_tree}" }; + act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::generate_dep_tree); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::cxx_opt::no_link}" }; + act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::no_link); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::cxx_opt::include_path, \"foo\"}" }; + act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::include_path, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::cxx_opt::cpp_std, \"foo\"}" }; + act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::cpp_std, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::cxx_opt::optimization, \"foo\"}" }; + act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::optimization, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::cxx_opt::position_independent_code}" }; + act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::position_independent_code); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::cxx_opt::position_independent_executable}" }; + act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::position_independent_executable); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::cxx_opt::custom, \"-foo\"}" }; + act = cxx_option(ctor::toolchain::any, ctor::cxx_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + } + + void getOption_toolchain_ld_test() + { + std::vector<std::string> exp; + std::vector<std::string> act; + + // + // gcc + // + exp = { "-o", "foo" }; + act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::output, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-s" }; + act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::strip); + uASSERT_EQUAL(exp, act); + + exp = { "-Wall" }; + act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::warn_all); + uASSERT_EQUAL(exp, act); + + exp = { "-Werror" }; + act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::warnings_as_errors); + uASSERT_EQUAL(exp, act); + + exp = { "-Lfoo" }; + act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::library_path, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-lfoo" }; + act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::link, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-std=foo" }; + act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::cpp_std, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-shared" }; + act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::build_shared); + uASSERT_EQUAL(exp, act); + + exp = { "-pthread" }; + act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::threads); + uASSERT_EQUAL(exp, act); + + exp = { "-fPIC" }; + act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::position_independent_code); + uASSERT_EQUAL(exp, act); + + exp = { "-fPIE" }; + act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::position_independent_executable); + uASSERT_EQUAL(exp, act); + + exp = { "-foo" }; + act = ld_option(ctor::toolchain::gcc, ctor::ld_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + + // + // clang + // + exp = { "-o", "foo" }; + act = ld_option(ctor::toolchain::clang, ctor::ld_opt::output, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-s" }; + act = ld_option(ctor::toolchain::clang, ctor::ld_opt::strip); + uASSERT_EQUAL(exp, act); + + exp = { "-Wall" }; + act = ld_option(ctor::toolchain::clang, ctor::ld_opt::warn_all); + uASSERT_EQUAL(exp, act); + + exp = { "-Werror" }; + act = ld_option(ctor::toolchain::clang, ctor::ld_opt::warnings_as_errors); + uASSERT_EQUAL(exp, act); + + exp = { "-Lfoo" }; + act = ld_option(ctor::toolchain::clang, ctor::ld_opt::library_path, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-lfoo" }; + act = ld_option(ctor::toolchain::clang, ctor::ld_opt::link, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-std=foo" }; + act = ld_option(ctor::toolchain::clang, ctor::ld_opt::cpp_std, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-shared" }; + act = ld_option(ctor::toolchain::clang, ctor::ld_opt::build_shared); + uASSERT_EQUAL(exp, act); + + exp = { "-pthread" }; + act = ld_option(ctor::toolchain::clang, ctor::ld_opt::threads); + uASSERT_EQUAL(exp, act); + + exp = { "-fPIC" }; + act = ld_option(ctor::toolchain::clang, ctor::ld_opt::position_independent_code); + uASSERT_EQUAL(exp, act); + + exp = { "-fPIE" }; + act = ld_option(ctor::toolchain::clang, ctor::ld_opt::position_independent_executable); + uASSERT_EQUAL(exp, act); + + exp = { "-foo" }; + act = ld_option(ctor::toolchain::clang, ctor::ld_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + + // + // any + // + exp = { "{ctor::ld_opt::output, \"foo\"}" }; + act = ld_option(ctor::toolchain::any, ctor::ld_opt::output, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::ld_opt::strip}" }; + act = ld_option(ctor::toolchain::any, ctor::ld_opt::strip); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::ld_opt::warn_all}" }; + act = ld_option(ctor::toolchain::any, ctor::ld_opt::warn_all); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::ld_opt::warnings_as_errors}" }; + act = ld_option(ctor::toolchain::any, ctor::ld_opt::warnings_as_errors); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::ld_opt::library_path, \"foo\"}" }; + act = ld_option(ctor::toolchain::any, ctor::ld_opt::library_path, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::ld_opt::link, \"foo\"}" }; + act = ld_option(ctor::toolchain::any, ctor::ld_opt::link, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::ld_opt::cpp_std, \"foo\"}" }; + act = ld_option(ctor::toolchain::any, ctor::ld_opt::cpp_std, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::ld_opt::build_shared}" }; + act = ld_option(ctor::toolchain::any, ctor::ld_opt::build_shared); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::ld_opt::threads}" }; + act = ld_option(ctor::toolchain::any, ctor::ld_opt::threads); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::ld_opt::position_independent_code}" }; + act = ld_option(ctor::toolchain::any, ctor::ld_opt::position_independent_code); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::ld_opt::position_independent_executable}" }; + act = ld_option(ctor::toolchain::any, ctor::ld_opt::position_independent_executable); + uASSERT_EQUAL(exp, act); + + exp = { "{ctor::ld_opt::custom, \"-foo\"}" }; + act = ld_option(ctor::toolchain::any, ctor::ld_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + } + + void getOption_toolchain_ar_test() + { + std::vector<std::string> exp; + std::vector<std::string> act; + + // + // gcc + // + exp = { "-r" }; + act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::replace); + uASSERT_EQUAL(exp, act); + + exp = { "-s" }; + act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::add_index); + uASSERT_EQUAL(exp, act); + + exp = { "-c" }; + act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::create); + uASSERT_EQUAL(exp, act); + + exp = { "foo" }; + act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::output, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-foo" }; + act = ar_option(ctor::toolchain::gcc, ctor::ar_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + + // + // clang + // + exp = { "-r" }; + act = ar_option(ctor::toolchain::clang, ctor::ar_opt::replace); + uASSERT_EQUAL(exp, act); + + exp = { "-s" }; + act = ar_option(ctor::toolchain::clang, ctor::ar_opt::add_index); + uASSERT_EQUAL(exp, act); + + exp = { "-c" }; + act = ar_option(ctor::toolchain::clang, ctor::ar_opt::create); + uASSERT_EQUAL(exp, act); + + exp = { "foo" }; + act = ar_option(ctor::toolchain::clang, ctor::ar_opt::output, "foo"); + uASSERT_EQUAL(exp, act); + + exp = { "-foo" }; + act = ar_option(ctor::toolchain::clang, ctor::ar_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + + // + // any + // + exp = { "{ctor::ar_opt::custom, \"-foo\"}" }; + act = ar_option(ctor::toolchain::any, ctor::ar_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); +} + + void getOption_toolchain_asm_test() + { + std::vector<std::string> exp; + std::vector<std::string> act; + + // + // gcc + // + exp = { "-foo" }; + act = asm_option(ctor::toolchain::gcc, ctor::asm_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + + // + // clang + // + exp = { "-foo" }; + act = asm_option(ctor::toolchain::clang, ctor::asm_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + + // + // any + // + exp = { "{ctor::asm_opt::custom, \"-foo\"}" }; + act = asm_option(ctor::toolchain::any, ctor::asm_opt::custom, "-foo"); + uASSERT_EQUAL(exp, act); + } + + + void getOption_str_c_test() + { + ctor::c_flag exp(""); + ctor::c_flag act(""); + + // + // gcc + // + exp = { ctor::c_opt::include_path, "foo" }; + act = c_option("-Ifoo", ctor::toolchain::gcc); + uASSERT_EQUAL(exp, act); + + exp = { ctor::c_opt::custom, "foo" }; + act = c_option("foo", ctor::toolchain::gcc); + uASSERT_EQUAL(exp, act); + + // + // clang + // + exp = { ctor::c_opt::include_path, "foo" }; + act = c_option("-Ifoo", ctor::toolchain::clang); + uASSERT_EQUAL(exp, act); + + exp = { ctor::c_opt::custom, "foo" }; + act = c_option("foo", ctor::toolchain::clang); + uASSERT_EQUAL(exp, act); + } + + void getOption_str_cxx_test() + { + ctor::cxx_flag exp(""); + ctor::cxx_flag act(""); + + // + // gcc + // + exp = { ctor::cxx_opt::include_path, "foo" }; + act = cxx_option("-Ifoo", ctor::toolchain::gcc); + uASSERT_EQUAL(exp, act); + + exp = { ctor::cxx_opt::custom, "foo" }; + act = cxx_option("foo", ctor::toolchain::gcc); + uASSERT_EQUAL(exp, act); + + // + // clang + // + exp = { ctor::cxx_opt::include_path, "foo" }; + act = cxx_option("-Ifoo", ctor::toolchain::clang); + uASSERT_EQUAL(exp, act); + + exp = { ctor::cxx_opt::custom, "foo" }; + act = cxx_option("foo", ctor::toolchain::clang); + uASSERT_EQUAL(exp, act); + } + + void getOption_str_ld_test() + { + ctor::ld_flag exp(""); + ctor::ld_flag act(""); + + // + // gcc + // + exp = { ctor::ld_opt::library_path, "foo" }; + act = ld_option("-Lfoo", ctor::toolchain::gcc); + uASSERT_EQUAL(exp, act); + + exp = { ctor::ld_opt::custom, "foo" }; + act = ld_option("foo", ctor::toolchain::gcc); + uASSERT_EQUAL(exp, act); + + // + // clang + // + exp = { ctor::ld_opt::library_path, "foo" }; + act = ld_option("-Lfoo", ctor::toolchain::clang); + uASSERT_EQUAL(exp, act); + + exp = { ctor::ld_opt::custom, "foo" }; + act = ld_option("foo", ctor::toolchain::clang); + uASSERT_EQUAL(exp, act); + } + + void getOption_str_ar_test() + { + ctor::ar_flag exp(""); + ctor::ar_flag act(""); + + // + // gcc + // + exp = { ctor::ar_opt::custom, "foo" }; + act = ar_option("foo", ctor::toolchain::gcc); + uASSERT_EQUAL(exp, act); + + // + // clang + // + exp = { ctor::ar_opt::custom, "foo" }; + act = ar_option("foo", ctor::toolchain::clang); + uASSERT_EQUAL(exp, act); + } + + void getOption_str_asm_test() + { + ctor::asm_flag exp(""); + ctor::asm_flag act(""); + + // + // gcc + // + exp = { ctor::asm_opt::custom, "foo" }; + act = asm_option("foo", ctor::toolchain::gcc); + uASSERT_EQUAL(exp, act); + + // + // clang + // + exp = { ctor::asm_opt::custom, "foo" }; + act = asm_option("foo", ctor::toolchain::clang); + uASSERT_EQUAL(exp, act); + } + + + void to_strings_c_test() + { + std::vector<std::string> exp; + std::vector<std::string> act; + + // Mismatching toolchain (required vs actual) results in no output + // otherwise to_strings is just a proxy for c_option + act = to_strings(ctor::toolchain::gcc, {ctor::toolchain::clang, ctor::c_opt::no_link}); + uASSERT_EQUAL(exp, act); + } + + void to_strings_cxx_test() + { + std::vector<std::string> exp; + std::vector<std::string> act; + + // Mismatching toolchain (required vs actual) results in no output + // otherwise to_strings is just a proxy for cxx_option + act = to_strings(ctor::toolchain::gcc, {ctor::toolchain::clang, ctor::cxx_opt::no_link}); + uASSERT_EQUAL(exp, act); + } + + void to_strings_ld_test() + { + std::vector<std::string> exp; + std::vector<std::string> act; + + // Mismatching toolchain (required vs actual) results in no output + // otherwise to_strings is just a proxy for ld_option + act = to_strings(ctor::toolchain::gcc, {ctor::toolchain::clang, ctor::ld_opt::strip}); + uASSERT_EQUAL(exp, act); + } + + void to_strings_ar_test() + { + std::vector<std::string> exp; + std::vector<std::string> act; + + // Mismatching toolchain (required vs actual) results in no output + // otherwise to_strings is just a proxy for ar_option + act = to_strings(ctor::toolchain::gcc, {ctor::toolchain::clang, ctor::ar_opt::custom, "foo"}); + uASSERT_EQUAL(exp, act); + } + + void to_strings_asm_test() + { + std::vector<std::string> exp; + std::vector<std::string> act; + + // Mismatching toolchain (required vs actual) results in no output + // otherwise to_strings is just a proxy for asm_option + act = to_strings(ctor::toolchain::gcc, {ctor::toolchain::clang, ctor::asm_opt::custom, "foo"}); + uASSERT_EQUAL(exp, act); + } +}; + +// Registers the fixture into the 'registry' +static ToolsTest test; |