#! /bin/sh

# Python module for parsing and processing .ninja files.
#
# Author: Paolo Bonzini
#
# Copyright (C) 2019 Red Hat, Inc.


# We don't want to put "#! @PYTHON@" as the shebang and
# make the file executable, so instead we make this a
# Python/shell polyglot.  The first line below starts a
# multiline string literal for Python, while it is just
# ":" for bash.  The closing of the multiline string literal
# is never parsed by bash since it exits before.

'''':
case "$0" in
  /*) me=$0 ;;
  *) me=$(command -v "$0") ;;
esac
python="@PYTHON@"
case $python in
  @*) python=python3 ;;
esac
exec $python "$me" "$@"
exit 1
'''


from collections import namedtuple, defaultdict
import sys
import os
import re
import json
import argparse
import hashlib
import shutil


class InvalidArgumentError(Exception):
    pass

# faster version of os.path.normpath: do nothing unless there is a double
# slash or a "." or ".." component.  The filter does not have to be super
# precise, but it has to be fast.  os.path.normpath is the hottest function
# for ninja2make without this optimization!
if os.path.sep == '/':
    def normpath(path, _slow_re=re.compile('/[./]')):
        return os.path.normpath(path) if _slow_re.search(path) or path[0] == '.' else path
else:
    normpath = os.path.normpath


def sha1_text(text):
    return hashlib.sha1(text.encode()).hexdigest()

# ---- lexer and parser ----

PATH_RE = r"[^$\s:|]+|\$[$ :]|\$[a-zA-Z0-9_-]+|\$\{[a-zA-Z0-9_.-]+\}"

SIMPLE_PATH_RE = re.compile(r"^[^$\s:|]+$")
IDENT_RE = re.compile(r"[a-zA-Z0-9_.-]+$")
STRING_RE = re.compile(r"(" + PATH_RE + r"|[\s:|])(?:\r?\n)?|.")
TOPLEVEL_RE = re.compile(r"([=:#]|\|\|?|^ +|(?:" + PATH_RE + r")+)\s*|.")
VAR_RE=re.compile(r'\$\$|\$\{([^}]*)\}')

BUILD = 1
POOL = 2
RULE = 3
DEFAULT = 4
EQUALS = 5
COLON = 6
PIPE = 7
PIPE2 = 8
IDENT = 9
INCLUDE = 10
INDENT = 11
EOL = 12


class LexerError(Exception):
    pass


class ParseError(Exception):
    pass


class NinjaParserEvents(object):
    def __init__(self, parser):
        self.parser = parser

    def dollar_token(self, word, in_path=False):
        return '$$' if word == '$' else word

    def variable_expansion_token(self, varname):
        return '${%s}' % varname

    def variable(self, name, arg):
        pass

    def begin_file(self):
        pass

    def end_file(self):
        pass

    def end_scope(self):
        pass

    def begin_pool(self, name):
        pass

    def begin_rule(self, name):
        pass

    def begin_build(self, out, iout, rule, in_, iin, orderdep):
        pass

    def default(self, targets):
        pass


class NinjaParser(object):

    InputFile = namedtuple('InputFile', 'filename iter lineno')

    def __init__(self, filename, input):
        self.stack = []
        self.top = None
        self.iter = None
        self.lineno = None
        self.match_keyword = False
        self.push(filename, input)

    def file_changed(self):
        self.iter = self.top.iter
        self.lineno = self.top.lineno
        if self.top.filename is not None:
            os.chdir(os.path.dirname(self.top.filename) or '.')

    def push(self, filename, input):
        if self.top:
            self.top.lineno = self.lineno
            self.top.iter = self.iter
            self.stack.append(self.top)
        self.top = self.InputFile(filename=filename or 'stdin',
                                  iter=self._tokens(input), lineno=0)
        self.file_changed()

    def pop(self):
        if len(self.stack):
            self.top = self.stack[-1]
            self.stack.pop()
            self.file_changed()
        else:
            self.top = self.iter = None

    def next_line(self, input):
        line = next(input).rstrip()
        self.lineno += 1
        while len(line) and line[-1] == '$':
            line = line[0:-1] + next(input).strip()
            self.lineno += 1
        return line

    def print_token(self, tok):
        if tok == EOL:
            return "end of line"
        if tok == BUILD:
            return '"build"'
        if tok == POOL:
            return '"pool"'
        if tok == RULE:
            return '"rule"'
        if tok == DEFAULT:
            return '"default"'
        if tok == EQUALS:
            return '"="'
        if tok == COLON:
            return '":"'
        if tok == PIPE:
            return '"|"'
        if tok == PIPE2:
            return '"||"'
        if tok == INCLUDE:
            return '"include"'
        if tok == IDENT:
            return 'identifier'
        return '"%s"' % tok

    def error(self, msg):
        raise LexerError("%s:%d: %s" % (self.stack[-1].filename, self.lineno, msg))

    def parse_error(self, msg):
        raise ParseError("%s:%d: %s" % (self.stack[-1].filename, self.lineno, msg))

    def expected(self, expected, tok):
        msg = "found %s, expected " % (self.print_token(tok), )
        for i, exp_tok in enumerate(expected):
            if i > 0:
                msg = msg + (' or ' if i == len(expected) - 1 else ', ')
            msg = msg + self.print_token(exp_tok)
        self.parse_error(msg)

    def _variable_tokens(self, value):
        for m in STRING_RE.finditer(value):
            match = m.group(1)
            if not match:
                self.error("unexpected '%s'" % (m.group(0), ))
            yield match

    def _tokens(self, input):
        while True:
            try:
                line = self.next_line(input)
            except StopIteration:
                return
            for m in TOPLEVEL_RE.finditer(line):
                match = m.group(1)
                if not match:
                    self.error("unexpected '%s'" % (m.group(0), ))
                if match == ':':
                    yield COLON
                    continue
                if match == '|':
                    yield PIPE
                    continue
                if match == '||':
                    yield PIPE2
                    continue
                if match[0] == ' ':
                    yield INDENT
                    continue
                if match[0] == '=':
                    yield EQUALS
                    value = line[m.start() + 1:].lstrip()
                    yield from self._variable_tokens(value)
                    break
                if match[0] == '#':
                    break

                # identifier
                if self.match_keyword:
                    if match == 'build':
                        yield BUILD
                        continue
                    if match == 'pool':
                        yield POOL
                        continue
                    if match == 'rule':
                        yield RULE
                        continue
                    if match == 'default':
                        yield DEFAULT
                        continue
                    if match == 'include':
                        filename = line[m.start() + 8:].strip()
                        self.push(filename, open(filename, 'r'))
                        break
                    if match == 'subninja':
                        self.error('subninja is not supported')
                yield match
            yield EOL

    def parse(self, events):
        global_var = True

        def look_for(*expected):
            # The last token in the token stream is always EOL.  This
            # is exploited to avoid catching StopIteration everywhere.
            tok = next(self.iter)
            if tok not in expected:
                self.expected(expected, tok)
            return tok

        def look_for_ident(*expected):
            tok = next(self.iter)
            if isinstance(tok, str):
                if not IDENT_RE.match(tok):
                    self.parse_error('variable expansion not allowed')
            elif tok not in expected:
                self.expected(expected + (IDENT,), tok)
            return tok

        def parse_assignment_rhs(gen, expected, in_path):
            tokens = []
            for tok in gen:
                if not isinstance(tok, str):
                    if tok in expected:
                        break
                    self.expected(expected + (IDENT,), tok)
                if tok[0] != '$':
                    tokens.append(tok)
                elif tok == '$ ' or tok == '$$' or tok == '$:':
                    tokens.append(events.dollar_token(tok[1], in_path))
                else:
                    var = tok[2:-1] if tok[1] == '{' else tok[1:]
                    tokens.append(events.variable_expansion_token(var))
            else:
                # gen must have raised StopIteration
                tok = None

            if tokens:
                # Fast path avoiding str.join()
                value = tokens[0] if len(tokens) == 1 else ''.join(tokens)
            else:
                value = None
            return value, tok

        def look_for_path(*expected):
            # paths in build rules are parsed one space-separated token
            # at a time and expanded
            token = next(self.iter)
            if not isinstance(token, str):
                return None, token
            # Fast path if there are no dollar and variable expansion
            if SIMPLE_PATH_RE.match(token):
                return token, None
            gen = self._variable_tokens(token)
            return parse_assignment_rhs(gen, expected, True)

        def parse_assignment(tok):
            name = tok
            assert isinstance(name, str)
            look_for(EQUALS)
            value, tok = parse_assignment_rhs(self.iter, (EOL,), False)
            assert tok == EOL
            events.variable(name, value)

        def parse_build():
            # parse outputs
            out = []
            iout = []
            while True:
                value, tok = look_for_path(COLON, PIPE)
                if value is None:
                    break
                out.append(value)
            if tok == PIPE:
                while True:
                    value, tok = look_for_path(COLON)
                    if value is None:
                        break
                    iout.append(value)

            # parse rule
            assert tok == COLON
            rule = look_for_ident()

            # parse inputs and dependencies
            in_ = []
            iin = []
            orderdep = []
            while True:
                value, tok = look_for_path(PIPE, PIPE2, EOL)
                if value is None:
                    break
                in_.append(value)
            if tok == PIPE:
                while True:
                    value, tok = look_for_path(PIPE2, EOL)
                    if value is None:
                        break
                    iin.append(value)
            if tok == PIPE2:
                while True:
                    value, tok = look_for_path(EOL)
                    if value is None:
                        break
                    orderdep.append(value)
            assert tok == EOL
            events.begin_build(out, iout, rule, in_, iin, orderdep)
            nonlocal global_var
            global_var = False

        def parse_pool():
            # pool declarations are ignored.  Just gobble all the variables
            ident = look_for_ident()
            look_for(EOL)
            events.begin_pool(ident)
            nonlocal global_var
            global_var = False

        def parse_rule():
            ident = look_for_ident()
            look_for(EOL)
            events.begin_rule(ident)
            nonlocal global_var
            global_var = False

        def parse_default():
            idents = []
            while True:
                ident = look_for_ident(EOL)
                if ident == EOL:
                    break
                idents.append(ident)
            events.default(idents)

        def parse_declaration(tok):
            if tok == EOL:
                return

            nonlocal global_var
            if tok == INDENT:
                if global_var:
                    self.parse_error('indented line outside rule or edge')
                tok = look_for_ident(EOL)
                if tok == EOL:
                    return
                parse_assignment(tok)
                return

            if not global_var:
                events.end_scope()
                global_var = True
            if tok == POOL:
                parse_pool()
            elif tok == BUILD:
                parse_build()
            elif tok == RULE:
                parse_rule()
            elif tok == DEFAULT:
                parse_default()
            elif isinstance(tok, str):
                parse_assignment(tok)
            else:
                self.expected((POOL, BUILD, RULE, INCLUDE, DEFAULT, IDENT), tok)

        events.begin_file()
        while self.iter:
            try:
                self.match_keyword = True
                token = next(self.iter)
                self.match_keyword = False
                parse_declaration(token)
            except StopIteration:
                self.pop()
        events.end_file()


# ---- variable handling ----

def expand(x, rule_vars=None, build_vars=None, global_vars=None):
    if x is None:
        return None
    changed = True
    have_dollar_replacement = False
    while changed:
        changed = False
        matches = list(VAR_RE.finditer(x))
        if not matches:
            break

        # Reverse the match so that expanding later matches does not
        # invalidate m.start()/m.end() for earlier ones.  Do not reduce $$ to $
        # until all variables are dealt with.
        for m in reversed(matches):
            name = m.group(1)
            if not name:
                have_dollar_replacement = True
                continue
            changed = True
            if build_vars and name in build_vars:
                value = build_vars[name]
            elif rule_vars and name in rule_vars:
                value = rule_vars[name]
            elif name in global_vars:
                value = global_vars[name]
            else:
                value = ''
            x = x[:m.start()] + value + x[m.end():]
    return x.replace('$$', '$') if have_dollar_replacement else x


class Scope(object):
    def __init__(self, events):
        self.events = events

    def on_left_scope(self):
        pass

    def on_variable(self, key, value):
        pass


class BuildScope(Scope):
    def __init__(self, events, out, iout, rule, in_, iin, orderdep, rule_vars):
        super().__init__(events)
        self.rule = rule
        self.out = [events.expand_and_normalize(x) for x in out]
        self.in_ = [events.expand_and_normalize(x) for x in in_]
        self.iin = [events.expand_and_normalize(x) for x in iin]
        self.orderdep = [events.expand_and_normalize(x) for x in orderdep]
        self.iout = [events.expand_and_normalize(x) for x in iout]
        self.rule_vars = rule_vars
        self.build_vars = dict()
        self._define_variable('out', ' '.join(self.out))
        self._define_variable('in', ' '.join(self.in_))

    def expand(self, x):
        return self.events.expand(x, self.rule_vars, self.build_vars)

    def on_left_scope(self):
        self.events.variable('out', self.build_vars['out'])
        self.events.variable('in', self.build_vars['in'])
        self.events.end_build(self, self.out, self.iout, self.rule, self.in_,
                              self.iin, self.orderdep)

    def _define_variable(self, key, value):
        # The value has been expanded already, quote it for further
        # expansion from rule variables
        value = value.replace('$', '$$')
        self.build_vars[key] = value

    def on_variable(self, key, value):
        # in and out are at the top of the lookup order and cannot
        # be overridden.  Also, unlike what the manual says, build
        # variables only lookup global variables.  They never lookup
        # rule variables, earlier build variables, or in/out.
        if key not in ('in', 'in_newline', 'out'):
            self._define_variable(key, self.events.expand(value))


class RuleScope(Scope):
    def __init__(self, events, name, vars_dict):
        super().__init__(events)
        self.name = name
        self.vars_dict = vars_dict
        self.generator = False

    def on_left_scope(self):
        self.events.end_rule(self, self.name)

    def on_variable(self, key, value):
        self.vars_dict[key] = value
        if key == 'generator':
            self.generator = True


class NinjaParserEventsWithVars(NinjaParserEvents):
    def __init__(self, parser):
        super().__init__(parser)
        self.rule_vars = defaultdict(lambda: dict())
        self.global_vars = dict()
        self.scope = None

    def variable(self, name, value):
        if self.scope:
            self.scope.on_variable(name, value)
        else:
            self.global_vars[name] = self.expand(value)

    def begin_build(self, out, iout, rule, in_, iin, orderdep):
        if rule != 'phony' and rule not in self.rule_vars:
            self.parser.parse_error("undefined rule '%s'" % rule)

        self.scope = BuildScope(self, out, iout, rule, in_, iin, orderdep, self.rule_vars[rule])

    def begin_pool(self, name):
        # pool declarations are ignored.  Just gobble all the variables
        self.scope = Scope(self)

    def begin_rule(self, name):
        if name in self.rule_vars:
            self.parser.parse_error("duplicate rule '%s'" % name)
        self.scope = RuleScope(self, name, self.rule_vars[name])

    def end_scope(self):
        self.scope.on_left_scope()
        self.scope = None

    # utility functions:

    def expand(self, x, rule_vars=None, build_vars=None):
        return expand(x, rule_vars, build_vars, self.global_vars)

    def expand_and_normalize(self, x):
        return normpath(self.expand(x))

    # extra events not present in the superclass:

    def end_build(self, scope, out, iout, rule, in_, iin, orderdep):
        pass

    def end_rule(self, scope, name):
        pass


# ---- test client that just prints back whatever it parsed  ----

class Writer(NinjaParserEvents):
    ARGS = argparse.ArgumentParser(description='Rewrite input build.ninja to stdout.')

    def __init__(self, output, parser, args):
        super().__init__(parser)
        self.output = output
        self.indent = ''
        self.had_vars = False

    def dollar_token(self, word, in_path=False):
        return '$' + word

    def print(self, *args, **kwargs):
        if len(args):
            self.output.write(self.indent)
        print(*args, **kwargs, file=self.output)

    def variable(self, name, value):
        self.print('%s = %s' % (name, value))
        self.had_vars = True

    def begin_scope(self):
        self.indent = '  '
        self.had_vars = False

    def end_scope(self):
        if self.had_vars:
            self.print()
        self.indent = ''
        self.had_vars = False

    def begin_pool(self, name):
        self.print('pool %s' % name)
        self.begin_scope()

    def begin_rule(self, name):
        self.print('rule %s' % name)
        self.begin_scope()

    def begin_build(self, outputs, implicit_outputs, rule, inputs, implicit, order_only):
        all_outputs = list(outputs)
        all_inputs = list(inputs)

        if implicit:
            all_inputs.append('|')
            all_inputs.extend(implicit)
        if order_only:
            all_inputs.append('||')
            all_inputs.extend(order_only)
        if implicit_outputs:
            all_outputs.append('|')
            all_outputs.extend(implicit_outputs)

        self.print('build %s: %s' % (' '.join(all_outputs),
                                     ' '.join([rule] + all_inputs)))
        self.begin_scope()

    def default(self, targets):
        self.print('default %s' % ' '.join(targets))


# ---- emit compile_commands.json ----

class Compdb(NinjaParserEventsWithVars):
    ARGS = argparse.ArgumentParser(description='Emit compile_commands.json.')
    ARGS.add_argument('rules', nargs='*',
                      help='The ninja rules to emit compilation commands for.')

    def __init__(self, output, parser, args):
        super().__init__(parser)
        self.output = output
        self.rules = args.rules
        self.sep = ''

    def begin_file(self):
        self.output.write('[')
        self.directory = os.getcwd()

    def print_entry(self, **entry):
        entry['directory'] = self.directory
        self.output.write(self.sep + json.dumps(entry))
        self.sep = ',\n'

    def begin_build(self, out, iout, rule, in_, iin, orderdep):
        if in_ and rule in self.rules:
            super().begin_build(out, iout, rule, in_, iin, orderdep)
        else:
            self.scope = Scope(self)

    def end_build(self, scope, out, iout, rule, in_, iin, orderdep):
        self.print_entry(command=scope.expand('${command}'), file=in_[0])

    def end_file(self):
        self.output.write(']\n')


# ---- clean output files ----

class Clean(NinjaParserEventsWithVars):
    ARGS = argparse.ArgumentParser(description='Remove output build files.')
    ARGS.add_argument('-g', dest='generator', action='store_true',
                      help='clean generated files too')

    def __init__(self, output, parser, args):
        super().__init__(parser)
        self.dry_run = args.dry_run
        self.verbose = args.verbose or args.dry_run
        self.generator = args.generator

    def begin_file(self):
        print('Cleaning... ', end=(None if self.verbose else ''), flush=True)
        self.cnt = 0

    def end_file(self):
        print('%d files' % self.cnt)

    def do_clean(self, *files):
        for f in files:
            if self.dry_run:
                if os.path.exists(f):
                    self.cnt += 1
                    print('Would remove ' + f)
                    continue
            else:
                try:
                    if os.path.isdir(f):
                        shutil.rmtree(f)
                    else:
                        os.unlink(f)
                    self.cnt += 1
                    if self.verbose:
                        print('Removed ' + f)
                except FileNotFoundError:
                    pass

    def end_build(self, scope, out, iout, rule, in_, iin, orderdep):
        if rule == 'phony':
            return
        if self.generator:
            rspfile = scope.expand('${rspfile}')
            if rspfile:
                self.do_clean(rspfile)
        if self.generator or not scope.expand('${generator}'):
            self.do_clean(*out, *iout)
            depfile = scope.expand('${depfile}')
            if depfile:
                self.do_clean(depfile)


# ---- convert build.ninja to makefile ----

class Ninja2Make(NinjaParserEventsWithVars):
    ARGS = argparse.ArgumentParser(description='Convert build.ninja to a Makefile.')
    ARGS.add_argument('--clean', dest='emit_clean', action='store_true',
                      help='Emit clean/distclean rules.')
    ARGS.add_argument('--doublecolon', action='store_true',
                      help='Emit double-colon rules for phony targets.')
    ARGS.add_argument('--omit', metavar='TARGET', nargs='+',
                      help='Targets to omit.')

    def __init__(self, output, parser, args):
        super().__init__(parser)
        self.output = output

        self.emit_clean = args.emit_clean
        self.doublecolon = args.doublecolon
        self.omit = set(args.omit)

        if self.emit_clean:
            self.omit.update(['clean', 'distclean'])

        # Lists of targets are kept in memory and emitted only at the
        # end because appending is really inefficient in GNU make.
        # We only do it when it's O(#rules) or O(#variables), but
        # never when it could be O(#targets).
        self.depfiles = list()
        self.rspfiles = list()
        self.build_vars = defaultdict(lambda: dict())
        self.rule_targets = defaultdict(lambda: list())
        self.stamp_targets = defaultdict(lambda: list())
        self.all_outs = set()
        self.all_ins = set()
        self.all_phony = set()
        self.seen_default = False

    def print(self, *args, **kwargs):
        print(*args, **kwargs, file=self.output)

    def dollar_token(self, word, in_path=False):
        if in_path and word == ' ':
            self.parser.parse_error('Make does not support spaces in filenames')
        return '$$' if word == '$' else word

    def print_phony(self, outs, ins):
        targets = ' '.join(outs).replace('$', '$$')
        deps = ' '.join(ins).replace('$', '$$')
        deps = deps.strip()
        if self.doublecolon:
            self.print(targets + '::' + (' ' if deps else '') + deps + ';@:')
        else:
            self.print(targets + ':' + (' ' if deps else '') + deps)
        self.all_phony.update(outs)

    def begin_file(self):
        self.print(r'# This is an automatically generated file, and it shows.')
        self.print(r'ninja-default:')
        self.print(r'.PHONY: ninja-default ninja-clean ninja-distclean')
        if self.emit_clean:
            self.print(r'ninja-clean:: ninja-clean-start; $(if $V,,@)rm -f ${ninja-depfiles}')
            self.print(r'ninja-clean-start:; $(if $V,,@echo Cleaning...)')
            self.print(r'ninja-distclean:: clean; $(if $V,,@)rm -f ${ninja-rspfiles}')
            self.print(r'.PHONY: ninja-clean-start')
            self.print_phony(['clean'], ['ninja-clean'])
            self.print_phony(['distclean'], ['ninja-distclean'])
        self.print(r'vpath')
        self.print(r'NULL :=')
        self.print(r'SPACE := ${NULL} #')
        self.print(r'MAKEFLAGS += -rR')
        self.print(r'define NEWLINE')
        self.print(r'')
        self.print(r'endef')
        self.print(r'.var.in_newline = $(subst $(SPACE),$(NEWLINE),${.var.in})')
        self.print(r"ninja-command = $(if $V,,$(if ${.var.description},@printf '%s\n' '$(subst ','\'',${.var.description})' && ))${.var.command}")
        self.print(r"ninja-command-restat = $(if $V,,$(if ${.var.description},@printf '%s\n' '$(subst ','\'',${.var.description})' && ))${.var.command} && if test -e $(firstword ${.var.out}); then printf '%s\n' ${.var.out} > $@; fi")

    def end_file(self):
        def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
            return [int(text) if text.isdigit() else text.lower()
                    for text in _nsre.split(s)]

        self.print()
        self.print('ninja-outputdirs :=')
        for rule in self.rule_vars:
            if rule == 'phony':
                continue
            self.print('ninja-targets-%s := %s' % (rule, ' '.join(self.rule_targets[rule])))
            self.print('ninja-stamp-%s := %s' % (rule, ' '.join(self.stamp_targets[rule])))
            self.print('ninja-outputdirs += $(sort $(dir ${ninja-targets-%s}))' % rule)
            self.print()
        self.print('dummy := $(shell mkdir -p . $(sort $(ninja-outputdirs)))')
        self.print('ninja-depfiles :=' + ' '.join(self.depfiles))
        self.print('ninja-rspfiles :=' + ' '.join(self.rspfiles))
        self.print('-include ${ninja-depfiles}')
        self.print()
        for targets in self.build_vars:
            for name, value in self.build_vars[targets].items():
                self.print('%s: private .var.%s := %s' %
                           (targets, name, value.replace('$', '$$')))
            self.print()
        if not self.seen_default:
            default_targets = sorted(self.all_outs - self.all_ins, key=natural_sort_key)
            self.print('ninja-default: ' + ' '.join(default_targets))

        # This is a hack...  Meson declares input meson.build files as
        # phony, because Ninja does not have an equivalent of Make's
        # "path/to/file:" declaration that ignores "path/to/file" even
        # if it is absent.  However, Makefile.ninja wants to depend on
        # build.ninja, which in turn depends on these phony targets which
        # would cause Makefile.ninja to be rebuilt in a loop.
        phony_targets = sorted(self.all_phony - self.all_ins, key=natural_sort_key)
        self.print('.PHONY: ' + ' '.join(phony_targets))

    def variable(self, name, value):
        super().variable(name, value)
        if self.scope is None:
            self.global_vars[name] = self.expand(value)
            self.print('.var.%s := %s' % (name, self.global_vars[name]))

    def begin_build(self, out, iout, rule, in_, iin, orderdep):
        if any(x in self.omit for x in out):
            self.scope = Scope(self)
            return

        super().begin_build(out, iout, rule, in_, iin, orderdep)
        self.current_targets = ' '.join(self.scope.out + self.scope.iout).replace('$', '$$')

    def end_build(self, scope, out, iout, rule, in_, iin, orderdep):
        self.rule_targets[rule] += self.scope.out
        self.rule_targets[rule] += self.scope.iout

        self.all_outs.update(self.scope.iout)
        self.all_outs.update(self.scope.out)
        self.all_ins.update(self.scope.in_)
        self.all_ins.update(self.scope.iin)

        targets = self.current_targets
        self.current_targets = None
        if rule == 'phony':
            # Phony rules treat order-only dependencies as normal deps
            self.print_phony(out + iout, in_ + iin + orderdep)
            return

        inputs = ' '.join(in_ + iin).replace('$', '$$')
        orderonly = ' '.join(orderdep).replace('$', '$$')

        rspfile = scope.expand('${rspfile}')
        if rspfile:
            rspfile_content = scope.expand('${rspfile_content}')
            with open(rspfile, 'w') as f:
                f.write(rspfile_content)
            inputs += ' ' + rspfile
            self.rspfiles.append(rspfile)

        restat = 'restat' in self.scope.build_vars or 'restat' in self.rule_vars[rule]
        depfile = scope.expand('${depfile}')
        build_vars = {
            'command': scope.expand('${command}'),
            'description': scope.expand('${description}'),
            'out': scope.expand('${out}')
        }

        if restat and not depfile:
            if len(out) == 1:
                stamp = out[0] + '.stamp'
            else:
                stamp = '%s@%s.stamp' % (rule, sha1_text(targets)[0:11])
            self.print('%s: %s; @:' % (targets, stamp))
            self.print('%s: %s | %s; ${ninja-command-restat}' % (stamp, inputs, orderonly))
            self.rule_targets[rule].append(stamp)
            self.stamp_targets[rule].append(stamp)
            self.build_vars[stamp] = build_vars
        else:
            self.print('%s: %s | %s; ${ninja-command}' % (targets, inputs, orderonly))
            self.build_vars[targets] = build_vars
            if depfile:
                self.depfiles.append(depfile)

    def end_rule(self, scope, name):
        # Note that the generator pseudo-variable could also be attached
        # to a build block rather than a rule.  This is not handled here
        # in order to reduce the number of "rm" invocations.  However,
        # "ninjatool.py -t clean" does that correctly.
        target = 'distclean' if scope.generator else 'clean'
        self.print('ninja-%s:: ; $(if $V,,@)rm -f ${ninja-stamp-%s}' % (target, name))
        if self.emit_clean:
            self.print('ninja-%s:: ; $(if $V,,@)rm -rf ${ninja-targets-%s}' % (target, name))

    def default(self, targets):
        self.print("ninja-default: " + ' '.join(targets))
        self.seen_default = True


# ---- command line parsing ----

# we cannot use subparsers because tools are chosen through the "-t"
# option.

class ToolAction(argparse.Action):
    def __init__(self, option_strings, dest, choices, metavar='TOOL', nargs=None, **kwargs):
        if nargs is not None:
            raise ValueError("nargs not allowed")
        super().__init__(option_strings, dest, required=True, choices=choices,
                         metavar=metavar, **kwargs)

    def __call__(self, parser, namespace, value, option_string):
        tool = self.choices[value]
        setattr(namespace, self.dest, tool)
        tool.ARGS.prog = '%s %s %s' % (parser.prog, option_string, value)


class ToolHelpAction(argparse.Action):
    def __init__(self, option_strings, dest, nargs=None, **kwargs):
        if nargs is not None:
            raise ValueError("nargs not allowed")
        super().__init__(option_strings, dest, nargs=0, **kwargs)

    def __call__(self, parser, namespace, values, option_string=None):
        if namespace.tool:
            namespace.tool.ARGS.print_help()
        else:
            parser.print_help()
        parser.exit()


tools = {
    'test': Writer,
    'ninja2make': Ninja2Make,
    'compdb': Compdb,
    'clean': Clean,
}

parser = argparse.ArgumentParser(description='Process and transform build.ninja files.',
                                 add_help=False)
parser.add_argument('-C', metavar='DIR', dest='dir', default='.',
                    help='change to DIR before doing anything else')
parser.add_argument('-f', metavar='FILE', dest='file', default='build.ninja',
                    help='specify input build file [default=build.ninja]')
parser.add_argument('-n', dest='dry_run', action='store_true',
                    help='do not actually do anything')
parser.add_argument('-v', dest='verbose', action='store_true',
                    help='be more verbose')

parser.add_argument('-t', dest='tool', choices=tools, action=ToolAction,
                    help='choose the tool to run')
parser.add_argument('-h', '--help', action=ToolHelpAction,
                    help='show this help message and exit')

if len(sys.argv) >= 2 and sys.argv[1] == '--version':
    print('1.8')
    sys.exit(0)

args, tool_args = parser.parse_known_args()
args.tool.ARGS.parse_args(tool_args, args)

os.chdir(args.dir)
with open(args.file, 'r') as f:
    parser = NinjaParser(args.file, f)
    try:
        events = args.tool(sys.stdout, parser, args)
    except InvalidArgumentError as e:
        parser.error(str(e))
    parser.parse(events)
