Skip to content

Commit

Permalink
add Function.if_nest_level() returning max
Browse files Browse the repository at this point in the history
nesting level
  • Loading branch information
Felipe cruz committed Sep 15, 2012
1 parent eb996c1 commit 2551f93
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 0 deletions.
39 changes: 39 additions & 0 deletions README.markdown
Expand Up @@ -15,6 +15,45 @@ data = analyze("tests/test_file1.c")
[func.name for func in data.functions if func.it_calls("read")]
```

Get max if nest level:

```python
from qc.parser import analyze
code = """
int main (int argc, char *argv[]) {
char *space;
space = malloc(sizeof(char) * 10);
if (space == NULL) {
if (1 > 2) {
if (3 == 4) {
return -1;
}
} else {
if (1 == 1) {
return -1;
} else {
if (1 == 2) {
return -1;
} else {
if (1 == 2) {
return -1;
} else {
return -1;
}
}
}
}
return -1;
}
return 0;
}
"""

parsed_content = parse(code, "<string>")
main = parsed_content.functions[0]
assert 5 == main.if_nest_level()
```

## Testing

```sh
Expand Down
31 changes: 31 additions & 0 deletions qc/domain.py
Expand Up @@ -16,5 +16,36 @@ def it_calls(self, inner_function_name):
isinstance(call.rvalue, c_ast.FuncCall) and
call.rvalue.name.name == inner_function_name)])

def if_nest_level(self):
def nest_meter(if_statement):
values = []
if hasattr(if_statement, 'iftrue') and if_statement.iftrue and \
len(if_statement.iftrue.block_items):
nested_ifs = [if_stm for if_stm
in if_statement.iftrue.block_items
if isinstance(if_stm, c_ast.If)]
for nested_if in nested_ifs:
values.append(1 + nest_meter(nested_if))
if hasattr(if_statement, 'iffalse') and if_statement.iffalse and \
len(if_statement.iffalse.block_items):
nested_ifs = [if_stm for if_stm
in if_statement.iffalse.block_items
if isinstance(if_stm, c_ast.If)]
for nested_if in nested_ifs:
values.append(1 + nest_meter(nested_if))

if not values:
return 1

return max(values)

values = []
for block in self.blocks:
if isinstance(block, c_ast.If):
values.append(nest_meter(block))

return max(values)


def __str__(self):
return str(self.node)
58 changes: 58 additions & 0 deletions qc/tests/test_qc_parser.py
Expand Up @@ -43,3 +43,61 @@ def test_parse_check_functions_calling_malloc():
assert "main" == [function.name for function
in parsed_content.functions
if function.it_calls("malloc")][0]

def test_parse_check_if_nest_level():
code = """
int main (int argc, char *argv[]) {
char *space;
space = malloc(sizeof(char) * 10);
if (space == NULL) {
if (1 > 2) {
if (3 == 4) {
return -1;
}
}
return -1;
}
return 0;
}
"""
parsed_content = parse(code, "<string>")
assert parsed_content
assert 1 == len(parsed_content.functions)
assert "main" == parsed_content.functions[0].name
assert 3 == parsed_content.functions[0].if_nest_level()

def test_parse_check_if_else_nest_level():
code = """
int main (int argc, char *argv[]) {
char *space;
space = malloc(sizeof(char) * 10);
if (space == NULL) {
if (1 > 2) {
if (3 == 4) {
return -1;
}
} else {
if (1 == 1) {
return -1;
} else {
if (1 == 2) {
return -1;
} else {
if (1 == 2) {
return -1;
} else {
return -1;
}
}
}
}
return -1;
}
return 0;
}
"""
parsed_content = parse(code, "<string>")
assert parsed_content
assert 1 == len(parsed_content.functions)
assert "main" == parsed_content.functions[0].name
assert 5 == parsed_content.functions[0].if_nest_level()

0 comments on commit 2551f93

Please sign in to comment.