Arcane  4.2.3.0
User documentation
Loading...
Searching...
No Matches
ArcaNetReader.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ArcaNetReader.cc (C) 2000-2026 */
9/* */
10/* Reader for ArcaNet files. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arccore/common/ArcaNetReader.h"
15
16#include "arccore/base/FatalErrorException.h"
17#include "arccore/base/PlatformUtils.h"
18#include "arccore/common/JSONReader.h"
19
20/*---------------------------------------------------------------------------*/
21/*---------------------------------------------------------------------------*/
22
23namespace Arcane
24{
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
30ArcaNetReader(const JSONValue& root)
31: m_build_path(!platform::getEnvironmentVariable("ARCCORE_ARCANET_PATH").null())
32, m_root(root)
33{
34}
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
40init(const String& case_and_variations_values, const String& prog_name)
41{
42 m_prog_part_name = prog_name;
43 if (!case_and_variations_values.empty()) {
44 // Tous les éléments sont séparés par des ":".
45 UniqueArray<String> split_case;
46 case_and_variations_values.split(split_case, ':');
47
48 for (const String& elem : split_case) {
49 // Si on "=" est présent, c'est une variation à résoudre.
50 if (elem.contains("=")) {
51 UniqueArray<String> split_variation;
52 elem.split(split_variation, '=');
53 if (split_variation.size() != 2) {
54 ARCCORE_FATAL("Bad element in Case option.");
55 }
56 m_variations_key_resolved.add(split_variation[0]);
57 m_variations_value_resolved.add(split_variation[1]);
58 // std::cout << "Add key=value : " << split_elem[0] << " = " << split_elem[1] << std::endl;
59 }
60 else {
61 if (!m_case_name.empty()) {
62 ARCCORE_FATAL("You must choose a variation for '{0}'.", elem);
63 }
64 if (elem.contains("~")) {
65 UniqueArray<String> split_case_name_with_prog_subname;
66 elem.split(split_case_name_with_prog_subname, '~');
67 if (split_case_name_with_prog_subname.size() != 2) {
68 ARCCORE_FATAL("Bad element in Case option.");
69 }
70 m_case_name = split_case_name_with_prog_subname[0];
71 m_prog_custom_part_name = m_prog_part_name + "~" + split_case_name_with_prog_subname[1];
72 }
73 else {
74 m_case_name = elem;
75 }
76 }
77 }
78 }
79}
80
81/*---------------------------------------------------------------------------*/
82/*---------------------------------------------------------------------------*/
83
85read()
86{
87 if (m_prog_part_name.empty()) {
88 ARCCORE_FATAL("You must call 'init()' method before.");
89 }
90
91 // "general" part
92 {
93 const JSONValue cases = m_root.child("general");
94 if (!cases.isNull()) {
95 // std::cout << "General part" << std::endl;
96 m_explored.add("general");
97 _readConfigPart(cases, "general");
98 }
99 }
100 if (!m_case_name.empty()) {
101 const JSONValue cases = m_root.child("cases").child(m_case_name);
102 if (cases.null()) {
103 ARCCORE_FATAL("Case '{0}' not found.", m_case_name);
104 }
105 // std::cout << "Case part : " << case_clean << std::endl;
106 m_explored.add(m_case_name);
107 _readConfigPart(cases, m_case_name);
108 }
109}
110
111/*---------------------------------------------------------------------------*/
112/*---------------------------------------------------------------------------*/
113
115extractFilePart(const JSONValue& config_part)
116{
117 return config_part.child("_");
118}
119
120/*---------------------------------------------------------------------------*/
121/*---------------------------------------------------------------------------*/
122
124extractProgPart(const JSONValue& config_part)
125{
126 JSONValue arcane_part;
127 if (!m_prog_custom_part_name.empty()) {
128 arcane_part = config_part.child(m_prog_custom_part_name);
129 }
130 if (arcane_part.null()) {
131 arcane_part = config_part.child(m_prog_part_name);
132 }
133 return arcane_part;
134}
135
136/*---------------------------------------------------------------------------*/
137/*---------------------------------------------------------------------------*/
138
140extractPart(const String& part_name, const JSONValue& config_part)
141{
142 return config_part.child(part_name);
143}
144
145/*---------------------------------------------------------------------------*/
146/*---------------------------------------------------------------------------*/
147
148void ArcaNetReader::
149_readDependPart(const JSONValue& depend_part)
150{
151 if (depend_part.null())
152 return;
153
154 const JSONValueList array = depend_part.valueAsArray();
155 for (const JSONValue elem : array) {
156 JSONValue dependence_node;
157 String dependence_name = elem.valueAsStringView();
158 {
159 // S'il y a un "=", alors on est sur une variation résolue.
160 if (dependence_name.contains("=")) {
161 UniqueArray<String> split_variation;
162 dependence_name.split(split_variation, '=');
163 if (split_variation.size() != 2) {
164 ARCCORE_FATAL("Element '{0}' is invalid.", dependence_name);
165 }
166
167 const JSONValue variation = m_root.child("variations").child(split_variation[0]).child(split_variation[1]);
168 if (variation.null()) {
169 ARCCORE_FATAL("Element '//variations/{0}/{1}' not found.", split_variation[0], split_variation[1]);
170 }
171 if (m_explored.contains(dependence_name)) {
172 ARCCORE_FATAL("Element '//variations/{0}/{1}' already explored.", split_variation[0], split_variation[1]);
173 }
174 m_explored.add(dependence_name);
175 }
176 else {
177 dependence_node = m_root.child("commons").child(dependence_name);
178 if (!dependence_node.null()) {
179 if (m_explored.contains(dependence_name)) {
180 ARCCORE_FATAL("Element '//commons/{0}' already explored.", dependence_name);
181 }
182 m_explored.add(dependence_name);
183 }
184 // Si la dépendance n'est pas dans "commons", soit c'est une variation
185 // non résolue, soit c'est une dépendance inconnue.
186 else {
187 bool is_excluded_variants = true;
188 String cleaned_dependence_name;
189 UniqueArray<String> split_dependence_name;
190 // On stocke les variations exclues, s'il y en a.
191 if (dependence_name.contains("!")) {
192 is_excluded_variants = true;
193 dependence_name.split(split_dependence_name, '!');
194 cleaned_dependence_name = split_dependence_name[0];
195 }
196 else if (dependence_name.contains("+")) {
197 is_excluded_variants = false;
198 dependence_name.split(split_dependence_name, '+');
199 cleaned_dependence_name = split_dependence_name[0];
200 }
201 else {
202 cleaned_dependence_name = dependence_name;
203 }
204 auto pos_elem = m_variations_key_resolved.span().findFirst(cleaned_dependence_name);
205
206 if (!pos_elem.has_value()) {
207 const JSONValue error_ = m_root.child("variations").child(cleaned_dependence_name);
208 if (error_.null()) {
209 ARCCORE_FATAL("Element '//commons/{0}' not found.", cleaned_dependence_name);
210 }
211 ARCCORE_FATAL("Element '{0}' not found in 'Case' cmd line option.", cleaned_dependence_name);
212 }
213
214 String value = m_variations_value_resolved[pos_elem.value()];
215 if (!split_dependence_name.empty()) {
216 ArrayView excluded_or_included_values(split_dependence_name.subView(1, split_dependence_name.size() - 1));
217 if (is_excluded_variants && excluded_or_included_values.contains(value)) {
218 ARCCORE_FATAL("Element '//variations/{0}/{1}' is excluded.", cleaned_dependence_name, value);
219 }
220 if (!is_excluded_variants && !excluded_or_included_values.contains(value)) {
221 ARCCORE_FATAL("Element '//variations/{0}/{1}' is not included.", cleaned_dependence_name, value);
222 }
223 }
224
225 // On résout la variation.
226 dependence_name = cleaned_dependence_name + "=" + value;
227
228 dependence_node = m_root.child("variations").child(cleaned_dependence_name).child(value);
229 if (dependence_node.null()) {
230 ARCCORE_FATAL("Element '//variations/{0}/{1}' not found.", cleaned_dependence_name, value);
231 }
232 if (m_explored.contains(dependence_name)) {
233 ARCCORE_FATAL("Element '//variations/{0}/{1}' already explored.", cleaned_dependence_name, value);
234 }
235 m_explored.add(dependence_name);
236 }
237 }
238 }
239 _readConfigPart(dependence_node, dependence_name);
240 }
241}
242
243/*---------------------------------------------------------------------------*/
244/*---------------------------------------------------------------------------*/
245
246void ArcaNetReader::
247_readConfigPart(const JSONValue& config_part, const String& node_name)
248{
249 if (m_build_path) {
250 _addElemInPath("{");
251 m_level_path++;
252 _readFileBeforePart(config_part);
253 _addElemInPath(node_name);
254 m_values.add(config_part);
255 _readArcanePart(config_part);
256 _readFileAfterPart(config_part);
257 m_level_path--;
258 _addElemInPath("}");
259 }
260 else {
261 _readFileBeforePart(config_part);
262 m_values.add(config_part);
263 _readFileAfterPart(config_part);
264 }
265}
266
267/*---------------------------------------------------------------------------*/
268/*---------------------------------------------------------------------------*/
269
270void ArcaNetReader::
271_addElemInPath(const String& elem)
272{
273 m_path += "\n";
274 for (Integer i = 0; i < m_level_path; ++i)
275 m_path += " ";
276 m_path += elem;
277}
278
279/*---------------------------------------------------------------------------*/
280/*---------------------------------------------------------------------------*/
281
282void ArcaNetReader::
283_readFileBeforePart(const JSONValue& config_part)
284{
285 const JSONValue depend_before_var = config_part.child("_").child("depend_b");
286 _readDependPart(depend_before_var);
287}
288
289/*---------------------------------------------------------------------------*/
290/*---------------------------------------------------------------------------*/
291
292void ArcaNetReader::
293_readFileAfterPart(const JSONValue& config_part)
294{
295 const JSONValue depend_after_var = config_part.child("_").child("depend_a");
296 _readDependPart(depend_after_var);
297}
298
299/*---------------------------------------------------------------------------*/
300/*---------------------------------------------------------------------------*/
301
302void ArcaNetReader::
303_readArcanePart(const JSONValue& config_part)
304{
305 if (!m_prog_custom_part_name.empty() && !config_part.child(m_prog_custom_part_name).null()) {
306 m_path += "(";
307 m_path += m_prog_custom_part_name;
308 m_path += ")";
309 }
310}
311
312/*---------------------------------------------------------------------------*/
313/*---------------------------------------------------------------------------*/
314
315} // namespace Arcane
316
317/*---------------------------------------------------------------------------*/
318/*---------------------------------------------------------------------------*/
#define ARCCORE_FATAL(...)
Macro throwing a FatalErrorException.
Integer size() const
Number of elements in the vector.
JSONValue extractFilePart(const JSONValue &config_part)
Method allowing to get the file part of a JSONValue (from 'jsonValues()' array).
void read()
Method allowing to read the file and fill the chain of dependencies. First, you need to call 'init()'...
ArcaNetReader(const JSONValue &root)
Constructor.
JSONValue extractPart(const String &part_name, const JSONValue &config_part)
Method allowing to get a part of a JSONValue (from 'jsonValues()' array).
JSONValue extractProgPart(const JSONValue &config_part)
Method allowing to get the program part of a JSONValue (from 'jsonValues()' array).
void init(const String &case_and_variations_values, const String &prog_name)
Method allowing to initialise the file reader.
void add(ConstReferenceType val)
Adds element val to the end of the array.
bool null() const
True if the node is null.
bool isNull() const
True if the value is of 'null' type.
JSONValue child(StringView name) const
Child value with name name. Returns a null value if not found.
bool empty() const
True if the string is empty (null or "").
Definition String.cc:317
void split(StringContainer &str_array, char c) const
Splits the string based on the character c.
bool contains(const String &s) const
Indicates if the string contains s.
Definition String.cc:1079
1D data vector with value semantics (STL style).
Namespace for platform-dependent functions.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.