comp.lang.ada
 help / color / mirror / Atom feed
* Importing C function with variable argument list
@ 2012-04-10  9:21 Maxim Reznik
  2012-04-10 11:22 ` Patrick
                   ` (4 more replies)
  0 siblings, 5 replies; 34+ messages in thread
From: Maxim Reznik @ 2012-04-10  9:21 UTC (permalink / raw)


Hi, All

It seems it's impossible to call C function variable argument lists
from Ada.
Even when one knows in advace all arguments at compile time.

Functions with Variable Argument Lists have their own ABI. For
instance, in x86_64:

> When a function taking variable-arguments is called, %rax must be set to the
> total number of floating point parameters passed to the function in vector registers.

But it's impossible to specify this fact in pragma Import (C, ...

Small example:

C declaration:
void syslog (int __pri, __const char *__fmt, ...);

Supposed Import declaration:

procedure C_Syslog (Priority : int; Format : chars_ptr; Msg :
chars_ptr);
pragma Import (C, C_Syslog, "syslog");

Call to C_Syslog fails, because %rax has not zero value.

What do you think?



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-10  9:21 Importing C function with variable argument list Maxim Reznik
@ 2012-04-10 11:22 ` Patrick
  2012-04-10 13:09   ` Maxim Reznik
  2012-04-10 13:18 ` Markus Schöpflin
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 34+ messages in thread
From: Patrick @ 2012-04-10 11:22 UTC (permalink / raw)


Hi Maxim.

Warning I am just learning myself... but I have read that Ada does not have variable arguments due to it's unsafeness.

Here is a document I found, it might help:

http://pihtt.free.fr/secure/L3/x11ada_v1.30/doc/interf4.ps

Please search for Ada, Printf, unsafe, for more information.

Have a great day-Patrick



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-10 11:22 ` Patrick
@ 2012-04-10 13:09   ` Maxim Reznik
  2012-04-10 13:50     ` Georg Bauhaus
  0 siblings, 1 reply; 34+ messages in thread
From: Maxim Reznik @ 2012-04-10 13:09 UTC (permalink / raw)


Interfacing with C is often unsafe, due to properties of C.
Nevertheless Ada has interfacing features in standard.

I'm just trying to say that these features are kind of incomplete.



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-10  9:21 Importing C function with variable argument list Maxim Reznik
  2012-04-10 11:22 ` Patrick
@ 2012-04-10 13:18 ` Markus Schöpflin
  2012-04-10 16:47   ` Simon Wright
  2012-04-10 20:02 ` Tero Koskinen
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 34+ messages in thread
From: Markus Schöpflin @ 2012-04-10 13:18 UTC (permalink / raw)


Am 10.04.2012 11:21, schrieb Maxim Reznik:
> Hi, All
>
> It seems it's impossible to call C function variable argument lists
> from Ada.

There is a very vague note in the LRM about this, see B.3.75: "10  A C 
function that takes a variable number of arguments can correspond to several 
Ada subprograms, taking various specific numbers and types of parameters."

This seems to imply that support for variadic argument lists was meant to be 
used like this:

---%<---
with INTERFACES.C;

procedure TEST
is
    use INTERFACES.C;
    function PRINTF
       (FORMAT : in CHAR_ARRAY; N1 : in INT) return INT;
    function PRINTF
       (FORMAT : in CHAR_ARRAY; N1 : in INT; N2 : in INT) return INT;
    pragma IMPORT (C, PRINTF, "printf");

    DUMMY : INT;
begin
    DUMMY := PRINTF(TO_C("%08d" & ASCII.LF), 123);
    DUMMY := PRINTF(TO_C("%02d:%02d" & ASCII.LF), 123, 321);
end TEST;
--->%---

This worked for me in the past using GNAT on 32bit Linux systems, e.g. using 
GNAT 4.1.2 on RHEL5.

> Even when one knows in advace all arguments at compile time.
>
> Functions with Variable Argument Lists have their own ABI. For
> instance, in x86_64:

[...]

Compiling above code on an x86_64 Linux system (Debian Squeeze, using GNAT 
4.4.5) still works, but executing the resulting binary results in: "raised 
PROGRAM_ERROR : unhandled signal".

Unfortunately the GNAT RM doesn't say anything about its handling of the notes 
just after the implementation advice for B.3, but given that it worked for 32 
bit I'm inclined to say that it also should work for 64 bit and it's a bug 
that it doesn't.

Regards,
Markus



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-10 13:09   ` Maxim Reznik
@ 2012-04-10 13:50     ` Georg Bauhaus
  0 siblings, 0 replies; 34+ messages in thread
From: Georg Bauhaus @ 2012-04-10 13:50 UTC (permalink / raw)


On 10.04.12 15:09, Maxim Reznik wrote:
> Interfacing with C is often unsafe, due to properties of C.
> Nevertheless Ada has interfacing features in standard.
> 
> I'm just trying to say that these features are kind of incomplete.

The "incompleteness" reflecting, in this case, a hack that
happens to be inspired by a computer architecture, a von Neumann
CPU with a stack together with the capabilities of a macro
processor.

Is it not possible to have a list-of-typed-arguments built
into a language, and then have the compiler map this type
to tricks from the Bronze Age of computing as needed?

Eiffel has a TUPLE type that, I think, comes close.

The mapping could be to C and to Forth alike :-)



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-10 13:18 ` Markus Schöpflin
@ 2012-04-10 16:47   ` Simon Wright
  2012-04-12 10:08     ` Markus Schöpflin
  0 siblings, 1 reply; 34+ messages in thread
From: Simon Wright @ 2012-04-10 16:47 UTC (permalink / raw)


Markus Schöpflin <no.spam@spam.spam> writes:

> Compiling above code on an x86_64 Linux system (Debian Squeeze, using
> GNAT 4.4.5) still works, but executing the resulting binary results
> in: "raised PROGRAM_ERROR : unhandled signal".

Worked as one would hope on Mac OS X (GNAT GPL 2011, target
x86_64-apple-darwin10.2.0).



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-10  9:21 Importing C function with variable argument list Maxim Reznik
  2012-04-10 11:22 ` Patrick
  2012-04-10 13:18 ` Markus Schöpflin
@ 2012-04-10 20:02 ` Tero Koskinen
  2012-04-13  3:28   ` Tero Koskinen
  2012-04-10 20:25 ` sbelmont700
  2012-04-11 23:24 ` Randy Brukardt
  4 siblings, 1 reply; 34+ messages in thread
From: Tero Koskinen @ 2012-04-10 20:02 UTC (permalink / raw)


Hi,

On Tue, 10 Apr 2012 02:21:59 -0700 (PDT)
Maxim Reznik <reznikmm@gmail.com> wrote:

> Hi, All
> 
> It seems it's impossible to call C function variable argument lists
> from Ada.
> Even when one knows in advace all arguments at compile time.
> 
> Functions with Variable Argument Lists have their own ABI. For
> instance, in x86_64:
> 
> > When a function taking variable-arguments is called, %rax must be set to the
> > total number of floating point parameters passed to the function in vector registers.
...
> But it's impossible to specify this fact in pragma Import (C, ...
...
> What do you think?

To work-around this, I use a small wrapper for x86_64 (Linux)
environments in my curl bindings:
https://bitbucket.org/tkoskine/curl-ada/src/ebd5156f7334/Makefile#cl-6
https://bitbucket.org/tkoskine/curl-ada/src/ebd5156f7334/utils/easywrap.pl
https://bitbucket.org/tkoskine/curl-ada/src/ebd5156f7334/src/template/curl-easy.adb.tmpl#cl-144

Ada code is following:
         procedure curl_easy_setopt
           (C_Handle : CURL_Private_Access;
            C_Option : CURL.Options.CURL_Option_Type;
            C_Action : C_Action_Callback);
         pragma Import (C, curl_easy_setopt, "wrap_setopt");

         procedure curl_easy_setopt_data
           (C_Handle : CURL_Private_Access;
            C_Option : CURL.Options.CURL_Option_Type;
            Data     : Callback_Interface_Class_Access);
         pragma Import (C, curl_easy_setopt_data, "wrap_setopt");

And C wrapper:
CURLcode wrap_setopt(CURL* handle, CURLoption option, void* param)
{
        return curl_easy_setopt(handle, option, param);
}

For i386, I do s/wrap_setopt/curl_easy_setopt/ replacement before
compiling:

if ($Config{archname} =~ m/x86_86/) { $use_wrap = 1; }
while (<>) {
        if ($use_wrap == 0) {
                $_ =~ s/wrap_setopt/curl_easy_setopt/g;
        }
        print $_;
}

-- 
Tero Koskinen - http://iki.fi/tero.koskinen/



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-10  9:21 Importing C function with variable argument list Maxim Reznik
                   ` (2 preceding siblings ...)
  2012-04-10 20:02 ` Tero Koskinen
@ 2012-04-10 20:25 ` sbelmont700
  2012-04-11 23:24 ` Randy Brukardt
  4 siblings, 0 replies; 34+ messages in thread
From: sbelmont700 @ 2012-04-10 20:25 UTC (permalink / raw)


Hi,

I often have occasion to suffer through using a C API with variable argument in Ada, and there really is no good choice.  I have found basically two options:

1. Import the C function with a fixed-set of arguments, with a defaulted-to-zero parameter at the end.

or

2. Roll-your-own.

The first is cheap and easy, but clearly not extensible, as each version of the function must be overloaded, giving you an infinite number of prototypes to maintain.  The second is better, but hardware and implementation specific.  For instance, for x86, it might look something like this (where D is an array of unsigned longs, or whatever the C function needs):

procedure V_A (D : Array_Type) is

   procedure Variable_C_Function;
   pragma Import (C, Variable_C_Function, "Something");
   Result : Interfaces.C.int := 0;
   
begin

  Machine_Code.Asm (Template => "push %0",
                    Inputs => Interfaces.C.unsigned_long'Asm_Input("g", 0),
                    Volatile => true);
                      
  for i in reverse D'range loop
  
    Machine_Code.Asm (Template => "push %0",
                      Inputs => Interfaces.C.unsigned_long'Asm_Input("g", Data(i)),
                      Volatile => true);

  end loop;

  Variable_C_Function;
  
  Machine_Code.Asm (Template => "sub %%esp, %0",
                    Inputs => Integer'Asm_Input("g", ((D'last + 2) * 4)),
                    Volatile => true);
 
 end V_A;

Of course, this is completly non-portable and would depend greatly on both the hardware, O/S, and how the C function is setup, but it's perhaps the least-worst way of dealing a truly awful kludge.

-sb



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-10  9:21 Importing C function with variable argument list Maxim Reznik
                   ` (3 preceding siblings ...)
  2012-04-10 20:25 ` sbelmont700
@ 2012-04-11 23:24 ` Randy Brukardt
  4 siblings, 0 replies; 34+ messages in thread
From: Randy Brukardt @ 2012-04-11 23:24 UTC (permalink / raw)


"Maxim Reznik" <reznikmm@gmail.com> wrote in message 
news:610ee323-4c7f-413d-8568-aed4955f5152@z38g2000vbu.googlegroups.com...
...
> It seems it's impossible to call C function variable argument lists
> from Ada.
> Even when one knows in advace all arguments at compile time.
>
> Functions with Variable Argument Lists have their own ABI. For
> instance, in x86_64:
>
>> When a function taking variable-arguments is called, %rax must be set to 
>> the
>> total number of floating point parameters passed to the function in 
>> vector registers.

This is news to me! This is definitely not the case in the 32-bit interfaces 
with which I'm familar, so I'm not surprised that neither Ada nor 
implementers ever worried about this case. (Janus/Ada doesn't have any 
special handling for this case, and I've never seen any need for it, 
either.)

The "intended" solution would be for the language-name to be some 
implementation-defined name that specifies this ABI (much like "StdCall" 
specifies the "standard" ABI on Windows). That's necessarily not portable 
across implementations, but then again these sorts of bindings are almost 
never 100% portable.

                                       Randy.





^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-10 16:47   ` Simon Wright
@ 2012-04-12 10:08     ` Markus Schöpflin
  2012-04-12 16:58       ` Adam Beneschan
  0 siblings, 1 reply; 34+ messages in thread
From: Markus Schöpflin @ 2012-04-12 10:08 UTC (permalink / raw)


Am 10.04.2012 18:47, schrieb Simon Wright:
> Markus Schöpflin<no.spam@spam.spam>  writes:
>
>> Compiling above code on an x86_64 Linux system (Debian Squeeze, using
>> GNAT 4.4.5) still works, but executing the resulting binary results
>> in: "raised PROGRAM_ERROR : unhandled signal".
>
> Worked as one would hope on Mac OS X (GNAT GPL 2011, target
> x86_64-apple-darwin10.2.0).

I tried with GNAT GPL 2011 on 64 bit Debian and it still doesn't work. Does 
Mac OS X use the same 64 bit ABI as Linux?

Meanwhile I found the following in the GNAT user manual:

<quote>
A note on interfacing to a C "varargs" function:

     In C, varargs allows a function to take a variable number of arguments. 
There is no direct equivalent in this to Ada. One approach that can be used is 
to create a C wrapper for each different profile and then interface to this C 
wrapper. For example, to print an int value using printf, create a C function 
printfi that takes two arguments, a pointer to a string and an int, and calls 
printf. Then in the Ada program, use pragma Import to interface to printfi.

     It may work on some platforms to directly interface to a varargs function 
by providing a specific Ada profile for a particular call. However, this does 
not work on all platforms, since there is no guarantee that the calling 
sequence for a two argument normal C function is the same as for calling a 
varargs C function with the same two arguments.
</quote>

So the note from the Ada RM does not seem to be followed by GNAT, and it works 
by chance only on 32 bit Linux systems.

Markus



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-12 10:08     ` Markus Schöpflin
@ 2012-04-12 16:58       ` Adam Beneschan
  2012-04-12 20:47         ` Randy Brukardt
  2012-04-13  4:08         ` Tero Koskinen
  0 siblings, 2 replies; 34+ messages in thread
From: Adam Beneschan @ 2012-04-12 16:58 UTC (permalink / raw)


On Thursday, April 12, 2012 3:08:28 AM UTC-7, Markus Schöpflin wrote:
> 
>      It may work on some platforms to directly interface to a varargs function 
> by providing a specific Ada profile for a particular call. However, this does 
> not work on all platforms, since there is no guarantee that the calling 
> sequence for a two argument normal C function is the same as for calling a 
> varargs C function with the same two arguments.

Right.  My recollection is that on some RISC-type machines, the normal calling conventions require that subprograms know the exact size of the parameter frame getting passed to it, and they adjust the stack pointer by that amount before returning.  I'm not entirely sure I'm correct; perhaps the caller does the adjusting on all of those machines.  But if I'm right, then C functions with varargs would definitely have to follow a different convention, and the RM note is wrong.

I hadn't realized this problem in the RM before.  But it looks to me like B.3(75) should be removed, or at least changed to say that it's correct only on some platforms whose calling conventions meet certain conditions.

> So the note from the Ada RM does not seem to be followed by GNAT

I don't think GNAT has a choice whether to follow it or not, since GNAT can't be expected to know what the code of the imported C subprogram is going to look like.  All it can do is obey what the user tells it to do.

                        -- Adam




^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-12 16:58       ` Adam Beneschan
@ 2012-04-12 20:47         ` Randy Brukardt
  2012-04-13  8:43           ` Markus Schöpflin
  2012-04-27  8:24           ` Natasha Kerensikova
  2012-04-13  4:08         ` Tero Koskinen
  1 sibling, 2 replies; 34+ messages in thread
From: Randy Brukardt @ 2012-04-12 20:47 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1051 bytes --]

"Adam Beneschan" <adam@irvine.com> wrote in message 
news:1288794.275.1334249936588.JavaMail.geo-discussion-forums@ynlp2...
On Thursday, April 12, 2012 3:08:28 AM UTC-7, Markus Sch�pflin wrote:
...
>> So the note from the Ada RM does not seem to be followed by GNAT
>
>I don't think GNAT has a choice whether to follow it or not, since GNAT 
>can't be expected
> to know what the code of the imported C subprogram is going to look like. 
> All it can do is
> obey what the user tells it to do.

Right. If the calling convention is different for normal C subprograms and 
vararg ones, then clearly there needs to be a different convention name for 
varargs. (As I noted, I've never worked on such a machine, but it doesn't 
surprise me that much that they exist.)

Probably the RM ought to suggest such a convention name as Implementation 
Advice (something like C_Varargs) in order to increase portability.

Someone ought to submit a suggestion to Ada-Comment so that it gets on the 
ARG's radar/agenda.

                                 Randy.





^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-10 20:02 ` Tero Koskinen
@ 2012-04-13  3:28   ` Tero Koskinen
  0 siblings, 0 replies; 34+ messages in thread
From: Tero Koskinen @ 2012-04-13  3:28 UTC (permalink / raw)


On Tue, 10 Apr 2012 23:02:15 +0300
Tero Koskinen <tero.koskinen@iki.fi> wrote:
> if ($Config{archname} =~ m/x86_86/) { $use_wrap = 1; }

Oops, jesselang from #Ada@Freenode irc channel got hit by this.
x86_86 should of course be x86_64. It is now fixed in my
curl-ada repository.

-- 
Tero Koskinen - http://iki.fi/tero.koskinen/



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-12 16:58       ` Adam Beneschan
  2012-04-12 20:47         ` Randy Brukardt
@ 2012-04-13  4:08         ` Tero Koskinen
  2012-04-13  8:04           ` Markus Schöpflin
  1 sibling, 1 reply; 34+ messages in thread
From: Tero Koskinen @ 2012-04-13  4:08 UTC (permalink / raw)


On Thu, 12 Apr 2012 09:58:56 -0700 (PDT)
Adam Beneschan <adam@irvine.com> wrote:

> On Thursday, April 12, 2012 3:08:28 AM UTC-7, Markus Schöpflin wrote:
> > 
> >      It may work on some platforms to directly interface to a varargs function 
> > by providing a specific Ada profile for a particular call. However, this does 
> > not work on all platforms, since there is no guarantee that the calling 
> > sequence for a two argument normal C function is the same as for calling a 
> > varargs C function with the same two arguments.
> 
> Right.  My recollection is that on some RISC-type machines, the normal calling conventions require that subprograms know the exact size of the parameter frame getting passed to it, and they adjust the stack pointer by that amount before returning.  I'm not entirely sure I'm correct; perhaps the caller does the adjusting on all of those machines.  But if I'm right, then C functions with varargs would definitely have to follow a different convention, and the RM note is wrong.

Wikipedia[1] pointed me to document
http://x86-64.org/documentation/abi.pdf

which has following text (page 21):
%rax
       temporary register; with variable arguments
       passes information about the number of vector
       registers used; 1st return register


So on amd64/x86_64 (unix) platform injecting asm code, which sets
%rax/%eax to 0, works in most cases (= 0 vector registers used).

(Of course, it would be better to have some standard way to
say this.)

-- 
Tero Koskinen - http://iki.fi/tero.koskinen/

[1] http://en.wikipedia.org/wiki/X86_calling_conventions



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-13  4:08         ` Tero Koskinen
@ 2012-04-13  8:04           ` Markus Schöpflin
  0 siblings, 0 replies; 34+ messages in thread
From: Markus Schöpflin @ 2012-04-13  8:04 UTC (permalink / raw)


Am 13.04.2012 06:08, schrieb Tero Koskinen:

[...]

> So on amd64/x86_64 (unix) platform injecting asm code, which sets
> %rax/%eax to 0, works in most cases (= 0 vector registers used).

Yes, I did read a similar document (I think it's actually %al that is looked 
at, not the full register) which lead me to try using inline assembly like this:

---%<---
with SYSTEM.MACHINE_CODE;
with INTERFACES.C;

procedure TEST
is
    use SYSTEM.MACHINE_CODE;
    use INTERFACES.C;

    function PRINTF (FORMAT : in CHAR_ARRAY; N1 : in INT) return INT;
    pragma IMPORT (C, PRINTF, "printf");

    F1 : constant CHAR_ARRAY := TO_C("%08d" & ASCII.LF);
    DUMMY : INT;
begin
    ASM ("mov $0, %%al", CLOBBER => "al", VOLATILE => TRUE);
    DUMMY := PRINTF(F1, N1 => 123);
end TEST;
--->%---

Using -O0 when compiling results in the following assembly code:

---%<---
   401696:       b0 00                   mov    $0x0,%al
   401698:       48 8b 85 40 ff ff ff    mov    -0xc0(%rbp),%rax
   40169f:       48 89 55 c0             mov    %rdx,-0x40(%rbp)
   4016a3:       48 89 4d c8             mov    %rcx,-0x38(%rbp)
   4016a7:       48 89 45 b0             mov    %rax,-0x50(%rbp)
   4016ab:       48 8d 45 c0             lea    -0x40(%rbp),%rax
   4016af:       48 89 45 b8             mov    %rax,-0x48(%rbp)
   4016b3:       48 8b 45 b0             mov    -0x50(%rbp),%rax
   4016b7:       be 7b 00 00 00          mov    $0x7b,%esi
   4016bc:       48 89 c7                mov    %rax,%rdi
   4016bf:       e8 2c fb ff ff          callq  4011f0 <printf@plt>
   4016c4:       89 45 ec                mov    %eax,-0x14(%rbp)
--->%---

The first line is from the inline assembly, the rest is code generated by gnat 
for the call to printf and the handling of the return value. Still no luck, as 
%rax is used between the first line and the call to printf for different things.

Interestingly, compiling with -O2 gives:

---%<---
   40157c:       b0 00                   mov    $0x0,%al
   40157e:       be 7b 00 00 00          mov    $0x7b,%esi
   401583:       e8 68 fc ff ff          callq  4011f0 <printf@plt>
--->%---

Et voil�, the resulting binary really works and prints out the expected result.

> (Of course, it would be better to have some standard way to
> say this.)

As others have already said, a new calling convention for variadic C functions 
would be the way to go, I think.

Markus



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-12 20:47         ` Randy Brukardt
@ 2012-04-13  8:43           ` Markus Schöpflin
  2012-04-13 23:01             ` Randy Brukardt
  2012-04-27  8:24           ` Natasha Kerensikova
  1 sibling, 1 reply; 34+ messages in thread
From: Markus Schöpflin @ 2012-04-13  8:43 UTC (permalink / raw)


Am 12.04.2012 22:47, schrieb Randy Brukardt:

> Someone ought to submit a suggestion to Ada-Comment so that it gets on the
> ARG's radar/agenda.

I took the liberty to send a mail to that address as instructed in the 
introduction of the ARM.

Markus



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-13  8:43           ` Markus Schöpflin
@ 2012-04-13 23:01             ` Randy Brukardt
  0 siblings, 0 replies; 34+ messages in thread
From: Randy Brukardt @ 2012-04-13 23:01 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 683 bytes --]

"Markus Sch�pflin" <no.spam@spam.spam> wrote in message 
news:jm8p08$q70$1@speranza.aioe.org...
> Am 12.04.2012 22:47, schrieb Randy Brukardt:
>
>> Someone ought to submit a suggestion to Ada-Comment so that it gets on 
>> the
>> ARG's radar/agenda.
>
> I took the liberty to send a mail to that address as instructed in the 
> introduction of the ARM.

Thanks. It's always best that people experiencing problems with the Ada 
standard report them, because they're much more likely to explain the 
problem properly. (Solutions aren't necessary, as the ARG will have no 
problem coming up with several solutions to every problem. ;-)

                                    Randy.





^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-12 20:47         ` Randy Brukardt
  2012-04-13  8:43           ` Markus Schöpflin
@ 2012-04-27  8:24           ` Natasha Kerensikova
  2012-04-27  9:18             ` Jacob Sparre Andersen
  2012-05-03 20:15             ` sbelmont700
  1 sibling, 2 replies; 34+ messages in thread
From: Natasha Kerensikova @ 2012-04-27  8:24 UTC (permalink / raw)


Hello,

On 2012-04-12, Randy Brukardt <randy@rrsoftware.com> wrote:
> "Adam Beneschan" <adam@irvine.com> wrote in message 
> news:1288794.275.1334249936588.JavaMail.geo-discussion-forums@ynlp2...
> On Thursday, April 12, 2012 3:08:28 AM UTC-7, Markus Schöpflin wrote:
> ...
>>> So the note from the Ada RM does not seem to be followed by GNAT
>>
>>I don't think GNAT has a choice whether to follow it or not, since GNAT 
>>can't be expected
>> to know what the code of the imported C subprogram is going to look like. 
>> All it can do is
>> obey what the user tells it to do.
>
> Right. If the calling convention is different for normal C subprograms and 
> vararg ones, then clearly there needs to be a different convention name for 
> varargs. (As I noted, I've never worked on such a machine, but it doesn't 
> surprise me that much that they exist.)
>
> Probably the RM ought to suggest such a convention name as Implementation 
> Advice (something like C_Varargs) in order to increase portability.
>
> Someone ought to submit a suggestion to Ada-Comment so that it gets on the 
> ARG's radar/agenda.

Sorry for the "necromancy", but I thought it might be useful to add:

Another significant difference between varargs and regular arguments is
"type promotion". Briefly, char and short types are promoted to int when
they are part of a variadic argument, while they are not when they are
an explicit argument.

So the following will probably fail more reliably than previous
examples:

function Print_Short (Format : in Interfaces.C.char_array;
                      Value : in Interfaces.C.short)
   return Interfaces.C.int;
pragma Import (C, Print_Short, "printf");


Would you all mind testing this on various platforms?


Moreover, the argument type promotion also happens in non-prototyped
functions (e.g. K&R style). For example consider the following C
function:

void print_k_r_short ();


void print_k_r_short (s)
   short s;
{
   printf ("%hd\n", s);
}


Then the following Ada import is unlikely to work:

   procedure Print_K_R_Short (S : in Interfaces.C.short);
   pragma Import (C, Print_K_R_Short, "print_k_r_short");

Though in that case, using Interfaces.C.int would work.

Of course, on platforms where calling convention transmits C.short
arguments exactly like C.int (e.g. for improved alignment, or because
the platform has C.short equivalent to C.int (but then you could use
C.char instead of C.short, since C.char is guaranteed to be strictly
smaller than C.int on conforming hosted implementations)).



Hoping this helps,
Natasha



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-27  8:24           ` Natasha Kerensikova
@ 2012-04-27  9:18             ` Jacob Sparre Andersen
  2012-04-27 16:48               ` Natasha Kerensikova
  2012-05-03 20:15             ` sbelmont700
  1 sibling, 1 reply; 34+ messages in thread
From: Jacob Sparre Andersen @ 2012-04-27  9:18 UTC (permalink / raw)


Natasha Kerensikova wrote:

> Another significant difference between varargs and regular arguments
> is "type promotion". Briefly, char and short types are promoted to int
> when they are part of a variadic argument, while they are not when
> they are an explicit argument.
>
> So the following will probably fail more reliably than previous
> examples:

I'm afraid I have to disappoint you.  Your example (here with test
driver) works fine on Debian/stable (armv6l):

% cat c_varargs.adb
with Interfaces.C;
procedure C_Varargs is
   function Print_Short (Format : in Interfaces.C.char_array;
                         Value  : in Interfaces.C.short)
     return Interfaces.C.int;
   pragma Import (C, Print_Short, "printf");
   use type Interfaces.C.char_array;
   Result : Interfaces.C.int;
begin
   Result := Print_Short ("%hd" & Interfaces.C.char'Val (10), 42);
end C_Varargs;
% gnatmake c_varargs
[...]
% ./c_varargs
42
%

Greetings,

Jacob
-- 
"In space, no-one can press CTRL-ALT-DEL"
                                        -- An Ada programmer



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-27  9:18             ` Jacob Sparre Andersen
@ 2012-04-27 16:48               ` Natasha Kerensikova
  0 siblings, 0 replies; 34+ messages in thread
From: Natasha Kerensikova @ 2012-04-27 16:48 UTC (permalink / raw)


Hello,

On 2012-04-27, Jacob Sparre Andersen <sparre@nbi.dk> wrote:
> I'm afraid I have to disappoint you.  Your example (here with test
> driver) works fine on Debian/stable (armv6l):

OK. Let's pour in some more unsafety then (what an unusual for this
forums, isn't it?)

As I said, the previous example would fail to fail when C.short is
actually the same type as C.int, so let's fix that by using
C.signed_char, though I doubt that's the case here. It would also fail
to fail the extra space required by the type promotion is already
readable, so let's write stuff too. And lastly, some alignment
constraints might also cover up a failure, so let's use several
C.signed_char, assuming they will be packed.

That leads to the following example:

procedure Test is
   function Printf_Faulty (Format : in Interfaces.C.char_array;
                           Value_1 : in Interfaces.C.signed_char;
                           Value_2 : in Interfaces.C.signed_char;
                           Value_3 : in Interfaces.C.signed_char;
                           Result : out Interfaces.C.int)
      return Interfaces.C.int;
   pragma Import (C, Printf_Faulty, "printf");

   Result, Bytes_Written : Interfaces.C.int;
begin
   Bytes_Written := Printf_Faulty ("Values: %hhd, %hhd, %hhd\n%n",
                                   42, 89, 5, Result);
   pragma Assert (Bytes_Written = Result);
end Test;


Of course there would still be no symptoms if the calling convention
somehow already includes the type promotion. For example when the first
few parameters are passed through registers rather than a stack,
or when C.signed_char values have to be aligned like C.int.

I guess that's about as far as we can go in terms of failure rate.


Natasha



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-04-27  8:24           ` Natasha Kerensikova
  2012-04-27  9:18             ` Jacob Sparre Andersen
@ 2012-05-03 20:15             ` sbelmont700
  2012-05-13  4:18               ` David Thompson
  2012-05-14 15:21               ` Natasha Kerensikova
  1 sibling, 2 replies; 34+ messages in thread
From: sbelmont700 @ 2012-05-03 20:15 UTC (permalink / raw)


On Friday, April 27, 2012 4:24:59 AM UTC-4, Natasha Kerensikova wrote:
> Of course, on platforms where calling convention transmits C.short
> arguments exactly like C.int (e.g. for improved alignment, or because
> the platform has C.short equivalent to C.int (but then you could use
> C.char instead of C.short, since C.char is guaranteed to be strictly
> smaller than C.int on conforming hosted implementations)).

Isn't the general rule of thumb (since nothing in C is ever well-defined) that an int is the size of the default machine word (32-bit on 32-bit, 64 on 64, etc)?  If that's the case, whether it's stack or register, the calling convention is very likely going to use an int sized argument for anything smaller than an int anyway (e.g. if it uses the 32-bit stack, it would have to push a one-byte char as an int-sized value anyway).



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-05-03 20:15             ` sbelmont700
@ 2012-05-13  4:18               ` David Thompson
  2012-05-13  9:03                 ` Simon Wright
  2012-05-14 15:21               ` Natasha Kerensikova
  1 sibling, 1 reply; 34+ messages in thread
From: David Thompson @ 2012-05-13  4:18 UTC (permalink / raw)


On Thu, 3 May 2012 13:15:09 -0700 (PDT), sbelmont700@gmail.com wrote:

> On Friday, April 27, 2012 4:24:59 AM UTC-4, Natasha Kerensikova wrote:
> > Of course, on platforms where calling convention transmits C.short
> > arguments exactly like C.int (e.g. for improved alignment, or because
> > the platform has C.short equivalent to C.int (but then you could use
> > C.char instead of C.short, since C.char is guaranteed to be strictly
> > smaller than C.int on conforming hosted implementations)).
> 
> Isn't the general rule of thumb (since nothing in C is ever well-defined) 
that an int is the size of the default machine word (32-bit on 32-bit,
64 on 64, etc)?  If that's the case, whether it's stack or register,
the calling convention is very likely going to use an int sized
argument for anything smaller than an int anyway (e.g. if it uses the
32-bit stack, it would have to push a one-byte char as an int-sized
value anyway).

Yes. There are _some_ things well-defined in C (not nearly all), but
to your main point, 6.2.5p5 (formerly 6.1.2.5) says: A [signed] int
object has the natural size suggested by the architecture of the
execution environment (large enough to contain any value in the range
INT_MIN to INT_MAX as defined in the header <limits.h>). And p6 says
that unsigned int has the same size as signed int, and 5.2.4 requires
(without explicitly saying so) that size be at least 16 bits.

Technically this is normative text but there is no formal definition
of 'natural' so it can't actually be verified/enforced. And there are
machines where there can be legitimate controversy which of two (or
even more) widths is more natural. But where the machine does have a
word size, it is >= 16, and a C implementor doesn't use it for int,
they deserve to be tarred and feathered (not gzipped! <G>).

And yes, for all ABIs I've seen and most I can imagine, this means
that C.char and C.short will be passed the same as C.int, even though
formally they have different types in C (as well as Ada). However, the
default argument promotions in C (for varargs and also K&R1, as PP
correctly noted) also take 'float' to 'double'; it is fairly common
(though not required) for these to be passed differently in C, and
thus probably demonstrate PP's issue.

Also it isn't absolutely guaranteed that C char is smaller than int
(or more precisely that sizeof(int)>1). c.l.c loves to discuss offbeat
architectures like DSPs where it may actually make sense to have
char=short=int all 22-bit or somesuch, and thus 110%-portable code
can't assume that getchar()==EOF isn't actually a data character and
must 'confirm' it with feof() and/or ferror(). In practice no one has
reported any system where it both makes sense to have (C) char other
than 8 or at most 9 bits, and using stdio makes any sense at all.




^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-05-13  4:18               ` David Thompson
@ 2012-05-13  9:03                 ` Simon Wright
  2012-05-13 17:01                   ` Jeffrey Carter
  0 siblings, 1 reply; 34+ messages in thread
From: Simon Wright @ 2012-05-13  9:03 UTC (permalink / raw)


David Thompson <dave.thompson2@verizon.net> writes:

> Isn't the general rule of thumb (since nothing in C is ever
> well-defined) that an int is the size of the default machine word
> (32-bit on 32-bit, 64 on 64, etc)?

On Mac OS X (definitely Lion, probably all) C uses i386/limits.h for
both i386 and x86_64. So it's 32-bit ints for both.

And for Ada, Integer'Size is 32.



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-05-13  9:03                 ` Simon Wright
@ 2012-05-13 17:01                   ` Jeffrey Carter
  2012-05-13 18:20                     ` Simon Wright
  0 siblings, 1 reply; 34+ messages in thread
From: Jeffrey Carter @ 2012-05-13 17:01 UTC (permalink / raw)


On 05/13/2012 02:03 AM, Simon Wright wrote:
>
> And for Ada, Integer'Size is 32.

No, it's not.

-- 
Jeff Carter
"Blessed is just about anyone with a vested interest in the status quo."
Monty Python's Life of Brian
73



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-05-13 17:01                   ` Jeffrey Carter
@ 2012-05-13 18:20                     ` Simon Wright
  2012-05-13 19:11                       ` Jeffrey Carter
  0 siblings, 1 reply; 34+ messages in thread
From: Simon Wright @ 2012-05-13 18:20 UTC (permalink / raw)


Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> writes:

> On 05/13/2012 02:03 AM, Simon Wright wrote:
>>
>> And for Ada, Integer'Size is 32.
>
> No, it's not.

What I originally wrote was

>> On Mac OS X (definitely Lion, probably all) C uses i386/limits.h for
>> both i386 and x86_64. So it's 32-bit ints for both.
>> 
>> And for Ada, Integer'Size is 32.

and although it is certainly true that there is nothing in the ARM that
says that Integer'Size should be 32 the fact is that *on Mac OS X Lion*
it very definitely is.

Also on Debian 6 amd64.

Now, the size of an 'access Integer' is 64 on both.



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-05-13 18:20                     ` Simon Wright
@ 2012-05-13 19:11                       ` Jeffrey Carter
  2012-05-13 19:55                         ` Ludovic Brenta
  2012-05-13 21:12                         ` Simon Wright
  0 siblings, 2 replies; 34+ messages in thread
From: Jeffrey Carter @ 2012-05-13 19:11 UTC (permalink / raw)


On 05/13/2012 11:20 AM, Simon Wright wrote:
>
> and although it is certainly true that there is nothing in the ARM that
> says that Integer'Size should be 32 the fact is that *on Mac OS X Lion*
> it very definitely is.
>
> Also on Debian 6 amd64.
>
> Now, the size of an 'access Integer' is 64 on both.

No, they're not.

Those may be the values for a specific compiler on those platforms, but a 
specific compiler is not Ada. Nothing stops another compiler for those platforms 
from using other values.

-- 
Jeff Carter
"Blessed is just about anyone with a vested interest in the status quo."
Monty Python's Life of Brian
73



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-05-13 19:11                       ` Jeffrey Carter
@ 2012-05-13 19:55                         ` Ludovic Brenta
  2012-05-14  0:52                           ` Jeffrey Carter
  2012-05-13 21:12                         ` Simon Wright
  1 sibling, 1 reply; 34+ messages in thread
From: Ludovic Brenta @ 2012-05-13 19:55 UTC (permalink / raw)


Jeffrey Carter writes on comp.lang.ada:
> On 05/13/2012 11:20 AM, Simon Wright wrote:
>> and although it is certainly true that there is nothing in the ARM
>> that says that Integer'Size should be 32 the fact is that *on Mac OS
>> X Lion* it very definitely is.
>>
>> Also on Debian 6 amd64.
>>
>> Now, the size of an 'access Integer' is 64 on both.
>
> No, they're not.
>
> Those may be the values for a specific compiler on those platforms,
> but a specific compiler is not Ada.

The way I understood Simon, he *was* talking about specific compilers on
specific platforms.  By "Ada" he really meant "the Ada front-end of
GCC".

> Nothing stops another compiler for those platforms from using other
> values.

Yes, the ABI does.  Granted, a compiler may choose not to obey the ABI
but then programs compiled with it will not be able to load any shared
libraries not compiled with the same compiler.  So, not obeying the ABI
of the target platform would be really stupid.

-- 
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-05-13 19:11                       ` Jeffrey Carter
  2012-05-13 19:55                         ` Ludovic Brenta
@ 2012-05-13 21:12                         ` Simon Wright
  2012-05-13 23:57                           ` Georg Bauhaus
  2012-05-14  0:54                           ` Jeffrey Carter
  1 sibling, 2 replies; 34+ messages in thread
From: Simon Wright @ 2012-05-13 21:12 UTC (permalink / raw)


Jeffrey Carter <spam.jrcarter.not@spam.not.acm.org> writes:

> Nothing stops another compiler for those platforms from using other
> values.

No, but there isn't one for the Mac, where I started. And it seems very
unlikely (for the Mac, at any rate) that anyone will produce another.

And since Interfaces.C.int'Size needs to be 32, you'd have to have a
very good reason to make a different choice for Integer, no?



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-05-13 21:12                         ` Simon Wright
@ 2012-05-13 23:57                           ` Georg Bauhaus
  2012-05-14  0:54                           ` Jeffrey Carter
  1 sibling, 0 replies; 34+ messages in thread
From: Georg Bauhaus @ 2012-05-13 23:57 UTC (permalink / raw)


On 13.05.12 23:12, Simon Wright wrote:
> Jeffrey Carter<spam.jrcarter.not@spam.not.acm.org>  writes:
>
>> Nothing stops another compiler for those platforms from using other
>> values.
>
> No, but there isn't one for the Mac, where I started. And it seems very
> unlikely (for the Mac, at any rate) that anyone will produce another.

I'll speculate that SofCheck's AdaMagic (emitting C or C++)
is available in some form for Macs. (A picture shows one of
its authors with a Mac in front of him.)

And it likely has Integer'Size >= 32. But see below.

> And since Interfaces.C.int'Size needs to be 32, you'd have to have a
> very good reason to make a different choice for Integer, no?

I understand that Janus/Ada produces 32 bit executables for Win32,
but that its Integer'Size = 16. What size of int does the Windows ABI
suggest?




^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-05-13 19:55                         ` Ludovic Brenta
@ 2012-05-14  0:52                           ` Jeffrey Carter
  0 siblings, 0 replies; 34+ messages in thread
From: Jeffrey Carter @ 2012-05-14  0:52 UTC (permalink / raw)


On 05/13/2012 12:55 PM, Ludovic Brenta wrote:
>
> Yes, the ABI does.  Granted, a compiler may choose not to obey the ABI
> but then programs compiled with it will not be able to load any shared
> libraries not compiled with the same compiler.  So, not obeying the ABI
> of the target platform would be really stupid.

Since the ABI is, to Ada, a set of non-Ada subprograms, it makes sense not to 
use predefined, convention-Ada types to interface to them, so the ABI should 
have no effect on the choice of size for Integer.

Consider Janus/Ada, a compiler for Win32 (ABI uses 32-bits) with Integer'Size = 
16. Maybe you think Brukardt is "really stupid", but I suspect the editor of the 
ARM has a better understanding of the language than either of us.

-- 
Jeff Carter
"Run away! Run away!"
Monty Python and the Holy Grail
58



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-05-13 21:12                         ` Simon Wright
  2012-05-13 23:57                           ` Georg Bauhaus
@ 2012-05-14  0:54                           ` Jeffrey Carter
  2012-05-14  8:10                             ` Nomen Nescio
  1 sibling, 1 reply; 34+ messages in thread
From: Jeffrey Carter @ 2012-05-14  0:54 UTC (permalink / raw)


On 05/13/2012 02:12 PM, Simon Wright wrote:
>
> And since Interfaces.C.int'Size needs to be 32, you'd have to have a
> very good reason to make a different choice for Integer, no?

Punishing those who would use Integer when interfacing with C seems like an 
excellent reason to me.

-- 
Jeff Carter
"Run away! Run away!"
Monty Python and the Holy Grail
58



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-05-14  0:54                           ` Jeffrey Carter
@ 2012-05-14  8:10                             ` Nomen Nescio
  0 siblings, 0 replies; 34+ messages in thread
From: Nomen Nescio @ 2012-05-14  8:10 UTC (permalink / raw)


Intel IA32 and Intel 64 (AMD64) word size is 16 bits. That is not the same
as a "standard integer" on either of those two architectures. Go figure...




^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-05-03 20:15             ` sbelmont700
  2012-05-13  4:18               ` David Thompson
@ 2012-05-14 15:21               ` Natasha Kerensikova
  2012-05-14 20:53                 ` sbelmont700
  1 sibling, 1 reply; 34+ messages in thread
From: Natasha Kerensikova @ 2012-05-14 15:21 UTC (permalink / raw)


On 2012-05-03, sbelmont700@gmail.com <sbelmont700@gmail.com> wrote:
> Isn't the general rule of thumb (since nothing in C is ever
> well-defined) that an int is the size of the default machine word
> (32-bit on 32-bit, 64 on 64, etc)? 

Actually it's common for 64-bit-extended i386 architecture (so-called
"amd64") to have 32 bit int, since there is no speed penalty for
handling 32 bit integers compared to 64 ones, but the extra memory for
64 bit integers is often wasted (and that has a direct impact on
percieved speed because of caches).

> If that's the case, whether it's stack or register, the calling
> convention is very likely going to use an int sized argument for
> anything smaller than an int anyway (e.g. if it uses the 32-bit stack,
> it would have to push a one-byte char as an int-sized value anyway).

Why would it?

When dealing with 3 consecutive byte arguments, I don't see any reason
to store them as int-sized values on the stack, on both i386-derived
platforms.



Natasha



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: Importing C function with variable argument list
  2012-05-14 15:21               ` Natasha Kerensikova
@ 2012-05-14 20:53                 ` sbelmont700
  0 siblings, 0 replies; 34+ messages in thread
From: sbelmont700 @ 2012-05-14 20:53 UTC (permalink / raw)


On Monday, May 14, 2012 11:21:21 AM UTC-4, Natasha Kerensikova wrote:
> 
> Why would it?
> 
> When dealing with 3 consecutive byte arguments, I don't see any reason
> to store them as int-sized values on the stack, on both i386-derived
> platforms.
> 

I doubt most compilers would misalign the stack to save a couple bytes of RAM, but i suppose anything is possible.  Personally I have never seen this, but I would be interested in seeing an example.

-sb



^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2012-05-14 20:55 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-10  9:21 Importing C function with variable argument list Maxim Reznik
2012-04-10 11:22 ` Patrick
2012-04-10 13:09   ` Maxim Reznik
2012-04-10 13:50     ` Georg Bauhaus
2012-04-10 13:18 ` Markus Schöpflin
2012-04-10 16:47   ` Simon Wright
2012-04-12 10:08     ` Markus Schöpflin
2012-04-12 16:58       ` Adam Beneschan
2012-04-12 20:47         ` Randy Brukardt
2012-04-13  8:43           ` Markus Schöpflin
2012-04-13 23:01             ` Randy Brukardt
2012-04-27  8:24           ` Natasha Kerensikova
2012-04-27  9:18             ` Jacob Sparre Andersen
2012-04-27 16:48               ` Natasha Kerensikova
2012-05-03 20:15             ` sbelmont700
2012-05-13  4:18               ` David Thompson
2012-05-13  9:03                 ` Simon Wright
2012-05-13 17:01                   ` Jeffrey Carter
2012-05-13 18:20                     ` Simon Wright
2012-05-13 19:11                       ` Jeffrey Carter
2012-05-13 19:55                         ` Ludovic Brenta
2012-05-14  0:52                           ` Jeffrey Carter
2012-05-13 21:12                         ` Simon Wright
2012-05-13 23:57                           ` Georg Bauhaus
2012-05-14  0:54                           ` Jeffrey Carter
2012-05-14  8:10                             ` Nomen Nescio
2012-05-14 15:21               ` Natasha Kerensikova
2012-05-14 20:53                 ` sbelmont700
2012-04-13  4:08         ` Tero Koskinen
2012-04-13  8:04           ` Markus Schöpflin
2012-04-10 20:02 ` Tero Koskinen
2012-04-13  3:28   ` Tero Koskinen
2012-04-10 20:25 ` sbelmont700
2012-04-11 23:24 ` Randy Brukardt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox