mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 19:36:18 +01:00
Merge branch '1793-genmarshal-variant' into 'master'
Add glib-genmarshal tests and fix some valist marshaller bugs Closes #1792 and #1793 See merge request GNOME/glib!904
This commit is contained in:
commit
686bf2a665
@ -330,6 +330,7 @@ IN_ARGS = {
|
||||
'ctype': 'gpointer',
|
||||
'getter': 'g_marshal_value_peek_string',
|
||||
'box': ['g_strdup', 'g_free'],
|
||||
'static-check': True,
|
||||
},
|
||||
'PARAM': {
|
||||
'signal': 'PARAM',
|
||||
@ -360,7 +361,7 @@ IN_ARGS = {
|
||||
'signal': 'VARIANT',
|
||||
'ctype': 'gpointer',
|
||||
'getter': 'g_marshal_value_peek_variant',
|
||||
'box': ['g_variant_ref', 'g_variant_unref'],
|
||||
'box': ['g_variant_ref_sink', 'g_variant_unref'],
|
||||
'static-check': True,
|
||||
'takes-type': False,
|
||||
},
|
||||
|
599
gobject/tests/genmarshal.py
Normal file
599
gobject/tests/genmarshal.py
Normal file
@ -0,0 +1,599 @@
|
||||
#!/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 tempfile
|
||||
from textwrap import dedent
|
||||
import unittest
|
||||
|
||||
import taptestrunner
|
||||
|
||||
|
||||
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.
|
||||
"""
|
||||
def setUp(self):
|
||||
self.timeout_seconds = 10 # seconds per test
|
||||
self.tmpdir = tempfile.TemporaryDirectory()
|
||||
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):
|
||||
self.tmpdir.cleanup()
|
||||
|
||||
def runGenmarshal(self, *args):
|
||||
argv = [self.__genmarshal]
|
||||
argv.extend(args)
|
||||
print('Running:', argv)
|
||||
|
||||
env = os.environ.copy()
|
||||
env['LC_ALL'] = 'C.UTF-8'
|
||||
print('Environment:', env)
|
||||
|
||||
info = subprocess.run(argv, timeout=self.timeout_seconds,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
env=env)
|
||||
info.check_returncode()
|
||||
out = info.stdout.decode('utf-8').strip()
|
||||
err = info.stderr.decode('utf-8').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') 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())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(testRunner=taptestrunner.TAPTestRunner())
|
@ -56,6 +56,11 @@ if cc.get_id() != 'msvc'
|
||||
gobject_tests += {'autoptr' : {}}
|
||||
endif
|
||||
|
||||
python_tests = [
|
||||
'genmarshal.py',
|
||||
'mkenums.py',
|
||||
]
|
||||
|
||||
# FIXME: put common bits of test environment() in one location
|
||||
# Not entirely random of course, but at least it changes over time
|
||||
random_number = minor_version + meson.version().split('.').get(1).to_int()
|
||||
@ -106,10 +111,39 @@ foreach test_name, extra_args : gobject_tests
|
||||
test(test_name, exe, env : test_env, timeout : timeout, suite : suite)
|
||||
endforeach
|
||||
|
||||
foreach test_name : python_tests
|
||||
test(
|
||||
'mkenums.py',
|
||||
test_name,
|
||||
python,
|
||||
args: files('mkenums.py'),
|
||||
args: files(test_name),
|
||||
env: test_env,
|
||||
suite: ['gobject'],
|
||||
)
|
||||
|
||||
if installed_tests_enabled
|
||||
install_data(
|
||||
files(test_name),
|
||||
install_dir: installed_tests_execdir,
|
||||
install_mode: 'rwxr-xr-x',
|
||||
)
|
||||
|
||||
test_conf = configuration_data()
|
||||
test_conf.set('installed_tests_dir', installed_tests_execdir)
|
||||
test_conf.set('program', test_name)
|
||||
test_conf.set('env', '')
|
||||
configure_file(
|
||||
input: installed_tests_template_tap,
|
||||
output: test_name + '.test',
|
||||
install_dir: installed_tests_metadir,
|
||||
configuration: test_conf,
|
||||
)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
# TAP test runner for Python tests
|
||||
if installed_tests_enabled
|
||||
install_data(
|
||||
files('taptestrunner.py'),
|
||||
install_dir: installed_tests_execdir,
|
||||
)
|
||||
endif
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
import collections
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import textwrap
|
||||
@ -57,7 +58,7 @@ class TestMkenums(unittest.TestCase):
|
||||
os.path.join(os.environ['G_TEST_BUILDDIR'], '..',
|
||||
'glib-mkenums')
|
||||
else:
|
||||
self.__mkenums = os.path.join('/', 'usr', 'bin', 'glib-mkenums')
|
||||
self.__mkenums = shutil.which('glib-mkenums')
|
||||
print('rspfile: {}, mkenums:'.format(self.rspfile), self.__mkenums)
|
||||
|
||||
def tearDown(self):
|
||||
|
Loading…
Reference in New Issue
Block a user