diff --git a/lib/signal.cpp b/lib/signal.cpp index a60e06383..972d69f79 100644 --- a/lib/signal.cpp +++ b/lib/signal.cpp @@ -585,7 +585,7 @@ int signal_data_parse_str(union signal_data *data, const struct signal *sig, con break; case SignalType::COMPLEX: { - float real, imag; + float real, imag = 0; real = strtod(ptr, end); if (*end == ptr) @@ -593,14 +593,22 @@ int signal_data_parse_str(union signal_data *data, const struct signal *sig, con ptr = *end; - imag = strtod(ptr, end); - if (*end == ptr) - return -1; + if (*ptr == 'i' || *ptr == 'j') { + imag = real; + real = 0; - if (**end != 'i') - return -1; + (*end)++; + } + else if (*ptr == '-' || *ptr == '+') { + imag = strtod(ptr, end); + if (*end == ptr) + return -1; - (*end)++; + if (**end != 'i' && **end != 'j') + return -1; + + (*end)++; + } data->z = std::complex(real, imag); break; diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 2cab31ca5..1a099de33 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -30,13 +30,14 @@ set(TEST_SRC pool.cpp queue.cpp queue_signalled.cpp + signal.cpp ) add_executable(unit-tests ${TEST_SRC}) target_link_libraries(unit-tests PUBLIC PkgConfig::CRITERION - villas Threads::Threads + villas ) add_custom_target(run-unit-tests diff --git a/tests/unit/signal.cpp b/tests/unit/signal.cpp new file mode 100644 index 000000000..1bf3a51a4 --- /dev/null +++ b/tests/unit/signal.cpp @@ -0,0 +1,87 @@ +/** Unit tests for memory management + * + * @author Steffen Vogel + * @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * 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 3 of the License, or + * 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, see . + *********************************************************************************/ + +#include + +#include + +extern void init_memory(); + +Test(signal, parse, .init = init_memory) { + int ret; + struct signal sig; + union signal_data sd; + const char *str; + char *end; + + + str = "1"; + sig.type = SignalType::INTEGER; + + ret = signal_data_parse_str(&sd, &sig, str, &end); + cr_assert_eq(ret, 0); + cr_assert_eq(end, str + strlen(str)); + cr_assert_eq(sd.i, 1); + + str = "1.2"; + sig.type = SignalType::FLOAT; + + ret = signal_data_parse_str(&sd, &sig, str, &end); + cr_assert_eq(ret, 0); + cr_assert_eq(end, str + strlen(str)); + cr_assert_float_eq(sd.f, 1.2, 1e-6); + + str = "1"; + sig.type = SignalType::BOOLEAN; + + ret = signal_data_parse_str(&sd, &sig, str, &end); + cr_assert_eq(ret, 0); + cr_assert_eq(end, str + strlen(str)); + cr_assert_eq(sd.b, 1); + + str = "1"; + sig.type = SignalType::COMPLEX; + + ret = signal_data_parse_str(&sd, &sig, str, &end); + cr_assert_eq(ret, 0); + cr_assert_eq(end, str + strlen(str)); + cr_assert_float_eq(std::real(sd.z), 1, 1e-6); + cr_assert_float_eq(std::imag(sd.z), 0, 1e-6); + + str = "-1-3i"; + sig.type = SignalType::COMPLEX; + + ret = signal_data_parse_str(&sd, &sig, str, &end); + cr_assert_eq(ret, 0); + cr_assert_eq(end, str + strlen(str)); + cr_assert_float_eq(std::real(sd.z), -1, 1e-6); + cr_assert_float_eq(std::imag(sd.z), -3, 1e-6); + + str = "-3i"; + sig.type = SignalType::COMPLEX; + + ret = signal_data_parse_str(&sd, &sig, str, &end); + cr_assert_eq(ret, 0); + cr_assert_eq(end, str + strlen(str)); + cr_assert_float_eq(std::real(sd.z), 0, 1e-6); + cr_assert_float_eq(std::imag(sd.z), -3, 1e-6); +}