diff --git a/sources/ysfx_parse.cpp b/sources/ysfx_parse.cpp index a340c1f..8ce3fb8 100644 --- a/sources/ysfx_parse.cpp +++ b/sources/ysfx_parse.cpp @@ -149,7 +149,8 @@ void ysfx_parse_header(ysfx_section_t *section, ysfx_header_t &header) header.out_pins.push_back(ysfx::trim(rest, &ysfx::ascii_isspace)); } else if (unprefix(linep, &rest, "options:")) { - for (const std::string &opt : ysfx::split_strings_noempty(rest, &ysfx::ascii_isspace)) { + auto option_line = ysfx::trim_spaces_around_equals(rest); + for (const std::string &opt : ysfx::split_strings_noempty(option_line.c_str(), &ysfx::ascii_isspace)) { size_t pos = opt.find('='); std::string name = (pos == opt.npos) ? opt : opt.substr(0, pos); std::string value = (pos == opt.npos) ? std::string{} : opt.substr(pos + 1); diff --git a/sources/ysfx_utils.cpp b/sources/ysfx_utils.cpp index 2a0a674..cfab4cc 100644 --- a/sources/ysfx_utils.cpp +++ b/sources/ysfx_utils.cpp @@ -259,6 +259,20 @@ char *strdup_using_new(const char *src) return dst; } +std::string trim_spaces_around_equals(const char* input) { + auto output = std::string(input); + for (size_t i = 0; (i = output.find('=', i)) != std::string::npos; ) { + size_t start = i; + while (start > 0 && std::isspace(output[start - 1])) --start; + size_t end = i + 1; + while (end < output.size() && std::isspace(output[end])) ++end; + output.replace(start, end - start, "="); + i = start + 1; + } + + return output; +} + string_list split_strings_noempty(const char *input, bool(*pred)(char)) { string_list list; diff --git a/sources/ysfx_utils.hpp b/sources/ysfx_utils.hpp index 86a4dc6..de7f558 100644 --- a/sources/ysfx_utils.hpp +++ b/sources/ysfx_utils.hpp @@ -95,6 +95,7 @@ uint32_t latin1_toupper(uint32_t c); uint32_t latin1_tolower(uint32_t c); char *strdup_using_new(const char *src); string_list split_strings_noempty(const char *input, bool(*pred)(char)); +std::string trim_spaces_around_equals(const char* input); std::string trim(const char *input, bool(*pred)(char)); //------------------------------------------------------------------------------ diff --git a/tests/ysfx_test_integration.cpp b/tests/ysfx_test_integration.cpp index 662197e..faf8082 100644 --- a/tests/ysfx_test_integration.cpp +++ b/tests/ysfx_test_integration.cpp @@ -169,6 +169,7 @@ TEST_CASE("integration", "[integration]") compile_and_check("desc:test" "\noptions:gfx_hz=45334954317053419571340971349057134051345\nout_pin:output\n@init\n", 30); compile_and_check("desc:test" "\noptions:gfx_hz=invalid\nout_pin:output\n@init\n", 30); compile_and_check("desc:test" "\nout_pin:output\n@init\n", 30); + compile_and_check("desc:test" "\nout_pin:output\n@init\n", 30); } SECTION("pre_alloc none") @@ -256,4 +257,32 @@ TEST_CASE("integration", "[integration]") REQUIRE(ysfx_calculate_used_mem(fx.get()) == 13434880); // Note that this always rounds to the next full block }; + + SECTION("multi_config") + { + auto compile_and_check = [](const char *text, uint32_t ref_value, bool want_meter) { + scoped_new_dir dir_fx("${root}/Effects"); + scoped_new_txt file_main("${root}/Effects/example.jsfx", text); + + ysfx_config_u config{ysfx_config_new()}; + ysfx_u fx{ysfx_new(config.get())}; + + REQUIRE(ysfx_load_file(fx.get(), file_main.m_path.c_str(), 0)); + REQUIRE(ysfx_compile(fx.get(), 0)); + + REQUIRE(ysfx_get_requested_framerate(fx.get()) == ref_value); + REQUIRE(ysfx_wants_meters(fx.get()) == want_meter); + }; + + compile_and_check("desc:test" "\noptions:gfx_hz=60 no_meter\nout_pin:output\n@init\n", 60, false); + compile_and_check("desc:test" "\noptions:no_meter gfx_hz=60\nout_pin:output\n@init\n", 60, false); + compile_and_check("desc:test" "\noptions:no_meter gfx_hz = 60\nout_pin:output\n@init\n", 60, false); + compile_and_check("desc:test" "\noptions:no_meter gfx_hz= 60\nout_pin:output\n@init\n", 60, false); + compile_and_check("desc:test" "\noptions:no_meter gfx_hz =60\nout_pin:output\n@init\n", 60, false); + compile_and_check("desc:test" "\noptions:=\nout_pin:output\n@init\n", 30, true); + compile_and_check("desc:test" "\noptions:= = = = =\nout_pin:output\n@init\n", 30, true); + compile_and_check("desc:test" "\noptions:\nout_pin:output\n@init\n", 30, true); + compile_and_check("desc:test" "\noptions:gfx_hz=60\nout_pin:output\n@init\n", 60, true); + compile_and_check("desc:test" "\noptions:gfx_hz=60\noptions:no_meter\nout_pin:output\n@init\n", 60, false); + } }