Normal view

There are new articles available, click to refresh the page.
Before yesterdayNews from the Ada programming language world

Question about setting up the dev environment in VScode

Hey all,

I'm new to the Ada programming language. I plan to learn this language well and help others learn it. I really like what I understand about the design. I'm also hoping to get into Embedded Systems, which is how I first heard about Ada.

What are your recommendations for setting up a dev environment? Are things such as alire important to have to use the language? I don't really understand the difference between SPARK and just regular Ada.

Thanks for helping me understand better.

submitted by /u/sanforsaken
[link] [comments]

Declare function with undefined type

I want to create a library taking a kind of generic type (or something like this, I don't know how it is called).

What I have :

package A is
    type A_Type is record
        Field : Field_Type;
        A_Access : access A;
    end record;
end A;

package B is
    type B_Type is record
        OtherField : OtherField_Type;
        B_Access : access B;
    end record;
end B;

I want to create a common library taking A_Type or B_Type as parameters. My library cannot include A or B. It will be something like :

package CommonLib is
    procedure DoStuff (Param : Generic_Type);
end CommonLib;

-- Can be used by A :
A : A_Type;

-- Can be used by B :
B : B_Type;

How can I do ?

Import C function with void* parameter

I want to import a C function in Ada.

There is the C part :

void Register(const void *ctxt)
   saved_ctxt = ctxt; // This is a global variable 

void Send_Trace(const void *ctxt,
                const char *msg)
    if (saved_ctxt == ctxt)
        // Do stuff with msg

Now I want to use this function in a Ada program. There is my code :

type T_void is tagged null record;
package C renames Interfaces.C;

procedure Send_Trace_From_C(ctxt : in T_void;
                            msg  : in String)
    pragma Convention(C, T_void);

    procedure send_trace (A: out T_void; B : C.Strings.char_ptr);
    pragma import (C, Send_Trace, "Send_Trace");

    Char_ptr : C.Strings.char_ptr := C.Strings.New_String(msg);
    send_trace (ctxt, Char_ptr);
end Send_Trace_From_C;

But I have errors :

pragma "convention" argument must be in same declarative part

warning "send_trace" involves a tagged type which does not correspond to any C type

How can I use a *void in Ada ?

Is Ada truly seriously much more complex than Pascal?

15 September 2023 at 16:34

I expect to get a lot of negative response here, maybe even insulates, but I honestly don't mean any offence.

I have been an imbedded developer for a few decades, about equally C, C++ and Ada.

A few days ago I was chatting with an Ada dev, whom I am unlikely to see again. I was bitching about the complexity of C++ and said that I liked Ada as it was "just Pascal with a few twiddly bits".

He may have felt insulted, or defensive, as he immediately replied "oh, no, it's much more complex than that", but didn't have a chance to explain why.

We were talking about Ada 95, BTW.

Again, I did not mean to offend either him or you; I am more concerned that I have been missing something that could make me a better developer.

I realize that there are minor language feature differences, but did I miss a paradigm shift? Please don't flame me - pretty please?

submitted by /u/jamawg
[link] [comments]

String from integer8

I'm using a library in ada which contains many types :

type Int8 is range -8 ** 7 .. 2 ** 7 - 1;
subtype T_Name_String is Int8;
type T_Name_String_Fixed20 is array (range 1..20) of T_Name_String ;

And there is a record with :

type The_Record is record
   name : T_Name_String_Fixed20;
   -- and others
end record;

I can't change that, I don't know why there are using Int8 for ada strings but I'm not able to initiate the field name. I've try :

-- First try: = "hello               ";
-- Error : expected type T_Name_String_Fixed20 found a string type

-- Second try
Ada.Strings.Fixed.Move(Target =>;
                       Source => "hello               "

Gprbuild can’t find tool chain for Ada

Hi, On my Fedora 37 64-bit (Linux 6.3.8-100.fc3) I have two gnat installed, one for the host in /usr/bin and one for ARM targets in /opt/gnat/arm-elf/bin.

I removed /opt/gnat/bin from my PATH to avoid any complication. So now I have /usr/bon in my path, when I run which gnat, it does point to /usr/bin/gnat.

gnat -v gives me: GNAT 12.3.1 20230508 (Red Hat 12.3.1-1)

When I run gprbuild on my project (either with the terminal or through Gnat studio) I get: gprconfig: Can’t find a native tool chain for language ‘ada’ No compiler for language Ada

So I try to run gprconfig: gprconfig has found the following compilers on your PATH. Only those matching the target and the selected compilers are displayed. 1. GCC-ASM for Asm in /usr/bin version 12.3.1 2. GCC-ASM for Asm2 in /usr/bin version 12.3.1 3. GCC-ASM for Asm_Cpp in /usr/bin version 12.3.1 4. LD for Bin_Img in /usr/bin version 2.38-27.fc37 5. GCC for C un /usr/bin version 12.3.1

alr toolchain gives me: gprbuild 22.0.0 Available Detected at /usr/local/bin/gprbuild gnat_external 12.3.1 Available Detected at /usr/bin

Although Alire detects it (so it would probably work with it), I don’t want to use it, I don’t like it.

How can gprbuild see my gnat?

Thanks for your help!

submitted by /u/louis_etn
[link] [comments]

AUnit - Usefullness of the `Test_Caller` package

There seem to be two different ways to do the same thing when using the AUnit library:

Using the AUnit.Test_Cases.Test_Case type, creating some function tests, then register each tests with the AUnit.Test_Cases.Register_Tests function. We can then add this Test_Case to a Suite using the function AUnit.Test_Suites.Add_Test.

There some example of this:

(Surprisingly, there no examples using this way in the AUnit repository.)

The other way is to use the AUnit.Test_Fixtures.Test_Fixture type, creating some function tests. These tests can then be added to a Suite using the generic package AUnit.Test_Caller with the functions AUnit.Test_Suites.Add_Test and AUnit.Test_Caller.Create.

I can see way of using Test_Caller in:

The only difference I can see is that, when using the AUnit.Test_Cases.Test_Case, you can override the Set_Up_Case, Set_Up, Tear_Down and Tear_Down_Case functions. While with the AUnit.Test_Fixtures.Test_Fixture you can only override the Set_Up and Tear_Down functions (because the tests are not group under a Test_Case).

Appart from that, I don't really see much difference.

So, what is the use of the AUnit.Test_Fixtures.Test_Fixture type with the generic package AUnit.Test_Caller ? Why would use this over the (simpler ?) AUnit.Test_Cases.Test_Case type ?

Every example I have seen in one format can be transformed into the other (the Set_Up_Case and Tear_Down_Case set appart). Could give an example which use one but cannot be done by the other ?

How do I ensure a record's discriminant value is equal to another record component's value?

I have a File_Reader composed of two records, File and Buffer. I would like to ensure both Records always have a valid buffer size when initialized, i.e. Data_File.IO_Buffer_Size is equal to Data_In.Size.

I couldn't find a way of initializing a record component's value with another record's component value or discriminant, so I figured I would at least apply a static predicate which was unsuccessful. Using dynamic predicate as,an alternative poses issues in a LightRuntime environment.

I could easily add a Buffer_Size discriminant to File_Reader, but I would like to explore alternative solutions. Lastly, the record layouts must be preserved since they are memory mapped using representation clauses which are not shown:

type File is 
      Name           : String;
      IO_Buffer_Size : Buffer_Size;
   end record; 

type Buffer(Size : Buffer_Size := 300)  is         
      Pos   : Buffer_Size := 0;
      Value : String(1 .. Size);
   end record;

type File_Reader(Name : String) is 
       Data_In      : Buffer;    
       Data_File    : File := (Name, Data_In.Size); -- Won't work
   end record;

object "Antal_rader" cannot be used before end of its declaration

OBS! My code is written with Swedish terms.

I have to code a VAT table but i have run in to some problems concerning Floats and the way that it rounds values. At first, I was using a while loop but that didn't work since it (after a while) got too affected by the float-issue.

I created a For-loop instead which in theory should work better. However. I'm having an issue with one of my variables.

The variable "Antal_Rader" is being declared before the For-loop but i still get the error code: "object "Antal_rader" cannot be used before end of its declaration"


with Ada.Text_IO;              use Ada.Text_IO;
with Ada.Float_Text_IO;        use Ada.Float_Text_IO;

procedure Momstabellen is
   Forsta_Pris : Float;
   Sista_Pris : Float;
   Steglangd : Float;
   Momsprocent : Float;
   Moms : Float;
   Antal_Rader : Float;
   Nuvarande_Rad : Float;
   -- 1. Ta emot alla variabler för momstabellen:
   Put("Första pris: ");
   while Forsta_Pris < 0.0 loop
      Put("Felaktigt värde!");
      Put("Första pris: ");
    end loop;
   Put("Sista pris: ");
   while Sista_Pris < Forsta_Pris loop
      Put("Felaktigt värde!");
      Put("Sista pris: ");
   end loop;
   Put("Steg: ");
   while Steglangd < 0.0 loop
      Put("Felaktigt värde!");
      Put("Steg: ");
   end loop;
   Put("Momsprocent: ");
   while Momsprocent < 0.0 or Momsprocent > 100.0 loop
      Put("Felaktigt värde!");
      Put("Momsprocent: ");
   end loop;

-- 2. Skapa en layout för momstabellen:
   Put("============ Momstabell ============");
   Put("Pris utan moms  Moms   Pris med moms");

Issue lies here:


   Antal_Rader := (Sista_Pris - Forsta_Pris)/Steglangd;
   for I in 0 .. Antal_Rader loop
      Nuvarande_Rad := Antal_Rader * Steglangd + Forsta_Pris;   
      Moms := Nuvarande_Rad/100.0 * Momsprocent;
      Put(Nuvarande_Rad, Fore=> 6, Aft => 2, Exp => 0);
      Put(Moms, Fore => 8, Aft => 2, Exp => 0);
      Put(Nuvarande_Rad + Moms, Fore => 9, Aft => 2, Exp => 0);
   end loop;
end Momstabellen;

I have tried changing the first line of the For-loop and also tried changing the position of "Antal_Rader" but nothing has worked.

I am quite new to this so i can't think of many more things to do.