def _handle_if_block()

in contrib/freestanding_lib/freestanding.py [0:0]


    def _handle_if_block(self, macro, idx, is_true, prepend):
        """
        Remove the #if or #elif block starting on this line.
        """
        REMOVE_ONE = 0
        KEEP_ONE = 1
        REMOVE_REST = 2

        if is_true:
            state = KEEP_ONE
        else:
            state = REMOVE_ONE

        line = self._inlines[idx]
        is_if = self._if.match(line) is not None
        assert is_if or self._elif.match(line) is not None
        depth = 0

        start_idx = idx

        idx += 1
        replace = prepend
        finished = False
        while idx < len(self._inlines):
            line = self._inlines[idx]
            # Nested if statement
            if self._if.match(line):
                depth += 1
                idx += 1
                continue
            # We're inside a nested statement
            if depth > 0:
                if self._endif.match(line):
                    depth -= 1
                idx += 1
                continue

            # We're at the original depth

            # Looking only for an endif.
            # We've found a true statement, but haven't
            # completely elided the if block, so we just
            # remove the remainder.
            if state == REMOVE_REST:
                if self._endif.match(line):
                    if is_if:
                        # Remove the endif because we took the first if
                        idx += 1
                    finished = True
                    break
                idx += 1
                continue

            if state == KEEP_ONE:
                m = self._elif.match(line)
                if self._endif.match(line):
                    replace += self._inlines[start_idx + 1:idx]
                    idx += 1
                    finished = True
                    break
                if self._elif.match(line) or self._else.match(line):
                    replace += self._inlines[start_idx + 1:idx]
                    state = REMOVE_REST
                idx += 1
                continue

            if state == REMOVE_ONE:
                m = self._elif.match(line)
                if m is not None:
                    if is_if:
                        idx += 1
                        b = m.start('elif')
                        e = m.end('elif')
                        assert e - b == 2
                        replace.append(line[:b] + line[e:])
                    finished = True
                    break
                m = self._else.match(line)
                if m is not None:
                    if is_if:
                        idx += 1
                        while self._endif.match(self._inlines[idx]) is None:
                            replace.append(self._inlines[idx])
                            idx += 1
                        idx += 1
                    finished = True
                    break
                if self._endif.match(line):
                    if is_if:
                        # Remove the endif because no other elifs
                        idx += 1
                    finished = True
                    break
                idx += 1
                continue
        if not finished:
            raise RuntimeError("Unterminated if block!")

        replace = self._fixup_indentation(macro, replace)

        self._log(f"\tHardwiring {macro}")
        if start_idx > 0:
            self._log(f"\t\t  {self._inlines[start_idx - 1][:-1]}")
        for x in range(start_idx, idx):
            self._log(f"\t\t- {self._inlines[x][:-1]}")
        for line in replace:
            self._log(f"\t\t+ {line[:-1]}")
        if idx < len(self._inlines):
            self._log(f"\t\t  {self._inlines[idx][:-1]}")

        return idx, replace