def apply_to_lines(pre_lines): # Complain after level has exceeded threshold until it has been reduced res = list() max_level = Threshold.IFDEF_NESTING max_level += 1 if sense_for_include_guard(pre_lines) else 0 max_level += 1 if sense_for_global_cplusplus_guard(pre_lines) else 0 level = 0 opened_if_stack = [] # To track encompassing if-endif blocks for directive in pre_lines: lineno = directive.lineno if is_open_directive(directive.hashword): level += 1 if level > max_level: description = make_deep_warning(opened_if_stack) diagnostic = IfdefNestingDiagnostic(directive, description) res.append(diagnostic) opened_if_stack.append(lineno) elif is_close_directive(directive.hashword): level += -1 if len(opened_if_stack) == 0: # Unbalanced #endif. Abort further processing. break opened_if_stack.pop() return res
def apply_to_lines(pre_lines): res = list() depth = 0 for directive in pre_lines: if is_open_directive(directive.hashword): depth += 1 elif is_close_directive(directive.hashword): if depth == 0: unbalanced_endif = UnbalancedEndifDiagnostic( directive, "Unbalanced closing directive found") res.append(unbalanced_endif) break depth -= 1 return res
def apply_to_lines(pre_lines): res = list() opened_if_stack = [] for directive in pre_lines: if is_open_directive(directive.hashword): opened_if_stack.append(directive) elif is_close_directive(directive.hashword): if len(opened_if_stack) == 0: # endifs are unbalanced, bail out break opened_if_stack.pop() while len(opened_if_stack) > 0: directive = opened_if_stack.pop() unbalanced_if = UnbalancedIfDiagnostic( directive, "Unbalanced opening directive found") res.append(unbalanced_if) return res
def apply_to_lines(pre_lines): # Check that #if COND # has matching comment at endif: #endif // COND # or similar max_distance = Threshold.MAX_IFDEF_ENDIF_DISTANCE res = list() opened_if_stack = [] for directive in pre_lines: lineno = directive.lineno if is_open_directive(directive.hashword): opened_if_stack.append((lineno, directive)) elif is_close_directive(directive.hashword): if len(opened_if_stack) == 0: # unbalanced #endif. Abort further processing. break (start_lineno, start_directive) = opened_if_stack.pop() start_text = start_directive.first_line.strip() scope_distance = lineno - start_lineno assert scope_distance > 0 if scope_distance <= max_distance: continue # Close lines are visible, no need to warn about endif_tokens = directive.tokens # Ideally, we need to check if the text of the comment # matched the #if condition, but given it is a freeform text, # it cannot be reliably done for complex cases. # Instead, require that some comment is present # TODO at least the first alphanumeric token should match, and # it can be easily checked if len(endif_tokens) < 2: # #endif plus at least something description = ( "No trailing comment to match opening" + " directive '%s' at line %d (%d lines apart)" % (start_text, start_lineno, scope_distance)) unmarked_w = UnmarkedEndifDiagnostic( directive, description) res.append(unmarked_w) return res
def test_is_open_directive(self): self.assertTrue(is_open_directive("#if")) self.assertTrue(is_open_directive("#ifdef")) self.assertTrue(is_open_directive("#ifndef")) self.assertFalse(is_open_directive("#define")) self.assertFalse(is_open_directive("#endif"))