[Pkg-vala-maintainers] Bug#619345: Bug#619345: valac produces invalid c-code when using pulseaudio's official bindings

Alexander Kurtz kurtz.alex at googlemail.com
Wed Mar 23 12:28:28 UTC 2011


reopen 619345
thanks

> This looks more like a bug in the bindings. The channel map bindings
> can't work the way they're written because there's no destroy function.

I don't think so. I tried adding a destructor:

	$ diff -u libpulse.vapi.old libpulse.vapi
	--- libpulse.vapi.old	2011-03-23 12:54:24.423038993 +0100
	+++ libpulse.vapi	2011-03-23 12:54:36.414475642 +0100
	@@ -377,6 +377,9 @@
		 public struct ChannelMap {
		         public uint8 channels;
		         public ChannelPosition map[];
	+                
	+                ~ChannelMap(){
	+                }
	 
		         [CCode (cname="PA_CHANNEL_MAP_SNPRINT_MAX")]
		         public static const size_t SNPRINT_MAX;
	$

It didn't work:

	$ valac --pkg=libpulse --vapidir=. test.vala 
	libpulse.vapi:381.17-381.29: error: unexpected declaration in struct
		        ~ChannelMap(){
		        ^^^^^^^^^^^^^
	Compilation failed: 1 error(s), 0 warning(s)
	$

This didn't surprise me, since structs are (normally) fixed-size,
stack-allocated and passed by value, not reference. Therefore they
shouldn't need a destructor.

This seems to be the problematic line:

	$ sed --quiet '379p' libpulse.vapi
		        public ChannelPosition map[];
	$

This makes valac compile just fine:

	$ diff -u libpulse.vapi.old libpulse.vapi
	--- libpulse.vapi.old	2011-03-23 12:54:24.423038993 +0100
	+++ libpulse.vapi	2011-03-23 13:04:00.330037971 +0100
	@@ -376,7 +376,7 @@
		 [CCode (cname="pa_channel_map")]
		 public struct ChannelMap {
		         public uint8 channels;
	-                public ChannelPosition map[];
	+                public ChannelPosition map;
	 
		         [CCode (cname="PA_CHANNEL_MAP_SNPRINT_MAX")]
		         public static const size_t SNPRINT_MAX;
	$

But it of course breaks pulseaudio. Looking at the upstream code[1]
reveals this:

	00264 typedef struct pa_channel_map {
	00265     uint8_t channels;
	00268     pa_channel_position_t map[PA_CHANNELS_MAX];
	00270 } pa_channel_map;

So map[] should be a fixed size-array. However, this doesn't seem to
work in vala:

	$ diff -u libpulse.vapi.old libpulse.vapi
	--- libpulse.vapi.old	2011-03-23 12:54:24.423038993 +0100
	+++ libpulse.vapi	2011-03-23 13:10:16.838205646 +0100
	@@ -376,7 +376,7 @@
		 [CCode (cname="pa_channel_map")]
		 public struct ChannelMap {
		         public uint8 channels;
	-                public ChannelPosition map[];
	+                public ChannelPosition map[CHANNELS_MAX];
	 
		         [CCode (cname="PA_CHANNEL_MAP_SNPRINT_MAX")]
		         public static const size_t SNPRINT_MAX;
	$ valac --pkg=libpulse --vapidir=. test.vala 
	libpulse.vapi:379.44-379.55: error: syntax error, expected `]' or integer literal
		        public ChannelPosition map[CHANNELS_MAX];
		                                   ^^^^^^^^^^^^
	Compilation failed: 1 error(s), 0 warning(s)
	$

Setting the array size directly doesn't work either:

	$ diff -u libpulse.vapi.old libpulse.vapi
	--- libpulse.vapi.old	2011-03-23 12:54:24.423038993 +0100
	+++ libpulse.vapi	2011-03-23 13:10:56.863538104 +0100
	@@ -376,7 +376,7 @@
		 [CCode (cname="pa_channel_map")]
		 public struct ChannelMap {
		         public uint8 channels;
	-                public ChannelPosition map[];
	+                public ChannelPosition map[32];
	 
		         [CCode (cname="PA_CHANNEL_MAP_SNPRINT_MAX")]
		         public static const size_t SNPRINT_MAX;
	$ valac --pkg=libpulse --vapidir=. test.vala 
	test.vala:2.2-2.26: warning: field `MyClass.map' never used
		PulseAudio.ChannelMap map;
		^^^^^^^^^^^^^^^^^^^^^^^^^
	/tmp/ccaQ1eM8.o: In function `myclass_finalize':
	test.vala.c:(.text+0x152): undefined reference to `pulse_audio_channel_map_destroy'
	collect2: ld returned 1 exit status
	error: cc exited with status 256
	Compilation failed: 1 error(s), 1 warning(s)
	$ 

So, IMHO we've got four (!) vala bugs here:

 (1) valac doesn't fail if you try to put a dynamically-sized array 
     into a struct
 (2) valac doesn't allow adding a destructor function to a struct
 (3) valac doesn't allow making fixed-sized arrays from constants.
     This is absolutely necessary since there are no preprocessor 
     directives in vala and most C libraries define symbolic names
     for these things.
 (4) valac doesn't handle fixed-size arrays correctly, as it still
     thinks they need to freed after use.

> Please report this against pulseaudio.

Pulseaudio's vala bindings have a lot of bugs, but I think this is
actually vala's fault here. What do you think?

Best regards

Alexander Kurtz

[1] http://0pointer.de/lennart/projects/pulseaudio/doxygen/channelmap_8h_source.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.alioth.debian.org/pipermail/pkg-vala-maintainers/attachments/20110323/670ef1a6/attachment.pgp>


More information about the Pkg-vala-maintainers mailing list