comp.lang.ada
 help / color / mirror / Atom feed
* How to access this package written in C?
@ 2010-04-21 16:43 resander
  2010-04-21 17:39 ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: resander @ 2010-04-21 16:43 UTC (permalink / raw)


I am working on software that manipulates SQL databases via a GUI. It
is written in C or C++ without classes and compiled on Linux. Would
also want it to run on Windows eventually. This software has
essentially one entry procedure:

  int guidb ( int appno , int recaddress );  // in C

which returns an outcome as an int, takes an int appno which specifies
application and an address of a record in recaddress. The latter is
used for passing the memory address of any recordtype variable and is
cast to a byte address inside guidb.

guidb uses appno to locate field-offsets and length of the recordtype
in tables built by initialisation functions for all recordtypes that
take part.

Typical use in C/C++:

typedef struct { int prodcode; float price; char descr [50]... }
PRODUCT;
typedef struct { bool bitesyou; int speciescode; char name[20] ... }
ANIMAL ;

void getproduct ( PRODUCT * pout , int * resultout )
   {
   *resultout = guidb ( 0 , (int)pout ) ;
   }

void addtozoo ( ANIMAL * a , int * resultout )
   {
   *resultout = guidb ( 1 , (int)a ) ;
   }

PRODUCT prod ;
ANIMAL addthis ;
int outcome ;

//  use as...

  getproduct ( &prod , &outcome );
  // get addthis animal data then
  addtozoo ( &addthis , &outcome );

All wrappers like getproduct and addtozoo are automatically generated
from other specs. That is easy in C by using fldoffset macro to get
field offsets and sizeof(rectypename) to get record length and a cast
that changes the interpretation of address to an int.

Desired use in Ada (same as above):

type PRODUCT is RECORD int prodcode; float price; char descr
[50]...END RECORD;

procedure getproduct ( p : out PRODUCT ; result : out int ) is
begin
   result = guidb ( 0 , address_of(p) how ??? ) ;
end

prod : PRODUCT;
outcome : int ;

  getproduct ( prod , outcome );


To be able to use the guidb with Ada I need to know how to:

 - get the memory address carried (how?) by the record formal
parameter
 - obtain field offsets for a record type
 - obtain length of a record object/variable

How to do this in in Ada? If it cannot be done, can the interface
above be changed to make it possible?

Ken




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

* Re: How to access this package written in C?
  2010-04-21 16:43 How to access this package written in C? resander
@ 2010-04-21 17:39 ` Dmitry A. Kazakov
  2010-04-22 20:12 ` Björn Persson
  2010-04-22 21:12 ` Keith Thompson
  2 siblings, 0 replies; 19+ messages in thread
From: Dmitry A. Kazakov @ 2010-04-21 17:39 UTC (permalink / raw)


On Wed, 21 Apr 2010 09:43:02 -0700 (PDT), resander wrote:

> I am working on software that manipulates SQL databases via a GUI. It
> is written in C or C++ without classes and compiled on Linux. Would
> also want it to run on Windows eventually. This software has
> essentially one entry procedure:
> 
>   int guidb ( int appno , int recaddress );  // in C

This is awful even on C standards.

> which returns an outcome as an int, takes an int appno which specifies
> application and an address of a record in recaddress. The latter is
> used for passing the memory address of any recordtype variable and is
> cast to a byte address inside guidb.

[...]

> Desired use in Ada (same as above):
> 
> type PRODUCT is RECORD int prodcode; float price; char descr
> [50]...END RECORD;
> 
> procedure getproduct ( p : out PRODUCT ; result : out int ) is
> begin
>    result = guidb ( 0 , address_of(p) how ??? ) ;
> end
> 
> prod : PRODUCT;
> outcome : int ;

[...]

> How to do this in in Ada? If it cannot be done, can the interface
> above be changed to make it possible?

Make it a generic function:

   SQL_Error : exception;
   
   generic
      type Data_Type is private;
   function Generic_Get (No : Integer) return Data_Type;

The implementation of:
   
   with Ada.Exceptions;  use Ada.Exceptions;
   with Interfaces.C;    use Interfaces.C;

   function Generic_Get (No : Integer) return Data_Type is
      function Internal (No : int; Data : access Data_Type) return int;
      pragma Import (C, Internal, "guilib");
      Data   : aliased Data_Type;
      Result : int;
   begin
      Result := Internal (int (No), Data'Access);
      if Result /= 0 then
         Raise_Exception
         (SQL_Error'Identity, "Error code:" & int'Image (Result));
      else
         return Data;
      end if;
   end Generic_Get;

Declare a type you need, e.g. Product:

   type Product is record
      Code : int;
      Price  : float;
      Descr : char_array (1..50);
   end record;
   pragma Convention (C, Product); -- Note this pragma!

Instantiate the function:

   function Get is new Generic_Get (Product);

Use it as:

   X : Product := Get (0);

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: How to access this package written in C?
  2010-04-21 16:43 How to access this package written in C? resander
  2010-04-21 17:39 ` Dmitry A. Kazakov
@ 2010-04-22 20:12 ` Björn Persson
  2010-04-22 21:12 ` Keith Thompson
  2 siblings, 0 replies; 19+ messages in thread
From: Björn Persson @ 2010-04-22 20:12 UTC (permalink / raw)


resander wrote:

> void getproduct ( PRODUCT * pout , int * resultout )
>    {
>    *resultout = guidb ( 0 , (int)pout ) ;
>    }

Who is forcing you to cast pointers to int? I recommend applying a clue-by-
four to that person's head. That code is broken on 64-bit GNU/Linux. Good 
luck porting that program to Windows if what you have shown is 
representative of its quality.

Before you write the Ada binding you should fix the interface so that it's 
sane according to the C standard.

-- 
Bj�rn Persson
PGP key A88682FD



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

* Re: How to access this package written in C?
  2010-04-21 16:43 How to access this package written in C? resander
  2010-04-21 17:39 ` Dmitry A. Kazakov
  2010-04-22 20:12 ` Björn Persson
@ 2010-04-22 21:12 ` Keith Thompson
  2010-04-23 12:58   ` resander
  2 siblings, 1 reply; 19+ messages in thread
From: Keith Thompson @ 2010-04-22 21:12 UTC (permalink / raw)


resander <kresander@gmail.com> writes:
> I am working on software that manipulates SQL databases via a GUI. It
> is written in C or C++ without classes and compiled on Linux. Would
> also want it to run on Windows eventually. This software has
> essentially one entry procedure:
>
>   int guidb ( int appno , int recaddress );  // in C
>
> which returns an outcome as an int, takes an int appno which specifies
> application and an address of a record in recaddress. The latter is
> used for passing the memory address of any recordtype variable and is
> cast to a byte address inside guidb.
[...]

As others have mentioned, this is bad C.

There is no guarantee that an int can hold the value of an address,
and there are common systems (including Linux systems) where it
can't.  Worse, you're not likely to get a warning if you convert
a pointer to int, even if there's a loss of information.

The right type for this parameter is void* (which is roughly
analogous to Ada's System.Address).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"



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

* Re: How to access this package written in C?
  2010-04-22 21:12 ` Keith Thompson
@ 2010-04-23 12:58   ` resander
  2010-04-23 14:15     ` Dmitry A. Kazakov
                       ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: resander @ 2010-04-23 12:58 UTC (permalink / raw)


On Apr 22, 10:12 pm, Keith Thompson <ks...@mib.org> wrote:
> resander <kresan...@gmail.com> writes:
> > I am working on software that manipulates SQL databases via a GUI. It
> > is written in C or C++ without classes and compiled on Linux. Would
> > also want it to run on Windows eventually. This software has
> > essentially one entry procedure:
>
> >   int guidb ( int appno , int recaddress );  // in C
>
> > which returns an outcome as an int, takes an int appno which specifies
> > application and an address of a record in recaddress. The latter is
> > used for passing the memory address of any recordtype variable and is
> > cast to a byte address inside guidb.
>
> [...]
>
> As others have mentioned, this is bad C.
>
> There is no guarantee that an int can hold the value of an address,
> and there are common systems (including Linux systems) where it
> can't.  Worse, you're not likely to get a warning if you convert
> a pointer to int, even if there's a loss of information.
>
> The right type for this parameter is void* (which is roughly
> analogous to Ada's System.Address).
>
> --
> Keith Thompson (The_Other_Keith) ks...@mib.org  <http://www.ghoti.net/~kst>
> Nokia
> "We must do something.  This is something.  Therefore, we must do this."
>     -- Antony Jay and Jonathan Lynn, "Yes Minister"




Thank you all for your concerns about using an int for passing an
address. The interface actually uses a void * (could also be char * as
that is what is needed), but I changed it for the post because I
thought an all-int interface would be easier to handle at the Ada-to-C
boundary. That seems to have backfired!

It may help if I give some background info, so just briefly the
program (with guidb as the main entry routine) moves record data to/
from GUI dialogs and to and from SQL databases via ODBC. A record in
host language may be passed in or in-and-out. The guidb is not
compiled with host language units and would exist as a dll, shared
object or a static library. It uses a record memory address, record
length and field offsets and field types/length in order to access a
record and move the record around. This information is held in tables
local to guidb. The record length and field data are passed accross
via another entry point:

 void givefldinfo ( int recordtypeid ,  -- key
                    int recordlength ,
                    int numflds ,
                    int fldoffsets[] ,
                    int typeinfo[] );

The givefldinfo is called for each record type by initialisation
routines that are generated automatically from design-time or
repository information. They are compiled and linked with the host
application and called behind the scenes.

Usually GUI events are handled internally, but may also be handled by
event procedures in the host language. Host language handlers have
signatures ( bool valin ),( int valin ), ( char valin[] ) and
( RECORDTP * valinout ). There are four additional entry points, one
for each event handler signature to get the proc address across from
host language. These are called in a manner similar to givefldinfo.

I am on Linux and installed Ada GPS yesterday. Experimented a bit and
found that X.fld'Position gave me the field offsets and X'Size the
record size. I also tried getting the address of a record and its
fields using X'Address and X.fld'Address, but they all came out
negative.

Prodrecord address: -1079352648
 code field address: -1079352648
 bcode field address: -1079352644
 ccode field address: -1079352643
 third field address: -1079352640
 descr field address: -1079352636
 price field address: -1079352624

for record
   code : integer; bcode : character;
   ccode : character; third : integer;
   descr : String(1..10); price : float;
by:
 prod : PRODUCT;
 a: System.Address;
   function Conv is new Ada.Unchecked_Conversion (
                     Source => System.Address,
                     Target => Integer);
  ...
  a := prod'Address;
  put( "Prodrecord address: " );
  s := conv ( a ) ;
  put(s);
  new_line;

  a := prod.code'Address;
  put( " code field address: " );
  s := conv ( a ) ;
  put(s);
  new_lin
  ...
Q1.
Addresses are not negative. How do I output a System.Address?


Dmitri:
Many thanks for showing how to code the generic Get routine. I have
never used generics or interfaced to C before and it was so long time
ago I used Ada (where is my walking stick?) so I don't understand it
well enough.

Q2.
What is the effect of aliased in 'Data : aliased Data_Type;'?

Data is a local variable. I am confused by the aliased keyword, but it
would seem guidb copies the record into this and then the record value
is copied once more into final location (X:Product). If so, one copy
operation is redundant.

Q3.
The wrapper:
procedure getprod (p:out PRODUCT;res:out int) is
begin
   result = guidb ( 0 , addrin(p)??? ) ;
end

hides the details of calling the C function and returns data to the
record variable in the calling program if the address carried by the
formal parameter can be obtained inside the wrapper. Using p'Address
for the second actual parameter of guidb would probably just give the
address of the formal (will check when I know how to output a
System.Address).
Is it possible to obtain the memory address of the record variable via
formal parameter p?

Q4.
Would it be easier to implement this if the wrapper was changed to:

procedure getprod (p: in System.Address; res:out int) is
begin
   result = guidb ( 0 , what goes here??? ) ;
end

with user calling it as:

  getprod ( recordvar'Address , result );


Q5.
Host language event handler procedures are stored as an array of
procedure addresses which is local to guidb. A procedure is called
indirectly via this array. This was designed for C/C++, but it would
be nice to use the same or similar mechanism for Ada.
Is this going to be possible?


I think interfacing to Ada can be done, but my knowledge about this is
still very limited. Your help would be most appreciated.

Regards
Ken




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

* Re: How to access this package written in C?
  2010-04-23 12:58   ` resander
@ 2010-04-23 14:15     ` Dmitry A. Kazakov
  2010-04-23 14:44     ` John B. Matthews
  2010-04-26 18:16     ` Robert A Duff
  2 siblings, 0 replies; 19+ messages in thread
From: Dmitry A. Kazakov @ 2010-04-23 14:15 UTC (permalink / raw)


On Fri, 23 Apr 2010 05:58:05 -0700 (PDT), resander wrote:

> It may help if I give some background info, so just briefly the
> program (with guidb as the main entry routine) moves record data to/
> from GUI dialogs and to and from SQL databases via ODBC.

There is GNADE ODBC, Ada bindings to ODBC. So you can drop C/C++
altogether.

> for record
>    code : integer; bcode : character;
>    ccode : character; third : integer;
>    descr : String(1..10); price : float;
> by:
>  prod : PRODUCT;
>  a: System.Address;
>    function Conv is new Ada.Unchecked_Conversion (
>                      Source => System.Address,
>                      Target => Integer);
>   ...
>   a := prod'Address;
>   put( "Prodrecord address: " );
>   s := conv ( a ) ;
>   put(s);
>   new_line;
> 
>   a := prod.code'Address;
>   put( " code field address: " );
>   s := conv ( a ) ;
>   put(s);
>   new_lin
>   ...
> Q1.
> Addresses are not negative.

Never use Unchecked_Conversion unless you exactly know what you are
doing... Address is modular, when bit-wise converted to a *signed* integer
the result is expectedly surprising.

> How do I output a System.Address?

The example above in legal Ada:

with Ada.Text_IO;              use Ada.Text_IO;
with System.Storage_Elements;  use System.Storage_Elements;
with Interfaces.C;             use Interfaces.C;

procedure Test_Fields is
   type Product is record
      Code : int;     -- Use only C-compatible types when you communicate
      Bcode : char; -- to C
      Ccode : char;
      Third : int;
      Descr : char_array (1..10);
      Price : c_float;
   end record;
   pragma Convention (C, Product);
   P : aliased Product;
begin
   Put_Line ("P'Address:" & Integer_Address'Image (To_Integer
(P'Address)));
   Put_Line ("P.Code'Address:" & Integer_Address'Image (To_Integer
(P.Code'Address)));
   Put_Line ("P.Descr'Address:" & Integer_Address'Image (To_Integer
(P.Descr'Address)));
end Test_Fields;

gives:

P'Address: 38207168
P.Code'Address: 38207168
P.Descr'Address: 38207180

> Dmitri:
> Many thanks for showing how to code the generic Get routine. I have
> never used generics or interfaced to C before and it was so long time
> ago I used Ada (where is my walking stick?) so I don't understand it
> well enough.

Ada generic is roughly what C++ calls template.

> Q2.
> What is the effect of aliased in 'Data : aliased Data_Type;'?
> 
> Data is a local variable. I am confused by the aliased keyword, but it
> would seem guidb copies the record into this and then the record value
> is copied once more into final location (X:Product). If so, one copy
> operation is redundant.

"aliased" means "dear compiler, I plan to take pointers (access type) to
this thing." The compiler will reject Data'Access otherwise, because
without your hint it is free to allocate it in a way that Data would have
no valid machine address at all.

> Q3.
> The wrapper:
> procedure getprod (p:out PRODUCT;res:out int) is
> begin
>    result = guidb ( 0 , addrin(p)??? ) ;
> end
> 
> hides the details of calling the C function and returns data to the
> record variable in the calling program if the address carried by the
> formal parameter can be obtained inside the wrapper. Using p'Address
> for the second actual parameter of guidb would probably just give the
> address of the formal (will check when I know how to output a
> System.Address).
> Is it possible to obtain the memory address of the record variable via
> formal parameter p?

In general case no, because see above. However if you declare PRODUCT a
"limited type" it will be passed by reference. You also [worse] can

   procedure getprod (p: access PRODUCT; ...);

BTW, your concern about copying records is absolutely ungrounded.
Especially because you are using ODBC + a relational DBMS! These are so
extraordinary slow, that you will note no difference even if you did
hundreds of copies.

> Q4.
> Would it be easier to implement this if the wrapper was changed to:
> 
> procedure getprod (p: in System.Address; res:out int) is
> begin
>    result = guidb ( 0 , what goes here??? ) ;
> end
> 
> with user calling it as:
> 
>   getprod ( recordvar'Address , result );

The preferences are as follows:

in out >> access >>>>>>>>>>> address

> Q5.
> Host language event handler procedures are stored as an array of
> procedure addresses which is local to guidb. A procedure is called
> indirectly via this array. This was designed for C/C++, but it would
> be nice to use the same or similar mechanism for Ada.
> Is this going to be possible?

Yes, it is possible, you can have an array of access-to-procedure type. But
an OO way is preferable.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: How to access this package written in C?
  2010-04-23 12:58   ` resander
  2010-04-23 14:15     ` Dmitry A. Kazakov
@ 2010-04-23 14:44     ` John B. Matthews
  2010-04-23 15:39       ` John B. Matthews
  2010-04-26 18:16     ` Robert A Duff
  2 siblings, 1 reply; 19+ messages in thread
From: John B. Matthews @ 2010-04-23 14:44 UTC (permalink / raw)


In article 
<e98bcf01-46cc-44dd-b57b-3cc7e273d9e2@j21g2000yqh.googlegroups.com>,
 resander <kresander@gmail.com> wrote:

> Prodrecord address: -1079352648
>  code field address: -1079352648
>  bcode field address: -1079352644
>  ccode field address: -1079352643
>  third field address: -1079352640
>  descr field address: -1079352636
>  price field address: -1079352624
>   ...
> Q1.
> Addresses are not negative. How do I output a System.Address?

-1079352648 = 0xBFAA62B8
-1079352644 = 0xBFAA62BC
...

This recent thread discusses several ways to display hexadecimal:

<http://groups.google.com/group/comp.lang.ada/browse_frm/thread/f3514db0a21f9b44>

A.10.8 Input-Output for Integer Types may be the most straightforward:

<http://www.adaic.com/standards/05rm/html/RM-A-10-8.html>

-- 
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>



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

* Re: How to access this package written in C?
  2010-04-23 14:44     ` John B. Matthews
@ 2010-04-23 15:39       ` John B. Matthews
  0 siblings, 0 replies; 19+ messages in thread
From: John B. Matthews @ 2010-04-23 15:39 UTC (permalink / raw)


In article <nospam-84056C.10444823042010@news.aioe.org>,
 "John B. Matthews" <nospam@nospam.invalid> wrote:

> In article 
> <e98bcf01-46cc-44dd-b57b-3cc7e273d9e2@j21g2000yqh.googlegroups.com>,
>  resander <kresander@gmail.com> wrote:
> 
> > Prodrecord address: -1079352648
> >  code field address: -1079352648
> >  bcode field address: -1079352644
> >  ccode field address: -1079352643
> >  third field address: -1079352640
> >  descr field address: -1079352636
> >  price field address: -1079352624
> >   ...
> > Q1.
> > Addresses are not negative. How do I output a System.Address?
> 
> -1079352648 = 0xBFAA62B8
> -1079352644 = 0xBFAA62BC
> ...
> 
> This recent thread discusses several ways to display hexadecimal:
> 
> <http://groups.google.com/group/comp.lang.ada/browse_frm/thread/f3514db0a21f9b
> 44>
> 
> A.10.8 Input-Output for Integer Types may be the most straightforward:
> 
> <http://www.adaic.com/standards/05rm/html/RM-A-10-8.html>

For example,

with Ada.Text_IO;
with System.Storage_Elements;

procedure Modular is

package Memory renames System.Storage_Elements;
package Address_IO is
   new Ada.Text_IO.Modular_IO(Memory.Integer_Address);
     
begin
   Ada.Text_IO.Put("Address of procedure Modular: ");
   Address_IO.Put(
      Item => Memory.To_Integer(Modular'Address),
      Width => 0,
      Base => 16);
   Ada.Text_IO.New_Line;
end Modular;

-- 
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>



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

* Re: How to access this package written in C?
  2010-04-23 12:58   ` resander
  2010-04-23 14:15     ` Dmitry A. Kazakov
  2010-04-23 14:44     ` John B. Matthews
@ 2010-04-26 18:16     ` Robert A Duff
  2010-04-26 19:57       ` Keith Thompson
  2 siblings, 1 reply; 19+ messages in thread
From: Robert A Duff @ 2010-04-26 18:16 UTC (permalink / raw)


resander <kresander@gmail.com> writes:

> On Apr 22, 10:12�pm, Keith Thompson <ks...@mib.org> wrote:
>> There is no guarantee that an int can hold the value of an address,
>> and there are common systems (including Linux systems) where it
>> can't. �Worse, you're not likely to get a warning if you convert
>> a pointer to int, even if there's a loss of information.

Why?  I'd think if int is smaller than whatever*, then
a cast to int clearly deserves a warning.

>> The right type for this parameter is void* (which is roughly
>> analogous to Ada's System.Address).

Yeah, roughly.  System.Address is somewhat lower level than
C's void*.

> Thank you all for your concerns about using an int for passing an
> address. The interface actually uses a void * (could also be char * as
> that is what is needed), but I changed it for the post because I
> thought an all-int interface would be easier to handle at the Ada-to-C
> boundary. That seems to have backfired!

You should look at section B (especially B.3) of the Ada RM.
There's a type char_star you can use.

There's no void_star.  I'm not sure why -- probably this
part of Ada predates void* in C, and nobody bothered
to upgrade Ada to match the new C.

> Q1.
> Addresses are not negative. How do I output a System.Address?

In GNAT, there is a function System.Address_Image.
Look at the file s-addima.ads in your GNAT
distribution.

Beware: this is not portable to other Ada compilers.

- Bob



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

* Re: How to access this package written in C?
  2010-04-26 18:16     ` Robert A Duff
@ 2010-04-26 19:57       ` Keith Thompson
  2010-04-26 21:20         ` Maciej Sobczak
  2010-04-27  0:20         ` Robert A Duff
  0 siblings, 2 replies; 19+ messages in thread
From: Keith Thompson @ 2010-04-26 19:57 UTC (permalink / raw)


Robert A Duff <bobduff@shell01.TheWorld.com> writes:
> resander <kresander@gmail.com> writes:
>
>> On Apr 22, 10:12 pm, Keith Thompson <ks...@mib.org> wrote:
>>> There is no guarantee that an int can hold the value of an address,
>>> and there are common systems (including Linux systems) where it
>>> can't.  Worse, you're not likely to get a warning if you convert
>>> a pointer to int, even if there's a loss of information.
>
> Why?  I'd think if int is smaller than whatever*, then
> a cast to int clearly deserves a warning.

I made an assumption, thereby making an ass out of me and umption.

In fact gcc does warn about converting a pointer to a smaller integer
type:

    warning: cast from pointer to integer of different size

As the wording implies, it produces the same warning for a cast from a
pointer to a larger integer type.

I haven't checked other C compilers.

In many cases, though, C compilers tend to take a cast operator to mean
"do this conversion and don't bother me, I know what I'm doing".

[...]

>> Thank you all for your concerns about using an int for passing an
>> address. The interface actually uses a void * (could also be char * as
>> that is what is needed), but I changed it for the post because I
>> thought an all-int interface would be easier to handle at the Ada-to-C
>> boundary. That seems to have backfired!
>
> You should look at section B (especially B.3) of the Ada RM.
> There's a type char_star you can use.
>
> There's no void_star.  I'm not sure why -- probably this
> part of Ada predates void* in C, and nobody bothered
> to upgrade Ada to match the new C.

As I recall, Ada 83 didn't have any of this; it was introduced in Ada
95.

void* was introduced in the ANSI C standard in 1989 (reissued with
cosmetic changes as the ISO C standard in 1990).

But C still requires char* and void* to have the same representation.

But in the Ada RM, I only see char_star in an example:

    subtype Char_Star is Char_Ptrs.Pointer;

[snip]

The document I'm looking at is "Ada Reference Manual, ISO/IEC
8652:2007(E) Ed. 3", "ISO/IEC 8652:1995(E) with Technical Corrigendum 1
and Amendment 1".  Is that the most current version?

A few comments on Interfaces.C:

plain_char is a subtype of either unsigned_char or signed_char.  In C,
plain char is actually a distinct type, though it has the same
representation as either unsigned char or signed char.  It would be more
consistent to have either
    type plain_char is new signed_char;
or
    type plain_char is new unsigned_char;
depending on the implementation.

There's no need for nul, wide_nul, and char32_nul to be
implementation-defined; they're all zero by definition:

    nul : constant char := char'val(0);
    ...
    wide_nul : constant wchar_t := wchar_t'val(0);
    ...
    char32_nul : constant char32_t := char32_t'val(0);

C doesn't actually have a type corresponding to char32_t; it has
wchar_t, but its size is implementation-defined.

    Execution of Free(X) is also erroneous if the chars_ptr X was not
    returned by New_Char_Array or New_String.

It should also be mentioned that calling Free twice on the same
pointer value is erroneous (you can do this by saving a copy of the
pointer before the first call to Free).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"



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

* Re: How to access this package written in C?
  2010-04-26 19:57       ` Keith Thompson
@ 2010-04-26 21:20         ` Maciej Sobczak
  2010-04-27  6:52           ` Alex R. Mosteo
  2010-04-27  0:20         ` Robert A Duff
  1 sibling, 1 reply; 19+ messages in thread
From: Maciej Sobczak @ 2010-04-26 21:20 UTC (permalink / raw)


On 26 Kwi, 21:57, Keith Thompson <ks...@mib.org> wrote:

> But C still requires char* and void* to have the same representation.
>
> But in the Ada RM, I only see char_star in an example:
>
>     subtype Char_Star is Char_Ptrs.Pointer;

I use this:

    subtype Void_Ptr is System.Address;

It works like a charm. Please note that in order to link Ada with C
there is a need for a *pair* of *compatible* compilers - you cannot
compile the Ada part with a random Ada compiler and a C part with a
random C compiler and expect them to work together. There is a lot of
hand-waving in the multilanguage development, which means lots of
under-the-table assumptions can be taken for granted even though they
are not explicitly covered by any of the language standards.

--
Maciej Sobczak * http://www.inspirel.com

YAMI4 - Messaging Solution for Distributed Systems
http://www.inspirel.com/yami4



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

* Re: How to access this package written in C?
  2010-04-26 19:57       ` Keith Thompson
  2010-04-26 21:20         ` Maciej Sobczak
@ 2010-04-27  0:20         ` Robert A Duff
  2010-04-27  1:01           ` Keith Thompson
  2010-04-27  1:31           ` Randy Brukardt
  1 sibling, 2 replies; 19+ messages in thread
From: Robert A Duff @ 2010-04-27  0:20 UTC (permalink / raw)


Keith Thompson <kst-u@mib.org> writes:

> Robert A Duff <bobduff@shell01.TheWorld.com> writes:
>> resander <kresander@gmail.com> writes:
>>
>>> On Apr 22, 10:12�pm, Keith Thompson <ks...@mib.org> wrote:
>>>> There is no guarantee that an int can hold the value of an address,
>>>> and there are common systems (including Linux systems) where it
>>>> can't. �Worse, you're not likely to get a warning if you convert
>>>> a pointer to int, even if there's a loss of information.
>>
>> Why?  I'd think if int is smaller than whatever*, then
>> a cast to int clearly deserves a warning.
>
> I made an assumption, thereby making an ass out of me and umption.

;-)

> In fact gcc does warn about converting a pointer to a smaller integer
> type:
>
>     warning: cast from pointer to integer of different size
>
> As the wording implies, it produces the same warning for a cast from a
> pointer to a larger integer type.

As well it should.

Thanks for checking gcc.  Of course I have a gcc at hand (which compiles
both Ada and C), but I was too lazy to try it.  Thanks!

> I haven't checked other C compilers.
>
> In many cases, though, C compilers tend to take a cast operator to mean
> "do this conversion and don't bother me, I know what I'm doing".

Ada is somewhat better, here, in that safer conversions
have a different syntax from unsafer conversions.

A cast, in C, might mean something fairly innocuous, or it might mean
"damn the torpedoes, full speed ahead!", and it's hard for a C compiler
to know which is which.

> [...]
>
>>> Thank you all for your concerns about using an int for passing an
>>> address. The interface actually uses a void * (could also be char * as
>>> that is what is needed), but I changed it for the post because I
>>> thought an all-int interface would be easier to handle at the Ada-to-C
>>> boundary. That seems to have backfired!
>>
>> You should look at section B (especially B.3) of the Ada RM.
>> There's a type char_star you can use.
>>
>> There's no void_star.  I'm not sure why -- probably this
>> part of Ada predates void* in C, and nobody bothered
>> to upgrade Ada to match the new C.
>
> As I recall, Ada 83 didn't have any of this; it was introduced in Ada
> 95.

Right.  Ada 83 just had pragma Interface (now called pragma Import),
and it just let implementations provide whatever interface-to-C
or interface-to-whatever they liked.  Ada 95, 2005, and 2012
offer much more.

> void* was introduced in the ANSI C standard in 1989 (reissued with
> cosmetic changes as the ISO C standard in 1990).
>
> But C still requires char* and void* to have the same representation.
>
> But in the Ada RM, I only see char_star in an example:
>
>     subtype Char_Star is Char_Ptrs.Pointer;

Yes, you're right.  My mistake -- there's no char_star in Ada.
You have to instantiate the C.Pointers generic package,
which is a bit of a pain.

On the other hand, Ada has the Interfaces.C.Strings package,
which has convenient things like char_array_access and
chars_ptr.

Note that GNAT tries pretty hard to make Ada types match
C types in representation, so if you're willing to stick
with gcc to compile your Ada and C programs, it works nicely.

> [snip]
>
> The document I'm looking at is "Ada Reference Manual, ISO/IEC
> 8652:2007(E) Ed. 3", "ISO/IEC 8652:1995(E) with Technical Corrigendum 1
> and Amendment 1".  Is that the most current version?

No.  The most current standard is here:

    http://www.ada-auth.org/

after you rummage aroung a bit.  Look for the Ada 2005 version.  The
most current future to-be-standardized version (for Ada 2012) is here:

    http://www.adaic.org/standards/ada1z.html

Note that this one has no official ISO status yet.

> A few comments on Interfaces.C:

Note that you can send comments on the Ada standard to
ada-comment@ada-auth.org.  I know you are an expert on
both C and Ada, so I think your comments about Ada-interfacing-to-C
should be taken very seriously.

> plain_char is a subtype of either unsigned_char or signed_char.  In C,
> plain char is actually a distinct type, though it has the same
> representation as either unsigned char or signed char.  It would be more
> consistent to have either
>     type plain_char is new signed_char;
> or
>     type plain_char is new unsigned_char;
> depending on the implementation.

I think I disagree with that, because "distinct type"
means different things in C versus Ada, because there
are different implicit conversions in the two languages.

In C, you can freely assign amongst these types (I think),
whereas Ada is more strict.

I'm not sure about that, but in any case, we're not going
to make incompatible changes (as subtype --> type surely
would be).

> There's no need for nul, wide_nul, and char32_nul to be
> implementation-defined; they're all zero by definition:
>
>     nul : constant char := char'val(0);
>     ...
>     wide_nul : constant wchar_t := wchar_t'val(0);
>     ...
>     char32_nul : constant char32_t := char32_t'val(0);

Yes, I think that makes sense.  See also AI95-00037.

> C doesn't actually have a type corresponding to char32_t; it has
> wchar_t, but its size is implementation-defined.

So what do you think it should say?

>     Execution of Free(X) is also erroneous if the chars_ptr X was not
>     returned by New_Char_Array or New_String.
>
> It should also be mentioned that calling Free twice on the same
> pointer value is erroneous (you can do this by saving a copy of the
> pointer before the first call to Free).

Yes, I agree.

- Bob



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

* Re: How to access this package written in C?
  2010-04-27  0:20         ` Robert A Duff
@ 2010-04-27  1:01           ` Keith Thompson
  2010-04-27 16:07             ` Robert A Duff
  2010-04-27  1:31           ` Randy Brukardt
  1 sibling, 1 reply; 19+ messages in thread
From: Keith Thompson @ 2010-04-27  1:01 UTC (permalink / raw)


Robert A Duff <bobduff@shell01.TheWorld.com> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> Robert A Duff <bobduff@shell01.TheWorld.com> writes:
>>> resander <kresander@gmail.com> writes:
>>>> On Apr 22, 10:12 pm, Keith Thompson <ks...@mib.org> wrote:
>>>>> There is no guarantee that an int can hold the value of an address,
>>>>> and there are common systems (including Linux systems) where it
>>>>> can't.  Worse, you're not likely to get a warning if you convert
>>>>> a pointer to int, even if there's a loss of information.
>>>
>>> Why?  I'd think if int is smaller than whatever*, then
>>> a cast to int clearly deserves a warning.
>>
>> I made an assumption, thereby making an ass out of me and umption.
>
> ;-)
>
>> In fact gcc does warn about converting a pointer to a smaller integer
>> type:
>>
>>     warning: cast from pointer to integer of different size
>>
>> As the wording implies, it produces the same warning for a cast from a
>> pointer to a larger integer type.
>
> As well it should.
>
> Thanks for checking gcc.  Of course I have a gcc at hand (which compiles
> both Ada and C), but I was too lazy to try it.  Thanks!
>
>> I haven't checked other C compilers.
>>
>> In many cases, though, C compilers tend to take a cast operator to mean
>> "do this conversion and don't bother me, I know what I'm doing".
>
> Ada is somewhat better, here, in that safer conversions
> have a different syntax from unsafer conversions.
>
> A cast, in C, might mean something fairly innocuous, or it might mean
> "damn the torpedoes, full speed ahead!", and it's hard for a C compiler
> to know which is which.

Casts (i.e., explicit conversions) are rarely necessary in
well-written C.  (They're unfortunately common in C in general.)
Most conversions in C are performed implicitly.  All arithmetic types
are implicitly convertible to each other, and all pointer-to-object
types are implicitly convertible to and from void*.

Casts are useful when you need to override the default conversions
in an arithmetic expression, for certain kinds of arguments to
variadic functions such as printf, and when you need to play games
with pointers in non-portable code.

(That's probably more information about C than most people here are
interested in, so I'll stop now.)

>> The document I'm looking at is "Ada Reference Manual, ISO/IEC
>> 8652:2007(E) Ed. 3", "ISO/IEC 8652:1995(E) with Technical Corrigendum 1
>> and Amendment 1".  Is that the most current version?
>
> No.  The most current standard is here:
>
>     http://www.ada-auth.org/
>
> after you rummage aroung a bit.  Look for the Ada 2005 version.

I did.  <http://www.ada-auth.org/arm.html> has links to several versions
of the Ada 2005 RM.  "RM-Final.pdf" is byte-for-byte identical to the
version I'm using, and has the above-quoted text on the title page.

> The most current future to-be-standardized version (for Ada 2012) is
> here:
>
>     http://www.adaic.org/standards/ada1z.html
>
> Note that this one has no official ISO status yet.

I'll check that out, thanks.

>> A few comments on Interfaces.C:
>
> Note that you can send comments on the Ada standard to
> ada-comment@ada-auth.org.  I know you are an expert on
> both C and Ada, so I think your comments about Ada-interfacing-to-C
> should be taken very seriously.

Thanks, I'll do that.  I seem to recall they expect some particular
format for comments (it's been a long time since I've submitted any); is
that still the case, or should I just send free-form English text?

>> plain_char is a subtype of either unsigned_char or signed_char.  In C,
>> plain char is actually a distinct type, though it has the same
>> representation as either unsigned char or signed char.  It would be more
>> consistent to have either
>>     type plain_char is new signed_char;
>> or
>>     type plain_char is new unsigned_char;
>> depending on the implementation.
>
> I think I disagree with that, because "distinct type"
> means different things in C versus Ada, because there
> are different implicit conversions in the two languages.
>
> In C, you can freely assign amongst these types (I think),
> whereas Ada is more strict.
>
> I'm not sure about that, but in any case, we're not going
> to make incompatible changes (as subtype --> type surely
> would be).

Yeah, breaking compatibility would be bad.

Still, the current situation means that this:

    P: plain_char := 0;
    S: signed_char := P;

is either valid or illegal, depending on the implementation.

It's also odd that char and plain_char are two distinct types, but
there's only so much you can do to make C and Ada work together.

>> There's no need for nul, wide_nul, and char32_nul to be
>> implementation-defined; they're all zero by definition:
>>
>>     nul : constant char := char'val(0);
>>     ...
>>     wide_nul : constant wchar_t := wchar_t'val(0);
>>     ...
>>     char32_nul : constant char32_t := char32_t'val(0);
>
> Yes, I think that makes sense.  See also AI95-00037.
>
>> C doesn't actually have a type corresponding to char32_t; it has
>> wchar_t, but its size is implementation-defined.
>
> So what do you think it should say?

I don't know.  C201X might have some additional support in this area
(but since even C99 isn't universally supported, I'm not sure how useful
that is).

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"



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

* Re: How to access this package written in C?
  2010-04-27  0:20         ` Robert A Duff
  2010-04-27  1:01           ` Keith Thompson
@ 2010-04-27  1:31           ` Randy Brukardt
  1 sibling, 0 replies; 19+ messages in thread
From: Randy Brukardt @ 2010-04-27  1:31 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
news:wcceii1g308.fsf@shell01.TheWorld.com...
> Keith Thompson <kst-u@mib.org> writes:
...
>> The document I'm looking at is "Ada Reference Manual, ISO/IEC
>> 8652:2007(E) Ed. 3", "ISO/IEC 8652:1995(E) with Technical Corrigendum 1
>> and Amendment 1".  Is that the most current version?
>
> No.  The most current standard is here:
>
>    http://www.ada-auth.org/

Actually, the title Keith gives is that of the most recent "official" 
consolidated edition. And the on-line versions of the Ada 2005 stuff are 
found in
     http://www.adaic.org/standards/ada05.html
(You can get the source and tools for generating the standard from 
www.ada-auth.org, but that is something that very few people need.)

> after you rummage aroung a bit.  Look for the Ada 2005 version.  The
> most current future to-be-standardized version (for Ada 2012) is here:
>
>    http://www.adaic.org/standards/ada1z.html
>
> Note that this one has no official ISO status yet.

Note that the above URL is going to change drastically when the next draft 
version is posted (probably next week). It is going to move to 
www.ada-auth.org and will be named Ada 2012 (instead of the "1z"). I'll try 
to maintain some sort of forwarding, but it is best to change you bookmarks 
then.

So to sum up, Bob got it exactly backwards. ;-)

...
>> There's no need for nul, wide_nul, and char32_nul to be
>> implementation-defined; they're all zero by definition:
>>
>>     nul : constant char := char'val(0);
>>     ...
>>     wide_nul : constant wchar_t := wchar_t'val(0);
>>     ...
>>     char32_nul : constant char32_t := char32_t'val(0);
>
> Yes, I think that makes sense.  See also AI95-00037.
>
>> C doesn't actually have a type corresponding to char32_t; it has
>> wchar_t, but its size is implementation-defined.

I believe that the char16 and char32 types were to match some proposed C 
update; not sure if that was ever adopted. Ah, here's what AI95-00285-1 has 
to say on the subject:

-- SC22/WG14 is planning to include support for Unicode 16- and 32-bit 
characters
-- in C. Their proposal is presented in ISO/IEC TR 19769:2004
-- (http://www.open-std.org/jtc1/sc22//WG14/www/docs/n1040.pdf). In order to
-- provide compatibility with the upcoming C standard, new types are added 
to
-- Interfaces.C that correspond to C char16_t and char32_t. It is recognized 
that
-- adding new declarations to predefined units can cause incompatibilities, 
but it
-- is thought that the new identifiers are unlikely to conflict with 
existing
-- code.

We may have jumped the gun on adding these, but as Bob noted, we're not 
going to remove them as the incompatibility would be significant and it's 
harmless to have them.

                                   Randy.





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

* Re: How to access this package written in C?
  2010-04-26 21:20         ` Maciej Sobczak
@ 2010-04-27  6:52           ` Alex R. Mosteo
  2010-04-27 22:29             ` Randy Brukardt
  0 siblings, 1 reply; 19+ messages in thread
From: Alex R. Mosteo @ 2010-04-27  6:52 UTC (permalink / raw)


Maciej Sobczak wrote:

> On 26 Kwi, 21:57, Keith Thompson <ks...@mib.org> wrote:
> 
>> But C still requires char* and void* to have the same representation.
>>
>> But in the Ada RM, I only see char_star in an example:
>>
>> subtype Char_Star is Char_Ptrs.Pointer;
> 
> I use this:
> 
>     subtype Void_Ptr is System.Address;

I have sometimes used

      type Void is null record;
      pragma Convention (Void, C);
      type Void_Ptr is access all Void;
      pragma Convention (Void_Ptr, C);

Curious here about any implications of using the different approaches.

When doing bindings I tend to avoid 'Access and 'Address whenever possible, 
though; using in out parameters seems to be sufficient in the 99% of cases.

On the one hand I like to remain as high-level as possible; on the other I 
could see that System.Address leaves less room for compiler fancies...

> It works like a charm. Please note that in order to link Ada with C
> there is a need for a *pair* of *compatible* compilers - you cannot
> compile the Ada part with a random Ada compiler and a C part with a
> random C compiler and expect them to work together. There is a lot of
> hand-waving in the multilanguage development, which means lots of
> under-the-table assumptions can be taken for granted even though they
> are not explicitly covered by any of the language standards.
> 
> --
> Maciej Sobczak * http://www.inspirel.com
> 
> YAMI4 - Messaging Solution for Distributed Systems
> http://www.inspirel.com/yami4




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

* Re: How to access this package written in C?
  2010-04-27  1:01           ` Keith Thompson
@ 2010-04-27 16:07             ` Robert A Duff
  2010-04-27 22:29               ` Randy Brukardt
  0 siblings, 1 reply; 19+ messages in thread
From: Robert A Duff @ 2010-04-27 16:07 UTC (permalink / raw)


Keith Thompson <kst-u@mib.org> writes:

> I did.  <http://www.ada-auth.org/arm.html> has links to several versions
> of the Ada 2005 RM.  "RM-Final.pdf" is byte-for-byte identical to the
> version I'm using, and has the above-quoted text on the title page.

Sorry for the misinformation.

> Thanks, I'll do that.  I seem to recall they expect some particular
> format for comments (it's been a long time since I've submitted any); is
> that still the case, or should I just send free-form English text?

I think there are instructions near the beginning of the RM.
I think if you disobey those instructions, your comment
will still get processed and shipped out to the mailing
list.

I think you're not supposed to cc: other addresses
when sending to ada-comment@ada-auth.org.

But Randy is the expert on these procedures.

- Bob



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

* Re: How to access this package written in C?
  2010-04-27  6:52           ` Alex R. Mosteo
@ 2010-04-27 22:29             ` Randy Brukardt
  2010-05-03  8:12               ` Alex R. Mosteo
  0 siblings, 1 reply; 19+ messages in thread
From: Randy Brukardt @ 2010-04-27 22:29 UTC (permalink / raw)


...
>> I use this:
>>
>>     subtype Void_Ptr is System.Address;
>
> I have sometimes used
>
>      type Void is null record;
>      pragma Convention (Void, C);
>      type Void_Ptr is access all Void;
>      pragma Convention (Void_Ptr, C);

Most of the time, I've avoided any version of void* and simply written 
overloadings for each type that I needed (using in out parameters if 
possible, or access parameters if I needed the function result). That only 
works of course when the number of types that you need is limited, and it's 
not as flexible as some more direct mapping.

But void* is exactly the opposite of strong typing, and it simply doesn't 
fit well into the Ada type model. So avoiding it if possible is the best 
approach.

                        Randy.








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

* Re: How to access this package written in C?
  2010-04-27 16:07             ` Robert A Duff
@ 2010-04-27 22:29               ` Randy Brukardt
  0 siblings, 0 replies; 19+ messages in thread
From: Randy Brukardt @ 2010-04-27 22:29 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
news:wccbpd4x4j9.fsf@shell01.TheWorld.com...
> Keith Thompson <kst-u@mib.org> writes:
>
>> I did.  <http://www.ada-auth.org/arm.html> has links to several versions
>> of the Ada 2005 RM.  "RM-Final.pdf" is byte-for-byte identical to the
>> version I'm using, and has the above-quoted text on the title page.
>
> Sorry for the misinformation.
>
>> Thanks, I'll do that.  I seem to recall they expect some particular
>> format for comments (it's been a long time since I've submitted any); is
>> that still the case, or should I just send free-form English text?
>
> I think there are instructions near the beginning of the RM.
> I think if you disobey those instructions, your comment
> will still get processed and shipped out to the mailing
> list.
>
> I think you're not supposed to cc: other addresses
> when sending to ada-comment@ada-auth.org.
>
> But Randy is the expert on these procedures.

Bob got these right this time. :-)

                     Randy.





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

* Re: How to access this package written in C?
  2010-04-27 22:29             ` Randy Brukardt
@ 2010-05-03  8:12               ` Alex R. Mosteo
  0 siblings, 0 replies; 19+ messages in thread
From: Alex R. Mosteo @ 2010-05-03  8:12 UTC (permalink / raw)


Randy Brukardt wrote:

> ...
>>> I use this:
>>>
>>>     subtype Void_Ptr is System.Address;
>>
>> I have sometimes used
>>
>>      type Void is null record;
>>      pragma Convention (Void, C);
>>      type Void_Ptr is access all Void;
>>      pragma Convention (Void_Ptr, C);
> 
> Most of the time, I've avoided any version of void* and simply written
> overloadings for each type that I needed (using in out parameters if
> possible, or access parameters if I needed the function result). That only
> works of course when the number of types that you need is limited, and
> it's not as flexible as some more direct mapping.
> 
> But void* is exactly the opposite of strong typing, and it simply doesn't
> fit well into the Ada type model. So avoiding it if possible is the best
> approach.

I've lived both ways, and I understand your point. In the particular case I 
had in mind, the C side changed too frequently for my own good, so using an 
opaque type and passing the pointer to it to C-side routines was the less 
maintenance-intensive approach. Massaging the C data returns into my own set 
of Ada types worked well, since the trick is hidden from user code.

This reminds me of another thing that bores me about bindings, which is that 
even if you mimic C types with Ada types using convention C, these types are 
not always nice to propagate to client code, so in the end I find myself 
with even more duplicated types.



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

end of thread, other threads:[~2010-05-03  8:12 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-21 16:43 How to access this package written in C? resander
2010-04-21 17:39 ` Dmitry A. Kazakov
2010-04-22 20:12 ` Björn Persson
2010-04-22 21:12 ` Keith Thompson
2010-04-23 12:58   ` resander
2010-04-23 14:15     ` Dmitry A. Kazakov
2010-04-23 14:44     ` John B. Matthews
2010-04-23 15:39       ` John B. Matthews
2010-04-26 18:16     ` Robert A Duff
2010-04-26 19:57       ` Keith Thompson
2010-04-26 21:20         ` Maciej Sobczak
2010-04-27  6:52           ` Alex R. Mosteo
2010-04-27 22:29             ` Randy Brukardt
2010-05-03  8:12               ` Alex R. Mosteo
2010-04-27  0:20         ` Robert A Duff
2010-04-27  1:01           ` Keith Thompson
2010-04-27 16:07             ` Robert A Duff
2010-04-27 22:29               ` Randy Brukardt
2010-04-27  1:31           ` Randy Brukardt

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