Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

glib-mkenums and glib-genmarshal support #718

Merged
merged 7 commits into from
Oct 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
157 changes: 157 additions & 0 deletions mesonbuild/modules/gnome.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,163 @@ def gdbus_codegen(self, state, args, kwargs):
}
return build.CustomTarget(namebase + '-gdbus', state.subdir, custom_kwargs)

def mkenums(self, state, args, kwargs):
if len(args) != 1:
raise MesonException('Mkenums requires one positional argument.')
basename = args[0]

if 'sources' not in kwargs:
raise MesonException('Missing keyword argument "sources".')
sources = kwargs.pop('sources')
if isinstance(sources, str):
sources = [sources]
elif not isinstance(sources, list):
raise MesonException(
'Sources keyword argument must be a string or array.')

cmd = []
known_kwargs = ['comments', 'eprod', 'fhead', 'fprod', 'ftail',
'identifier_prefix', 'symbol_prefix', 'template',
'vhead', 'vprod', 'vtail']
known_custom_target_kwargs = ['install', 'install_dir', 'build_always',
'depends', 'depend_files']
c_template = h_template = None
install_header = False
for arg, value in kwargs.items():
if arg == 'sources':
sources = [value] + sources
elif arg == 'c_template':
c_template = value
elif arg == 'h_template':
h_template = value
elif arg == 'install_header':
install_header = value
elif arg in known_kwargs:
cmd += ['--' + arg.replace('_', '-'), value]
elif arg not in known_custom_target_kwargs:
raise MesonException(
'Mkenums does not take a %s keyword argument.' % (arg, ))
cmd = ['glib-mkenums'] + cmd
custom_kwargs = {}
for arg in known_custom_target_kwargs:
if arg in kwargs:
custom_kwargs[arg] = kwargs[arg]

targets = []

if h_template is not None:
h_output = os.path.splitext(h_template)[0]
# We always set template as the first element in the source array
# so --template consumes it.
h_cmd = cmd + ['--template', '@INPUT@']
h_sources = [h_template] + sources
custom_kwargs['install'] = install_header
if 'install_dir' not in custom_kwargs:
custom_kwargs['install_dir'] = \
state.environment.coredata.get_builtin_option('includedir')
h_target = self.make_mkenum_custom_target(state, h_sources,
h_output, h_cmd,
custom_kwargs)
targets.append(h_target)

if c_template is not None:
c_output = os.path.splitext(c_template)[0]
# We always set template as the first element in the source array
# so --template consumes it.
c_cmd = cmd + ['--template', '@INPUT@']
c_sources = [c_template] + sources
# Never install the C file. Complain on bug tracker if you need it.
custom_kwargs['install'] = False
if h_template is not None:
if 'depends' in custom_kwargs:
custom_kwargs['depends'] += [h_target]
else:
custom_kwargs['depends'] = h_target
c_target = self.make_mkenum_custom_target(state, c_sources,
c_output, c_cmd,
custom_kwargs)
targets.insert(0, c_target)

if c_template is None and h_template is None:
generic_cmd = cmd + ['@INPUT@']
custom_kwargs['install'] = install_header
if 'install_dir' not in custom_kwargs:
custom_kwargs['install_dir'] = \
state.environment.coredata.get_builtin_option('includedir')
target = self.make_mkenum_custom_target(state, sources, basename,
generic_cmd, custom_kwargs)
return target
elif len(targets) == 1:
return targets[0]
else:
return targets

def make_mkenum_custom_target(self, state, sources, output, cmd, kwargs):
custom_kwargs = {
'input': sources,
'output': output,
'capture': True,
'command': cmd
}
custom_kwargs.update(kwargs)
return build.CustomTarget(output, state.subdir, custom_kwargs)

def genmarshal(self, state, args, kwargs):
if len(args) != 1:
raise MesonException(
'Genmarshal requires one positional argument.')
output = args[0]

if 'sources' not in kwargs:
raise MesonException('Missing keyword argument "sources".')
sources = kwargs.pop('sources')
if isinstance(sources, str):
sources = [sources]
elif not isinstance(sources, list):
raise MesonException(
'Sources keyword argument must be a string or array.')

cmd = ['glib-genmarshal']
known_kwargs = ['internal', 'nostdinc', 'skip_source', 'stdinc',
'valist_marshallers']
known_custom_target_kwargs = ['build_always', 'depends',
'depend_files', 'install_dir',
'install_header']
for arg, value in kwargs.items():
if arg == 'prefix':
cmd += ['--prefix', value]
elif arg in known_kwargs and value:
cmd += ['--' + arg.replace('_', '-')]
elif arg not in known_custom_target_kwargs:
raise MesonException(
'Genmarshal does not take a %s keyword argument.' % (
arg, ))

install_header = kwargs.pop('install_header', False)
install_dir = kwargs.pop('install_dir', None)

custom_kwargs = {
'input': sources,
'capture': True,
}
for arg in known_custom_target_kwargs:
if arg in kwargs:
custom_kwargs[arg] = kwargs[arg]

custom_kwargs['command'] = cmd + ['--header', '--body', '@INPUT@']
custom_kwargs['output'] = output + '.c'
body = build.CustomTarget(output + '_c', state.subdir, custom_kwargs)

custom_kwargs['install'] = install_header
if install_dir is not None:
custom_kwargs['install_dir'] = install_dir
custom_kwargs['command'] = cmd + ['--header', '@INPUT@']
custom_kwargs['output'] = output + '.h'
header = build.CustomTarget(output + '_h', state.subdir, custom_kwargs)

return [body, header]


def initialize():
return GnomeModule()

Expand Down
102 changes: 102 additions & 0 deletions test cases/frameworks/7 gnome/genmarshal/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include<stdio.h>
#include<stdlib.h>
#include<glib-object.h>
#include"marshaller.h"

static int singleton = 42;

void foo(gpointer user_data, gpointer data) {
if (user_data != &singleton) {
fprintf(stderr, "Invoked foo function was passed incorrect user data.\n");
exit(1);
}
}

void bar(gpointer user_data, gint param1, gpointer data) {
if (param1 != singleton) {
fprintf(stderr, "Invoked bar function was passed incorrect param1, but %d.\n", param1);
exit(2);
}
if (user_data != &singleton) {
fprintf(stderr, "Invoked bar function was passed incorrect user data.\n");
exit(3);
}
}

gfloat baz(gpointer user_data, gboolean param1, guchar param2, gpointer data) {
if (param1 != TRUE) {
fprintf(stderr, "Invoked baz function was passed incorrect param1.\n");
exit(4);
}
if (param2 != singleton) {
fprintf(stderr, "Invoked baz function was passed incorrect param2.\n");
exit(5);
}
if (user_data != &singleton) {
fprintf(stderr, "Invoked baz function was passed incorrect user data.\n");
exit(6);
}
return (gfloat)param2;
}

int main(int argc, char **argv) {
GClosure *cc_foo, *cc_bar, *cc_baz;
GValue return_value = G_VALUE_INIT;
GValue param_values[3] = {G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT};

fprintf(stderr, "Invoking foo function.\n");
cc_foo = g_cclosure_new(G_CALLBACK(foo), NULL, NULL);
g_closure_set_marshal(cc_foo, g_cclosure_user_marshal_VOID__VOID);
g_value_init(&param_values[0], G_TYPE_POINTER);
g_value_set_pointer(&param_values[0], &singleton);
g_closure_invoke(cc_foo, &return_value, 1, param_values, NULL);
if (G_VALUE_TYPE(&return_value) != G_TYPE_INVALID) {
fprintf(stderr, "Invoked foo function did not return empty value, but %s.\n",
G_VALUE_TYPE_NAME(&return_value));
return 7;
}
g_value_unset(&param_values[0]);
g_value_unset(&return_value);
g_closure_unref(cc_foo);

fprintf(stderr, "Invoking bar function.\n");
cc_bar = g_cclosure_new(G_CALLBACK(bar), NULL, NULL);
g_closure_set_marshal(cc_bar, g_cclosure_user_marshal_VOID__INT);
g_value_init(&param_values[0], G_TYPE_POINTER);
g_value_set_pointer(&param_values[0], &singleton);
g_value_init(&param_values[1], G_TYPE_INT);
g_value_set_int(&param_values[1], 42);
g_closure_invoke(cc_bar, &return_value, 2, param_values, NULL);
if (G_VALUE_TYPE(&return_value) != G_TYPE_INVALID) {
fprintf(stderr, "Invoked bar function did not return empty value.\n");
return 8;
}
g_value_unset(&param_values[0]);
g_value_unset(&param_values[1]);
g_value_unset(&return_value);
g_closure_unref(cc_bar);

fprintf(stderr, "Invoking baz function.\n");
cc_baz = g_cclosure_new(G_CALLBACK(baz), NULL, NULL);
g_closure_set_marshal(cc_baz, g_cclosure_user_marshal_FLOAT__BOOLEAN_UCHAR);
g_value_init(&param_values[0], G_TYPE_POINTER);
g_value_set_pointer(&param_values[0], &singleton);
g_value_init(&param_values[1], G_TYPE_BOOLEAN);
g_value_set_boolean(&param_values[1], TRUE);
g_value_init(&param_values[2], G_TYPE_UCHAR);
g_value_set_uchar(&param_values[2], 42);
g_value_init(&return_value, G_TYPE_FLOAT);
g_closure_invoke(cc_baz, &return_value, 3, param_values, NULL);
if (g_value_get_float(&return_value) != 42.0f) {
fprintf(stderr, "Invoked baz function did not return expected value.\n");
return 9;
}
g_value_unset(&param_values[0]);
g_value_unset(&param_values[1]);
g_value_unset(&param_values[2]);
g_value_unset(&return_value);
g_closure_unref(cc_baz);

fprintf(stderr, "All ok.\n");
return 0;
}
3 changes: 3 additions & 0 deletions test cases/frameworks/7 gnome/genmarshal/marshaller.list
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
VOID:VOID
VOID:INT
FLOAT:BOOLEAN,UCHAR
11 changes: 11 additions & 0 deletions test cases/frameworks/7 gnome/genmarshal/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
marshallers = gnome.genmarshal('marshaller',
sources : 'marshaller.list',
install_header : true,
install_dir : get_option('includedir'))

marshaller_c = marshallers[0]
marshaller_h = marshallers[1]

genmarshalexe = executable('genmarshalprog', 'main.c', marshaller_c, marshaller_h,
dependencies : gobj)
test('genmarshal test', genmarshalexe)
4 changes: 4 additions & 0 deletions test cases/frameworks/7 gnome/installed_files.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
usr/include/enums.h
usr/include/enums2.h
usr/include/enums3.h
usr/include/marshaller.h
usr/lib/girepository-1.0/Meson-1.0.typelib
usr/lib/libgirlib.so
usr/share/gir-1.0/Meson-1.0.gir
Expand Down
3 changes: 2 additions & 1 deletion test cases/frameworks/7 gnome/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ subdir('resources')
subdir('gir')
subdir('schemas')
subdir('gdbus')

subdir('mkenums')
subdir('genmarshal')
41 changes: 41 additions & 0 deletions test cases/frameworks/7 gnome/mkenums/enums.c.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*** BEGIN file-header ***/

#include "enums.h"

/*** END file-header ***/
/*** BEGIN file-production ***/

/* enumerations from "@basename@" */
#include "@basename@"

/*** END file-production ***/

/*** BEGIN value-header ***/
GType
@enum_name@_get_type(void) {
static volatile gsize g_define_type_id__volatile = 0;

if(g_once_init_enter(&g_define_type_id__volatile)) {
static const G@Type@Value values [] = {
/*** END value-header ***/

/*** BEGIN value-production ***/
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
/*** END value-production ***/

/*** BEGIN value-tail ***/
{ 0, NULL, NULL }
};

GType g_define_type_id =
g_@type@_register_static(g_intern_static_string("@EnumName@"), values);
g_once_init_leave(&g_define_type_id__volatile, g_define_type_id);
}

return g_define_type_id__volatile;
}

/*** END value-tail ***/

/*** BEGIN file-tail ***/
/*** END file-tail ***/
24 changes: 24 additions & 0 deletions test cases/frameworks/7 gnome/mkenums/enums.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*** BEGIN file-header ***/
#ifndef MESON_ENUMS_H
#define MESON_ENUMS_H

#include <glib-object.h>

G_BEGIN_DECLS
/*** END file-header ***/

/*** BEGIN file-production ***/

/* enumerations from "@basename@" */
/*** END file-production ***/
/*** BEGIN value-header ***/
GType @enum_name@_get_type(void) G_GNUC_CONST;
#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
/*** END value-header ***/

/*** BEGIN file-tail ***/

G_END_DECLS

#endif /* MESON_ENUMS_H */
/*** END file-tail ***/