Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
CaseOptionExtended.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/* CaseOptionExtended.cc (C) 2000-2025 */
9/* */
10/* Option of the 'Extended' data set type. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/core/CaseOptionExtended.h"
15
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/FatalErrorException.h"
18#include "arcane/utils/StringBuilder.h"
19#include "arcane/utils/internal/ParameterCaseOption.h"
20
21#include "arcane/core/ICaseMng.h"
22#include "arcane/core/CaseOptionError.h"
23#include "arcane/core/ICaseDocumentVisitor.h"
24#include "arcane/core/XmlNodeList.h"
25#include "arcane/core/ICaseOptionList.h"
26#include "arcane/core/MeshHandle.h"
27#include "arcane/core/ICaseDocument.h"
28#include "arcane/core/CaseOptionException.h"
29#include "arcane/core/internal/StringVariableReplace.h"
30#include "arcane/core/internal/ICaseMngInternal.h"
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35namespace Arcane
36{
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
50_search(bool is_phase1)
51{
52 ITraceMng* tm = traceMng();
54 const ParameterCaseOption pco{ params.getParameterCaseOption(caseDocumentFragment()->language()) };
55 String full_xpath = String::format("{0}/{1}", rootElement().xpathFullName(), name());
56
57 // !!! In XML, we start at 1 and not 0.
58 UniqueArray<Integer> option_in_param;
59
60 pco.indexesInParam(full_xpath, option_in_param, false);
61
62 XmlNodeList elem_list = rootElement().children(name());
63 Integer size = elem_list.size();
64 bool is_optional = isOptional();
65
66 if (size == 0 && option_in_param.empty() && is_optional) {
67 return;
68 }
69
70 Integer min_occurs = minOccurs();
71 Integer max_occurs = maxOccurs();
72
73 Integer max_in_param = 0;
74
75 // We check if the user provided too high an index for the option on the command line.
76 if (!option_in_param.empty()) {
77 max_in_param = option_in_param[0];
78 for (Integer index : option_in_param) {
79 if (index > max_in_param)
80 max_in_param = index;
81 }
82 if (max_occurs >= 0) {
83 if (max_in_param > max_occurs) {
84 StringBuilder msg = "Bad number of occurences in command line (greater than max)";
85 msg += " index_max_in_param=";
86 msg += max_in_param;
87 msg += " max_occur=";
88 msg += max_occurs;
89 msg += " option=";
90 msg += full_xpath;
91 throw CaseOptionException(A_FUNCINFO, msg.toString(), true);
92 }
93 }
94 }
95
96 if (max_occurs >= 0) {
97 if (size > max_occurs) {
98 StringBuilder msg = "Bad number of occurences (greater than max)";
99 msg += " nb_occur=";
100 msg += size;
101 msg += " max_occur=";
102 msg += max_occurs;
103 msg += " option=";
104 msg += full_xpath;
105 throw CaseOptionException(A_FUNCINFO, msg.toString(), true);
106 }
107 }
108
109 // There will always be at least min_occurs options.
110 // If there are not enough options in the data set and in the command line parameters,
111 // default values are added (if no default exists, it will crash).
112 Integer final_size = std::max(size, std::max(min_occurs, max_in_param));
113
114 if (is_phase1) {
115 _allocate(final_size);
116 m_values.resize(final_size);
117 }
118 else {
119 // First, we get the data set options: since we cannot define an index
120 // for options in the data set, they will necessarily be at the beginning and contiguous.
121 // Then, if options are missing to reach min_occurs, default options are added.
122 // If there is no default option, an exception will occur.
123 // Finally, the user may have added options from the command line. We add them then.
124 // If the user wishes to modify data set values from the command line, we
125 // replace the options during reading.
126 for (Integer i = 0; i < final_size; ++i) {
127 String str_val;
128
129 // Command line parameters part.
130 if (option_in_param.contains(i + 1)) {
131 str_val = pco.getParameterOrNull(full_xpath, i + 1, false);
132 }
133
134 // Data set part.
135 else if (i < size) {
136 XmlNode velem = elem_list[i];
137 if (!velem.null()) {
138 str_val = velem.value();
139 }
140 }
141
142 // Default value.
143 if (str_val.null()) {
144 str_val = _defaultValue();
145 }
146 else {
147 // In an else: Symbol replacement does not apply to default values from the .axl.
148 str_val = StringVariableReplace::replaceWithCmdLineArgs(params, str_val, true);
149 }
150
151 // Now, this crash also concerns the case where there are no default values and there are
152 // not enough options to reach min_occurs.
153 if (str_val.null()) {
155 name(), rootElement());
156 continue;
157 }
158 tm->info(5) << "TryConvert opt=" << _xpathFullName() << " i=" << i
159 << " mesh_name=" << parentOptionList()->meshHandle().meshName()
160 << " value=" << str_val;
161 bool is_bad = _tryToConvert(str_val, i);
162 if (is_bad) {
163 m_values[i] = String();
165 name(), rootElement(), str_val, _typeName());
166 continue;
167 }
168 m_values[i] = str_val;
169 //ptr_value[i] = val;
170 //cerr << "** FOUND " << val << endl;
171 }
172 }
173}
174
175/*---------------------------------------------------------------------------*/
176/*---------------------------------------------------------------------------*/
177
179print(const String& lang, std::ostream& o) const
180{
181 ARCANE_UNUSED(lang);
182 for (Integer i = 0, s = _nbElem(); i < s; ++i)
183 o << m_values[i] << " ";
184}
185
186/*---------------------------------------------------------------------------*/
187/*---------------------------------------------------------------------------*/
188
190visit(ICaseDocumentVisitor* visitor) const
191{
192 visitor->applyVisitor(this);
193}
194
195/*---------------------------------------------------------------------------*/
196/*---------------------------------------------------------------------------*/
197
199setDefaultValue(const String& def_value)
200{
201 // If a value is provided by the user, we do nothing.
202 if (isPresent())
203 return;
204
205 // Value already initialized. In this case, we also replace the
206 // current value.
207 if (_isInitialized()) {
208 bool is_bad = _tryToConvert(def_value);
209 if (is_bad) {
210 m_value = String();
211 ARCANE_FATAL("Can not convert '{0}' to type '{1}' (option='{2}')",
212 def_value, _typeName(), xpathFullName());
213 }
214 m_value = def_value;
215 }
216
217 // The default value does not have an associated language.
218 _setDefaultValue(def_value);
219}
220
221/*---------------------------------------------------------------------------*/
222/*---------------------------------------------------------------------------*/
223
233_search(bool is_phase1)
234{
235 CaseOptionSimple::_search(is_phase1);
236 if (is_phase1)
237 return;
238 ITraceMng* tm = traceMng();
239 // If the option is not present in the data set, we take
240 // the default option.
241 String str_val = (_element().null()) ? _defaultValue() : _element().value();
242 bool has_valid_value = true;
243 if (str_val.null()) {
244 m_value = String();
245 if (!isOptional()) {
247 name(), rootElement());
248 return;
249 }
250 else
251 has_valid_value = false;
252 }
253 _setHasValidValue(has_valid_value);
254 if (has_valid_value) {
255 tm->info(5) << "TryConvert opt=" << xpathFullName()
256 << " mesh_name=" << parentOptionList()->meshHandle().meshName()
257 << " value=" << str_val;
258 bool is_bad = _tryToConvert(str_val);
259 if (is_bad) {
260 m_value = String();
262 name(), rootElement(), str_val, _typeName());
263 return;
264 }
265 m_value = str_val;
266 }
267 _setIsInitialized();
268}
269
270/*---------------------------------------------------------------------------*/
271/*---------------------------------------------------------------------------*/
272
274print(const String& lang, std::ostream& o) const
275{
276 ARCANE_UNUSED(lang);
277 _checkIsInitialized();
278 if (hasValidValue())
279 o << m_value;
280 else
281 o << "undefined";
282}
283
284/*---------------------------------------------------------------------------*/
285/*---------------------------------------------------------------------------*/
286
288visit(ICaseDocumentVisitor* visitor) const
289{
290 visitor->applyVisitor(this);
291}
292
293/*---------------------------------------------------------------------------*/
294/*---------------------------------------------------------------------------*/
295
296} // End namespace Arcane
297
298/*---------------------------------------------------------------------------*/
299/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
bool empty() const
Capacity (number of allocated elements) of the vector.
bool contains(ConstReferenceType v) const
True if the array contains the value element v.
String name() const
Returns the option name corresponding to the data set language.
String _defaultValue() const
Returns the default value of the option or 0 if none exists.
ICaseMng * caseMng() const
Case manager.
ICaseDocumentFragment * caseDocumentFragment() const
Returns the document associated with this option.
bool isOptional() const
Allows knowing if an option is optional.
Integer maxOccurs() const
Maximum number of occurrences (for a multiple option) (-1 == unbounded).
XmlNode rootElement() const
Returns the root element of the DOM.
ITraceMng * traceMng() const
Trace manager.
ICaseOptionList * parentOptionList() const
Parent OptionList.
Integer minOccurs() const
Minimum number of occurrences (for a multiple option).
static void addInvalidTypeError(ICaseDocumentFragment *document, const TraceInfo &where, const String &node_name, const XmlNode &parent, const String &value, const String &expected_type)
Error when a dataset value is not of the correct type. This error is collective.
static void addOptionNotFoundError(ICaseDocumentFragment *document, const TraceInfo &where, const String &node_name, const XmlNode &parent)
Error when a dataset option is not found. This error is collective.
Exception related to the dataset.
void _search(bool is_phase1) override
Searches for the option value in the data set.
void setDefaultValue(const String &def_value)
Sets the default value of the option.
String m_value
Value of the option in unicode string format.
void print(const String &lang, std::ostream &o) const override
Prints the option value in the language lang, to the stream o.
void visit(ICaseDocumentVisitor *visitor) const override
Applies the visitor to this option.
UniqueArray< String > m_values
Values in unicode string format.
void print(const String &lang, std::ostream &o) const override
Prints the option value in the language lang, to the stream o.
void _search(bool is_phase1) override
Searches for the option value in the data set.
void visit(ICaseDocumentVisitor *visitor) const override
Applies the visitor to this option.
String xpathFullName() const
Full name in the format provided by the XPath standard.
bool hasValidValue() const
Indicates if the option has an invalid value.
bool isOptional() const
Indicates if the option is optional.
bool isPresent() const
Returns true if the option is present.
Visitor interface for a dataset option.
virtual const ParameterListWithCaseOption & parameters() const =0
List of parameters that can override the dataset.
virtual ICaseMngInternal * _internalImpl()=0
Internal implementation.
virtual MeshHandle meshHandle() const =0
Handle of the associated mesh.
virtual TraceMessage info()=0
Stream for an information message.
Class representing the set of parameters that can modify the dataset options.
void indexesInParam(const String &xpath_before_index, const String &xpath_after_index, UniqueArray< Integer > &indexes) const
Method allowing retrieval of the index or indices of the option.
String getParameterOrNull(const String &xpath_before_index, const String &xpath_after_index, Integer index) const
Method allowing retrieval of an option's value.
Parameter list with information to override dataset options.
ParameterCaseOption getParameterCaseOption(const String &language) const
Method to retrieve an object of type ParameterCaseOption.
Unicode character string constructor.
String toString() const
Returns the constructed character string.
bool null() const
Returns true if the string is null.
Definition String.cc:306
1D data vector with value semantics (STL style).
List of nodes of a DOM tree.
Definition XmlNodeList.h:36
Node of a DOM tree.
Definition XmlNode.h:51
String value() const
Node value.
Definition XmlNode.cc:208
XmlNodeList children(const String &name) const
Set of child nodes of this node having the name name.
Definition XmlNode.cc:102
bool null() const
True if the node is null.
Definition XmlNode.h:303
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.