22#include " openPMD/Error.hpp"
33#include " openPMD/auxiliary/JSON_internal.hpp"
44
5+ #include < iostream>
56#include < nlohmann/json.hpp>
67#include < sstream>
8+ #include < stdexcept>
79
810namespace openPMD ::json
911{
@@ -16,6 +18,8 @@ namespace
1618 * The "select" key is optional, indicating the default configuration if it
1719 * is missing.
1820 *
21+ * @param backend_name For error messages.
22+ * @param index_in_list For error messages.
1923 * @param patterns Output parameter: Emplace a parsed pattern into this
2024 * list.
2125 * @param defaultConfig Output parameter: If the pattern was the default
@@ -24,6 +28,8 @@ namespace
2428 * @return Whether the pattern was the default configuration or not.
2529 */
2630 auto readPattern (
31+ std::string const &backend_name,
32+ size_t index_in_list,
2733 std::vector<Pattern> &patterns,
2834 std::optional<nlohmann::json> &defaultConfig,
2935 nlohmann::json object) -> void;
@@ -53,19 +59,23 @@ void MatcherPerBackend::init(TracingJSON tracing_config)
5359 {
5460 std::optional<nlohmann::json> defaultConfig;
5561 // enhanced PIConGPU-defined layout
56- for (auto &value : config)
62+ for (size_t i = 0 ; i < config. size (); ++i )
5763 {
58- readPattern (m_patterns, defaultConfig, std::move (value));
64+ readPattern (
65+ backendName,
66+ i,
67+ m_patterns,
68+ defaultConfig,
69+ std::move (config.at (i)));
5970 }
6071 // now replace the pattern list with the default config
6172 tracing_config.json () =
6273 std::move (defaultConfig).value_or (nlohmann::json::object ());
6374 }
6475 else
6576 {
66- throw std::runtime_error (
67- " [openPMD plugin] Expecting an object or an array as JSON "
68- " configuration." );
77+ throw error::BackendConfigSchema (
78+ {backendName, " dataset" }, " Expecting an object or an array." );
6979 }
7080}
7181
@@ -171,66 +181,104 @@ auto JsonMatcher::getDefault() -> TracingJSON
171181namespace
172182{
173183 auto readPattern (
184+ std::string const &backend_name,
185+ size_t index_in_list,
174186 std::vector<Pattern> &patterns,
175187 std::optional<nlohmann::json> &defaultConfig,
176188 nlohmann::json object) -> void
177189 {
178- constexpr char const *errorMsg = &R"END(
179- Each single pattern in an extended JSON configuration must be a JSON object
180- with keys 'select' and 'cfg'.
181- The key 'select' is optional, indicating a default configuration if it is
182- not set.
183- The key 'select' must point to either a single string or an array of strings.)END"
184- [1 ];
190+ constexpr char const *errorMsg = R"END(
191+ Each single pattern in an dataset-specific JSON/TOML configuration must be
192+ an object with mandatory key 'cfg' and optional key 'select'.
193+ When the key 'select' is not specified, the given configuration is used
194+ for setting up the default dataset configuration upon backend initialization.
195+ The key 'select' must point to either a single string or an array of strings
196+ and is interpreted as a regular expression against which the dataset name
197+ (full path or path within an iteration) must match.)END" ;
198+ auto throw_up = [&](std::string const &additional_info,
199+ auto &&...additional_path ) {
200+ throw error::BackendConfigSchema (
201+ {backend_name,
202+ " dataset" ,
203+ std::to_string (index_in_list),
204+ additional_path...},
205+ additional_info + errorMsg);
206+ };
185207
186208 if (!object.is_object ())
187209 {
188- throw std::runtime_error (errorMsg);
210+ throw_up (" Not an object!" );
211+ }
212+ if (!object.contains (" cfg" ))
213+ {
214+ throw_up (" Mandatory key missing: 'cfg'!" );
189215 }
190- try
191216 {
192- nlohmann::json &cfg = object. at ( " cfg " ) ;
193- if (! object.contains ( " select " ) )
217+ std::vector<std::string> unrecognized_keys ;
218+ for ( auto it = object. begin (); it != object.end (); ++it )
194219 {
195- if (defaultConfig. has_value () )
220+ if (it. key () == " select " || it. key () == " cfg " )
196221 {
197- throw std::runtime_error (
198- " Specified more than one default configuration." );
222+ continue ;
199223 }
200- defaultConfig.emplace (std::move (cfg));
201- return ;
224+ unrecognized_keys.emplace_back (it.key ());
202225 }
203- else
226+ if (!unrecognized_keys. empty ())
204227 {
205- nlohmann::json const &pattern = object.at (" select" );
206- std::string pattern_str = [&]() -> std::string {
207- if (pattern.is_string ())
208- {
209- return pattern.get <std::string>();
210- }
211- else if (pattern.is_array ())
228+ std::cerr << " [Warning] JSON/TOML config at '" << backend_name
229+ << " .dataset." << index_in_list
230+ << " ' has unrecognized keys:" ;
231+ for (auto const &item : unrecognized_keys)
232+ {
233+ std::cerr << " '" << item << ' \' ' ;
234+ }
235+ std::cerr << ' .' << std::endl;
236+ }
237+ }
238+
239+ nlohmann::json &cfg = object.at (" cfg" );
240+ if (!object.contains (" select" ))
241+ {
242+ if (defaultConfig.has_value ())
243+ {
244+ throw_up (" Specified more than one default configuration!" );
245+ }
246+ defaultConfig.emplace (std::move (cfg));
247+ return ;
248+ }
249+ else
250+ {
251+ nlohmann::json const &pattern = object.at (" select" );
252+ std::string pattern_str = [&]() -> std::string {
253+ if (pattern.is_string ())
254+ {
255+ return pattern.get <std::string>();
256+ }
257+ else if (pattern.is_array ())
258+ {
259+ std::stringstream res;
260+ res << " ($^)" ;
261+ for (auto const &sub_pattern : pattern)
212262 {
213- std::stringstream res;
214- res << " ($^)" ;
215- for (auto const &sub_pattern : pattern)
263+ if (!sub_pattern.is_string ())
216264 {
217- res << " |(" << sub_pattern.get <std::string>()
218- << " )" ;
265+ throw_up (
266+ " Must be a string or an array of string!" ,
267+ " select" );
219268 }
220- return res.str ();
221- }
222- else
223- {
224- throw std::runtime_error (errorMsg);
269+ res << " |(" << sub_pattern.get <std::string>() << " )" ;
225270 }
226- }();
227- patterns.emplace_back (pattern_str, std::move (cfg));
228- return ;
229- }
230- }
231- catch (nlohmann::json::out_of_range const &)
232- {
233- throw std::runtime_error (errorMsg);
271+ return res.str ();
272+ }
273+ else
274+ {
275+ throw_up (
276+ " Must be a string or an array of string!" , " select" );
277+ throw std::runtime_error (" Unreachable!" );
278+ }
279+ }();
280+ patterns.emplace_back (pattern_str, std::move (cfg));
281+ return ;
234282 }
235283 }
236284} // namespace
0 commit comments