add an "expand" function to ninja_syntax
authorEvan Martin <martine@danga.com>
Tue, 18 Nov 2014 15:48:26 +0000 (07:48 -0800)
committerEvan Martin <martine@danga.com>
Tue, 18 Nov 2014 16:15:36 +0000 (08:15 -0800)
Implements basic variable expansion for use in configure.py.

misc/ninja_syntax.py
misc/ninja_syntax_test.py

index 14b932f..e200514 100644 (file)
@@ -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):
@@ -154,3 +155,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)
index 2aef7ff..36b2e7b 100755 (executable)
@@ -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()