9 #include <boost/format.hpp> 26 static bool IncludeNode(gp::Node* node,
28 gp::IncludedFiles* included, gp::Messages* messages) {
29 gp::Node include_root;
30 bool status =
gp::Parse(node->position, node->value, search_path, included,
31 messages, &include_root);
32 if (!status)
return false;
33 node->value = include_root.value;
34 node->children.reserve( node->children.size() + include_root.children.size());
40 static bool UnitsNode(gp::Node* node,
42 gp::IncludedFiles* included, gp::Messages* messages) {
44 bool status =
gp::ParseUnits(node->position, node->value, search_path,
45 included, messages, &units_root);
46 if (!status)
return false;
47 node->value = units_root.value;
48 node->children.reserve( node->children.size() + units_root.children.size());
55 if (node->children.size() == 1) {
61 for(
unsigned int i=0; i < (node->children.size() - 1); ++i) {
62 client += delim+node->children[i].value;
66 node->children[node->children.size() - 1].value, node->position));
76 case gp::Node::kReal: {
82 if (node->children.size() == 1) {
85 double unit_value = 0;
86 if (units->Find(unit_name, unit_value)) {
93 gp::PositionalPropertyValueException::CouldNotFindUnit(
94 node->children[0].position, unit_name);
97 value.
reset(
new gp::PropertyValue(node->value));
102 case gp::Node::kString: {
104 value.
reset(
new gp::PropertyValue(
'"'+node->value+
'"'));
108 case gp::Node::kBool: {
109 value.
reset(
new gp::PropertyValue(node->value));
113 case gp::Node::kVector: {
117 return GetPropertyValue(&child, catalog, units)->ToString();
123 case gp::Node::kMap: {
125 for(
const auto& child : node->children) {
126 auto kvalue = GetPropertyValue(&child.children[0], catalog, units);
127 auto vvalue = GetPropertyValue(&child.children[1], catalog, units);
128 result.
emplace( kvalue->ToString(), vvalue->ToString() );
134 case gp::Node::kProperty: {
135 auto property = GetPropertyName(node);
138 value.
reset(
new gp::PropertyValue(exists->property_value()));
141 gp::PositionalPropertyValueException::CouldNotFindProperty(
142 node->position,
property->ToString());
146 case gp::Node::kPropertyRef: {
147 auto property = GetPropertyName(node);
169 case gp::Node::kEqual : {
173 case gp::Node::kPlusEqual : {
177 case gp::Node::kMinusEqual : {
189 static bool AssignNode(
const gp::Node* node,
190 gp::Messages* messages, gp::Catalog* catalog, gp::Units* units,
195 auto property = GetPropertyName(&node->children[0]);
197 value = GetPropertyValue(&node->children[2], catalog, units);
198 }
catch(
const gp::PositionalPropertyValueException& ex){
199 messages->AddError(ex.position(), ex.what());
203 bool reassign =
false;
211 if (node->children[1].type == gp::Node::kEqual) {
214 if (exists->HasDefinedPosition()) {
215 message +=
" Previously defined at " +
216 exists->DefinedPosition().ToString() +
".";
221 }
else if (node->children[1].type == gp::Node::kPlusEqual) {
223 }
else if (node->children[1].type == gp::Node::kMinusEqual) {
226 }
catch(
const gp::PropertyValueException& ex) {
228 if (exists->HasDefinedPosition()) {
229 message +=
" Previously defined at "+exists->DefinedPosition().
232 messages->AddError(node->position, message);
238 if ( !exists || reassign) {
242 if (result && is_print) {
245 % SignString(node->children[1].type)
246 % value->ToString());
247 messages->AddInfo(node->position, message);
252 static bool UnitNode(
const gp::Node* node,
253 gp::Messages* messages, gp::Units* units,
bool is_print) {
259 gp::Units::Container::mapped_type exists;
260 if (units->Find(name, exists)) {
263 if (exists.second.Exists()) {
264 message +=
" at "+exists.second.ToString();
266 messages->AddError(node->children[1].position, message);
270 bool result = units->Add(name, right / left, node->children[1].position);
271 if (result && is_print) {
276 messages->AddInfo(node->position, message);
281 static bool ConditionNode(gp::Node* node,
282 gp::Catalog* catalog, gp::Node** next) {
284 auto property_name = GetPropertyName(&node->children[0]);
286 bool is_defined = (
nullptr != catalog->Find(property_name->client(),
287 property_name->property()));
289 if ((is_defined && (node->children[1].type == gp::Node::kIfdef))
290 || (!is_defined && (node->children[1].type == gp::Node::kIfndef))
292 *next = &node->children[1];
293 }
else if (node->children.size()>2){
294 *next = &node->children[2];
301 static bool Analyze(gp::Node* node,
302 const std::string& search_path, gp::IncludedFiles* included,
303 gp::Messages* messages, gp::Catalog* catalog, gp::Units* units,
304 gp::PragmaOptions* pragma) {
307 bool local_result =
true;
308 bool skip_childs =
true;
309 gp::Node* next_root = node;
311 switch (node->type) {
313 case gp::Node::kRoot: {
318 case gp::Node::kInclude: {
319 local_result = IncludeNode(node, search_path, included, messages);
324 case gp::Node::kUnits: {
325 local_result = UnitsNode(node, search_path, included, messages);
330 case gp::Node::kAssign: {
331 local_result = AssignNode(node, messages, catalog, units,
336 case gp::Node::kUnit: {
337 local_result = UnitNode(node, messages, units, pragma->is_print());
341 case gp::Node::kCondition: {
342 local_result = ConditionNode(node, catalog, &next_root);
347 case gp::Node::kPrintOptions: {
348 pragma->setIsPrintOptions(
true);
352 case gp::Node::kPrintOn : {
353 pragma->setIsPrint(
true);
357 case gp::Node::kPrintOff : {
358 pragma->setIsPrint(
false);
362 case gp::Node::kPrintTree : {
363 pragma->setIsPrintTree(
true);
367 case gp::Node::kDumpFile : {
370 pragma->setDumpFile(file);
372 pragma->setDumpFile(node->value);
381 if (result) result = local_result;
383 if (!skip_childs && next_root) {
384 for(
auto& child : next_root->children) {
386 Analyze(&child, search_path, included, messages, catalog, units,
388 if (result) result = local_result;
395 bool unreference_result =
true;
396 for(
auto& client : catalog) {
397 for (
auto& current : client.second ) {
398 if (current.IsReference()) {
399 gp::PropertyValue& value = current.property_value();
401 gp::Property*
property = catalog.Find(names[0], names[1]);
403 messages->AddError(value.position(),
404 "Could not unreference " + current.ValueAsString());
405 unreference_result =
false;
407 value =
property->property_value();
412 return unreference_result;
421 bool result =
Parse(filename, search_path, &included, messages, root);
422 if (!result)
return false;
424 bool result1 = Analyze(root, search_path, &included, messages, catalog, units,
427 return result1 && result2;
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
GAUDI_API StatusCode resolveEnv(const std::string &var, std::string &res, int recusions=124)
bool ParseUnits(const Position &from, const std::string &filename, const std::string &search_path, IncludedFiles *included, Messages *messages, Node *root)
Gaudi::Details::PropertyBase * property(const std::string &name) const
bool ReadOptions(const std::string &filename, const std::string &search_path, Messages *messages, Catalog *catalog, Units *units, PragmaOptions *pragma, Node *root)
Parse and analyze filename, save all messages and properties.
Gaudi::Details::PropertyBase Property
backward compatibility hack for old Property base class
bool Parse(const std::string &filename, const std::string &search_path, IncludedFiles *included, Messages *messages, Node *root)
T back_inserter(T...args)
bool Unreference(gp::Catalog &catalog, gp::Messages *messages)
TO * reference(FROM *from)