diff --git a/.gitattributes b/.gitattributes index cf79b26ea3313eae2a8ca97cc6420f6fcaa83355..85c24b294323d05cbeb8c0d286397b52c9c14b62 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2432,6 +2432,7 @@ MAC/APL/PIC/RSP_Driver/src/SetSwapxyCmd.h -text MAC/APL/PIC/RSP_Driver/src/UpdBitModeCmd.cc -text MAC/APL/PIC/RSP_Driver/src/UpdBitModeCmd.h -text MAC/APL/PIC/RSP_Driver/src/rspctl.log_prop -text +MAC/APL/PIC/RSP_Driver/src/rspctl_main.cc -text MAC/APL/PIC/RSP_Driver/test/tCableAttenuation.in_1 -text MAC/APL/PIC/RSP_Driver/test/tCableAttenuation.in_2 -text MAC/APL/PIC/RSP_Driver/test/tCableAttenuation.in_3 -text @@ -2445,6 +2446,7 @@ MAC/APL/PIC/RSP_Driver/test/tRCUCables.in_4 -text MAC/APL/PIC/RSP_Driver/test/tRCUCables.in_5 -text MAC/APL/PIC/RSP_Driver/test/tRCUCables.in_6 -text MAC/APL/PIC/RSP_Driver/test/tRCUCables.in_CableAtts -text +MAC/APL/PIC/RSP_Driver/test/tRSPCtl.cc -text MAC/APL/PIC/RSP_Protocol/doc/package.dox -text MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/Bitmode.h -text MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/SDOMode.h -text diff --git a/MAC/APL/PIC/RSP_Driver/CMakeLists.txt b/MAC/APL/PIC/RSP_Driver/CMakeLists.txt index 9e1e876447b4f2e1f0ec62e68b837c6f3e8d3b2e..d13e6d337da1d583a8db19a97129a2b06bb1c5fe 100644 --- a/MAC/APL/PIC/RSP_Driver/CMakeLists.txt +++ b/MAC/APL/PIC/RSP_Driver/CMakeLists.txt @@ -6,6 +6,7 @@ lofar_package(RSP_Driver 6.0 DEPENDS ApplCommon Common TestSuite GCFTM MACIO RTC include(LofarFindPackage) lofar_find_package(Boost REQUIRED) lofar_find_package(Blitz REQUIRED) +lofar_find_package(UnitTest++) add_subdirectory(src) add_subdirectory(test) diff --git a/MAC/APL/PIC/RSP_Driver/src/CMakeLists.txt b/MAC/APL/PIC/RSP_Driver/src/CMakeLists.txt index 55239b312398d59904f96973281a3d06a69ebf10..d89cff49f2db44db3ae5355701bf8ff3c28c054a 100644 --- a/MAC/APL/PIC/RSP_Driver/src/CMakeLists.txt +++ b/MAC/APL/PIC/RSP_Driver/src/CMakeLists.txt @@ -16,7 +16,7 @@ lofar_add_library(epa lofar_add_sbin_program(geni2c geni2c.cc) lofar_add_bin_program(versionrsp_driver versionrsp_driver.cc) -lofar_add_bin_program(rspctl rspctl.cc) +lofar_add_bin_program(rspctl rspctl.cc rspctl_main.cc) lofar_add_bin_program(RSPDriver RSPDriver.cc Scheduler.cc diff --git a/MAC/APL/PIC/RSP_Driver/src/rspctl.cc b/MAC/APL/PIC/RSP_Driver/src/rspctl.cc index 4be6294fe610930715bb2ef1404e03f95941d515..0c3f5a4a25789fb6af3183dc28af6b8573242ed9 100644 --- a/MAC/APL/PIC/RSP_Driver/src/rspctl.cc +++ b/MAC/APL/PIC/RSP_Driver/src/rspctl.cc @@ -4013,7 +4013,7 @@ Command* RSPCtl::parse_options(int argc, char** argv) rspctl_exit_code = EXIT_FAILURE; exit(EXIT_FAILURE); } - select = strtolist(optarg, command->get_ndevices()); + select = utility::strtolist(optarg, command->get_ndevices()); if (select.empty()) { logMessage(cerr,"Error: invalid or missing '--select' option"); rspctl_exit_code = EXIT_FAILURE; @@ -4033,7 +4033,7 @@ Command* RSPCtl::parse_options(int argc, char** argv) rspctl_exit_code = EXIT_FAILURE; exit(EXIT_FAILURE); } - beamlets = strtolist(optarg, maxBeamlets(itsNbitsPerSample)); + beamlets = utility::strtolist(optarg, maxBeamlets(itsNbitsPerSample)); if (beamlets.empty()) { logMessage(cerr,"Error: invalid or missing '--beamlets' option"); rspctl_exit_code = EXIT_FAILURE; @@ -4116,7 +4116,7 @@ Command* RSPCtl::parse_options(int argc, char** argv) if (optarg) { subbandscommand->setMode(false); - list<int> subbandlist = strtolist(optarg, MAX_SUBBANDS); + list<int> subbandlist = utility::strtolist(optarg, MAX_SUBBANDS); if (subbandlist.empty()) { logMessage(cerr,"Error: invalid or empty '--subbands' option"); rspctl_exit_code = EXIT_FAILURE; @@ -4419,7 +4419,7 @@ Command* RSPCtl::parse_options(int argc, char** argv) if (optarg) { sdocommand->setMode(false); - list<int> subbandlist = strtolist(optarg, MAX_SUBBANDS); + list<int> subbandlist = utility::strtolist(optarg, MAX_SUBBANDS); if (subbandlist.empty()) { logMessage(cerr,"Error: invalid or empty '--sdo' option"); rspctl_exit_code = EXIT_FAILURE; @@ -4600,7 +4600,7 @@ Command* RSPCtl::parse_options(int argc, char** argv) if (optarg) { hbacommand->setMode(false); // set the HBA delays - hbacommand->setDelayList(strtolist(optarg, (uint8)-1)); + hbacommand->setDelayList(utility::strtolist(optarg, (uint8)-1)); } } break; @@ -4624,7 +4624,7 @@ Command* RSPCtl::parse_options(int argc, char** argv) char* liststring = strchr(optarg, ','); liststring++; // skip the , if (liststring && *liststring) { - list<int> subbandlist = strtolist(liststring, MAX_SUBBANDS); + list<int> subbandlist = utility::strtolist(liststring, MAX_SUBBANDS); if (subbandlist.empty()) { logMessage(cerr,"Error: missing or invalid subband set '--tbbmode=subbands' option"); rspctl_exit_code = EXIT_FAILURE; @@ -4900,7 +4900,67 @@ Command* RSPCtl::parse_options(int argc, char** argv) return (command); } -std::list<int> RSPCtl::strtolist(const char* str, int max) +void utility::logMessage(ostream& stream, const string& message) { + stream << message << endl; +} + +std::list<complex<double>> utility::strtocomplexlist(const char* str) +{ + std::string input_string(str); + list<complex<double>> result; + + char* start = (char*)input_string.c_str(); + char* end = 0; + bool pair = false; + bool img = false; + double first = 0; + double second = 0; + + while(start) { + double val = strtod(start, &end); // read decimal numbers + std::cout << "Val: " << val << " end: " << end << std::endl; + start = (end ? (*end ? end + 1 : 0) : 0); // advance + if(end) { + switch(*end) { + case 0: + break; + case ',': + if(pair) { + first = val; + img = true; + } + break; + case '(': + pair = true; + break; + case ')': + if(img) { + second = val; + } + else { + first = val; + } + + result.push_back(std::complex<double>(first, second)); + pair = false; + img = false; + first = 0; + second = 0; + break; + default: + logMessage(cerr,formatString("Error: invalid character %c",*end)); + rspctl_exit_code = EXIT_FAILURE; + result.clear(); + return result; + break; + } // switch + } // if (end) + } + + return result; +} + +std::list<int> utility::strtolist(const char* str, int max) { string inputstring(str); char* start = (char*)inputstring.c_str(); @@ -4976,31 +5036,3 @@ void RSPCtl::logMessage(ostream& stream, const string& message) } // namespace rspctl } // namespace LOFAR -//) -// MAIN -// - -using namespace LOFAR; -using namespace LOFAR::rspctl; - -int main(int argc, char** argv) -{ - GCFScheduler::instance()->init(argc, argv, "rspctl"); - - LOG_INFO(formatString("Program %s has started", argv[0])); - - RSPCtl c("RSPCtl", argc, argv); - - try { - c.start(); // make initial transition - GCFScheduler::instance()->run(); - } - catch (Exception& e) { - cerr << "Exception: " << e.text() << endl; - exit(EXIT_FAILURE); - } - - LOG_INFO("Normal termination of program"); - - return (rspctl_exit_code); -} diff --git a/MAC/APL/PIC/RSP_Driver/src/rspctl.h b/MAC/APL/PIC/RSP_Driver/src/rspctl.h index 54775cc3c33e22ea57b961d536262efa48d561f3..e876edd886f587c854760d30fe88f58531f0f486 100644 --- a/MAC/APL/PIC/RSP_Driver/src/rspctl.h +++ b/MAC/APL/PIC/RSP_Driver/src/rspctl.h @@ -807,6 +807,13 @@ public: virtual GCFEvent::TResult ack(GCFEvent& e); }; +namespace utility +{ + void logMessage(ostream& stream, const string& message); + std::list<int> strtolist(const char* str, int max); + std::list<std::complex<double>> strtocomplexlist(const char* str); +} + // Controller class for rspctl // // class RSPCtl @@ -847,7 +854,6 @@ public: private: // private methods Command* parse_options(int argc, char** argv); - std::list<int> strtolist(const char* str, int max); void logMessage(ostream& stream, const string& message); // ports diff --git a/MAC/APL/PIC/RSP_Driver/src/rspctl_main.cc b/MAC/APL/PIC/RSP_Driver/src/rspctl_main.cc new file mode 100644 index 0000000000000000000000000000000000000000..341fd9061467eac81f8c79f4c6f3499a54d49c74 --- /dev/null +++ b/MAC/APL/PIC/RSP_Driver/src/rspctl_main.cc @@ -0,0 +1,31 @@ +#include <GCF/TM/GCF_Scheduler.h> + +#include "rspctl.h" + +extern int rspctl_exit_code; + +using namespace LOFAR; +using namespace LOFAR::rspctl; +using namespace LOFAR::GCF::TM; + +int main(int argc, char** argv) +{ + GCFScheduler::instance()->init(argc, argv, "rspctl"); + + LOG_INFO(formatString("Program %s has started", argv[0])); + + RSPCtl c("RSPCtl", argc, argv); + + try { + c.start(); // make initial transition + GCFScheduler::instance()->run(); + } + catch (Exception& e) { + cerr << "Exception: " << e.text() << endl; + exit(EXIT_FAILURE); + } + + LOG_INFO("Normal termination of program"); + + return (rspctl_exit_code); +} diff --git a/MAC/APL/PIC/RSP_Driver/test/CMakeLists.txt b/MAC/APL/PIC/RSP_Driver/test/CMakeLists.txt index 63d8808e728e61b59e4590d8f28652a3feb091e2..51ee8711119d523e97584f82e21f23849fa833c1 100644 --- a/MAC/APL/PIC/RSP_Driver/test/CMakeLists.txt +++ b/MAC/APL/PIC/RSP_Driver/test/CMakeLists.txt @@ -5,6 +5,10 @@ include(LofarCTest) # Add project's source directory to -I path. include_directories(${PACKAGE_SOURCE_DIR}/src) +lofar_add_test(tRSPCtl + tRSPCtl.cc + ${PACKAGE_SOURCE_DIR}/src/rspctl.cc) + lofar_add_test(tCableAttenuation tCableAttenuation.cc ${PACKAGE_SOURCE_DIR}/src/CableAttenuation.cc) diff --git a/MAC/APL/PIC/RSP_Driver/test/tRSPCtl.cc b/MAC/APL/PIC/RSP_Driver/test/tRSPCtl.cc new file mode 100644 index 0000000000000000000000000000000000000000..b8d2dbe144e944fe221b95f5be40cd7c04771364 --- /dev/null +++ b/MAC/APL/PIC/RSP_Driver/test/tRSPCtl.cc @@ -0,0 +1,49 @@ +#include <UnitTest++.h> +#include <complex> +#include <list> + +#include "rspctl.h" + +using namespace LOFAR::TYPES; +using namespace LOFAR::rspctl::utility; + +TEST(returns_empty_complex_list_with_empty_string) +{ + std::list<std::complex<double>> list = strtocomplexlist(""); + CHECK_EQUAL(0, list.size()); +} + +TEST(returns_list_contains_one_complex_number_when_string_has_a_pair_of_ints) +{ + std::list<std::complex<double>> list = strtocomplexlist("(0,0)"); + CHECK_EQUAL(1, list.size()); +} + +TEST(returns_list_contains_two_complex_numbers_when_string_has_two_pairs_of_ints) +{ + std::list<std::complex<double>> list = strtocomplexlist("(0,0),(1,1)"); + CHECK_EQUAL(2, list.size()); +} + +TEST(returns_list_contains_correct_complex_number_when_string_has_a_pair_of_doubles) +{ + std::list<std::complex<double>> list = strtocomplexlist("(2.3,5.4)"); + std::complex<double> first_value = list.front(); + + CHECK_EQUAL(2.3, first_value.real()); + CHECK_EQUAL(5.4, first_value.imag()); +} + +TEST(strtocomplexlist_contains_correct_complex_number_when_string_has_a_pair_with_only_a_real_number) +{ + std::list<std::complex<double>> list = strtocomplexlist("(2.3)"); + std::complex<double> first_value = list.front(); + + CHECK_EQUAL(2.3, first_value.real()); + CHECK_EQUAL(0, first_value.imag()); +} + +int main(int, const char *[]) +{ + return UnitTest::RunAllTests(); +}