diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2013-05-24 22:21:48 +0300 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2013-05-24 22:21:48 +0300 |
commit | 6ff098bea6c2722b659d8f8b03604fc365950045 (patch) | |
tree | c66bd65f826c2b8b984aa4e6d5f9d20618970865 | |
parent | 4bbc75427a87b27a6d8533ab9d6150b256cc41be (diff) | |
download | meson-6ff098bea6c2722b659d8f8b03604fc365950045.zip meson-6ff098bea6c2722b659d8f8b03604fc365950045.tar.gz meson-6ff098bea6c2722b659d8f8b03604fc365950045.tar.bz2 |
Store configuration values in an object rather than global variables.
-rwxr-xr-x | backends.py | 19 | ||||
-rwxr-xr-x | interpreter.py | 63 | ||||
-rw-r--r-- | test cases/common/16 configure file/meson.build | 14 | ||||
-rw-r--r-- | test cases/common/28 config subdir/include/meson.build | 6 |
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) |