AbortFormatting exception while modifing the ast node - eclipse-cdt

In short, while I tried to modify AST, the eclipse cdt gives me org.eclipse.cdt.internal.formatter.AbortFormatting, Code sample:
for ( IASTNode node : nodes) {
rewriter.replace(node, node.copy(), null);
}
Change change = rewriter.rewriteAST();
change = change.perform(new NullProgressMonitor());
this simple code just replace a node with a same copy of it, just for sake of testing, some nodes replaced successuflly and other gives me this exception
org.eclipse.cdt.internal.formatter.AbortFormatting: [1783/54] Unexpected token type, expecting:23, actual:Token type=1 image =IdleTime offset=89705
I have been struggling for a while to know the reason and how to solve it but with no luck

Related

list package `MoveToFront` not working for me

New to Go and building a simple LRU cache in Go to get used to syntax and Go development.
Having an issue with the MoveToFront list method, it fails on the following check in the MoveToFront body
if e.list != l || l.root.next == e
I want to move the element (e) to the front of the list when I retrieve it from cache , like this
if elem, ok := lc.entries[k]; ok {
lc.list.MoveToFront(elem) // needs fixing
return elem
}
return nil
The Code can be seen here on line 32 the issue occurs
https://github.com/hajjboy95/golrucache/blob/master/lru_cache/lrucache.go#L32
There seem to be two problems, to me. First, this isn't how the List data type is meant to be used: lc.list.PushFront() will create a List.Element and return a pointer to it. That's not fatal, but at the least, it is kind of annoying—the caller has to dig through the returned List.Element when using Get, instead of just getting the value.
Meanwhile, presumably the failure you see is because you remove elements in Put when the LRU-list runs out of space, but you don't remove them from the corresponding map. Hence a later Put of the just-removed key will try to re-use the element in place, even though the element was removed from the list. To fix this, you'll need to hold both key and value. (In my simple experiment I did not see any failures here, but the problem became clear enough.)
I restructured the code somewhat and turned it into a working example on the Go Playground. I make no promises as to suitability, etc.

Eclipse CDT: Modify and save AST

I'm exploring ways to alter the AST of a C/C++ code (e.g., rename a node, add a new variable) and apply these changes to the source file.
I did a lot of reading here in SO and in Eclipse forums. However I didn't find a minimal working example.
It seems that the correct way to make changes in an AST is by using the ASTRewrite class.
A similar question was asked in SO a few months ago, but it is still pending.
Here is where I'm stuck at the moment:
//get the factory
INodeFactory nodeFactory = myAST.getASTNodeFactory();
//create a new function declarator
IASTNode n = nodeFactory.newFunctionDeclarator(nodeFactory.newName("testMe"));
//get the rewriter
ASTRewrite rewriter = ASTRewrite.create(mainAST);
//replace node with n, node is not null
rewriter.replace(node, n, null);
//make the changes
Change c = rewriter.rewriteAST();
c.perform(new NullProgressMonitor());
When I run this code snippet, I get a
java.lang.NoClassDefFoundError: org/eclipse/ltk/core/refactoring/Change
Any hints are appreciated.

xerces_3_1 adoptNode() method returns NULL

i'm currently working with xerces 3.1 in visual studio 2010.
I've written this (very simple) piece of code:
XMLPlatformUtils::Initialize();
DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(L"XML 1.0");
DOMDocument* doc1 = impl->createDocument(L"nsURI", L"abc:root1", 0);
DOMDocument* doc2 = impl->createDocument(0, L"root2", 0);
DOMElement* root1 = doc1->getDocumentElement();
DOMElement* root2 = doc2->getDocumentElement();
DOMElement* el1 = doc1->createElement(L"el1");
root1->appendChild(el1);
DOMNode* tmpNode = doc2->adoptNode(el1); //tmpNode is null after this line
root2->appendChild(tmpNode);
doc1->release();
doc2->release();
xercesc::XMLPlatformUtils::Terminate();
The problem is, the adoptNode(...) method will always return a null-pointer no matter what. I really don't understand what's going on here, please help me!
PS: I know i could use the importNode(...) method and remove and release the old node from the old document, but i was hoping there was a way to fix my problem with adoptNode(...)!
The xerces api states the following for adoptNode(DOMNode* source):
Changes the ownerDocument of a node, its children, as well as the attached attribute nodes if there are any.
After some research i took a look at the implementation of adoptNode in xerces 3.1 and the sad truth is that it's not possible. Quoting the sourcecode:
if(sourceNode->getOwnerDocument()!=this)
{
// cannot take ownership of a node created by another document, as it comes from its memory pool
// and would be delete when the original document is deleted
return 0;
}
EDIT:
There is a workaround for this method but it requires some knowledge of the DOM-Implementation (especially when using UserData). You can import the node with importNode(...) and delete the other node out of the old document.
The old nodes should be released in order to not waste memory!
If you've got userdata attached to the old nodes, the new document has to have some UserDataHandler which adopts the userdata from the old node to the new node!
Please note that possible references on the old nodes do not point onto the new nodes now. They'll have to be changed manually (or with some UserDataHandler workaround)

Xerces, xpaths, and XML namespaces

I'm trying to use xerces-c in order to parse a rather massive XML document generated from StarUML in order to change some things, but I'm running into issues getting the xpath query to work because it keeps crashing.
To simplify things I split out part of the file into a smaller XML file for testing, which looks like this:
<?xml version="1.0" encoding="utf-8"?>
<XPD:UNIT xmlns:XPD="http://www.staruml.com" version="1">
<XPD:HEADER>
<XPD:SUBUNITS>
</XPD:SUBUNITS>
</XPD:HEADER>
<XPD:BODY>
<XPD:OBJ name="Attributes[3]" type="UMLAttribute" guid="onMjrHQ0rUaSkyFAWtLzKwAA">
<XPD:ATTR name="StereotypeName" type="string">ConditionInteraction</XPD:ATTR>
</XPD:OBJ>
</XPD:BODY>
</XPD:UNIT>
All I'm trying to do for this example is to find all of the XPD:OBJ elements, of which there is only one. The problem seems to stem from trying to query with the namespace. When I pass a very simple xpath query of XPD:OBJ it will crash, but if I pass just OBJ it won't crash but it won't find the XPD:OBJ element.
I assume there's some important property or setting that I'm missing during initialization that I need to set but I have no idea what it might be. I looked up all of the properties of the parser having to do with namespace and enabled the ones I could but it didn't help at all so I'm completely stuck. The initialization code looks something like this, with lots of things removed obviously:
const tXercesXMLCh tXMLManager::kDOMImplementationFeatures[] =
{
static_cast<tXercesXMLCh>('L'),
static_cast<tXercesXMLCh>('S'),
static_cast<tXercesXMLCh>('\0')
};
// Instantiate the DOM parser.
fImplementation = static_cast<tXercesDOMImplementationLS *>(tXercesDOMImplementationRegistry::getDOMImplementation(kDOMImplementationFeatures));
if (fImplementation != nullptr)
{
fParser = fImplementation->createLSParser(tXercesDOMImplementationLS::MODE_SYNCHRONOUS, nullptr);
fConfig = fParser->getDomConfig();
// Let the validation process do its datatype normalization that is defined in the used schema language.
//fConfig->setParameter(tXercesXMLUni::fgDOMDatatypeNormalization, true);
// Ignore comments and whitespace so we don't get extra nodes to process that just waste time.
fConfig->setParameter(tXercesXMLUni::fgDOMComments, false);
fConfig->setParameter(tXercesXMLUni::fgDOMElementContentWhitespace, false);
// Setup some properties that look like they might be required to get namespaces to work but doesn't seem to help at all.
fConfig->setParameter(tXercesXMLUni::fgXercesUseCachedGrammarInParse, true);
fConfig->setParameter(tXercesXMLUni::fgDOMNamespaces, true);
fConfig->setParameter(tXercesXMLUni::fgDOMNamespaceDeclarations, true);
// Install our custom error handler.
fConfig->setParameter(tXercesXMLUni::fgDOMErrorHandler, &fErrorHandler);
}
Then later on I parse the document, find the root node, and then run the xpath query to find the node I want. I'll leave out the bulk of that and just show you where I'm running the xpath query in case there's something obviously wrong there:
tXercesDOMDocument * doc; // Comes from parsing the file.
tXercesDOMNode * contextNode; // This is the root node retrieved from the document.
tXercesDOMXPathResult * xPathResult;
doc->evaluate("XPD:OBJ", contextNode, nullptr, tXercesDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE), xPathResult);
The call to evaluate() is where it crashes somewhere deep inside xerces that I can't see very clearly, but from what I can see there are a lot of things that look deleted or uninitialized so I'm not sure what's causing the crash exactly.
So is there anything here that looks obviously wrong or missing that is required to make xerces work with XML namespaces?
The solution was right in front of my face the whole time. The problem was that you need to create and pass a resolver to the evaluate() call or else it will not be able to figure out any of the namespaces and will throw an exception. The crash seems to be a bug in xerces since it's crashing on trying to throw the exception when it can't resolve the namespace. I had to debug deep into the xerces code to find it, which gave me the solution.
So to fix the problem I changed the call to evaluate() slightly to create a resolver with the root node and now it works perfectly:
tXercesDOMDocument * doc; // Comes from parsing the file.
tXercesDOMNode * contextNode; // This is the root node retrieved from the document.
tXercesDOMXPathResult * xPathResult;
// Create the resolver with the root node, which contains the namespace definition.
tXercesDOMXPathNSResolver * resolver(doc->createNSResolver(contextNode));
doc->evaluate("XPD:OBJ", contextNode, resolver, tXercesDOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE), xPathResult);
// Make sure to release the resolver since anything created from a `create___()`
// function has to be manually released.
resolver->release();

Replace root node for Document

I found a memory leak in my application using libxml++ due to an XML document where I replace the root node. I took good care for removing any child nodes, but using the xmlpp::Document interface I find no way to replace the root node.
This is a sample of the offending code:
xmlpp::Document Doc;
Doc.create_root_node("root");
// Populate the document
// [...]
void ReplaceRootNode(const xmlpp::Element* NewRootNode)
{
// Remove all root node children
xmlpp::Element* RootNode = Doc.get_root_node();
const xmlpp::Node::NodeList Children = RootNode->get_children();
xmlpp::Node::NodeList::const_iterator itChild = Children.begin();
while (itChild != Children.end()) {
RootNode->remove_child(*itChild++);
}
// Replace root node
Doc.create_root_node_by_import(NewRootNode); // Leak: memory for previous root node is not freed
}
The solution I came up with so far is to edit the document's root node to change it's name and attributes but. Is there a simpler way to avoid this leak which does not involve edition of previous root node's name and attributes?
I work around this by setting the document to an empty Document object (Doc = xmlpp:Document()) before calling create_root_node_by_import instead of removing the root's child nodes explicitly. This appears to cause the previous contents of Doc to be freed.
I first encountered this problem several years ago, and it still does not appear to be fixed in recent versions of libxml++. Surely they must be aware of it. Could this case somehow be using create_root_node_by_import in an unintended fashion? I would not have thought so, but OTOH this seems too important not to fix.