Skip to content

Commit 7256e10

Browse files
authored
Merge pull request #718 from QuLogic/glib-mkenums-genmarshal
glib-mkenums and glib-genmarshal support
2 parents efc986e + 2840539 commit 7256e10

File tree

13 files changed

+575
-1
lines changed

13 files changed

+575
-1
lines changed

mesonbuild/modules/gnome.py

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,163 @@ def gdbus_codegen(self, state, args, kwargs):
477477
}
478478
return build.CustomTarget(namebase + '-gdbus', state.subdir, custom_kwargs)
479479

480+
def mkenums(self, state, args, kwargs):
481+
if len(args) != 1:
482+
raise MesonException('Mkenums requires one positional argument.')
483+
basename = args[0]
484+
485+
if 'sources' not in kwargs:
486+
raise MesonException('Missing keyword argument "sources".')
487+
sources = kwargs.pop('sources')
488+
if isinstance(sources, str):
489+
sources = [sources]
490+
elif not isinstance(sources, list):
491+
raise MesonException(
492+
'Sources keyword argument must be a string or array.')
493+
494+
cmd = []
495+
known_kwargs = ['comments', 'eprod', 'fhead', 'fprod', 'ftail',
496+
'identifier_prefix', 'symbol_prefix', 'template',
497+
'vhead', 'vprod', 'vtail']
498+
known_custom_target_kwargs = ['install', 'install_dir', 'build_always',
499+
'depends', 'depend_files']
500+
c_template = h_template = None
501+
install_header = False
502+
for arg, value in kwargs.items():
503+
if arg == 'sources':
504+
sources = [value] + sources
505+
elif arg == 'c_template':
506+
c_template = value
507+
elif arg == 'h_template':
508+
h_template = value
509+
elif arg == 'install_header':
510+
install_header = value
511+
elif arg in known_kwargs:
512+
cmd += ['--' + arg.replace('_', '-'), value]
513+
elif arg not in known_custom_target_kwargs:
514+
raise MesonException(
515+
'Mkenums does not take a %s keyword argument.' % (arg, ))
516+
cmd = ['glib-mkenums'] + cmd
517+
custom_kwargs = {}
518+
for arg in known_custom_target_kwargs:
519+
if arg in kwargs:
520+
custom_kwargs[arg] = kwargs[arg]
521+
522+
targets = []
523+
524+
if h_template is not None:
525+
h_output = os.path.splitext(h_template)[0]
526+
# We always set template as the first element in the source array
527+
# so --template consumes it.
528+
h_cmd = cmd + ['--template', '@INPUT@']
529+
h_sources = [h_template] + sources
530+
custom_kwargs['install'] = install_header
531+
if 'install_dir' not in custom_kwargs:
532+
custom_kwargs['install_dir'] = \
533+
state.environment.coredata.get_builtin_option('includedir')
534+
h_target = self.make_mkenum_custom_target(state, h_sources,
535+
h_output, h_cmd,
536+
custom_kwargs)
537+
targets.append(h_target)
538+
539+
if c_template is not None:
540+
c_output = os.path.splitext(c_template)[0]
541+
# We always set template as the first element in the source array
542+
# so --template consumes it.
543+
c_cmd = cmd + ['--template', '@INPUT@']
544+
c_sources = [c_template] + sources
545+
# Never install the C file. Complain on bug tracker if you need it.
546+
custom_kwargs['install'] = False
547+
if h_template is not None:
548+
if 'depends' in custom_kwargs:
549+
custom_kwargs['depends'] += [h_target]
550+
else:
551+
custom_kwargs['depends'] = h_target
552+
c_target = self.make_mkenum_custom_target(state, c_sources,
553+
c_output, c_cmd,
554+
custom_kwargs)
555+
targets.insert(0, c_target)
556+
557+
if c_template is None and h_template is None:
558+
generic_cmd = cmd + ['@INPUT@']
559+
custom_kwargs['install'] = install_header
560+
if 'install_dir' not in custom_kwargs:
561+
custom_kwargs['install_dir'] = \
562+
state.environment.coredata.get_builtin_option('includedir')
563+
target = self.make_mkenum_custom_target(state, sources, basename,
564+
generic_cmd, custom_kwargs)
565+
return target
566+
elif len(targets) == 1:
567+
return targets[0]
568+
else:
569+
return targets
570+
571+
def make_mkenum_custom_target(self, state, sources, output, cmd, kwargs):
572+
custom_kwargs = {
573+
'input': sources,
574+
'output': output,
575+
'capture': True,
576+
'command': cmd
577+
}
578+
custom_kwargs.update(kwargs)
579+
return build.CustomTarget(output, state.subdir, custom_kwargs)
580+
581+
def genmarshal(self, state, args, kwargs):
582+
if len(args) != 1:
583+
raise MesonException(
584+
'Genmarshal requires one positional argument.')
585+
output = args[0]
586+
587+
if 'sources' not in kwargs:
588+
raise MesonException('Missing keyword argument "sources".')
589+
sources = kwargs.pop('sources')
590+
if isinstance(sources, str):
591+
sources = [sources]
592+
elif not isinstance(sources, list):
593+
raise MesonException(
594+
'Sources keyword argument must be a string or array.')
595+
596+
cmd = ['glib-genmarshal']
597+
known_kwargs = ['internal', 'nostdinc', 'skip_source', 'stdinc',
598+
'valist_marshallers']
599+
known_custom_target_kwargs = ['build_always', 'depends',
600+
'depend_files', 'install_dir',
601+
'install_header']
602+
for arg, value in kwargs.items():
603+
if arg == 'prefix':
604+
cmd += ['--prefix', value]
605+
elif arg in known_kwargs and value:
606+
cmd += ['--' + arg.replace('_', '-')]
607+
elif arg not in known_custom_target_kwargs:
608+
raise MesonException(
609+
'Genmarshal does not take a %s keyword argument.' % (
610+
arg, ))
611+
612+
install_header = kwargs.pop('install_header', False)
613+
install_dir = kwargs.pop('install_dir', None)
614+
615+
custom_kwargs = {
616+
'input': sources,
617+
'capture': True,
618+
}
619+
for arg in known_custom_target_kwargs:
620+
if arg in kwargs:
621+
custom_kwargs[arg] = kwargs[arg]
622+
623+
custom_kwargs['command'] = cmd + ['--header', '--body', '@INPUT@']
624+
custom_kwargs['output'] = output + '.c'
625+
body = build.CustomTarget(output + '_c', state.subdir, custom_kwargs)
626+
627+
custom_kwargs['install'] = install_header
628+
if install_dir is not None:
629+
custom_kwargs['install_dir'] = install_dir
630+
custom_kwargs['command'] = cmd + ['--header', '@INPUT@']
631+
custom_kwargs['output'] = output + '.h'
632+
header = build.CustomTarget(output + '_h', state.subdir, custom_kwargs)
633+
634+
return [body, header]
635+
636+
480637
def initialize():
481638
return GnomeModule()
482639

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#include<stdio.h>
2+
#include<stdlib.h>
3+
#include<glib-object.h>
4+
#include"marshaller.h"
5+
6+
static int singleton = 42;
7+
8+
void foo(gpointer user_data, gpointer data) {
9+
if (user_data != &singleton) {
10+
fprintf(stderr, "Invoked foo function was passed incorrect user data.\n");
11+
exit(1);
12+
}
13+
}
14+
15+
void bar(gpointer user_data, gint param1, gpointer data) {
16+
if (param1 != singleton) {
17+
fprintf(stderr, "Invoked bar function was passed incorrect param1, but %d.\n", param1);
18+
exit(2);
19+
}
20+
if (user_data != &singleton) {
21+
fprintf(stderr, "Invoked bar function was passed incorrect user data.\n");
22+
exit(3);
23+
}
24+
}
25+
26+
gfloat baz(gpointer user_data, gboolean param1, guchar param2, gpointer data) {
27+
if (param1 != TRUE) {
28+
fprintf(stderr, "Invoked baz function was passed incorrect param1.\n");
29+
exit(4);
30+
}
31+
if (param2 != singleton) {
32+
fprintf(stderr, "Invoked baz function was passed incorrect param2.\n");
33+
exit(5);
34+
}
35+
if (user_data != &singleton) {
36+
fprintf(stderr, "Invoked baz function was passed incorrect user data.\n");
37+
exit(6);
38+
}
39+
return (gfloat)param2;
40+
}
41+
42+
int main(int argc, char **argv) {
43+
GClosure *cc_foo, *cc_bar, *cc_baz;
44+
GValue return_value = G_VALUE_INIT;
45+
GValue param_values[3] = {G_VALUE_INIT, G_VALUE_INIT, G_VALUE_INIT};
46+
47+
fprintf(stderr, "Invoking foo function.\n");
48+
cc_foo = g_cclosure_new(G_CALLBACK(foo), NULL, NULL);
49+
g_closure_set_marshal(cc_foo, g_cclosure_user_marshal_VOID__VOID);
50+
g_value_init(&param_values[0], G_TYPE_POINTER);
51+
g_value_set_pointer(&param_values[0], &singleton);
52+
g_closure_invoke(cc_foo, &return_value, 1, param_values, NULL);
53+
if (G_VALUE_TYPE(&return_value) != G_TYPE_INVALID) {
54+
fprintf(stderr, "Invoked foo function did not return empty value, but %s.\n",
55+
G_VALUE_TYPE_NAME(&return_value));
56+
return 7;
57+
}
58+
g_value_unset(&param_values[0]);
59+
g_value_unset(&return_value);
60+
g_closure_unref(cc_foo);
61+
62+
fprintf(stderr, "Invoking bar function.\n");
63+
cc_bar = g_cclosure_new(G_CALLBACK(bar), NULL, NULL);
64+
g_closure_set_marshal(cc_bar, g_cclosure_user_marshal_VOID__INT);
65+
g_value_init(&param_values[0], G_TYPE_POINTER);
66+
g_value_set_pointer(&param_values[0], &singleton);
67+
g_value_init(&param_values[1], G_TYPE_INT);
68+
g_value_set_int(&param_values[1], 42);
69+
g_closure_invoke(cc_bar, &return_value, 2, param_values, NULL);
70+
if (G_VALUE_TYPE(&return_value) != G_TYPE_INVALID) {
71+
fprintf(stderr, "Invoked bar function did not return empty value.\n");
72+
return 8;
73+
}
74+
g_value_unset(&param_values[0]);
75+
g_value_unset(&param_values[1]);
76+
g_value_unset(&return_value);
77+
g_closure_unref(cc_bar);
78+
79+
fprintf(stderr, "Invoking baz function.\n");
80+
cc_baz = g_cclosure_new(G_CALLBACK(baz), NULL, NULL);
81+
g_closure_set_marshal(cc_baz, g_cclosure_user_marshal_FLOAT__BOOLEAN_UCHAR);
82+
g_value_init(&param_values[0], G_TYPE_POINTER);
83+
g_value_set_pointer(&param_values[0], &singleton);
84+
g_value_init(&param_values[1], G_TYPE_BOOLEAN);
85+
g_value_set_boolean(&param_values[1], TRUE);
86+
g_value_init(&param_values[2], G_TYPE_UCHAR);
87+
g_value_set_uchar(&param_values[2], 42);
88+
g_value_init(&return_value, G_TYPE_FLOAT);
89+
g_closure_invoke(cc_baz, &return_value, 3, param_values, NULL);
90+
if (g_value_get_float(&return_value) != 42.0f) {
91+
fprintf(stderr, "Invoked baz function did not return expected value.\n");
92+
return 9;
93+
}
94+
g_value_unset(&param_values[0]);
95+
g_value_unset(&param_values[1]);
96+
g_value_unset(&param_values[2]);
97+
g_value_unset(&return_value);
98+
g_closure_unref(cc_baz);
99+
100+
fprintf(stderr, "All ok.\n");
101+
return 0;
102+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
VOID:VOID
2+
VOID:INT
3+
FLOAT:BOOLEAN,UCHAR
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
marshallers = gnome.genmarshal('marshaller',
2+
sources : 'marshaller.list',
3+
install_header : true,
4+
install_dir : get_option('includedir'))
5+
6+
marshaller_c = marshallers[0]
7+
marshaller_h = marshallers[1]
8+
9+
genmarshalexe = executable('genmarshalprog', 'main.c', marshaller_c, marshaller_h,
10+
dependencies : gobj)
11+
test('genmarshal test', genmarshalexe)

test cases/frameworks/7 gnome/installed_files.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
usr/include/enums.h
2+
usr/include/enums2.h
3+
usr/include/enums3.h
4+
usr/include/marshaller.h
15
usr/lib/girepository-1.0/Meson-1.0.typelib
26
usr/lib/libgirlib.so
37
usr/share/gir-1.0/Meson-1.0.gir

test cases/frameworks/7 gnome/meson.build

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ subdir('resources')
1313
subdir('gir')
1414
subdir('schemas')
1515
subdir('gdbus')
16-
16+
subdir('mkenums')
17+
subdir('genmarshal')
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*** BEGIN file-header ***/
2+
3+
#include "enums.h"
4+
5+
/*** END file-header ***/
6+
/*** BEGIN file-production ***/
7+
8+
/* enumerations from "@basename@" */
9+
#include "@basename@"
10+
11+
/*** END file-production ***/
12+
13+
/*** BEGIN value-header ***/
14+
GType
15+
@enum_name@_get_type(void) {
16+
static volatile gsize g_define_type_id__volatile = 0;
17+
18+
if(g_once_init_enter(&g_define_type_id__volatile)) {
19+
static const G@Type@Value values [] = {
20+
/*** END value-header ***/
21+
22+
/*** BEGIN value-production ***/
23+
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
24+
/*** END value-production ***/
25+
26+
/*** BEGIN value-tail ***/
27+
{ 0, NULL, NULL }
28+
};
29+
30+
GType g_define_type_id =
31+
g_@type@_register_static(g_intern_static_string("@EnumName@"), values);
32+
g_once_init_leave(&g_define_type_id__volatile, g_define_type_id);
33+
}
34+
35+
return g_define_type_id__volatile;
36+
}
37+
38+
/*** END value-tail ***/
39+
40+
/*** BEGIN file-tail ***/
41+
/*** END file-tail ***/
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*** BEGIN file-header ***/
2+
#ifndef MESON_ENUMS_H
3+
#define MESON_ENUMS_H
4+
5+
#include <glib-object.h>
6+
7+
G_BEGIN_DECLS
8+
/*** END file-header ***/
9+
10+
/*** BEGIN file-production ***/
11+
12+
/* enumerations from "@basename@" */
13+
/*** END file-production ***/
14+
/*** BEGIN value-header ***/
15+
GType @enum_name@_get_type(void) G_GNUC_CONST;
16+
#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
17+
/*** END value-header ***/
18+
19+
/*** BEGIN file-tail ***/
20+
21+
G_END_DECLS
22+
23+
#endif /* MESON_ENUMS_H */
24+
/*** END file-tail ***/

0 commit comments

Comments
 (0)