Is there a way to instruct the Ada compiler to select blocks of code?

I would like to instruct the Ada compiler to choose between two different blocks of code depending on the predefined static compiler directives, such as, for example, "DEBUG" or "RELEASE". I would like to do something like this:

if DEBUG then <COMPLEX THIS CODE> end if;

if RELEASE then <COMPLEX DATA OTHER CODE> end if;

C # and other languages ​​offer the #define directive for this. Ada something similar to offer? And if not, how is this done in Hell?

+4
source share
3 answers

Good Ada style - write it in the same way as you, making sure that the objects Debugand Releaseare static.

- , Compilation_Mode, :

package Compilation_Mode is
   Debug   : constant Boolean := False;
   Release : constant Boolean := True;
end Compilation_Mode;

package Compilation_Mode is
   Debug   : constant Boolean := True;
   Release : constant Boolean := False;
end Compilation_Mode;

. ( gprbuild, package Naming .)

+8

, - . , , Pkg , - ( GNAT GPRBuild, ). , , Do_Something, separate:

package body Pkg is 
   -- ...
   procedure Do_Something is separate;
   -- ...
end Pkg;

, . ( ) :

separate (Pkg) procedure Do_Something is
   -- ...
begin
   -- ...
end Do_Something;

, Pkg. , , ( n n = ) .

. . , GPRBuild:

project My_Project is
   -- define legal modes
   type Mode_Type is ("debug", "release");

   -- load mode from environment variable `Mode`, defaulting to "debug"
   Mode : Mode_Type = external ("Mode", "debug");

   -- add directory with appropriate separate implementations
   case Mode is
   when "debug" =>   My_Sources := My_Sources & "src/debug";
   when "release" => My_Sources := My_Sources & "src/release";
   end case;

   -- define where the compiler should load sources from
   for Source_Dirs use My_Sources;

   -- ...
end My_Project;

src :

src
   debug
      pkg-do_something.adb
   release
      pkg-do_something.adb
   pkg.adb
   pkg.ads

. , , ymmv.

+4

Ada does not, but the most popular Ada toolkit (GNAT) includes the gnatprep tool (see here ). Other tool kits may include equivalents.

For instance,

  RCC.RCC_Periph.AHB1ENR           := ($SCL_Enable => 1, others => <>);
  $SCL_GPIO.MODER.Arr ($SCL_Pin)     := 2; -- alternate function
  $SCL_GPIO.OTYPER.OT.Arr ($SCL_Pin) := 1; -- open drain
  $SCL_GPIO.OSPEEDR.Arr ($SCL_Pin)   := 1; -- medium speed
  $SCL_GPIO.PUPDR.Arr ($SCL_Pin)     := 0; -- nopullup, no pulldown
  #if SCL_Pin < 8 then
  $SCL_GPIO.AFRL.Arr ($SCL_Pin)   := 4; -- DocID022152 Rev 6 Table 9
  #else
  $SCL_GPIO.AFRH.Arr ($SCL_Pin)   := 4; -- DocID022152 Rev 6 Table 9
  #end if;

if it is translated using this Makefile fragment

src/i2c1-device.adb: ../i2c/src/i2c-device.adb.pp $(DEFINITION)
    gnatprep                \
      -c -v                 \
      $<                    \
      $@                    \
      $(DEFINITION)

where the file $(DEFINITION)contains

SCL_Enable := GPIOBEN
SCL_GPIO   := GPIO.GPIOB_Periph
SCL_Pin    := 8

leads to

      RCC.RCC_Periph.AHB1ENR           := (GPIOBEN => 1, others => <>);
      GPIO.GPIOB_Periph.MODER.Arr (8)     := 2; -- alternate function
      GPIO.GPIOB_Periph.OTYPER.OT.Arr (8) := 1; -- open drain
      GPIO.GPIOB_Periph.OSPEEDR.Arr (8)   := 1; -- medium speed
      GPIO.GPIOB_Periph.PUPDR.Arr (8)     := 0; -- nopullup, no pulldown
--!       #if SCL_Pin < 8 then
--!       $SCL_GPIO.AFRL.Arr ($SCL_Pin)   := 4; -- DocID022152 Rev 6 Table 9
--!       #else
      GPIO.GPIOB_Periph.AFRH.Arr (8)   := 4; -- DocID022152 Rev 6 Table 9
--!       #end if;
+2
source

Source: https://habr.com/ru/post/1667539/


All Articles