summaryrefslogtreecommitdiff
path: root/cpp/src/FreezeScript/Transformer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/FreezeScript/Transformer.cpp')
-rw-r--r--cpp/src/FreezeScript/Transformer.cpp395
1 files changed, 278 insertions, 117 deletions
diff --git a/cpp/src/FreezeScript/Transformer.cpp b/cpp/src/FreezeScript/Transformer.cpp
index 8f45f6ad093..db9a7aabdc6 100644
--- a/cpp/src/FreezeScript/Transformer.cpp
+++ b/cpp/src/FreezeScript/Transformer.cpp
@@ -99,7 +99,7 @@ protected:
private:
- typedef std::map<std::string, InitDescriptorPtr> InitMap;
+ typedef map<string, InitDescriptorPtr> InitMap;
InitMap _initMap;
bool _enabled;
};
@@ -122,9 +122,9 @@ protected:
Descriptor(const DescriptorPtr&, int, const TransformInfoIPtr&);
- NodePtr parse(const std::string&) const;
+ NodePtr parse(const string&) const;
- Slice::TypePtr findType(const Slice::UnitPtr&, const std::string&);
+ Slice::TypePtr findType(const Slice::UnitPtr&, const string&);
DescriptorPtr _parent;
int _line;
@@ -148,10 +148,10 @@ private:
EntityNodePtr _target;
NodePtr _value;
- std::string _valueStr;
- std::string _type;
+ string _valueStr;
+ string _type;
NodePtr _length;
- std::string _lengthStr;
+ string _lengthStr;
bool _convert;
};
@@ -170,9 +170,9 @@ public:
private:
- std::string _name;
+ string _name;
NodePtr _value;
- std::string _valueStr;
+ string _valueStr;
Slice::TypePtr _type;
bool _convert;
};
@@ -194,10 +194,12 @@ private:
EntityNodePtr _target;
NodePtr _key;
- std::string _keyStr;
+ string _keyStr;
+ NodePtr _index;
+ string _indexStr;
NodePtr _value;
- std::string _valueStr;
- std::string _type;
+ string _valueStr;
+ string _type;
bool _convert;
};
@@ -218,7 +220,9 @@ private:
EntityNodePtr _target;
NodePtr _key;
- std::string _keyStr;
+ string _keyStr;
+ NodePtr _index;
+ string _indexStr;
};
//
@@ -251,8 +255,8 @@ public:
private:
NodePtr _test;
- std::string _testStr;
- std::string _message;
+ string _testStr;
+ string _message;
};
//
@@ -270,9 +274,9 @@ public:
private:
- std::string _message;
+ string _message;
NodePtr _value;
- std::string _valueStr;
+ string _valueStr;
};
//
@@ -283,7 +287,7 @@ class ExecutableContainerDescriptor : public Descriptor
public:
ExecutableContainerDescriptor(const DescriptorPtr&, int, const TransformInfoIPtr&, const IceXML::Attributes&,
- const std::string&);
+ const string&);
virtual void addChild(const DescriptorPtr&);
virtual void validate();
@@ -291,11 +295,11 @@ public:
protected:
- std::vector<DescriptorPtr> _children;
+ vector<DescriptorPtr> _children;
private:
- std::string _name;
+ string _name;
};
//
@@ -312,7 +316,7 @@ public:
private:
NodePtr _test;
- std::string _testStr;
+ string _testStr;
};
//
@@ -329,10 +333,10 @@ public:
private:
EntityNodePtr _target;
- std::string _key;
- std::string _value;
- std::string _element;
- std::string _index;
+ string _key;
+ string _value;
+ string _element;
+ string _index;
};
//
@@ -345,9 +349,9 @@ public:
TransformDescriptor(const DescriptorPtr&, int, const TransformInfoIPtr&, const IceXML::Attributes&);
Slice::TypePtr type() const;
- std::string typeName() const;
+ string typeName() const;
Slice::TypePtr renameType() const;
- std::string renameTypeName() const;
+ string renameTypeName() const;
bool doDefaultTransform() const;
bool doBaseTransform() const;
@@ -371,7 +375,7 @@ public:
void initialize(const DataPtr&);
- std::string typeName() const;
+ string typeName() const;
private:
@@ -433,7 +437,7 @@ public:
private:
DatabaseDescriptorPtr _database;
- std::vector<DescriptorPtr> _children;
+ vector<DescriptorPtr> _children;
};
typedef IceUtil::Handle<TransformDBDescriptor> TransformDBDescriptorPtr;
@@ -518,10 +522,10 @@ public:
DescriptorHandler(const TransformInfoIPtr&);
- virtual void startElement(const std::string&, const IceXML::Attributes&, int, int);
- virtual void endElement(const std::string&, int, int);
- virtual void characters(const std::string&, int, int);
- virtual void error(const std::string&, int, int);
+ virtual void startElement(const string&, const IceXML::Attributes&, int, int);
+ virtual void endElement(const string&, int, int);
+ virtual void characters(const string&, int, int);
+ virtual void error(const string&, int, int);
TransformDBDescriptorPtr descriptor() const;
@@ -927,11 +931,16 @@ FreezeScript::AddDescriptor::AddDescriptor(const DescriptorPtr& parent, int line
target = p->second;
p = attributes.find("key");
- if(p == attributes.end())
+ if(p != attributes.end())
{
- _info->errorReporter->error("required attribute `key' is missing");
+ _keyStr = p->second;
+ }
+
+ p = attributes.find("index");
+ if(p != attributes.end())
+ {
+ _indexStr = p->second;
}
- _keyStr = p->second;
p = attributes.find("value");
if(p != attributes.end())
@@ -951,9 +960,19 @@ FreezeScript::AddDescriptor::AddDescriptor(const DescriptorPtr& parent, int line
_convert = p->second == "true";
}
+ if(!_keyStr.empty() && !_indexStr.empty())
+ {
+ _info->errorReporter->error("attributes `key' and `index' are mutually exclusive");
+ }
+
+ if(_keyStr.empty() && _indexStr.empty())
+ {
+ _info->errorReporter->error("one of attributes `key' or `index' is required");
+ }
+
if(!_valueStr.empty() && !_type.empty())
{
- _info->errorReporter->error("attributes `value' and 'type' are mutually exclusive");
+ _info->errorReporter->error("attributes `value' and `type' are mutually exclusive");
}
NodePtr node = parse(target);
@@ -963,8 +982,15 @@ FreezeScript::AddDescriptor::AddDescriptor(const DescriptorPtr& parent, int line
_info->errorReporter->error("`target' attribute is not an entity: `" + target + "'");
}
- assert(!_keyStr.empty());
- _key = parse(_keyStr);
+ if(!_keyStr.empty())
+ {
+ _key = parse(_keyStr);
+ }
+
+ if(!_indexStr.empty())
+ {
+ _index = parse(_indexStr);
+ }
if(!_valueStr.empty())
{
@@ -997,75 +1023,151 @@ FreezeScript::AddDescriptor::execute(const SymbolTablePtr& sym)
_info->errorReporter->error("target `" + ostr.str() + "' cannot be modified");
}
- DictionaryDataPtr dict = DictionaryDataPtr::dynamicCast(data);
- if(!dict)
+ if(_key)
{
- ostringstream ostr;
- ostr << _target;
- _info->errorReporter->error("target `" + ostr.str() + "' is not a dictionary");
- }
+ DictionaryDataPtr dict = DictionaryDataPtr::dynamicCast(data);
+ if(!dict)
+ {
+ ostringstream ostr;
+ ostr << _target;
+ _info->errorReporter->error("target `" + ostr.str() + "' is not a dictionary");
+ }
- Slice::DictionaryPtr type = Slice::DictionaryPtr::dynamicCast(dict->getType());
- assert(type);
+ Slice::DictionaryPtr type = Slice::DictionaryPtr::dynamicCast(dict->getType());
+ assert(type);
- DataPtr key;
- Destroyer<DataPtr> keyDestroyer;
- try
- {
- DataPtr v = _key->evaluate(sym);
- key = _info->factory->create(type->keyType(), false);
- keyDestroyer.set(key);
- assignOrTransform(key, v, _convert, _info);
+ DataPtr key;
+ Destroyer<DataPtr> keyDestroyer;
+ try
+ {
+ DataPtr v = _key->evaluate(sym);
+ key = _info->factory->create(type->keyType(), false);
+ keyDestroyer.set(key);
+ assignOrTransform(key, v, _convert, _info);
+ }
+ catch(const EvaluateException& ex)
+ {
+ _info->errorReporter->error("evaluation of key `" + _keyStr + "' failed:\n" + ex.reason());
+ }
+
+ if(dict->getElement(key))
+ {
+ ostringstream ostr;
+ printData(key, ostr);
+ _info->errorReporter->error("key " + ostr.str() + " already exists in dictionary");
+ }
+
+ DataPtr elem = _info->factory->create(type->valueType(), false);
+ Destroyer<DataPtr> elemDestroyer(elem);
+
+ DataPtr value;
+ if(_value)
+ {
+ try
+ {
+ value = _value->evaluate(sym);
+ }
+ catch(const EvaluateException& ex)
+ {
+ _info->errorReporter->error("evaluation of value `" + _valueStr + "' failed:\n" + ex.reason());
+ }
+ }
+
+ Destroyer<DataPtr> valueDestroyer;
+ if(!_type.empty())
+ {
+ assert(!value);
+ Slice::TypePtr type = sym->lookupType(_type);
+ if(!type)
+ {
+ _info->errorReporter->error("type `" + _type + "' not found");
+ }
+ value = _info->factory->createObject(type, false);
+ valueDestroyer.set(value);
+ }
+
+ if(value)
+ {
+ assignOrTransform(elem, value, _convert, _info);
+ }
+ DataMap& map = dict->getElements();
+ map.insert(DataMap::value_type(key, elem));
+ keyDestroyer.release();
+ elemDestroyer.release();
}
- catch(const EvaluateException& ex)
+ else
{
- _info->errorReporter->error("evaluation of key `" + _keyStr + "' failed:\n" + ex.reason());
- }
+ assert(_index);
- if(dict->getElement(key))
- {
- ostringstream ostr;
- printData(key, ostr);
- _info->errorReporter->error("key " + ostr.str() + " already exists in dictionary");
- }
+ SequenceDataPtr seq = SequenceDataPtr::dynamicCast(data);
+ if(!seq)
+ {
+ ostringstream ostr;
+ ostr << _target;
+ _info->errorReporter->error("target `" + ostr.str() + "' is not a sequence");
+ }
- DataPtr elem = _info->factory->create(type->valueType(), false);
- Destroyer<DataPtr> elemDestroyer(elem);
+ Slice::SequencePtr type = Slice::SequencePtr::dynamicCast(seq->getType());
+ assert(type);
- DataPtr value;
- if(_value)
- {
+ DataPtr index;
+ Destroyer<DataPtr> indexDestroyer;
try
{
- value = _value->evaluate(sym);
+ index = _index->evaluate(sym);
+ indexDestroyer.set(index);
}
catch(const EvaluateException& ex)
{
- _info->errorReporter->error("evaluation of value `" + _valueStr + "' failed:\n" + ex.reason());
+ _info->errorReporter->error("evaluation of index `" + _indexStr + "' failed:\n" + ex.reason());
}
- }
- Destroyer<DataPtr> valueDestroyer;
- if(!_type.empty())
- {
- assert(!value);
- Slice::TypePtr type = sym->lookupType(_type);
- if(!type)
+ DataList& elements = seq->getElements();
+ Ice::Long l = index->integerValue();
+ DataList::size_type i = static_cast<DataList::size_type>(l);
+ if(l < 0 || l > INT_MAX || i > elements.size())
{
- _info->errorReporter->error("type `" + _type + "' not found");
+ _info->errorReporter->error("sequence index " + index->toString() + " is out of range");
}
- value = _info->factory->createObject(type, false);
- valueDestroyer.set(value);
- }
- if(value)
- {
- assignOrTransform(elem, value, _convert, _info);
+ DataPtr elem = _info->factory->create(type->type(), false);
+ Destroyer<DataPtr> elemDestroyer(elem);
+
+ DataPtr value;
+ if(_value)
+ {
+ try
+ {
+ value = _value->evaluate(sym);
+ }
+ catch(const EvaluateException& ex)
+ {
+ _info->errorReporter->error("evaluation of value `" + _valueStr + "' failed:\n" + ex.reason());
+ }
+ }
+
+ Destroyer<DataPtr> valueDestroyer;
+ if(!_type.empty())
+ {
+ assert(!value);
+ Slice::TypePtr type = sym->lookupType(_type);
+ if(!type)
+ {
+ _info->errorReporter->error("type `" + _type + "' not found");
+ }
+ value = _info->factory->createObject(type, false);
+ valueDestroyer.set(value);
+ }
+
+ if(value)
+ {
+ assignOrTransform(elem, value, _convert, _info);
+ }
+
+ elements.insert(elements.begin() + i, elem);
+ indexDestroyer.release();
+ elemDestroyer.release();
}
- DataMap& map = dict->getElements();
- map.insert(DataMap::value_type(key, elem));
- keyDestroyer.release();
- elemDestroyer.release();
}
//
@@ -1088,11 +1190,16 @@ FreezeScript::RemoveDescriptor::RemoveDescriptor(const DescriptorPtr& parent, in
target = p->second;
p = attributes.find("key");
- if(p == attributes.end())
+ if(p != attributes.end())
{
- _info->errorReporter->error("required attribute `key' is missing");
+ _keyStr = p->second;
+ }
+
+ p = attributes.find("index");
+ if(p != attributes.end())
+ {
+ _indexStr = p->second;
}
- _keyStr = p->second;
NodePtr node = parse(target);
_target = EntityNodePtr::dynamicCast(node);
@@ -1101,7 +1208,25 @@ FreezeScript::RemoveDescriptor::RemoveDescriptor(const DescriptorPtr& parent, in
_info->errorReporter->error("`target' attribute is not an entity: `" + target + "'");
}
- _key = parse(_keyStr);
+ if(!_keyStr.empty() && !_indexStr.empty())
+ {
+ _info->errorReporter->error("attributes `key' and `index' are mutually exclusive");
+ }
+
+ if(_keyStr.empty() && _indexStr.empty())
+ {
+ _info->errorReporter->error("one of attributes `key' or `index' is required");
+ }
+
+ if(!_keyStr.empty())
+ {
+ _key = parse(_keyStr);
+ }
+
+ if(!_indexStr.empty())
+ {
+ _index = parse(_indexStr);
+ }
}
void
@@ -1121,16 +1246,6 @@ FreezeScript::RemoveDescriptor::execute(const SymbolTablePtr& sym)
{
DescriptorErrorContext ctx(_info->errorReporter, "remove", _line);
- DataPtr key;
- try
- {
- key = _key->evaluate(sym);
- }
- catch(const EvaluateException& ex)
- {
- _info->errorReporter->error("evaluation of key `" + _keyStr + "' failed:\n" + ex.reason());
- }
-
DataPtr data = sym->getValue(_target);
if(data->readOnly())
{
@@ -1139,21 +1254,67 @@ FreezeScript::RemoveDescriptor::execute(const SymbolTablePtr& sym)
_info->errorReporter->error("target `" + ostr.str() + "' cannot be modified");
}
- DictionaryDataPtr dict = DictionaryDataPtr::dynamicCast(data);
- if(!dict)
+ if(_key)
{
- ostringstream ostr;
- ostr << _target;
- _info->errorReporter->error("target `" + ostr.str() + "' is not a dictionary");
- }
+ DataPtr key;
+ try
+ {
+ key = _key->evaluate(sym);
+ }
+ catch(const EvaluateException& ex)
+ {
+ _info->errorReporter->error("evaluation of key `" + _keyStr + "' failed:\n" + ex.reason());
+ }
- DataMap& map = dict->getElements();
- DataMap::iterator p = map.find(key);
- if(p != map.end())
+ DictionaryDataPtr dict = DictionaryDataPtr::dynamicCast(data);
+ if(!dict)
+ {
+ ostringstream ostr;
+ ostr << _target;
+ _info->errorReporter->error("target `" + ostr.str() + "' is not a dictionary");
+ }
+
+ DataMap& map = dict->getElements();
+ DataMap::iterator p = map.find(key);
+ if(p != map.end())
+ {
+ p->first->destroy();
+ p->second->destroy();
+ map.erase(p);
+ }
+ }
+ else
{
- p->first->destroy();
- p->second->destroy();
- map.erase(p);
+ assert(_index);
+
+ DataPtr index;
+ try
+ {
+ index = _index->evaluate(sym);
+ }
+ catch(const EvaluateException& ex)
+ {
+ _info->errorReporter->error("evaluation of index `" + _indexStr + "' failed:\n" + ex.reason());
+ }
+
+ SequenceDataPtr seq = SequenceDataPtr::dynamicCast(data);
+ if(!seq)
+ {
+ ostringstream ostr;
+ ostr << _target;
+ _info->errorReporter->error("target `" + ostr.str() + "' is not a sequence");
+ }
+
+ DataList& elements = seq->getElements();
+ Ice::Long l = index->integerValue();
+ DataList::size_type i = static_cast<DataList::size_type>(l);
+ if(l < 0 || l > INT_MAX || i >= elements.size())
+ {
+ _info->errorReporter->error("sequence index " + index->toString() + " is out of range");
+ }
+
+ elements[i]->destroy();
+ elements.erase(elements.begin() + i);
}
}
@@ -2707,19 +2868,19 @@ FreezeScript::DescriptorHandler::startElement(const string& name, const IceXML::
}
void
-FreezeScript::DescriptorHandler::endElement(const std::string& name, int, int)
+FreezeScript::DescriptorHandler::endElement(const string& name, int, int)
{
assert(_current);
_current = _current->parent();
}
void
-FreezeScript::DescriptorHandler::characters(const std::string&, int, int)
+FreezeScript::DescriptorHandler::characters(const string&, int, int)
{
}
void
-FreezeScript::DescriptorHandler::error(const std::string& msg, int line, int col)
+FreezeScript::DescriptorHandler::error(const string& msg, int line, int col)
{
_info->errorReporter->descriptorError(msg, line);
}