Beispiel #1
0
    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
Beispiel #2
0
 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
Beispiel #3
0
    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
Beispiel #4
0
 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
Beispiel #5
0
def sense_for_include_guard(pre_lines):
    # Quite a fixed understanding what is considered to be include guards is
    # used
    if len(pre_lines) < 3:
        return False
    ifndef_candidate = pre_lines[0]
    define_candidate = pre_lines[1]
    endif_candidate = pre_lines[-1]
    # Check for all components of a proper guard:
    # #ifdef SYMBOL_H
    # define SYMBOL_H
    # endif
    if not ifndef_candidate.is_ifndef():
        return False
    header_symbol = ifndef_candidate.first_symbol()
    if not define_candidate.hashword == DEFINE:
        return False
    define_symbol = define_candidate.first_symbol()
    if header_symbol != define_symbol:
        return False
    if not is_close_directive(endif_candidate.hashword):
        return False

    return True
Beispiel #6
0
 def test_is_close_directive(self):
     self.assertTrue(is_close_directive("#endif"))
     self.assertFalse(is_close_directive("#if"))
     self.assertFalse(is_close_directive("#else"))