From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,d3037f71d9d26da1 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-12-10 14:29:54 PST Path: archiver1.google.com!news2.google.com!newsfeed2.dallas1.level3.net!news.level3.com!zeus.visi.com!priapus.visi.com!orange.octanews.net!news.octanews.net!news-out.visi.com!petbe.visi.com!news.tele.dk!news.tele.dk!small.news.tele.dk!news-fra1.dfn.de!news-ham1.dfn.de!news.uni-hamburg.de!cs.tu-berlin.de!uni-duisburg.de!not-for-mail From: Georg Bauhaus Newsgroups: comp.lang.ada Subject: Re: Preprocessor functionality equivalent ideas needed Date: Wed, 10 Dec 2003 22:29:54 +0000 (UTC) Organization: GMUGHDU Message-ID: References: NNTP-Posting-Host: l1-hrz.uni-duisburg.de X-Trace: a1-hrz.uni-duisburg.de 1071095394 20438 134.91.1.34 (10 Dec 2003 22:29:54 GMT) X-Complaints-To: usenet@news.uni-duisburg.de NNTP-Posting-Date: Wed, 10 Dec 2003 22:29:54 +0000 (UTC) User-Agent: tin/1.5.8-20010221 ("Blue Water") (UNIX) (HP-UX/B.11.00 (9000/800)) Xref: archiver1.google.com comp.lang.ada:3339 Date: 2003-12-10T22:29:54+00:00 List-Id: Greg Milford 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