#!/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


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())
