diff options
Diffstat (limited to 'misc')
-rw-r--r-- | misc/bash-completion | 2 | ||||
-rw-r--r-- | misc/ninja-mode.el | 76 | ||||
-rw-r--r-- | misc/ninja_syntax.py | 41 | ||||
-rwxr-xr-x | misc/ninja_syntax_test.py | 26 | ||||
-rw-r--r-- | misc/packaging/ninja.spec | 2 | ||||
-rw-r--r-- | misc/write_fake_manifests.py | 2 | ||||
-rw-r--r-- | misc/zsh-completion | 9 |
7 files changed, 122 insertions, 36 deletions
diff --git a/misc/bash-completion b/misc/bash-completion index 6edf4df..0536760 100644 --- a/misc/bash-completion +++ b/misc/bash-completion @@ -50,7 +50,7 @@ _ninja_target() { esac done; targets_command="eval ninja -C \"${dir}\" -t targets all" - targets=$((${targets_command} 2>/dev/null) | awk -F: '{print $1}') + targets=$(${targets_command} 2>/dev/null | awk -F: '{print $1}') COMPREPLY=($(compgen -W "$targets" -- "$cur")) fi return diff --git a/misc/ninja-mode.el b/misc/ninja-mode.el index 36ada6f..71825d5 100644 --- a/misc/ninja-mode.el +++ b/misc/ninja-mode.el @@ -1,4 +1,6 @@ -;;; ninja-mode.el --- Major mode for editing .ninja files +;;; ninja-mode.el --- Major mode for editing .ninja files -*- lexical-binding: t -*- + +;; Package-Requires: ((emacs "24")) ;; Copyright 2011 Google Inc. All Rights Reserved. ;; @@ -22,26 +24,58 @@ ;;; Code: (defvar ninja-keywords - (list - '("^#.*" . font-lock-comment-face) - (cons (concat "^" (regexp-opt '("rule" "build" "subninja" "include" - "pool" "default") - 'words)) - font-lock-keyword-face) - '("\\([[:alnum:]_]+\\) =" . (1 font-lock-variable-name-face)) - ;; Variable expansion. - '("\\($[[:alnum:]_]+\\)" . (1 font-lock-variable-name-face)) - ;; Rule names - '("rule \\([[:alnum:]_-]+\\)" . (1 font-lock-function-name-face)) - )) - -;;;###autoload -(define-derived-mode ninja-mode fundamental-mode "ninja" - (setq comment-start "#") - ; Pass extra "t" to turn off syntax-based fontification -- we don't want - ; quoted strings highlighted. - (setq font-lock-defaults '(ninja-keywords t)) - ) + `((,(concat "^" (regexp-opt '("rule" "build" "subninja" "include" + "pool" "default") + 'words)) + . font-lock-keyword-face) + ("\\([[:alnum:]_]+\\) =" 1 font-lock-variable-name-face) + ;; Variable expansion. + ("$[[:alnum:]_]+" . font-lock-variable-name-face) + ("${[[:alnum:]._]+}" . font-lock-variable-name-face) + ;; Rule names + ("rule +\\([[:alnum:]_.-]+\\)" 1 font-lock-function-name-face) + ;; Build Statement - highlight the rule used, + ;; allow for escaped $,: in outputs. + ("build +\\(?:[^:$\n]\\|$[:$]\\)+ *: *\\([[:alnum:]_.-]+\\)" + 1 font-lock-function-name-face))) + +(defvar ninja-mode-syntax-table + (let ((table (make-syntax-table))) + (modify-syntax-entry ?\" "." table) + table) + "Syntax table used in `ninja-mode'.") + +(defun ninja-syntax-propertize (start end) + (save-match-data + (save-excursion + (goto-char start) + (while (search-forward "#" end t) + (let ((match-pos (match-beginning 0))) + (when (and + ;; Is it the first non-white character on the line? + (eq match-pos (save-excursion (back-to-indentation) (point))) + (save-excursion + (goto-char (line-end-position 0)) + (or + ;; If we're continuting the previous line, it's not a + ;; comment. + (not (eq ?$ (char-before))) + ;; Except if the previous line is a comment as well, as the + ;; continuation dollar is ignored then. + (nth 4 (syntax-ppss))))) + (put-text-property match-pos (1+ match-pos) 'syntax-table '(11)) + (let ((line-end (line-end-position))) + ;; Avoid putting properties past the end of the buffer. + ;; Otherwise we get an `args-out-of-range' error. + (unless (= line-end (1+ (buffer-size))) + (put-text-property line-end (1+ line-end) 'syntax-table '(12)))))))))) + +;;;###autoload +(define-derived-mode ninja-mode prog-mode "ninja" + (set (make-local-variable 'comment-start) "#") + (set (make-local-variable 'parse-sexp-lookup-properties) t) + (set (make-local-variable 'syntax-propertize-function) #'ninja-syntax-propertize) + (setq font-lock-defaults '(ninja-keywords))) ;; Run ninja-mode for files ending in .ninja. ;;;###autoload diff --git a/misc/ninja_syntax.py b/misc/ninja_syntax.py index 14b932f..8673518 100644 --- a/misc/ninja_syntax.py +++ b/misc/ninja_syntax.py @@ -7,6 +7,7 @@ just a helpful utility for build-file-generation systems that already use Python. """ +import re import textwrap def escape_path(word): @@ -59,16 +60,16 @@ class Writer(object): def build(self, outputs, rule, inputs=None, implicit=None, order_only=None, variables=None): - outputs = self._as_list(outputs) + outputs = as_list(outputs) out_outputs = [escape_path(x) for x in outputs] - all_inputs = [escape_path(x) for x in self._as_list(inputs)] + all_inputs = [escape_path(x) for x in as_list(inputs)] if implicit: - implicit = [escape_path(x) for x in self._as_list(implicit)] + implicit = [escape_path(x) for x in as_list(implicit)] all_inputs.append('|') all_inputs.extend(implicit) if order_only: - order_only = [escape_path(x) for x in self._as_list(order_only)] + order_only = [escape_path(x) for x in as_list(order_only)] all_inputs.append('||') all_inputs.extend(order_only) @@ -93,7 +94,7 @@ class Writer(object): self._line('subninja %s' % path) def default(self, paths): - self._line('default %s' % ' '.join(self._as_list(paths))) + self._line('default %s' % ' '.join(as_list(paths))) def _count_dollars_before_index(self, s, i): """Returns the number of '$' characters right in front of s[i].""" @@ -140,12 +141,16 @@ class Writer(object): self.output.write(leading_space + text + '\n') - def _as_list(self, input): - if input is None: - return [] - if isinstance(input, list): - return input - return [input] + def close(self): + self.output.close() + + +def as_list(input): + if input is None: + return [] + if isinstance(input, list): + return input + return [input] def escape(string): @@ -154,3 +159,17 @@ def escape(string): assert '\n' not in string, 'Ninja syntax does not allow newlines' # We only have one special metacharacter: '$'. return string.replace('$', '$$') + + +def expand(string, vars, local_vars={}): + """Expand a string containing $vars as Ninja would. + + Note: doesn't handle the full Ninja variable syntax, but it's enough + to make configure.py's use of it work. + """ + def exp(m): + var = m.group(1) + if var == '$': + return '$' + return local_vars.get(var, vars.get(var, '')) + return re.sub(r'\$(\$|\w*)', exp, string) diff --git a/misc/ninja_syntax_test.py b/misc/ninja_syntax_test.py index 2aef7ff..36b2e7b 100755 --- a/misc/ninja_syntax_test.py +++ b/misc/ninja_syntax_test.py @@ -148,5 +148,31 @@ build out: cc in ''', self.out.getvalue()) +class TestExpand(unittest.TestCase): + def test_basic(self): + vars = {'x': 'X'} + self.assertEqual('foo', ninja_syntax.expand('foo', vars)) + + def test_var(self): + vars = {'xyz': 'XYZ'} + self.assertEqual('fooXYZ', ninja_syntax.expand('foo$xyz', vars)) + + def test_vars(self): + vars = {'x': 'X', 'y': 'YYY'} + self.assertEqual('XYYY', ninja_syntax.expand('$x$y', vars)) + + def test_space(self): + vars = {} + self.assertEqual('x y z', ninja_syntax.expand('x$ y$ z', vars)) + + def test_locals(self): + vars = {'x': 'a'} + local_vars = {'x': 'b'} + self.assertEqual('a', ninja_syntax.expand('$x', vars)) + self.assertEqual('b', ninja_syntax.expand('$x', vars, local_vars)) + + def test_double(self): + self.assertEqual('a b$c', ninja_syntax.expand('a$ b$$c', {})) + if __name__ == '__main__': unittest.main() diff --git a/misc/packaging/ninja.spec b/misc/packaging/ninja.spec index f0c46fe..fa244a6 100644 --- a/misc/packaging/ninja.spec +++ b/misc/packaging/ninja.spec @@ -23,7 +23,7 @@ seconds to start building after changing one file. Ninja is under a second. %build echo Building.. -./bootstrap.py +./configure.py --bootstrap ./ninja manual %install diff --git a/misc/write_fake_manifests.py b/misc/write_fake_manifests.py index 837007e..ca49535 100644 --- a/misc/write_fake_manifests.py +++ b/misc/write_fake_manifests.py @@ -182,7 +182,7 @@ def FileWriter(path): def random_targets(): - num_targets = 800 + num_targets = 1500 gen = GenRandom() # N-1 static libraries, and 1 executable depending on all of them. diff --git a/misc/zsh-completion b/misc/zsh-completion index 2fe16fb..af24f89 100644 --- a/misc/zsh-completion +++ b/misc/zsh-completion @@ -17,7 +17,14 @@ # . path/to/ninja/misc/zsh-completion __get_targets() { - ninja -t targets 2>/dev/null | while read -r a b; do echo $a | cut -d ':' -f1; done; + dir="." + if [ -n "${opt_args[-C]}" ]; + then + eval dir="${opt_args[-C]}" + fi + targets_command="ninja -C \"${dir}\" -t targets" + eval ${targets_command} 2>/dev/null | while read -r a b; do echo $a | cut -d ':' -f1; done; + } __get_tools() { |