aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2013-05-24 22:21:48 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2013-05-24 22:21:48 +0300
commit6ff098bea6c2722b659d8f8b03604fc365950045 (patch)
treec66bd65f826c2b8b984aa4e6d5f9d20618970865
parent4bbc75427a87b27a6d8533ab9d6150b256cc41be (diff)
downloadmeson-6ff098bea6c2722b659d8f8b03604fc365950045.zip
meson-6ff098bea6c2722b659d8f8b03604fc365950045.tar.gz
meson-6ff098bea6c2722b659d8f8b03604fc365950045.tar.bz2
Store configuration values in an object rather than global variables.
-rwxr-xr-xbackends.py19
-rwxr-xr-xinterpreter.py63
-rw-r--r--test cases/common/16 configure file/meson.build14
-rw-r--r--test cases/common/28 config subdir/include/meson.build6
4 files changed, 82 insertions, 20 deletions
diff --git a/backends.py b/backends.py
index 0ea9356..1abfdc2 100755
--- a/backends.py
+++ b/backends.py
@@ -31,12 +31,12 @@ else:
def ninja_quote(text):
return text.replace(' ', '$ ')
-def do_replacement(regex, line, variables):
+def do_replacement(regex, line, confdata):
match = re.search(regex, line)
while match:
varname = match.group(1)
- if varname in variables:
- var = variables[varname]
+ if varname in confdata.keys():
+ var = confdata.get(varname)
if isinstance(var, str):
pass
elif isinstance(var, nodes.StringStatement):
@@ -49,12 +49,12 @@ def do_replacement(regex, line, variables):
match = re.search(regex, line)
return line
-def do_mesondefine(line, variables):
+def do_mesondefine(line, confdata):
arr = line.split()
if len(arr) != 2:
raise interpreter.InvalidArguments('#mesondefine does not contain exactly two tokens.')
varname = arr[1]
- v = variables.get(varname, False)
+ v = confdata.get(varname, False)
if isinstance(v, bool):
value= v
elif isinstance(v, nodes.BoolStatement):
@@ -65,15 +65,15 @@ def do_mesondefine(line, variables):
return '#define %s\n' % varname
return '/* undef %s */\n' % varname
-def do_conf_file(src, dst, variables):
+def do_conf_file(src, dst, confdata):
data = open(src).readlines()
regex = re.compile('@(.*?)@')
result = []
for line in data:
if line.startswith('#mesondefine'):
- line = do_mesondefine(line, variables)
+ line = do_mesondefine(line, confdata)
else:
- line = do_replacement(regex, line, variables)
+ line = do_replacement(regex, line, confdata)
result.append(line)
dst_tmp = dst + '~'
open(dst_tmp, 'w').writelines(result)
@@ -209,7 +209,8 @@ class Backend():
cf.get_subdir())
os.makedirs(outdir, exist_ok=True)
outfile = os.path.join(outdir, cf.get_target_name())
- do_conf_file(infile, outfile, self.interpreter.get_variables())
+ confdata = cf.get_configuration_data()
+ do_conf_file(infile, outfile, confdata)
class NinjaBuildElement():
def __init__(self, outfilenames, rule, infilenames):
diff --git a/interpreter.py b/interpreter.py
index 49fcf82..a67286f 100755
--- a/interpreter.py
+++ b/interpreter.py
@@ -40,6 +40,37 @@ class InterpreterObject():
return self.methods[method_name](args, kwargs)
raise InvalidCode('Unknown method "%s" in object.' % method_name)
+class ConfigurationData(InterpreterObject):
+
+ def __init__(self):
+ super().__init__()
+ self.used = False # These objects become immutable after use in configure_file.
+ self.values = {}
+ self.methods.update({'set': self.set_method})
+
+ def is_used(self):
+ return self.used
+
+ def mark_used(self):
+ self.used = True
+
+ def set_method(self, args, kwargs):
+ if len(args) != 2:
+ raise InterpreterException("Configuration set requires 2 arguments.")
+ if self.used:
+ raise InterpreterException("Can not set values on configuration object that has been used.")
+ name = args[0]
+ val = args[1]
+ if not isinstance(name, str):
+ raise InterpreterException("First argument to set must be a string.")
+ self.values[name] = val
+
+ def get(self, *args):
+ return self.values.get(*args)
+
+ def keys(self):
+ return self.values.keys()
+
# Interpreter objects can not be pickled so we must have
# these wrappers.
@@ -243,11 +274,15 @@ class Data(InterpreterObject):
class ConfigureFile(InterpreterObject):
- def __init__(self, subdir, sourcename, targetname, kwargs):
+ def __init__(self, subdir, sourcename, targetname, configuration_data):
InterpreterObject.__init__(self)
self.subdir = subdir
self.sourcename = sourcename
self.targetname = targetname
+ self.configuration_data = configuration_data
+
+ def get_configuration_data(self):
+ return self.configuration_data
def get_sources(self):
return self.sources
@@ -574,6 +609,7 @@ class Interpreter():
'add_global_arguments' : self.func_add_global_arguments,
'find_program' : self.func_find_program,
'find_library' : self.func_find_library,
+ 'configuration_data' : self.func_configuration_data,
}
def get_build_def_files(self):
@@ -655,6 +691,11 @@ class Interpreter():
print(actual)
print(wanted)
raise InvalidArguments('Incorrect argument type.')
+
+ def func_configuration_data(self, node, args, kwargs):
+ if len(args) != 0:
+ raise InterpreterException('configuration_data takes no arguments')
+ return ConfigurationData()
def func_project(self, node, args, kwargs):
if len(args)< 2:
@@ -806,11 +847,25 @@ class Interpreter():
return data
def func_configure_file(self, node, args, kwargs):
- self.validate_arguments(args, 2, [str, str])
- conffile = os.path.join(self.subdir, args[0])
+ if len(args) > 0:
+ raise InterpreterException("configure_file takes only keyword arguments.")
+ if not 'input' in kwargs:
+ raise InterpreterException('Required keyword argument "input" not defined.')
+ if not 'output' in kwargs:
+ raise InterpreterException('Required keyword argument "output" not defined.')
+ if not 'configuration' in kwargs:
+ raise InterpreterException('Required keyword argument "configuration" not defined.')
+ inputfile = kwargs['input']
+ output = kwargs['output']
+ conf = kwargs['configuration']
+ if not isinstance(conf, ConfigurationData):
+ raise InterpreterException('Argument "configuration" is not of type configuration_data')
+
+ conffile = os.path.join(self.subdir, inputfile)
self.build_def_files.append(conffile)
- c = ConfigureFile(self.subdir, args[0], args[1], kwargs)
+ c = ConfigureFile(self.subdir, inputfile, output, conf)
self.build.configure_files.append(c)
+ conf.mark_used()
def func_include_directories(self, node, args, kwargs):
for a in args:
diff --git a/test cases/common/16 configure file/meson.build b/test cases/common/16 configure file/meson.build
index 1ec9f6c..ff4c9ea 100644
--- a/test cases/common/16 configure file/meson.build
+++ b/test cases/common/16 configure file/meson.build
@@ -1,11 +1,15 @@
project('configure file test', 'c')
-var = 'mystring'
-other = 'string 2'
-second = ' bonus'
-BE_TRUE = true
+conf = configuration_data()
-configure_file('config.h.in', 'config.h')
+conf.set('var', 'mystring')
+conf.set('other', 'string 2')
+conf.set('second', ' bonus')
+conf.set('BE_TRUE', true)
+
+configure_file(input : 'config.h.in',
+output : 'config.h',
+configuration : conf)
e = executable('inctest', 'prog.c', include_dirs : include_directories('.'))
add_test('inctest', e)
diff --git a/test cases/common/28 config subdir/include/meson.build b/test cases/common/28 config subdir/include/meson.build
index 8fb3282..f14111a 100644
--- a/test cases/common/28 config subdir/include/meson.build
+++ b/test cases/common/28 config subdir/include/meson.build
@@ -1,2 +1,4 @@
-number = '0'
-configure_file('config.h.in', 'config.h')
+conf_data = configuration_data()
+conf_data.set('number', '0')
+
+configure_file(input:'config.h.in', output:'config.h', configuration:conf_data)