From 9734e4854ebeaee684d566daa97cb518c4488b0e Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 27 Jan 2020 10:36:03 +0000 Subject: [PATCH] gdbus-codegen: Add --glib-max-allowed argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This complements the `--glib-min-required` argument, just like the `GLIB_MIN_REQUIRED` and `GLIB_MAX_ALLOWED` preprocessor defines which control access to APIs in C. Currently, it doesn’t affect code generation at all. When we next change code generation, we will need to gate any new API usage on this argument. Signed-off-by: Philip Withnall Fixes: #1993 --- docs/reference/gio/gdbus-codegen.xml | 22 ++++++++++++ gio/gdbus-2.0/codegen/codegen_main.py | 24 +++++++++++++ gio/gdbus-2.0/codegen/config.py.in | 2 ++ gio/gdbus-2.0/codegen/meson.build | 2 ++ gio/tests/codegen.py | 52 ++++++++++++++++++++++++++- 5 files changed, 101 insertions(+), 1 deletion(-) diff --git a/docs/reference/gio/gdbus-codegen.xml b/docs/reference/gio/gdbus-codegen.xml index 9d62c3757..9687681fd 100644 --- a/docs/reference/gio/gdbus-codegen.xml +++ b/docs/reference/gio/gdbus-codegen.xml @@ -51,6 +51,7 @@ VERSION + VERSION FILE FILE @@ -460,6 +461,27 @@ gdbus-codegen --c-namespace MyApp \ + + VERSION + + + Specifies the maximum version of GLib which the code generated by + gdbus-codegen can depend on. This may be used to + ensure that code generated by gdbus-codegen is + compilable with specific older versions of GLib that your software has + to support. + + + The version number must be of the form + MAJOR.MINOR.MICRO, + where all parts are integers. MINOR and + MICRO are optional. The version number must + be greater than or equal to that passed to . + It defaults to the version of GLib which provides this gdbus-codegen. + + + + diff --git a/gio/gdbus-2.0/codegen/codegen_main.py b/gio/gdbus-2.0/codegen/codegen_main.py index 60e1ae042..c938640e7 100644 --- a/gio/gdbus-2.0/codegen/codegen_main.py +++ b/gio/gdbus-2.0/codegen/codegen_main.py @@ -169,6 +169,8 @@ def codegen_main(): help='Add annotation (may be used several times)') arg_parser.add_argument('--glib-min-required', metavar='VERSION', help='Minimum version of GLib to be supported by the outputted code (default: 2.30)') + arg_parser.add_argument('--glib-max-allowed', metavar='VERSION', + help='Maximum version of GLib to be used by the outputted code (default: current GLib version)') group = arg_parser.add_mutually_exclusive_group() group.add_argument('--generate-c-code', metavar='OUTFILES', @@ -256,6 +258,28 @@ def codegen_main(): else: glib_min_required = (2, 30) + # And the maximum GLib version. + if args.glib_max_allowed: + try: + parts = args.glib_max_allowed.split('.', 3) + glib_max_allowed = (int(parts[0]), + int(parts[1] if len(parts) > 1 else 0)) + # Ignore micro component, but still validate it: + _ = int(parts[2] if len(parts) > 2 else 0) + except (ValueError, IndexError): + print_error('Unrecognized --glib-max-allowed string ‘{}’'.format( + args.glib_max_allowed)) + else: + glib_max_allowed = (config.MAJOR_VERSION, config.MINOR_VERSION) + + # Round --glib-max-allowed up to the next stable release. + glib_max_allowed = \ + (glib_max_allowed[0], glib_max_allowed[1] + (glib_max_allowed[1] % 2)) + + if glib_max_allowed < glib_min_required: + print_error('Invalid versions: --glib-min-required ({}) must be ' + 'less than or equal to --glib-max-allowed ({})'.format(glib_min_required, glib_max_allowed)) + glib_min_required_is_2_64 = (glib_min_required[0] > 2 or (glib_min_required[0] == 2 and glib_min_required[1] >= 64)) diff --git a/gio/gdbus-2.0/codegen/config.py.in b/gio/gdbus-2.0/codegen/config.py.in index a91178a95..4e6df5a09 100644 --- a/gio/gdbus-2.0/codegen/config.py.in +++ b/gio/gdbus-2.0/codegen/config.py.in @@ -20,3 +20,5 @@ # Author: David Zeuthen VERSION = "@VERSION@" +MAJOR_VERSION = @MAJOR_VERSION@ +MINOR_VERSION = @MINOR_VERSION@ diff --git a/gio/gdbus-2.0/codegen/meson.build b/gio/gdbus-2.0/codegen/meson.build index 121e9e6bb..ff5edb977 100644 --- a/gio/gdbus-2.0/codegen/meson.build +++ b/gio/gdbus-2.0/codegen/meson.build @@ -10,6 +10,8 @@ gdbus_codegen_files = [ gdbus_codegen_conf = configuration_data() gdbus_codegen_conf.set('VERSION', glib_version) +gdbus_codegen_conf.set('MAJOR_VERSION', major_version) +gdbus_codegen_conf.set('MINOR_VERSION', minor_version) gdbus_codegen_conf.set('PYTHON', python_name) gdbus_codegen_conf.set('DATADIR', glib_datadir) diff --git a/gio/tests/codegen.py b/gio/tests/codegen.py index bbb51117d..51de0ede4 100644 --- a/gio/tests/codegen.py +++ b/gio/tests/codegen.py @@ -384,7 +384,8 @@ G_END_DECLS result = self.runCodegenWithInterface('', '--output', '/dev/stdout', '--header', - '--glib-min-required', '3') + '--glib-min-required', '3', + '--glib-max-allowed', '3.2') self.assertEqual('', result.err) self.assertNotEqual('', result.out.strip()) @@ -397,6 +398,55 @@ G_END_DECLS self.assertEqual('', result.err) self.assertNotEqual('', result.out.strip()) + def test_glib_max_allowed_too_low(self): + """Test running with a --glib-max-allowed which is too low (and hence + probably a typo).""" + with self.assertRaises(subprocess.CalledProcessError): + self.runCodegenWithInterface('', + '--output', '/dev/stdout', + '--body', + '--glib-max-allowed', '2.6') + + def test_glib_max_allowed_major_only(self): + """Test running with a --glib-max-allowed which contains only a major version.""" + result = self.runCodegenWithInterface('', + '--output', '/dev/stdout', + '--header', + '--glib-max-allowed', '3') + self.assertEqual('', result.err) + self.assertNotEqual('', result.out.strip()) + + def test_glib_max_allowed_with_micro(self): + """Test running with a --glib-max-allowed which contains a micro version.""" + result = self.runCodegenWithInterface('', + '--output', '/dev/stdout', + '--header', + '--glib-max-allowed', '2.46.2') + self.assertEqual('', result.err) + self.assertNotEqual('', result.out.strip()) + + def test_glib_max_allowed_unstable(self): + """Test running with a --glib-max-allowed which is unstable. It should + be rounded up to the next stable version number, and hence should not + end up less than --glib-min-required.""" + result = self.runCodegenWithInterface('', + '--output', '/dev/stdout', + '--header', + '--glib-max-allowed', '2.63', + '--glib-min-required', '2.64') + self.assertEqual('', result.err) + self.assertNotEqual('', result.out.strip()) + + def test_glib_max_allowed_less_than_min_required(self): + """Test running with a --glib-max-allowed which is less than + --glib-min-required.""" + with self.assertRaises(subprocess.CalledProcessError): + self.runCodegenWithInterface('', + '--output', '/dev/stdout', + '--body', + '--glib-max-allowed', '2.62', + '--glib-min-required', '2.64') + def test_unix_fd_types_and_annotations(self): """Test an interface with `h` arguments, no annotation, and GLib < 2.64.