comp.lang.ada
 help / color / mirror / Atom feed
From: emery@goldfinger.mitre.org (David Emery)
Subject: Re: Rocket Science?
Date: 8 Dec 94 16:23:14
Date: 1994-12-08T16:23:14+00:00	[thread overview]
Message-ID: <EMERY.94Dec8162314@goldfinger.mitre.org> (raw)
In-Reply-To: Bob Crispen's message of Thu, 8 Dec 1994 11:13:07 CST

The 'right way' to implement this is to use an enumeration type, but
to hide the mapping/representation.

There's no guarantee that AF_UNSPEC = 0 and/or AF_UNIX = 1 and/or
AF_UNSPEC > AF_UNIX.  In fact, I've seen situations where the ordering
of #define values was significantly different on different machines
for the same header file.

When you specify an enumeration type, you specify the ordering of the
values.  If the underlying C binding does not 'respect' this ordering
(and there's no particular requrement that it do so), then you're in
very serious trouble when you port the binding.  The package
specification has to change, and who knows the ramifications of this
change.  

Additionally, I've encountered problems with the size of enumeration
types.  Some implementations have rejected a size clause for an
enumeration type (I won't mention any names here, but it's a compiler
that otherwise has gotten a lot of 'respect'...) when the request size
is greater than what the compiler wants to allocate.  When this happens,
again you're in serious trouble.

So here's how I handle this particular situation:

from C:

#define AF_UNSPEC 0
#define AF_UNIX 1

(void) <some_C_call> (dom);
	int dom; 
{...};

package spec:
  package <whatever> is

    type Domains_And_Addresses_Families is (
      AF_UNSPEC,             -- Unspecified
      AF_UNIX,               -- Unix internal protocols...
	...);

    procedure <some_Ada_call> (the_domain : Domains_And_Addresses_Families);

  end <whatever>;


package body
  
  with C_Types;	-- Ada83 analogy to Ada95 package Interfaces.C
  package body <whatever> is

    package C_Interfaces is
      
      procedure <some_C_call> (dom : C_Types.int);
      pragma interface (C, <some_C_call>);

      LAST : constant C_Types.int := <value of last #define>;
      domains_to_int : constant array 	-- note anonymous array object here 
			(domains_and_adresses_families)
		of C_Types.int
		     :=  (AF_UNSPEC => 0,
			  AF_UNIX => 1,
			  ...);
      int_to_domains : constant array
			(C_Types.int range 0..last)
		of domains_and_adresses_families
		     := (0 => AF_UNSPEC,
			 1 => AF_UNIX,
			 ...);

    end C_Interfaces;

    procedure <some_Ada_call> (the_domain : Domains_And_Addresses_Families)
    is
    begin
      C_Interfaces.<some_C_call> 
		(dom => C_Interfaces.domains_to_int (the_domain));
    end <some_Ada_call>;

  end <whatever>;

The reason for the nested package in the body is so I can use the
exact C function name in the nested package without any overloading
problems for operations defined in the parent package.  (In Ada95,
would this be a good place for a private child package?)

If the integer values aren't contiguous, then you can write a simple
function 
	function int_to_domains (int : C_Types.int) 
	    return domains_and_addreses_families;
that does the reverse mapping.  The nice thing is that this change in
package C_interfaces is completely transparent to the rest of the
implementation.  (When used on the 'right hand side', array indexing
and function calls look the same.)

---------------

In summary, it's not hard to cobble up something that works for a
given Ada/C/API implementation.  It IS hard to define an Ada binding
that is portable (at least at the package specification level) across
multiple Ada/C/API trios.  I've been at this for 10 years, and I'm
still learning what works and what doesn't work.

				dave

p.s.  For more information on how to do Ada bindings "right" , see the
POSIX/Ada rationale (IEEE Std 1003.5-1992), and my paper in the
proceedings of TRI-Ada '90 on my prototype implementation of
POSIX/Ada.  Since the TRI-Ada '90 paper, I've learned a bunch more
tricks, etc, but I haven't had the chance to write a successor paper.
--
--The preceeding opinions do not necessarily reflect the opinions of
--The MITRE Corporation or its sponsors. 
-- "A good plan violently executed -NOW- is better than a perfect plan
--  next week"                                      George Patton
-- "Any damn fool can write a plan.  It's the execution that gets you
--  all screwed up"                              James Hollingsworth
-------------------------------------------------------------------------



      reply	other threads:[~1994-12-08 16:23 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1994-12-08 17:13 Rocket Science? Bob Crispen
1994-12-08 16:23 ` David Emery [this message]
replies disabled

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