aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordabrain34 <scerveau@collabora.com>2020-04-10 20:14:54 +0200
committerGitHub <noreply@github.com>2020-04-10 11:14:54 -0700
commit97a72a1c53e68cf53541285075b4000f7c85ccc6 (patch)
tree86d0295e95e2d7d8a3c3372fa4eb66106aa0df09
parent2008cb21098e3d73d1b8f82c2c35c455c9435dfa (diff)
downloadmeson-97a72a1c53e68cf53541285075b4000f7c85ccc6.zip
meson-97a72a1c53e68cf53541285075b4000f7c85ccc6.tar.gz
meson-97a72a1c53e68cf53541285075b4000f7c85ccc6.tar.bz2
cmake: support cmake config file syntax (#6917)
* cmake: enhance support of cmake config file syntax Enhance the cmakedefine support by accepting 2 or 3 tokens in the conf line as mesondefine supports strictly 2 tokens * fixup! cmake: enhance support of cmake config file syntax * fixup! fixup! cmake: enhance support of cmake config file syntax
-rw-r--r--mesonbuild/mesonlib.py60
-rwxr-xr-xrun_unittests.py50
2 files changed, 96 insertions, 14 deletions
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index e215dcd..c72197e 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -877,7 +877,7 @@ def do_replacement(regex: T.Pattern[str], line: str, variable_format: str,
start_tag = '${'
backslash_tag = '\\${'
else:
- assert variable_format == 'meson'
+ assert variable_format in ['meson', 'cmake@']
start_tag = '@'
backslash_tag = '\\@'
@@ -908,11 +908,22 @@ def do_replacement(regex: T.Pattern[str], line: str, variable_format: str,
return var
return re.sub(regex, variable_replace, line), missing_variables
+def do_define(regex: T.Pattern[str], line: str, confdata: 'ConfigurationData', variable_format: str) -> str:
+ def get_cmake_define(line: str, confdata: 'ConfigurationData') -> str:
+ arr = line.split()
+ define_value=[]
+ for token in arr[2:]:
+ try:
+ (v, desc) = confdata.get(token)
+ define_value += [v]
+ except KeyError:
+ define_value += [token]
+ return ' '.join(define_value)
-def do_mesondefine(line: str, confdata: 'ConfigurationData') -> str:
arr = line.split()
- if len(arr) != 2:
- raise MesonException('#mesondefine does not contain exactly two tokens: %s' % line.strip())
+ if variable_format == 'meson' and len(arr) != 2:
+ raise MesonException('#mesondefine does not contain exactly two tokens: %s' % line.strip())
+
varname = arr[1]
try:
(v, desc) = confdata.get(varname)
@@ -926,18 +937,27 @@ def do_mesondefine(line: str, confdata: 'ConfigurationData') -> str:
elif isinstance(v, int):
return '#define %s %d\n' % (varname, v)
elif isinstance(v, str):
- return '#define %s %s\n' % (varname, v)
+ if variable_format == 'meson':
+ result = v
+ else:
+ result = get_cmake_define(line, confdata)
+ result = '#define %s %s\n' % (varname, result)
+ (result, missing_variable) = do_replacement(regex, result, variable_format, confdata)
+ return result
else:
raise MesonException('#mesondefine argument "%s" is of unknown type.' % varname)
+def do_conf_str (data: list, confdata: 'ConfigurationData', variable_format: str,
+ encoding: str = 'utf-8') -> T.Tuple[T.List[str],T.Set[str], bool]:
+ def line_is_valid(line : str, variable_format: str):
+ if variable_format == 'meson':
+ if '#cmakedefine' in line:
+ return False
+ else: #cmake format
+ if '#mesondefine' in line:
+ return False
+ return True
-def do_conf_file(src: str, dst: str, confdata: 'ConfigurationData', variable_format: str,
- encoding: str = 'utf-8') -> T.Tuple[T.Set[str], bool]:
- try:
- with open(src, encoding=encoding, newline='') as f:
- data = f.readlines()
- except Exception as e:
- raise MesonException('Could not read input file %s: %s' % (src, str(e)))
# Only allow (a-z, A-Z, 0-9, _, -) as valid characters for a define
# Also allow escaping '@' with '\@'
if variable_format in ['meson', 'cmake@']:
@@ -959,13 +979,27 @@ def do_conf_file(src: str, dst: str, confdata: 'ConfigurationData', variable_for
for line in data:
if line.startswith(search_token):
confdata_useless = False
- line = do_mesondefine(line, confdata)
+ line = do_define(regex, line, confdata, variable_format)
else:
+ if not line_is_valid(line,variable_format):
+ raise MesonException('Format "{}" mismatched'.format(variable_format))
line, missing = do_replacement(regex, line, variable_format, confdata)
missing_variables.update(missing)
if missing:
confdata_useless = False
result.append(line)
+
+ return result, missing_variables, confdata_useless
+
+def do_conf_file(src: str, dst: str, confdata: 'ConfigurationData', variable_format: str,
+ encoding: str = 'utf-8') -> T.Tuple[T.Set[str], bool]:
+ try:
+ with open(src, encoding=encoding, newline='') as f:
+ data = f.readlines()
+ except Exception as e:
+ raise MesonException('Could not read input file %s: %s' % (src, str(e)))
+
+ (result, missing_variables, confdata_useless) = do_conf_str(data, confdata, variable_format, encoding)
dst_tmp = dst + '~'
try:
with open(dst_tmp, 'w', encoding=encoding, newline='') as f:
diff --git a/run_unittests.py b/run_unittests.py
index ecd277d..a9ceddd 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -62,7 +62,7 @@ from mesonbuild.environment import detect_ninja
from mesonbuild.mesonlib import MesonException, EnvironmentException
from mesonbuild.dependencies import PkgConfigDependency, ExternalProgram
import mesonbuild.dependencies.base
-from mesonbuild.build import Target
+from mesonbuild.build import Target, ConfigurationData
import mesonbuild.modules.pkgconfig
from mesonbuild.mtest import TAPParser, TestResult
@@ -1870,6 +1870,54 @@ class AllPlatformTests(BasePlatformTests):
self.assertEqual(conf_file('@VAR@\n@VAR@\n', confdata), 'foo\nfoo\n')
self.assertEqual(conf_file('@VAR@\r\n@VAR@\r\n', confdata), 'foo\r\nfoo\r\n')
+ def test_do_conf_file_by_format(self):
+ def conf_str(in_data, confdata, vformat):
+ (result, missing_variables, confdata_useless) = mesonbuild.mesonlib.do_conf_str(in_data, confdata, variable_format = vformat)
+ return '\n'.join(result)
+
+ def check_formats (confdata, result):
+ self.assertEqual(conf_str(['#mesondefine VAR'], confdata, 'meson'),result)
+ self.assertEqual(conf_str(['#cmakedefine VAR ${VAR}'], confdata, 'cmake'),result)
+ self.assertEqual(conf_str(['#cmakedefine VAR @VAR@'], confdata, 'cmake@'),result)
+
+ confdata = ConfigurationData()
+ # Key error as they do not exists
+ check_formats(confdata, '/* #undef VAR */\n')
+
+ # Check boolean
+ confdata.values = {'VAR': (False,'description')}
+ check_formats(confdata, '#undef VAR\n')
+ confdata.values = {'VAR': (True,'description')}
+ check_formats(confdata, '#define VAR\n')
+
+ # Check string
+ confdata.values = {'VAR': ('value','description')}
+ check_formats(confdata, '#define VAR value\n')
+
+ # Check integer
+ confdata.values = {'VAR': (10,'description')}
+ check_formats(confdata, '#define VAR 10\n')
+
+ # Check multiple string with cmake formats
+ confdata.values = {'VAR': ('value','description')}
+ self.assertEqual(conf_str(['#cmakedefine VAR xxx @VAR@ yyy @VAR@'], confdata, 'cmake@'),'#define VAR xxx value yyy value\n')
+ self.assertEqual(conf_str(['#define VAR xxx @VAR@ yyy @VAR@'], confdata, 'cmake@'),'#define VAR xxx value yyy value')
+ self.assertEqual(conf_str(['#cmakedefine VAR xxx ${VAR} yyy ${VAR}'], confdata, 'cmake'),'#define VAR xxx value yyy value\n')
+ self.assertEqual(conf_str(['#define VAR xxx ${VAR} yyy ${VAR}'], confdata, 'cmake'),'#define VAR xxx value yyy value')
+
+ # Handles meson format exceptions
+ # Unknown format
+ self.assertRaises(mesonbuild.mesonlib.MesonException, conf_str,['#mesondefine VAR xxx'], confdata, 'unknown_format')
+ # More than 2 params in mesondefine
+ self.assertRaises(mesonbuild.mesonlib.MesonException, conf_str,['#mesondefine VAR xxx'], confdata, 'meson')
+ # Mismatched line with format
+ self.assertRaises(mesonbuild.mesonlib.MesonException, conf_str,['#cmakedefine VAR'], confdata, 'meson')
+ self.assertRaises(mesonbuild.mesonlib.MesonException, conf_str,['#mesondefine VAR'], confdata, 'cmake')
+ self.assertRaises(mesonbuild.mesonlib.MesonException, conf_str,['#mesondefine VAR'], confdata, 'cmake@')
+ # Dict value in confdata
+ confdata.values = {'VAR': (['value'],'description')}
+ self.assertRaises(mesonbuild.mesonlib.MesonException, conf_str,['#mesondefine VAR'], confdata, 'meson')
+
def test_absolute_prefix_libdir(self):
'''
Tests that setting absolute paths for --prefix and --libdir work. Can't