This is for C code detection. I'm trying to flag case statements that don't have a break. The hierarchy of the tree looks like this when there are multiple lines before the break statement. This is an example in C:
switch (x) {
case 1:
if (...) {...}
int y = 0;
for (...) {...}
break;
case 2:
It is somehow represented as this:
<switch>
<case>...</case>
<if>...</if>
<expression>...</expression>
<for>...</for>
<break>...</break>
<case>...</case>
</switch>
I need to find <case>
s where a <break>
exists after any number of lines, but before the next <case>
.
This code only helps me find those where the break doesn't immediately follow the case:
//case [name(following-sibling::*[1]) != 'break']
..but when I try to use following-sibling::* it will find a break, but not necessarily before the next case.
How can I do this?
Select any case
that has a following break
and either no following case
or where the position of the next break
is less than the position of the next case
. With the positions determined by running count()
on the preceding siblings.
//case
[
following-sibling::break and
(
not(following-sibling::case) or
(
count(following-sibling::break[1]/preceding-sibling::*) <
count(following-sibling::case[1]/preceding-sibling::*)
)
)
]
To grab the other cases, those without breaks, just throw a big old not()
in there like so:
//case
[not(
following-sibling::break and
(
not(following-sibling::case) or
(
count(following-sibling::break[1]/preceding-sibling::*) <
count(following-sibling::case[1]/preceding-sibling::*)
)
)
)]