comp.lang.ada
 help / color / mirror / Atom feed
From: Georg Bauhaus <sb463ba@l1-hrz.uni-duisburg.de>
Subject: Re: Preprocessor functionality equivalent ideas needed
Date: Wed, 10 Dec 2003 22:29:54 +0000 (UTC)
Date: 2003-12-10T22:29:54+00:00	[thread overview]
Message-ID: <br86p2$jum$1@a1-hrz.uni-duisburg.de> (raw)
In-Reply-To: Hpp3r9.6L0@news.boeing.com

Greg Milford <gregory.a.milford@boeing.com> wrote:
: Hello
: 
: I checked the FAQ for this group and did not get an answer to this.  I know
: Ada does not have a preprocessor, so how should I go about maintaining
: changes to a common code base that needs to be built under two different
: configurations?
: 
: Am I left with using Global variables or has a better method been used?  I
: am new to Ada so be kind :)

If configurations also refers to changes to effective source code
adapted to some (perhaps OS-) specifics, read on, otherwise please
forgive the many words.

As with a preprocessor, you can exchange parts of the program (a
package body for example, or a function body, ...), and the other
parts of the program do not have to be changed. But this can be
done by supplying one or another implemention to the compiler as a
compilation unit for the part in question. The tools will help, for
example by looking for program units in different configuration
specific directories.

But you can also use the language feature "renaming".

For the sake of an example, if you specify the function

function add_one (n: Natural) return Natural;
--  result = n + 1

and you might want to provide different implementations
(just as if you wanted the same function call to work in different
configurations, with the implementation changed).
One implementation of what is specified with add_one might be

   function add_one_using_plus (n: Natural) return Natural is
   begin
      return n + 1;
   end add_one_using_plus;

Another might use the 'Succ attribute of type Natural:

   function add_one_using_succ (n: Natural) return Natural is
   begin
      return Natural'succ(n);
   end add_one_using_succ;

What remains to do is to choose one of these implementions as
implementation for add_one. This can be done writing

   function add_one (n: Natural) return Natural
     renames add_one_using_plus;

(or
   function add_one (n: Natural) return Natural
     renames add_one_using_succ;
if you want the other implementation).

If some other part of your program now has "add_one(42)", 
the implementation of the renaming will be in effect.
However, one does not have to do that for each and every system
specific subprogram.

Instead you could collect the specifications of procedures and
functions that are likely to be system dependent in a package
called something like Operating_System_Specific. Then, you
create packages for Windows, Mac, Unix, VMS, whatever, providing
the same subprograms, adapted for each OS (or configuration, if
that requires different implementations). In order to use system
dependent subprograms, the rest of your program only needs to know
about the package Operation_System_Specific. (That is, you write
"with Operating_System_Specific;" before program units that need this
package's subprograms, no matter on what OS/configuration the program
is to run.)

Then rename the package written for the target operating system.
This time the "renames" will apply (sort of) to what is in the
packages, collectively.

with Windows_Specific;
package Operating_System_Specific renames Windows_Specific;

Now the program units that "with Operating_System_Specific;" will
effectively use the facilities of package Windows_Specific without
"knowing" this.
If you want your program to run on Unix, the only change would be

with Unix_Specific;
package Operating_System_Specific renames Unix_Specific;

in place of the two lines above.

There are two more ways I know of, one uses generics for listing
the configuration-specific things that your program needs. The other
uses tagged types, that is O-O types. Again for OSs,

generic
   type OS is private;

   with function available_disk_space (op_sys: OS) return Natural;
   --  free blocks

package System_Dependent is
   procedure Installation_Setup;
   procedure Unpack;
end System_Dependent;

If you now write

with BSD;
package Everywhere_Working_Installation is
  new Specifics (available_disk_space => BSD.free_blocks_count);

you can use the procedures in package Everywhere_Working_Installation
in your program.

The O-O type:

package Installation is

   type OS is abstract tagged private;
   --  an operating system abstraction

   procedure Installation_Setup(op_sys: OS) is abstract;
   procedure Unpack(op_sys: OS) is abstract;

private
   type OS is abstract tagged
      record
        --  ...
      end record;

end Installation;

You derive new concrete types from OS,

   type Windows is new OS with private;

and override the two procedures to work with Windows:

   procedure Installation_Setup(op_sys: Windows);
   procedure Unpack(op_sys: Windows);

After that you can have a variable (or constant) of one of the derived
types,

   my_system: Unix;

and from here onwards use the procedures defined with the type.
The correct version of Installation_Setup and Unpack will be chosen
depending on what type my_system actually is, and the translation
tools need not link the overriden procedures for other OSs.


If you are out for more, you can combine these methods (and
possibly more) :-)

my 2c

-- Georg




  parent reply	other threads:[~2003-12-10 22:29 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-12-10 20:04 Preprocessor functionality equivalent ideas needed Greg Milford
2003-12-10 21:41 ` Ludovic Brenta
2003-12-11 17:12   ` sed and perl - yuck [Was Re: Preprocessor functionality equivalent ideas needed] Martin Krischik
2003-12-16  0:40     ` Waldek Hebisch
2003-12-16 20:52       ` Martin Krischik
2003-12-10 22:29 ` Georg Bauhaus [this message]
2003-12-12  5:52   ` Preprocessor functionality equivalent ideas needed Simon Wright
2003-12-11  1:07 ` Jeffrey Carter
2003-12-11 13:34   ` Marin David Condic
2003-12-11 17:49     ` Jeffrey Carter
2003-12-11  5:39 ` Steve
2003-12-11 16:59 ` Martin Krischik
  -- strict thread matches above, loose matches on Subject: below --
2003-12-11 12:52 Lionel.DRAGHI
2003-12-11 15:51 Lionel.DRAGHI
replies disabled

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