| #!/usr/bin/python3 |
| # -*- coding: utf-8 -*- |
| # |
| # Copyright © 2019 Endless Mobile, Inc. |
| # |
| # This library is free software; you can redistribute it and/or |
| # modify it under the terms of the GNU Lesser General Public |
| # License as published by the Free Software Foundation; either |
| # version 2.1 of the License, or (at your option) any later version. |
| # |
| # This library is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| # Lesser General Public License for more details. |
| # |
| # You should have received a copy of the GNU Lesser General Public |
| # License along with this library; if not, write to the Free Software |
| # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
| # MA 02110-1301 USA |
| |
| """Integration tests for glib-genmarshal utility.""" |
| |
| import collections |
| import os |
| import shutil |
| import subprocess |
| import sys |
| import tempfile |
| from textwrap import dedent |
| import unittest |
| |
| import taptestrunner |
| |
| |
| # Disable line length warnings as wrapping the C code templates would be hard |
| # flake8: noqa: E501 |
| |
| |
| Result = collections.namedtuple("Result", ("info", "out", "err", "subs")) |
| |
| |
| class TestGenmarshal(unittest.TestCase): |
| """Integration test for running glib-genmarshal. |
| |
| This can be run when installed or uninstalled. When uninstalled, it |
| requires G_TEST_BUILDDIR and G_TEST_SRCDIR to be set. |
| |
| The idea with this test harness is to test the glib-genmarshal utility, its |
| handling of command line arguments, its exit statuses, and its handling of |
| various marshaller lists. In future we could split the core glib-genmarshal |
| parsing and generation code out into a library and unit test that, and |
| convert this test to just check command line behaviour. |
| """ |
| |
| # Track the cwd, we want to back out to that to clean up our tempdir |
| cwd = "" |
| |
| def setUp(self): |
| self.timeout_seconds = 10 # seconds per test |
| self.tmpdir = tempfile.TemporaryDirectory() |
| self.cwd = os.getcwd() |
| os.chdir(self.tmpdir.name) |
| print("tmpdir:", self.tmpdir.name) |
| if "G_TEST_BUILDDIR" in os.environ: |
| self.__genmarshal = os.path.join( |
| os.environ["G_TEST_BUILDDIR"], "..", "glib-genmarshal" |
| ) |
| else: |
| self.__genmarshal = shutil.which("glib-genmarshal") |
| print("genmarshal:", self.__genmarshal) |
| |
| def tearDown(self): |
| os.chdir(self.cwd) |
| self.tmpdir.cleanup() |
| |
| def runGenmarshal(self, *args): |
| argv = [self.__genmarshal] |
| |
| # shebang lines are not supported on native |
| # Windows consoles |
| if os.name == "nt": |
| argv.insert(0, sys.executable) |
| |
| argv.extend(args) |
| print("Running:", argv) |
| |
| env = os.environ.copy() |
| env["LC_ALL"] = "C.UTF-8" |
| print("Environment:", env) |
| |
| # We want to ensure consistent line endings... |
| info = subprocess.run( |
| argv, |
| timeout=self.timeout_seconds, |
| stdout=subprocess.PIPE, |
| stderr=subprocess.PIPE, |
| env=env, |
| universal_newlines=True, |
| ) |
| info.check_returncode() |
| out = info.stdout.strip() |
| err = info.stderr.strip() |
| |
| # Known substitutions for standard boilerplate |
| subs = { |
| "standard_top_comment": "This file is generated by glib-genmarshal, do not modify " |
| "it. This code is licensed under the same license as the " |
| "containing project. Note that it links to GLib, so must " |
| "comply with the LGPL linking clauses.", |
| "standard_top_pragma": dedent( |
| """ |
| #ifndef __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__ |
| #define __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__ |
| """ |
| ).strip(), |
| "standard_bottom_pragma": dedent( |
| """ |
| #endif /* __G_CCLOSURE_USER_MARSHAL_MARSHAL_H__ */ |
| """ |
| ).strip(), |
| "standard_includes": dedent( |
| """ |
| #include <glib-object.h> |
| """ |
| ).strip(), |
| "standard_marshal_peek_defines": dedent( |
| """ |
| #ifdef G_ENABLE_DEBUG |
| #define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) |
| #define g_marshal_value_peek_char(v) g_value_get_schar (v) |
| #define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) |
| #define g_marshal_value_peek_int(v) g_value_get_int (v) |
| #define g_marshal_value_peek_uint(v) g_value_get_uint (v) |
| #define g_marshal_value_peek_long(v) g_value_get_long (v) |
| #define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) |
| #define g_marshal_value_peek_int64(v) g_value_get_int64 (v) |
| #define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) |
| #define g_marshal_value_peek_enum(v) g_value_get_enum (v) |
| #define g_marshal_value_peek_flags(v) g_value_get_flags (v) |
| #define g_marshal_value_peek_float(v) g_value_get_float (v) |
| #define g_marshal_value_peek_double(v) g_value_get_double (v) |
| #define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) |
| #define g_marshal_value_peek_param(v) g_value_get_param (v) |
| #define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) |
| #define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) |
| #define g_marshal_value_peek_object(v) g_value_get_object (v) |
| #define g_marshal_value_peek_variant(v) g_value_get_variant (v) |
| #else /* !G_ENABLE_DEBUG */ |
| /* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. |
| * Do not access GValues directly in your code. Instead, use the |
| * g_value_get_*() functions |
| */ |
| #define g_marshal_value_peek_boolean(v) (v)->data[0].v_int |
| #define g_marshal_value_peek_char(v) (v)->data[0].v_int |
| #define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint |
| #define g_marshal_value_peek_int(v) (v)->data[0].v_int |
| #define g_marshal_value_peek_uint(v) (v)->data[0].v_uint |
| #define g_marshal_value_peek_long(v) (v)->data[0].v_long |
| #define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong |
| #define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 |
| #define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 |
| #define g_marshal_value_peek_enum(v) (v)->data[0].v_long |
| #define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong |
| #define g_marshal_value_peek_float(v) (v)->data[0].v_float |
| #define g_marshal_value_peek_double(v) (v)->data[0].v_double |
| #define g_marshal_value_peek_string(v) (v)->data[0].v_pointer |
| #define g_marshal_value_peek_param(v) (v)->data[0].v_pointer |
| #define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer |
| #define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer |
| #define g_marshal_value_peek_object(v) (v)->data[0].v_pointer |
| #define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer |
| #endif /* !G_ENABLE_DEBUG */ |
| """ |
| ).strip(), |
| } |
| |
| result = Result(info, out, err, subs) |
| |
| print("Output:", result.out) |
| return result |
| |
| def runGenmarshalWithList(self, list_contents, *args): |
| with tempfile.NamedTemporaryFile( |
| dir=self.tmpdir.name, suffix=".list", delete=False |
| ) as list_file: |
| # Write out the list. |
| list_file.write(list_contents.encode("utf-8")) |
| print(list_file.name + ":", list_contents) |
| list_file.flush() |
| |
| header_result = self.runGenmarshal(list_file.name, "--header", *args) |
| body_result = self.runGenmarshal(list_file.name, "--body", *args) |
| |
| header_result.subs["list_path"] = list_file.name |
| body_result.subs["list_path"] = list_file.name |
| |
| return (header_result, body_result) |
| |
| def test_help(self): |
| """Test the --help argument.""" |
| result = self.runGenmarshal("--help") |
| self.assertIn("usage: glib-genmarshal", result.out) |
| |
| def test_no_args(self): |
| """Test running with no arguments at all.""" |
| result = self.runGenmarshal() |
| self.assertEqual("", result.err) |
| self.assertEqual("", result.out) |
| |
| def test_empty_list(self): |
| """Test running with an empty list.""" |
| (header_result, body_result) = self.runGenmarshalWithList("", "--quiet") |
| |
| self.assertEqual("", header_result.err) |
| self.assertEqual("", body_result.err) |
| |
| self.assertEqual( |
| dedent( |
| """ |
| /* {standard_top_comment} */ |
| {standard_top_pragma} |
| |
| {standard_includes} |
| |
| G_BEGIN_DECLS |
| |
| |
| G_END_DECLS |
| |
| {standard_bottom_pragma} |
| """ |
| ) |
| .strip() |
| .format(**header_result.subs), |
| header_result.out.strip(), |
| ) |
| |
| self.assertEqual( |
| dedent( |
| """ |
| /* {standard_top_comment} */ |
| {standard_includes} |
| |
| {standard_marshal_peek_defines} |
| """ |
| ) |
| .strip() |
| .format(**body_result.subs), |
| body_result.out.strip(), |
| ) |
| |
| def test_void_boolean(self): |
| """Test running with a basic VOID:BOOLEAN list.""" |
| (header_result, body_result) = self.runGenmarshalWithList( |
| "VOID:BOOLEAN", "--quiet" |
| ) |
| |
| self.assertEqual("", header_result.err) |
| self.assertEqual("", body_result.err) |
| |
| self.assertEqual( |
| dedent( |
| """ |
| /* {standard_top_comment} */ |
| {standard_top_pragma} |
| |
| {standard_includes} |
| |
| G_BEGIN_DECLS |
| |
| /* VOID:BOOLEAN ({list_path}:1) */ |
| #define g_cclosure_user_marshal_VOID__BOOLEAN g_cclosure_marshal_VOID__BOOLEAN |
| |
| |
| G_END_DECLS |
| |
| {standard_bottom_pragma} |
| """ |
| ) |
| .strip() |
| .format(**header_result.subs), |
| header_result.out.strip(), |
| ) |
| |
| self.assertEqual( |
| dedent( |
| """ |
| /* {standard_top_comment} */ |
| {standard_includes} |
| |
| {standard_marshal_peek_defines} |
| """ |
| ) |
| .strip() |
| .format(**body_result.subs), |
| body_result.out.strip(), |
| ) |
| |
| def test_void_boolean_int64(self): |
| """Test running with a non-trivial VOID:BOOLEAN,INT64 list.""" |
| (header_result, body_result) = self.runGenmarshalWithList( |
| "VOID:BOOLEAN,INT64", "--quiet" |
| ) |
| |
| self.assertEqual("", header_result.err) |
| self.assertEqual("", body_result.err) |
| |
| self.assertEqual( |
| dedent( |
| """ |
| /* {standard_top_comment} */ |
| {standard_top_pragma} |
| |
| {standard_includes} |
| |
| G_BEGIN_DECLS |
| |
| /* VOID:BOOLEAN,INT64 ({list_path}:1) */ |
| extern |
| void g_cclosure_user_marshal_VOID__BOOLEAN_INT64 (GClosure *closure, |
| GValue *return_value, |
| guint n_param_values, |
| const GValue *param_values, |
| gpointer invocation_hint, |
| gpointer marshal_data); |
| |
| |
| G_END_DECLS |
| |
| {standard_bottom_pragma} |
| """ |
| ) |
| .strip() |
| .format(**header_result.subs), |
| header_result.out.strip(), |
| ) |
| |
| self.assertEqual( |
| dedent( |
| """ |
| /* {standard_top_comment} */ |
| {standard_includes} |
| |
| {standard_marshal_peek_defines} |
| |
| /* VOID:BOOLEAN,INT64 ({list_path}:1) */ |
| void |
| g_cclosure_user_marshal_VOID__BOOLEAN_INT64 (GClosure *closure, |
| GValue *return_value G_GNUC_UNUSED, |
| guint n_param_values, |
| const GValue *param_values, |
| gpointer invocation_hint G_GNUC_UNUSED, |
| gpointer marshal_data) |
| {{ |
| typedef void (*GMarshalFunc_VOID__BOOLEAN_INT64) (gpointer data1, |
| gboolean arg1, |
| gint64 arg2, |
| gpointer data2); |
| GCClosure *cc = (GCClosure *) closure; |
| gpointer data1, data2; |
| GMarshalFunc_VOID__BOOLEAN_INT64 callback; |
| |
| g_return_if_fail (n_param_values == 3); |
| |
| if (G_CCLOSURE_SWAP_DATA (closure)) |
| {{ |
| data1 = closure->data; |
| data2 = g_value_peek_pointer (param_values + 0); |
| }} |
| else |
| {{ |
| data1 = g_value_peek_pointer (param_values + 0); |
| data2 = closure->data; |
| }} |
| callback = (GMarshalFunc_VOID__BOOLEAN_INT64) (marshal_data ? marshal_data : cc->callback); |
| |
| callback (data1, |
| g_marshal_value_peek_boolean (param_values + 1), |
| g_marshal_value_peek_int64 (param_values + 2), |
| data2); |
| }} |
| """ |
| ) |
| .strip() |
| .format(**body_result.subs), |
| body_result.out.strip(), |
| ) |
| |
| def test_void_variant_nostdinc_valist_marshaller(self): |
| """Test running with a basic VOID:VARIANT list, but without the |
| standard marshallers, and with valist support enabled. This checks that |
| the valist marshaller for VARIANT correctly sinks floating variants. |
| |
| See issue #1793. |
| """ |
| (header_result, body_result) = self.runGenmarshalWithList( |
| "VOID:VARIANT", "--quiet", "--nostdinc", "--valist-marshaller" |
| ) |
| |
| self.assertEqual("", header_result.err) |
| self.assertEqual("", body_result.err) |
| |
| self.assertEqual( |
| dedent( |
| """ |
| /* {standard_top_comment} */ |
| {standard_top_pragma} |
| |
| G_BEGIN_DECLS |
| |
| /* VOID:VARIANT ({list_path}:1) */ |
| extern |
| void g_cclosure_user_marshal_VOID__VARIANT (GClosure *closure, |
| GValue *return_value, |
| guint n_param_values, |
| const GValue *param_values, |
| gpointer invocation_hint, |
| gpointer marshal_data); |
| extern |
| void g_cclosure_user_marshal_VOID__VARIANTv (GClosure *closure, |
| GValue *return_value, |
| gpointer instance, |
| va_list args, |
| gpointer marshal_data, |
| int n_params, |
| GType *param_types); |
| |
| |
| G_END_DECLS |
| |
| {standard_bottom_pragma} |
| """ |
| ) |
| .strip() |
| .format(**header_result.subs), |
| header_result.out.strip(), |
| ) |
| |
| self.assertEqual( |
| dedent( |
| """ |
| /* {standard_top_comment} */ |
| {standard_marshal_peek_defines} |
| |
| /* VOID:VARIANT ({list_path}:1) */ |
| void |
| g_cclosure_user_marshal_VOID__VARIANT (GClosure *closure, |
| GValue *return_value G_GNUC_UNUSED, |
| guint n_param_values, |
| const GValue *param_values, |
| gpointer invocation_hint G_GNUC_UNUSED, |
| gpointer marshal_data) |
| {{ |
| typedef void (*GMarshalFunc_VOID__VARIANT) (gpointer data1, |
| gpointer arg1, |
| gpointer data2); |
| GCClosure *cc = (GCClosure *) closure; |
| gpointer data1, data2; |
| GMarshalFunc_VOID__VARIANT callback; |
| |
| g_return_if_fail (n_param_values == 2); |
| |
| if (G_CCLOSURE_SWAP_DATA (closure)) |
| {{ |
| data1 = closure->data; |
| data2 = g_value_peek_pointer (param_values + 0); |
| }} |
| else |
| {{ |
| data1 = g_value_peek_pointer (param_values + 0); |
| data2 = closure->data; |
| }} |
| callback = (GMarshalFunc_VOID__VARIANT) (marshal_data ? marshal_data : cc->callback); |
| |
| callback (data1, |
| g_marshal_value_peek_variant (param_values + 1), |
| data2); |
| }} |
| |
| void |
| g_cclosure_user_marshal_VOID__VARIANTv (GClosure *closure, |
| GValue *return_value G_GNUC_UNUSED, |
| gpointer instance, |
| va_list args, |
| gpointer marshal_data, |
| int n_params, |
| GType *param_types) |
| {{ |
| typedef void (*GMarshalFunc_VOID__VARIANT) (gpointer data1, |
| gpointer arg1, |
| gpointer data2); |
| GCClosure *cc = (GCClosure *) closure; |
| gpointer data1, data2; |
| GMarshalFunc_VOID__VARIANT callback; |
| gpointer arg0; |
| va_list args_copy; |
| |
| G_VA_COPY (args_copy, args); |
| arg0 = (gpointer) va_arg (args_copy, gpointer); |
| if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) |
| arg0 = g_variant_ref_sink (arg0); |
| va_end (args_copy); |
| |
| |
| if (G_CCLOSURE_SWAP_DATA (closure)) |
| {{ |
| data1 = closure->data; |
| data2 = instance; |
| }} |
| else |
| {{ |
| data1 = instance; |
| data2 = closure->data; |
| }} |
| callback = (GMarshalFunc_VOID__VARIANT) (marshal_data ? marshal_data : cc->callback); |
| |
| callback (data1, |
| arg0, |
| data2); |
| if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) |
| g_variant_unref (arg0); |
| }} |
| """ |
| ) |
| .strip() |
| .format(**body_result.subs), |
| body_result.out.strip(), |
| ) |
| |
| def test_void_string_nostdinc(self): |
| """Test running with a basic VOID:STRING list, but without the |
| standard marshallers, and with valist support enabled. This checks that |
| the valist marshaller for STRING correctly skips a string copy if the |
| argument is static. |
| |
| See issue #1792. |
| """ |
| (header_result, body_result) = self.runGenmarshalWithList( |
| "VOID:STRING", "--quiet", "--nostdinc", "--valist-marshaller" |
| ) |
| |
| self.assertEqual("", header_result.err) |
| self.assertEqual("", body_result.err) |
| |
| self.assertEqual( |
| dedent( |
| """ |
| /* {standard_top_comment} */ |
| {standard_top_pragma} |
| |
| G_BEGIN_DECLS |
| |
| /* VOID:STRING ({list_path}:1) */ |
| extern |
| void g_cclosure_user_marshal_VOID__STRING (GClosure *closure, |
| GValue *return_value, |
| guint n_param_values, |
| const GValue *param_values, |
| gpointer invocation_hint, |
| gpointer marshal_data); |
| extern |
| void g_cclosure_user_marshal_VOID__STRINGv (GClosure *closure, |
| GValue *return_value, |
| gpointer instance, |
| va_list args, |
| gpointer marshal_data, |
| int n_params, |
| GType *param_types); |
| |
| |
| G_END_DECLS |
| |
| {standard_bottom_pragma} |
| """ |
| ) |
| .strip() |
| .format(**header_result.subs), |
| header_result.out.strip(), |
| ) |
| |
| self.assertEqual( |
| dedent( |
| """ |
| /* {standard_top_comment} */ |
| {standard_marshal_peek_defines} |
| |
| /* VOID:STRING ({list_path}:1) */ |
| void |
| g_cclosure_user_marshal_VOID__STRING (GClosure *closure, |
| GValue *return_value G_GNUC_UNUSED, |
| guint n_param_values, |
| const GValue *param_values, |
| gpointer invocation_hint G_GNUC_UNUSED, |
| gpointer marshal_data) |
| {{ |
| typedef void (*GMarshalFunc_VOID__STRING) (gpointer data1, |
| gpointer arg1, |
| gpointer data2); |
| GCClosure *cc = (GCClosure *) closure; |
| gpointer data1, data2; |
| GMarshalFunc_VOID__STRING callback; |
| |
| g_return_if_fail (n_param_values == 2); |
| |
| if (G_CCLOSURE_SWAP_DATA (closure)) |
| {{ |
| data1 = closure->data; |
| data2 = g_value_peek_pointer (param_values + 0); |
| }} |
| else |
| {{ |
| data1 = g_value_peek_pointer (param_values + 0); |
| data2 = closure->data; |
| }} |
| callback = (GMarshalFunc_VOID__STRING) (marshal_data ? marshal_data : cc->callback); |
| |
| callback (data1, |
| g_marshal_value_peek_string (param_values + 1), |
| data2); |
| }} |
| |
| void |
| g_cclosure_user_marshal_VOID__STRINGv (GClosure *closure, |
| GValue *return_value G_GNUC_UNUSED, |
| gpointer instance, |
| va_list args, |
| gpointer marshal_data, |
| int n_params, |
| GType *param_types) |
| {{ |
| typedef void (*GMarshalFunc_VOID__STRING) (gpointer data1, |
| gpointer arg1, |
| gpointer data2); |
| GCClosure *cc = (GCClosure *) closure; |
| gpointer data1, data2; |
| GMarshalFunc_VOID__STRING callback; |
| gpointer arg0; |
| va_list args_copy; |
| |
| G_VA_COPY (args_copy, args); |
| arg0 = (gpointer) va_arg (args_copy, gpointer); |
| if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) |
| arg0 = g_strdup (arg0); |
| va_end (args_copy); |
| |
| |
| if (G_CCLOSURE_SWAP_DATA (closure)) |
| {{ |
| data1 = closure->data; |
| data2 = instance; |
| }} |
| else |
| {{ |
| data1 = instance; |
| data2 = closure->data; |
| }} |
| callback = (GMarshalFunc_VOID__STRING) (marshal_data ? marshal_data : cc->callback); |
| |
| callback (data1, |
| arg0, |
| data2); |
| if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) |
| g_free (arg0); |
| }} |
| """ |
| ) |
| .strip() |
| .format(**body_result.subs), |
| body_result.out.strip(), |
| ) |
| |
| def test_void_param_nostdinc(self): |
| """Test running with a basic VOID:PARAM list, but without the |
| standard marshallers, and with valist support enabled. This checks that |
| the valist marshaller for PARAM correctly skips a param copy if the |
| argument is static. |
| |
| See issue #1792. |
| """ |
| self.maxDiff = None # TODO |
| (header_result, body_result) = self.runGenmarshalWithList( |
| "VOID:PARAM", "--quiet", "--nostdinc", "--valist-marshaller" |
| ) |
| |
| self.assertEqual("", header_result.err) |
| self.assertEqual("", body_result.err) |
| |
| self.assertEqual( |
| dedent( |
| """ |
| /* {standard_top_comment} */ |
| {standard_top_pragma} |
| |
| G_BEGIN_DECLS |
| |
| /* VOID:PARAM ({list_path}:1) */ |
| extern |
| void g_cclosure_user_marshal_VOID__PARAM (GClosure *closure, |
| GValue *return_value, |
| guint n_param_values, |
| const GValue *param_values, |
| gpointer invocation_hint, |
| gpointer marshal_data); |
| extern |
| void g_cclosure_user_marshal_VOID__PARAMv (GClosure *closure, |
| GValue *return_value, |
| gpointer instance, |
| va_list args, |
| gpointer marshal_data, |
| int n_params, |
| GType *param_types); |
| |
| |
| G_END_DECLS |
| |
| {standard_bottom_pragma} |
| """ |
| ) |
| .strip() |
| .format(**header_result.subs), |
| header_result.out.strip(), |
| ) |
| |
| self.assertEqual( |
| dedent( |
| """ |
| /* {standard_top_comment} */ |
| {standard_marshal_peek_defines} |
| |
| /* VOID:PARAM ({list_path}:1) */ |
| void |
| g_cclosure_user_marshal_VOID__PARAM (GClosure *closure, |
| GValue *return_value G_GNUC_UNUSED, |
| guint n_param_values, |
| const GValue *param_values, |
| gpointer invocation_hint G_GNUC_UNUSED, |
| gpointer marshal_data) |
| {{ |
| typedef void (*GMarshalFunc_VOID__PARAM) (gpointer data1, |
| gpointer arg1, |
| gpointer data2); |
| GCClosure *cc = (GCClosure *) closure; |
| gpointer data1, data2; |
| GMarshalFunc_VOID__PARAM callback; |
| |
| g_return_if_fail (n_param_values == 2); |
| |
| if (G_CCLOSURE_SWAP_DATA (closure)) |
| {{ |
| data1 = closure->data; |
| data2 = g_value_peek_pointer (param_values + 0); |
| }} |
| else |
| {{ |
| data1 = g_value_peek_pointer (param_values + 0); |
| data2 = closure->data; |
| }} |
| callback = (GMarshalFunc_VOID__PARAM) (marshal_data ? marshal_data : cc->callback); |
| |
| callback (data1, |
| g_marshal_value_peek_param (param_values + 1), |
| data2); |
| }} |
| |
| void |
| g_cclosure_user_marshal_VOID__PARAMv (GClosure *closure, |
| GValue *return_value G_GNUC_UNUSED, |
| gpointer instance, |
| va_list args, |
| gpointer marshal_data, |
| int n_params, |
| GType *param_types) |
| {{ |
| typedef void (*GMarshalFunc_VOID__PARAM) (gpointer data1, |
| gpointer arg1, |
| gpointer data2); |
| GCClosure *cc = (GCClosure *) closure; |
| gpointer data1, data2; |
| GMarshalFunc_VOID__PARAM callback; |
| gpointer arg0; |
| va_list args_copy; |
| |
| G_VA_COPY (args_copy, args); |
| arg0 = (gpointer) va_arg (args_copy, gpointer); |
| if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) |
| arg0 = g_param_spec_ref (arg0); |
| va_end (args_copy); |
| |
| |
| if (G_CCLOSURE_SWAP_DATA (closure)) |
| {{ |
| data1 = closure->data; |
| data2 = instance; |
| }} |
| else |
| {{ |
| data1 = instance; |
| data2 = closure->data; |
| }} |
| callback = (GMarshalFunc_VOID__PARAM) (marshal_data ? marshal_data : cc->callback); |
| |
| callback (data1, |
| arg0, |
| data2); |
| if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL) |
| g_param_spec_unref (arg0); |
| }} |
| """ |
| ) |
| .strip() |
| .format(**body_result.subs), |
| body_result.out.strip(), |
| ) |
| |
| |
| if __name__ == "__main__": |
| unittest.main(testRunner=taptestrunner.TAPTestRunner()) |