14#include "arcane/launcher/internal/ParamFile.h"
16#include "arcane/launcher/ArcaneLauncher.h"
18#include "arcane/utils/PlatformUtils.h"
19#include "arcane/utils/UniqueArray.h"
20#include "arcane/utils/FatalErrorException.h"
21#include "arcane/utils/StringBuilder.h"
22#include "arcane/utils/CommandLineArguments.h"
23#include "arcane/utils/JSONReader.h"
177 void read(
const String& case_and_variations_values);
178 bool displayDetails()
const {
return m_build_path; }
179 String path()
const {
return m_path; }
180 String configPartName() {
return m_arcane_custom_part_name.
empty() ? m_arcane_part_name : m_arcane_custom_part_name; }
184 void _readDependPart(
const JSONValue& depend_part);
185 void _readConfigPart(
const JSONValue& config_part,
const String& node_name);
186 void _addElemInPath(
const String& elem);
187 void _readFileBeforePart(
const JSONValue& config_part);
188 void _readFileAfterPart(
const JSONValue& config_part);
189 void _readArcanePart(
const JSONValue& config_part);
195 bool m_build_path =
false;
203 const String m_arcane_part_name =
"arcane";
204 String m_arcane_custom_part_name;
211: m_build_path(!
platform::getEnvironmentVariable(
"ARCANE_ARCANET_PATH").null())
220void ParamFile::Reader::
221read(
const String& case_and_variations_values)
224 if (!case_and_variations_values.
empty()) {
226 case_and_variations_values.
split(split_case,
':');
228 for (
const String& elem : split_case) {
229 if (elem.contains(
"=")) {
231 elem.split(split_variation,
'=');
232 if (split_variation.
size() != 2) {
235 m_variations_key_resolved.
add(split_variation[0]);
236 m_variations_value_resolved.add(split_variation[1]);
240 if (!case_name.
empty()) {
241 ARCANE_FATAL(
"You must choose a variation for '{0}'.", elem);
243 if (elem.contains(
"~")) {
244 UniqueArray<String> split_case_name_with_prog_subname;
245 elem.split(split_case_name_with_prog_subname,
'~');
246 if (split_case_name_with_prog_subname.size() != 2) {
249 case_name = split_case_name_with_prog_subname[0];
250 m_arcane_custom_part_name = m_arcane_part_name +
"~" + split_case_name_with_prog_subname[1];
261 const JSONValue cases = m_root.child(
"general");
262 if (!cases.isNull()) {
264 m_explored.add(
"general");
265 _readConfigPart(cases,
"general");
268 if (!case_name.
empty()) {
269 const JSONValue cases = m_root.child(
"cases").child(case_name);
274 m_explored.add(case_name);
275 _readConfigPart(cases, case_name);
282void ParamFile::Reader::
283_readDependPart(
const JSONValue& depend_part)
285 if (depend_part.null())
288 const JSONValueList array = depend_part.valueAsArray();
289 for (
const JSONValue elem : array) {
290 JSONValue dependence_node;
291 String dependence_name = elem.valueAsStringView();
293 if (dependence_name.contains(
"=")) {
294 UniqueArray<String> split_variation;
295 dependence_name.split(split_variation,
'=');
296 if (split_variation.size() != 2) {
297 ARCANE_FATAL(
"Element '{0}' is invalid.", dependence_name);
300 const JSONValue variation = m_root.child(
"variations").child(split_variation[0]).child(split_variation[1]);
301 if (variation.null()) {
302 ARCANE_FATAL(
"Element '//variations/{0}/{1}' not found.", split_variation[0], split_variation[1]);
304 if (m_explored.contains(dependence_name)) {
305 ARCANE_FATAL(
"Element '//variations/{0}/{1}' already explored.", split_variation[0], split_variation[1]);
307 m_explored.
add(dependence_name);
310 dependence_node = m_root.child(
"commons").child(dependence_name);
311 if (!dependence_node.null()) {
312 if (m_explored.contains(dependence_name)) {
313 ARCANE_FATAL(
"Element '//commons/{0}' already explored.", dependence_name);
315 m_explored.add(dependence_name);
318 String cleaned_dependence_name;
319 UniqueArray<String> split_dependence_name;
320 if (dependence_name.contains(
"!")) {
321 dependence_name.split(split_dependence_name,
'!');
322 cleaned_dependence_name = split_dependence_name[0];
325 cleaned_dependence_name = dependence_name;
327 auto pos_elem = m_variations_key_resolved.span().findFirst(cleaned_dependence_name);
329 if (!pos_elem.has_value()) {
330 const JSONValue error_ = m_root.child(
"variations").child(cleaned_dependence_name);
332 ARCANE_FATAL(
"Element '//commons/{0}' not found.", cleaned_dependence_name);
334 ARCANE_FATAL(
"Element '{0}' not found in 'Case' cmd line option.", cleaned_dependence_name);
337 String value = m_variations_value_resolved[pos_elem.value()];
338 if (!split_dependence_name.empty()) {
339 ArrayView excluded_values(split_dependence_name.subView(1, split_dependence_name.size() - 1));
340 if (excluded_values.contains(value)) {
341 ARCANE_FATAL(
"Element '//variations/{0}/{1}' is excluded.", cleaned_dependence_name, value);
344 dependence_name = cleaned_dependence_name +
"=" + value;
346 dependence_node = m_root.child(
"variations").child(cleaned_dependence_name).child(value);
347 if (dependence_node.null()) {
348 ARCANE_FATAL(
"Element '//variations/{0}/{1}' not found.", cleaned_dependence_name, value);
350 if (m_explored.contains(dependence_name)) {
351 ARCANE_FATAL(
"Element '//variations/{0}/{1}' already explored.", cleaned_dependence_name, value);
353 m_explored.add(dependence_name);
357 _readConfigPart(dependence_node, dependence_name);
364void ParamFile::Reader::
365_readConfigPart(
const JSONValue& config_part,
const String& node_name)
370 _readFileBeforePart(config_part);
371 _addElemInPath(node_name);
372 _readArcanePart(config_part);
373 _readFileAfterPart(config_part);
378 _readFileBeforePart(config_part);
379 _readArcanePart(config_part);
380 _readFileAfterPart(config_part);
387void ParamFile::Reader::
388_addElemInPath(
const String& elem)
391 for (
Integer i = 0; i < m_level_path; ++i)
399void ParamFile::Reader::
400_readFileBeforePart(
const JSONValue& config_part)
402 const JSONValue depend_before_var = config_part.child(
"_").child(
"depend_b");
403 _readDependPart(depend_before_var);
426void ParamFile::Reader::
427_readFileAfterPart(
const JSONValue& config_part)
429 const JSONValue depend_after_var = config_part.child(
"_").child(
"depend_a");
430 _readDependPart(depend_after_var);
436void ParamFile::Reader::
437_readArcanePart(
const JSONValue& config_part)
439 JSONValue arcane_part;
440 if (!m_arcane_custom_part_name.empty()) {
441 arcane_part = config_part.child(m_arcane_custom_part_name);
443 if (arcane_part.null()) {
444 arcane_part = config_part.child(m_arcane_part_name);
446 else if (m_build_path) {
448 m_path += m_arcane_custom_part_name;
455 const JSONValue dataset = arcane_part.child(
"dataset");
456 if (!dataset.isNull()) {
457 m_cargs.addParameterLine(String::format(
"CaseDatasetFileName={0}", dataset.value()));
461 const JSONValue arcane_params = arcane_part.child(
"options");
463 if (!arcane_params.isNull()) {
464 const JSONKeyValueList params = arcane_params.keyValueChildren();
466 for (
auto elem : params) {
467 m_cargs.addParameterLine(String::format(
"{0}={1}", elem.name(), elem.value().valueAsStringView()));
481editParams(
const String& param_file_name,
const String& variation)
485 JSONDocument json_doc;
487 UniqueArray<Byte> bytes;
496 const JSONValue root = json_doc.root();
497 Reader reader(cargs, root);
499 reader.read(variation);
501 if (reader.displayDetails()) {
502 std::cout <<
"ArcaNet path: " << reader.path() << std::endl;
503 std::cout <<
"ArcaNet config part readed: " << reader.configPartName() << std::endl;
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Integer size() const
Number of elements in the vector.
void setCommandLineArguments(const CommandLineArguments &args)
Sets the command line arguments.
const CommandLineArguments & commandLineArguments() const
Command line arguments.
static ApplicationInfo & applicationInfo()
Application information.
void add(ConstReferenceType val)
Adds element val to the end of the array.
@ ParseNumbersAsStringsFlag
Parse all numbers (ints/doubles) as strings.
@ ParseCommentsFlag
Allow one-line (//) and multi-line (/**/) comments.
Unicode character string constructor.
Unicode character string.
bool empty() const
True if the string is empty (null or "").
void split(StringContainer &str_array, char c) const
Splits the string based on the character c.
1D data vector with value semantics (STL style).
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
GenericReader< UTF8<>, UTF8<> > Reader
Reader with UTF8 encoding and default allocator.