10#include "AMReX_ParallelDescriptor.H"
17 for (
auto &child : node.children)
18 if (child.name == name)
29SameConditions(
const std::vector<IO::InputScraper::InputNode::Condition> &a,
30 const std::vector<IO::InputScraper::InputNode::Condition> &b)
32 if (a.size() != b.size())
return false;
33 for (std::size_t i = 0; i < a.size(); i++)
34 if (a[i].path != b[i].path || a[i].value != b[i].value)
40WriteConditions(std::ostream &os,
41 const std::vector<IO::InputScraper::InputNode::Condition> &conditions,
45 for (std::size_t i = 0; i < conditions.size(); i++)
53 if (!conditions.empty())
62WriteContextsField( std::ostream &os,
bool &first,
int indent,
63 const std::vector<std::vector<IO::InputScraper::InputNode::Condition>> &contexts)
66 os <<
"\"contexts\": [";
67 for (std::size_t i = 0; i < contexts.size(); i++)
72 WriteConditions(os, contexts[i], indent + 2);
74 if (!contexts.empty())
83WriteConstraint(std::ostream &os,
92 if (!constraint.
units.empty())
97 os <<
"\"conditions\": ";
98 WriteConditions(os, constraint.
conditions, indent + 2);
107WriteTraversalIgnore( std::ostream &os,
145 WriteContextsField(os, first, indent + 2, node.
contexts);
149 os <<
"\"constraints\": [";
150 for (std::size_t i = 0; i < node.
constraints.size(); i++)
155 WriteConstraint(os, node.
constraints[i], indent + 4);
164 os <<
"\"children\": [";
165 for (std::size_t i = 0; i < node.
children.size(); i++)
170 WriteNode(os, node.
children[i], indent + 4);
182WriteFlowNodes( std::ostream &os,
183 const std::vector<IO::InputScraper::FlowNode> &nodes,
199 os <<
"\"branches\": [";
200 for (std::size_t i = 0; i < node.
branches.size(); i++)
206 bool branch_first =
true;
210 os <<
"\"children\": ";
211 WriteFlowNodes(os, node.
branches[i].children, indent + 6);
223 os <<
"\"children\": ";
224 WriteFlowNodes(os, node.
children, indent + 2);
232WriteFlowNodes( std::ostream &os,
233 const std::vector<IO::InputScraper::FlowNode> &nodes,
237 for (std::size_t i = 0; i < nodes.size(); i++)
242 WriteFlowNode(os, nodes[i], indent + 2);
265InputScraper::InputNode &
269 std::size_t start = 0;
270 while (start < path.size())
272 std::size_t end = path.find(
'.', start);
273 std::string part = path.substr(start, end - start);
275 node = &GetChild(*node, part);
276 if (end == std::string::npos)
286 for (
const auto &context : node.
contexts)
287 if (SameConditions(context, conditions))
289 node.
contexts.push_back(conditions);
294 const std::string &directive,
295 const std::vector<std::string> &options,
296 const std::source_location &location,
297 bool has_unnamed_default)
304 if (it->input == path)
315 flow_node->
input = path;
323 flow_node->
kind =
"switch";
324 if (has_unnamed_default)
327 for (
const auto &branch : flow_node->
branches)
328 if (branch.value.empty())
333 for (
const auto &option : options)
336 for (
const auto &branch : flow_node->
branches)
337 if (branch.value == option)
342 branch.
value = option;
343 flow_node->
branches.push_back(std::move(branch));
350 const std::vector<std::string> &options)
352 if (directive ==
"query_switch" || directive ==
"query_if" ||
353 directive ==
"query_if_else")
355 if (directive ==
"select" || directive ==
"select_default")
return "switch";
356 if ((directive ==
"query" || directive ==
"query_required" || directive ==
"query_default") &&
357 options == std::vector<std::string>{
"0",
"1"})
359 if (directive ==
"select_enumerate")
return "sequence";
360 if (directive ==
"query_enumerate" || directive ==
"queryarr_enumerate" || directive ==
"queryclass_enumerate")
return "sequence";
361 if (directive ==
"queryclass")
return "scope";
368 if (old_kind ==
"scope")
return new_kind;
369 if (new_kind ==
"switch" || new_kind ==
"sequence")
return new_kind;
376 std::string name = location.function_name();
378 std::size_t paren = name.find(
'(');
379 if (paren != std::string::npos)
380 name = name.substr(0, paren);
382 std::size_t scope = name.rfind(
"::");
383 if (scope != std::string::npos)
384 name = name.substr(scope + 2);
386 std::size_t space = name.rfind(
' ');
387 if (space != std::string::npos)
388 name = name.substr(space + 1);
447 os <<
" \"schema_version\": 3,\n";
448 os <<
" \"format\": \"alamo.input_schema\",\n";
451 os <<
",\n \"flow\": ";
455 os <<
",\n \"traversal_ignored\": [";
471 if (path.empty())
return;
472 if (!amrex::ParallelDescriptor::IOProcessor())
return;
474 std::ofstream os(path);
482 if (!amrex::ParallelDescriptor::IOProcessor())
return;
487 std::cout <<
"-> " << pp.
full(name) <<
" = " << value << std::endl;
493 std::string directive,
494 const std::source_location &location,
495 std::vector<std::string> options,
496 std::optional<std::string> default_value,
497 bool has_unnamed_default)
505 if (!options.empty())
506 node.
options = std::move(options);
507 node.
required = node.
required || directive.find(
"required") != std::string::npos;
508 node.
has_default = node.
has_default || directive.find(
"default") != std::string::npos || default_value.has_value();
510 if (default_value.has_value())
517 has_unnamed_default);
519 if (!amrex::ParallelDescriptor::IOProcessor())
return;
528 for (std::size_t i = 0; i < node.
options.size(); i++)
530 if (i) std::cout <<
", ";
535 std::cout << std::endl;
540 const std::string &sequence_name,
541 const std::string &template_name)
545 const std::string sequence_path = pp.
full(sequence_name);
546 const std::string template_path = pp.
full(template_name);
547 const std::size_t dot = template_path.rfind(
'.');
548 const std::string parent_path =
549 dot == std::string::npos ? std::string() : template_path.substr(0, dot);
550 const std::string child_name =
551 dot == std::string::npos ? template_path : template_path.substr(dot + 1);
555 [&](
const InputNode &node) { return node.name == child_name; });
564 auto sequence = std::find_if(
566 [&](
const FlowNode &node) { return node.input == sequence_path; });
571 const bool template_root = it->input == template_path;
572 const bool template_child =
573 it->input.size() > template_path.size() &&
574 it->input.compare(0, template_path.size(), template_path) == 0 &&
575 it->input[template_path.size()] ==
'.';
576 if (!template_root && !template_child)
582 sequence->children.push_back(std::move(*it));
591 std::vector<std::string> members,
592 std::vector<std::string> units,
593 const std::source_location &location)
597 for (
auto &member : members)
598 member = pp.
full(member);
602 constraint.
kind = std::move(kind);
603 constraint.
count = count;
604 constraint.
members = std::move(members);
605 constraint.
units = std::move(units);
608 scope.
constraints.push_back(std::move(constraint));
617 const auto duplicate = std::find_if(
621 return std::string(ignore.location.file_name()) == location.file_name() &&
622 ignore.location.line() == location.line();
644 const std::string &value)
648 const std::string path = pp.
full(name);
652 if (it->input == path && it->kind ==
"switch")
663 switch_node->
kind =
"switch";
664 switch_node->
input = path;
668 for (
auto &branch : switch_node->
branches)
670 if (branch.value == value)
672 selected_branch = &branch;
676 if (!selected_branch)
679 branch.
value = value;
680 switch_node->
branches.push_back(std::move(branch));
681 selected_branch = &switch_node->
branches.back();
static void WriteStringField(std::ostream &os, bool &first, int indent, const std::string &name, const std::string &value)
static void Comma(std::ostream &os, bool &first, int indent)
static void WriteBoolField(std::ostream &os, bool &first, int indent, const std::string &name, bool value)
static void WriteSourceField(std::ostream &os, bool &first, int indent, const std::source_location &location)
static std::string Escape(const std::string &value)
static void WriteIntField(std::ostream &os, bool &first, int indent, const std::string &name, int value)
static void Indent(std::ostream &os, int indent)
static void WriteStringArrayField(std::ostream &os, bool &first, int indent, const std::string &name, const std::vector< std::string > &values)
std::string getPrefix() const
std::string full(std::string name)