Circular Double Linked list visualization using natvis - c++

I would like to write a natvis visualizer for a double linked list. The list does not have a count node stored, and the easy way does not work very well, as the expansion never stops (next is never null, the last item of the list is pointing to the list root).
<Type Name="TListBidir<*>">
<Expand>
<LinkedListItems>
<HeadPointer>next</HeadPointer>
<NextPointer>next</NextPointer>
<ValueNode>($T1 *)this</ValueNode>
</LinkedListItems>
</Expand>
</Type>
I hoped I will be able to add a Condition attribute the the NextPointer comparing it with the list head, but as the NextPoint is evaluated in the context of the node, I do not know what to compare it with:
<NextPointer Condition="next!=XXXXXXXXX">next</NextPointer>
This is how it looked like with previous (2010) visualizers, using the skip directive, as the #list was handling this automatically:
#list is protected against infinite traversals and will cope gracefully with a circular list. Also, you can use a skip: expression to denote a sentinel node that should not be reported. Although the name implies that the node will be skipped, it actually causes traversal to stop, so if your sentinel node is first you should start traversal after it.
TListBidir<*,*,*>{
children
(
#list(
head: ((($T2 *)&$c)->next),
next: next,
skip : &($c)
): (($T1 *)(&$e))
)
}
How can I explain in the natvis to the debugger it should stop expanding the list once it reaches the root element again?

I had a similar problem, not with a circular list, but with a sentinel node at the end that pointed at itself, and came up with an interesting solution that might be adaptable to your needs: You could use the ternary operator to fake out a real termination. The expressions inside <NextPointer> can be anything you can write in vanilla C, so you can do real computation in there (but sadly, no recursion).
(Note that you're not allowed to put a Condition attribute on <NextPointer>, so the ternary operator is the only way to accomplish conditions there.)
So in my case, the list terminated like this:
<LinkedListItems>
<HeadPointer>this</HeadPointer>
<NextPointer>next != this ? next : 0</NextPointer>
<ValueNode>items</ValueNode>
</LinkedListItems>
In your case, if the nodes each have a pointer to their container, you can use that to compare against the head node:
<LinkedListItems>
<HeadPointer>container->head</HeadPointer>
<NextPointer>next != container->head ? next : 0</NextPointer>
<ValueNode>items</ValueNode>
</LinkedListItems>
Or, without the > entities and written as more traditional C, that's equivalent to:
next != container->head ? next : NULL
If you don't have some kind of container back-pointer, though, you're probably out of luck on this, since there's no way by looking at only a single node in a circularly-linked list to answer whether it's effectively the "last" node.

You can do this with a CustomListItems element:
<CustomListItems>
<Variable Name="orig_head" InitialValue="head"/>
<Variable Name="iter" InitialValue="first_elem"/>
<Loop>
<Break Condition="iter == orig_head || iter == 0"/>
<Item>*iter</Item>
<Exec>iter = iter->next_elem</Exec>
</Loop>
</CustomListItems>
CustomListItems allows you to save the head in a variable so it can be used while traversing the list. If your head has a different type then the list nodes you will need to cast it to the node type.

The natvis framework does not currently support circular linked lists without a count provided. If you provide a count, it should work. However, without a count, there is no good way to prevent the expansion from just continuing on forever.

Related

xerces c++ getChildNodes getLength

I am trying to parse am XML string using xerces c++.
The structure is
<root>
<optionA>
<optionB/>
</optionA>
</root>
I read the xml string into MemBufInputSource and then parse it.
When I call getChildNodes() on root, it always returns 2. Should it not be 1? Here, only option A is the child of root. Also, for each child I check if its a node and of type element. For the first child, the check is always false.
Why does it show a count of 2 children?
getChildNodes() returns all child nodes, not just the ones that are elements.
The whitespace between the elements (new lines in this case) count as a text node (DOMNode::NodeType::TEXT_NODE). By my count there are actually 2 text nodes in your example, so 3 child nodes overall, though differences when transcribing into the question, or different configuration of Xerces may have resulted in 2 child nodes in your original code.
If you change your XML example to be all on one line with no whitespace
<root><optionA><optionB/></optionA></root>
you can see that Xerces will then report that there is only one child of root.
Here is the full list of node types that Xerces may encounter.

Delete Node of BOOST Spirit AST Tree

I have a question concerning Abstract Syntax Trees generated with Boost Spirit Library.
I've found many informations about deleting nodes and subtrees in a Binary Search Tree, but I cannot find the same information for ASTs. I have a node in an AS-Tree, and this node is root to a subtree of a complete tree. Now I want to delete the node and all of its children.
I don't know how to do it, and the Boost Spirit Documentation didn't help either.
Has anyone got any tips for me?
The Tree is generated with (Boost 1.46.1):
tree_parse_info<> info = ast_parse(expression.c_str(), parser, skipparser);
And the Expression is something like this:
(variable_17 OR variable_18) AND function( variable_17) <= 30 OR function( subkey_18) <= 30
I use
tree_match<iterator_t>::tree_iterator tree_it = info.trees.begin();
to get the beginning of the tree, and then I do check if one of the subtrees is redundant (doensn't have anything to do with the deleting itself). `Then I traverse through the tree using
tree_match<iterator_t>::tree_iterator children_it = tree_it->children.begin()
and calling the same function with its children (recursive). I can't post the complete code,but that's the most important part of it. I thought, that i can traverse to the leafnodes of a redundant subtree, and set them to null, or something like this. And then I go up the tree again, and delete all other children one after another. However, nothing has worked so far.
An example for traversing the tree: The Traversing
It's the answer.
If I can't delete any nodes, does anyone has an idea, how to create a new tree, based on the existing one, skiping the redundant parts of it.

How to add item to list in prolog

I have a list in prolog that contains several items. I need to 'normalized' the content of this list and write the result to a new list. But I still have problem in doing it.
The following code shows how I did it:
normalizeLists(SourceList, DestList) :-
% get all the member of the source list, one by one
member(Item, SourceList),
% normalize the item
normalizeItem(Item, NormItem),
% add the normalize Item to the Destination List (it was set [] at beginning)
append(NormItem, DestList, DestList).
The problem is in the append predicate. I guess it is because in prolog, I cannot do something like in imperative programming, such as:
DestList = DestList + NormItem,
But how can I do something like that in Prolog? Or if my approach is incorrect, how can I write prolog code to solve this kind of problem.
Any help is really appreciated.
Cheers
Variables in Prolog cannot be modified, once bound by unification. That is a variable is either free or has a definite value (a term, could be another variable). Then append(NormItem, DestList, DestList) will fail for any NormItem that it's not an empty list.
Another problem it's that NormItem it's not a list at all. You can try
normalizeLists([], []).
normalizeLists([Item|Rest], [NormItem|NormRest]) :-
% normalize the item
normalizeItem(Item, NormItem),
normalizeLists(Rest, NormRest).
or (if your Prolog support it) skip altogether such definition, and use an higher order predicate, like maplist
...
maplist(normalizeItem, Items, Normalized),
...

xpath / xslt: find the last node depending on the sub nodes

How can I find the last node that contains a specific structure?
<defect-event>
<event-assigned-to>
<assigned-to-user>
<last-name>Doe</last-name>
<first-name>John</first-name>
<middle-name></middle-name>
</assigned-to-user>
</event-assigned-to>
</defect-event>
There can be many "defect-event" nodes at the same level, below or above the one with the "assigned-to-user" sub node.
There can also be multiple "defect-event" nodes with the "assigned-to-user" sub node.
I need to find the last one "defect-event" node which contains the "assigned-to-user" sub node.
Thanks!
Something on these lines is probably what you want:
defect-event[event-assigned-to[assigned-to-user]][position()=last()]
In effect, you're saying "find me all the defect-event which contains an event-assigned-to containing an assigned-to-user, and then just give me the one whose position() is last()".
Having said that, you might need to tweak this depending on the context you're in when you try to find the node, and what you're doing to the node (eg: behaviour might vary if you're in a for-each loop as opposed to an apply-templates situation).

How do I de-duplicate a list of nodes in XSLT - and return the last node encountered?

I've seen lots of "de-duplicate this xml" questions but everyone wants the first node or the nodes are identical. I have a bit of a bigger puzzle.
I have a list of articles in XML, a relevant snippet is shown:
<item><key>Article1</key><stamp>100</stamp></item>
<item><key>Article1</key><stamp>130</stamp></item>
<item><key>Article2</key><stamp>800</stamp></item>
<item><key>Article1</key><stamp>180</stamp></item>
<item><key>Article3</key><stamp>900</stamp></item>
<item><key>Article3</key><stamp>950</stamp></item>
<item><key>Article4</key><stamp>990</stamp></item>
<item><key>Article5</key><stamp>999</stamp></item>
I'd like a list of nodes where the keys are unique and where the last instance is returned, not the first: Stamp (integer) is always increasing for elements of a particular key. Ideally I'd like "largest stamp" but they're always in order so the shortcut is ok.
Desired result: (Order doesn't really matter.)
<item><key>Article2</key><stamp>800</stamp></item>
<item><key>Article1</key><stamp>180</stamp></item>
<item><key>Article3</key><stamp>950</stamp></item>
<item><key>Article4</key><stamp>990</stamp></item>
<item><key>Article5</key><stamp>999</stamp></item>
I'm somewhat confused on how to get this list. Any ideas?
I'm using the Saxon processor if it matters.
The short version:
Instead of using [1] in the Muenchian grouping, use [last()]