* Preprocessor functionality equivalent ideas needed @ 2003-12-10 20:04 Greg Milford 2003-12-10 21:41 ` Ludovic Brenta ` (4 more replies) 0 siblings, 5 replies; 12+ messages in thread From: Greg Milford @ 2003-12-10 20:04 UTC (permalink / raw) 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 :) Greg ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preprocessor functionality equivalent ideas needed 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-10 22:29 ` Preprocessor functionality equivalent ideas needed Georg Bauhaus ` (3 subsequent siblings) 4 siblings, 1 reply; 12+ messages in thread From: Ludovic Brenta @ 2003-12-10 21:41 UTC (permalink / raw) "Greg Milford" <gregory.a.milford@boeing.com> writes: > 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 :) > > Greg GNAT does have a preprocessor called gnatprep, but it is not part of the language standard. If you cannot or won't use it, the usual way to deal with configuration management issues such as you describe is to write two or more different bodies for a single package specification, and let the build scripts (Makefiles or such) compile one or the other for each particular configuration. Of course, you'll want to isolate all configuration-dependent stuff into a separate package which you keep as small as possible; this is usual software engineering practice. There are various ways to achieve this. For example, assume you have: a.ads the package specification a1.adb package body for target 1 a2.adb package body for target 2 Your makefiles could select one of the *.adb files and symlink it to a.adb; then the compiler finds the proper file and compiles it. This is in fact the approach used by GNAT itself. Another approach could be to simulate a preprocessor with sed or perl scripts. HTH -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 12+ messages in thread
* sed and perl - yuck [Was Re: Preprocessor functionality equivalent ideas needed] 2003-12-10 21:41 ` Ludovic Brenta @ 2003-12-11 17:12 ` Martin Krischik 2003-12-16 0:40 ` Waldek Hebisch 0 siblings, 1 reply; 12+ messages in thread From: Martin Krischik @ 2003-12-11 17:12 UTC (permalink / raw) Ludovic Brenta wrote: > Another approach could be to simulate a preprocessor with sed or perl > scripts. Did that, hated it and wrote AdaCL. If you rather use Ada then perl and find find sed cumbersome you should look at AdaCL. If you disagree: Write a sed line which inserst "OS." bevore every CD_Recorder - but only if it is not allready there. sarDo --serarch="CD_Recorder" --insert-before="OS." *.ad[bs] There is no limit on the amout of text changes you can to with one call the the command. But realy cool thing about AdaCL is that it is a library and sarDo is only a front end to it. If you need something more complex you can write an Ada programm to do it. See http://adacl.sourceforge.net for Details. Complete Source in GNATHTML is available online. Browse the sar* and AdaCL-SAR-* Files. With Regards Martin -- mailto://krischik@users.sourceforge.net http://adacl.sourceforge.net ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: sed and perl - yuck [Was Re: Preprocessor functionality equivalent ideas needed] 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 0 siblings, 1 reply; 12+ messages in thread From: Waldek Hebisch @ 2003-12-16 0:40 UTC (permalink / raw) Martin Krischik (krischik@users.sourceforge.net) wrote: : Ludovic Brenta wrote: : > Another approach could be to simulate a preprocessor with sed or perl : > scripts. : Did that, hated it and wrote AdaCL. If you rather use Ada then perl and find : find sed cumbersome you should look at AdaCL. : If you disagree: Write a sed line which inserst "OS." bevore every : CD_Recorder - but only if it is not allready there. Well, if you have unused chars (say ';' and '#') the task is easy: s/CD_Recorder/;CD_Recorder/g s/OS\.;/OS.#/ s/;CD_Recorder/OS.CD_Recorder/g s/[;#]//g If all chars are used one have to quote first: s/./:&/g s/:C:D:_:R:e:c:o:r:d:e:r/;::C:D:_:R:e:c:o:r:d:e:r/g s/:O:S:\.;:/:O:S:.;#/g s/;::C:D:_:R:e:c:o:r:d:e:r/:O:S:.:C:D:_:R:e:c:o:r:d:e:r/g s/;#:/:/g s/.\(.\)/\1/g I have not put them on sigle line for readability. The above is slightly off-topic, but I think it ilustrates nicely that a sequence of simple steps can give result looking quite different then a single step. In that spirit Ada discourages preprocessors (since complexity grows quite a lot). -- Waldek Hebisch hebisch@math.uni.wroc.pl ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: sed and perl - yuck [Was Re: Preprocessor functionality equivalent ideas needed] 2003-12-16 0:40 ` Waldek Hebisch @ 2003-12-16 20:52 ` Martin Krischik 0 siblings, 0 replies; 12+ messages in thread From: Martin Krischik @ 2003-12-16 20:52 UTC (permalink / raw) Waldek Hebisch wrote: > Martin Krischik (krischik@users.sourceforge.net) wrote: > : Ludovic Brenta wrote: > > : > Another approach could be to simulate a preprocessor with sed or perl > : > scripts. > > : Did that, hated it and wrote AdaCL. If you rather use Ada then perl and > : find find sed cumbersome you should look at AdaCL. > > : If you disagree: Write a sed line which inserst "OS." bevore every > : CD_Recorder - but only if it is not allready there. > > Well, if you have unused chars (say ';' and '#') the task is easy: > > s/CD_Recorder/;CD_Recorder/g > s/OS\.;/OS.#/ > s/;CD_Recorder/OS.CD_Recorder/g > s/[;#]//g > > If all chars are used one have to quote first: > > s/./:&/g > s/:C:D:_:R:e:c:o:r:d:e:r/;::C:D:_:R:e:c:o:r:d:e:r/g > s/:O:S:\.;:/:O:S:.;#/g > s/;::C:D:_:R:e:c:o:r:d:e:r/:O:S:.:C:D:_:R:e:c:o:r:d:e:r/g > s/;#:/:/g > s/.\(.\)/\1/g > I have not put them on sigle line for readability. Cool. But you do prove my point: sed is to compicated. Isn't Ada a lot easier to read then sed: AdaCL.SAR.Filter.List.Append ( C => Filters, Elem => AdaCL.SAR.Filter.Insert.Text.New_Object ( SearchString => "AdaCL.Trace", InsertString => ".. ", Search_At => AdaCL.SAR.Filter.Insert.First, Insert_At => AdaCL.SAR.Filter.Insert.Before)); To much to type? With use and rename you could reduce it to: Append (Flt, IT.New_Object ("AdaCL.Trace", ".. ", First, Before)); But we are Ada programers so we don't do that, do we. > The above is > slightly off-topic, but I think it ilustrates nicely that a sequence > of simple steps can give result looking quite different then a single > step. In that spirit Ada discourages preprocessors (since complexity > grows quite a lot). Yes true. However, in OS dependen programming you might have package which is 90% the same and differ in 10%. Still, I might give some of the ideas here are thought and maybe I get rid of gnatprep. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preprocessor functionality equivalent ideas needed 2003-12-10 20:04 Preprocessor functionality equivalent ideas needed Greg Milford 2003-12-10 21:41 ` Ludovic Brenta @ 2003-12-10 22:29 ` Georg Bauhaus 2003-12-12 5:52 ` Simon Wright 2003-12-11 1:07 ` Jeffrey Carter ` (2 subsequent siblings) 4 siblings, 1 reply; 12+ messages in thread From: Georg Bauhaus @ 2003-12-10 22:29 UTC (permalink / raw) 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preprocessor functionality equivalent ideas needed 2003-12-10 22:29 ` Preprocessor functionality equivalent ideas needed Georg Bauhaus @ 2003-12-12 5:52 ` Simon Wright 0 siblings, 0 replies; 12+ messages in thread From: Simon Wright @ 2003-12-12 5:52 UTC (permalink / raw) Georg Bauhaus <sb463ba@l1-hrz.uni-duisburg.de> writes: > 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. A technique we've found handy is an extension of the "generic signature package" idea, for use when your code won't be written in a generic: generic with procedure Actual_P (I : Integer); with function Actual_Q return Boolean; package Signature is procedure P (I : Integer) renames Actual_P; function Q return Boolean renames Actual_Q; end Signature; That way you don't have to use the names P, Q in the actual package (indeed, the actual subprograms could come from more than one package). -- Simon Wright 100% Ada, no bugs. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preprocessor functionality equivalent ideas needed 2003-12-10 20:04 Preprocessor functionality equivalent ideas needed Greg Milford 2003-12-10 21:41 ` Ludovic Brenta 2003-12-10 22:29 ` Preprocessor functionality equivalent ideas needed Georg Bauhaus @ 2003-12-11 1:07 ` Jeffrey Carter 2003-12-11 13:34 ` Marin David Condic 2003-12-11 5:39 ` Steve 2003-12-11 16:59 ` Martin Krischik 4 siblings, 1 reply; 12+ messages in thread From: Jeffrey Carter @ 2003-12-11 1:07 UTC (permalink / raw) Greg Milford wrote: > 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? Generally, you define a package specification for the functionality you require, then implement different bodies for it for the different situations. -- Jeff Carter "Perfidious English mouse-dropping hoarders." Monty Python & the Holy Grail 10 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preprocessor functionality equivalent ideas needed 2003-12-11 1:07 ` Jeffrey Carter @ 2003-12-11 13:34 ` Marin David Condic 2003-12-11 17:49 ` Jeffrey Carter 0 siblings, 1 reply; 12+ messages in thread From: Marin David Condic @ 2003-12-11 13:34 UTC (permalink / raw) While I agree with the general concept of separate bodies for separate implementation-specific modules, I have occasionally run into situations where it would have been nice if I had a compiler directive of some sort to go one way or another depending on some condition. This is especially true where I might need to keep code portable between two different compilers. Also its a big problem when what needs to be different is in the *specification* of something. (Yes, I know, "One more layer of indirection...." can go fix it - but why should it be so hard?) Maintaining two sets of files has a problem - its two sets of files! :-) You change something in one file & you have to remember to make the update to the other one. You want to give the code off to someone else, you thus have to supply both sets of files and sufficient information to enable them to build it either way. Someone unaware of the parallel paths can really mess things up. Some sort of conditional compilation can simplify matters. (The existence of pragma Assert and pragma Debug in the Gnat compiler attest to at least *some* usefulness to conditional compilation.) I have sometimes been able to simulate conditional compilation by putting code into an if statement with a constant flag. Some compilers will optimize away the unreachable code. But that doesn't help much in declarative parts or in situations where a set of statements is acceptable to one compiler, but not another. I'd hate to see Ada develop into the unholy mess that C is with all of its macros and other confusing garbage, but maybe a couple of pragmas that let alternate versions of the code exist within a single file might not be a bad thing? MDC Jeffrey Carter wrote: > > > Generally, you define a package specification for the functionality you > require, then implement different bodies for it for the different > situations. > -- ====================================================================== Marin David Condic I work for: http://www.belcan.com/ My project is: http://www.jsf.mil/NSFrames.htm Send Replies To: m o d c @ a m o g c n i c . r "Trying is the first step towards failure." -- Homer Simpson ====================================================================== ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preprocessor functionality equivalent ideas needed 2003-12-11 13:34 ` Marin David Condic @ 2003-12-11 17:49 ` Jeffrey Carter 0 siblings, 0 replies; 12+ messages in thread From: Jeffrey Carter @ 2003-12-11 17:49 UTC (permalink / raw) Marin David Condic wrote: > While I agree with the general concept of separate bodies for separate > implementation-specific modules, I have occasionally run into situations > where it would have been nice if I had a compiler directive of some sort > to go one way or another depending on some condition. This is especially > true where I might need to keep code portable between two different > compilers. Also its a big problem when what needs to be different is in > the *specification* of something. (Yes, I know, "One more layer of > indirection...." can go fix it - but why should it be so hard?) There are several ways to deal with needing multiple versions of the spec. Sometimes you can use functions instead of constants: package P is -- Version X Num_Processors : constant := 4; end P; package P is -- Version Y Num_Processors : constant := 256; end P; becomes package P is function Num_Processors return Positive; end P; Functions are sometimes not acceptable because the value needs to be static. Sometimes you can have multiple versions with different names, and use renaming to select the appropriate one: package P_X is Num_Processors : constant := 4; Directory_Separator : constant Character := '\'; end P_X: package P_Y is Num_Processors : constant := 256; Directory_Separator : constant Character := '/'; end P_Y; with P_X; package P renames P_X; Now the values in P are static. And while another layer of information hiding may be harder in the short run, it's almost always easier in the long run. -- Jeff Carter "Sir Lancelot saves Sir Gallahad from almost certain temptation." Monty Python & the Holy Grail 69 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preprocessor functionality equivalent ideas needed 2003-12-10 20:04 Preprocessor functionality equivalent ideas needed Greg Milford ` (2 preceding siblings ...) 2003-12-11 1:07 ` Jeffrey Carter @ 2003-12-11 5:39 ` Steve 2003-12-11 16:59 ` Martin Krischik 4 siblings, 0 replies; 12+ messages in thread From: Steve @ 2003-12-11 5:39 UTC (permalink / raw) Support for multiple configurations is not built into the language, but many development environments do. What development environment are you using? Steve (The Duck) "Greg Milford" <gregory.a.milford@boeing.com> wrote in message news:Hpp3r9.6L0@news.boeing.com... > 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 :) > > Greg > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preprocessor functionality equivalent ideas needed 2003-12-10 20:04 Preprocessor functionality equivalent ideas needed Greg Milford ` (3 preceding siblings ...) 2003-12-11 5:39 ` Steve @ 2003-12-11 16:59 ` Martin Krischik 4 siblings, 0 replies; 12+ messages in thread From: Martin Krischik @ 2003-12-11 16:59 UTC (permalink / raw) 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 :) Some compilers do provide a preprocessor. GNAT for expample. Differenz to C ist that GNAT writes the file to the disk. Well an extra file to take up space but very handy when it comes to debugging. Also, you can distribute the preprocessed file to those ada users without. If you don't use GNAT you might want to take a look at AdaCL which comes with a Text search an replace Library powerfull enough to convert normal booch components into booch components for indefinite elements. Last not least: Most c compiler can be told to just do the preprocessing and then output there results into a file. With Regards Martin -- mailto://krischik@users.sourceforge.net http://adacl.sourceforge.net ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2003-12-16 20:52 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 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 ` Preprocessor functionality equivalent ideas needed Georg Bauhaus 2003-12-12 5:52 ` 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
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox