def _parse_directive_line()

in src/advisor/helpers/c/naive_cpp.py [0:0]


    def _parse_directive_line(self, line):
        parts = line.lstrip().split(maxsplit=1)
        directive = parts[0][1:]
        if directive == 'error':
            return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_ERROR)
        elif directive == 'pragma':
            return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_PRAGMA)
        elif directive == 'define':
            if len(parts) == 1:
                return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_INVALID)
            rest = parts[1]
            if rest:
                define_parts = rest.lstrip().split(maxsplit=1)
            else:
                define_parts = []
            macro_name = define_parts[0]
            body = define_parts[1] if len(define_parts) > 1 else None
            return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_DEFINE,
                                        macro_name=macro_name, body=body)
        elif directive == 'if':
            if len(parts) == 1:
                return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_INVALID)
            expression = parts[1]
            self.in_aarch64.append(NaiveCpp._is_expression_aarch64(expression))
            self.seen_aarch64.append(self.in_aarch64[-1])
            self.in_other_arch.append(
                NaiveCpp._is_expression_non_aarch64(expression))
            self.seen_other_arch.append(self.in_other_arch[-1])
            is_compiler = NaiveCpp._is_expression_compiler(expression)
            self.in_compiler.append(is_compiler)
            self.if_lines.append(line)
            return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_CONDITIONAL, if_line=line,
                                         is_compiler=is_compiler)
        elif directive == 'elif':
            if len(parts) == 1:
                return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_INVALID)
            expression = parts[1]
            if self.in_aarch64:
                self.in_aarch64[-1] = \
                    NaiveCpp._is_expression_aarch64(expression)
            if self.seen_aarch64:
                self.seen_aarch64[-1] = self.in_aarch64[-1] if self.seen_aarch64[-1] is None else \
                    self.seen_aarch64[-1] or self.in_aarch64[-1]
            if self.in_other_arch:
                self.in_other_arch[-1] = \
                    NaiveCpp._is_expression_non_aarch64(expression)
            if self.seen_other_arch:
                self.seen_other_arch[-1] = self.in_other_arch[-1] if self.seen_other_arch[-1] is None else \
                    self.seen_other_arch[-1] or self.in_other_arch[-1]
            if self.in_compiler:
                is_compiler = NaiveCpp._is_expression_compiler(expression)
                self.in_compiler[-1] = \
                    is_compiler
            else:
                is_compiler = False
            return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_CONDITIONAL, if_line=line,
                                         is_compiler=is_compiler)
        elif directive == 'ifdef':
            if len(parts) == 1:
                return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_INVALID)
            macro = parts[1]
            self.in_aarch64.append(
                NaiveCpp.AARCH64_MACROS_RE_PROG.match(macro) is not None or None)
            self.seen_aarch64.append(self.in_aarch64[-1])
            self.in_other_arch.append(
                NaiveCpp.NON_AARCH64_MACROS_RE_PROG.match(macro) is not None or None)
            self.seen_other_arch.append(self.in_other_arch[-1])
            is_compiler = NaiveCpp.COMPILER_MACROS_RE_PROG.match(
                macro) is not None or None
            self.in_compiler.append(is_compiler)
            self.if_lines.append(line)
            return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_CONDITIONAL, if_line=line,
                                         is_compiler=is_compiler, macro_name=macro)
        elif directive == 'ifndef':
            if len(parts) == 1:
                return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_INVALID)
            macro = parts[1]
            self.in_aarch64.append(
                False if NaiveCpp.AARCH64_MACROS_RE_PROG.match(macro) is not None else None)
            self.seen_aarch64.append(self.in_aarch64[-1])
            self.in_other_arch.append(
                False if NaiveCpp.NON_AARCH64_MACROS_RE_PROG.match(macro) is not None else None)
            self.seen_other_arch.append(self.in_other_arch[-1])
            is_compiler = False if NaiveCpp.COMPILER_MACROS_RE_PROG.match(
                macro) else None
            self.in_compiler.append(is_compiler)
            self.if_lines.append(line)
            return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_CONDITIONAL, if_line=line,
                                         is_compiler=is_compiler, macro_name=macro)
        elif directive == 'else':
            if self.in_aarch64:
                self.in_aarch64[-1] = \
                    not self.seen_aarch64[-1] if self.seen_aarch64[-1] is not None else None
            if self.in_other_arch:
                self.in_other_arch[-1] = \
                    None if self.seen_aarch64[-1] else \
                        (not self.seen_other_arch[-1] if self.seen_other_arch[-1] is not None else None)
            if self.in_compiler:
                self.in_compiler[-1] = \
                    NaiveCpp.tri_negate(
                        self.in_compiler[-1])
            if self.if_lines:
                if_line = self.if_lines[-1]
            else:
                if_line = line
            return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_CONDITIONAL, if_line=if_line)
        elif directive == 'endif':
            if self.in_aarch64:
                self.in_aarch64.pop()
            if self.seen_aarch64:
                self.seen_aarch64.pop()
            if self.in_other_arch:
                self.in_other_arch.pop()
            if self.seen_other_arch:
                self.seen_other_arch.pop()
            if self.in_compiler:
                self.in_compiler.pop()
            if self.if_lines:
                if_line = self.if_lines.pop()
            else:
                if_line = None
            return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_CONDITIONAL, if_line=if_line)
        else:
            return PreprocessorDirective(directive_type=PreprocessorDirective.TYPE_OTHER)