โŒ About FreshRSS

Reading view

There are new articles available, click to refresh the page.

Get call stack in string format

Is there a way to print call stack when printing a message ?

I have a procedure:

procedure DoSomething (myParameter : in MyType)
is
  isOk : Boolean := False;
begin
  isOk := FunctionReturningFalseWhenError(myParameter);
  if not isOk
  then
    MyDisplayFunction(GNAT.Source_Info.File & ":" & Positive'Image(GNAT.Source_Info.Line) & ": Error with DoSomething");
  end if;
end DoSomething;

This procedure is called many times and I want to have more information to print (like call stack).

Initialise type from address

I want to initialise a type from a System.address. For example :

generic
    type T_Generic is private;
package MyPackage is
    G_Addr : System.Address;
    procedure Register (myAddr : System.address);
    procedure MyProcedure (myAddr : System.address);
end MyPackage;

package body MyPackage is
    procedure Register(myAddr : System.address)
    is
        G_Addr := myAddr;
    end MyProcedure;

    procedure MyProcedure (myAddr : System.address)
        myVar : T_Generic with address => myAddr;
    is
        if (myAddr = G_Addr)
        then
            -- work with myVar 
        end if;
    end MyProcedure;
end MyPackage;
    

But I cannot compile this piece of code myVar : T_Generic with address => myAddr; :

aspect specification is an Ada 2012 feature

unit must be compiled with -gnat2012 switch

I cannot change compilation's options, how can I do ?

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;
CommonLib.DoStuff(A);

-- Can be used by B :
B : B_Type;
CommonLib.DoStuff(B);

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)
is
    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);
begin
    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 ?

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:
MyRecord.name = "hello               ";
-- Error : expected type T_Name_String_Fixed20 found a string type

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

Define address depending on target

I have a gpr project with 2 targets :

mySources  := "My project files"
case Rules.Target is
    when "CASE1" =>
         mySources := "File1" & mySources 
    when "CASE2" =>
         mySources := "File2"  & mySources 
    when others =>
end case
for Source_Dirs use mySources 

I have File1 containing the variable local_Address :

local_Address : constant System.Address := Function_to_get_Address();

On a commonFile I want to do :

-- Type definition
type My_Array_Type is array (Boolean) of My_Type;

-- Variable definition
My_Array : My_Array_Type;
for My_Array'Address use local_Address; --only for CASE1

How can I write my file2 to have default address ? Or maybe I have to redefine my software design ?

Edit:

In CASE2 I don't want to specify any address.

Create a record with a private part

According to this post, I'v try to do a record with a private part. What I've done :

MyFile.ads :

package MyPackage is
  type T_MyType is tagged private;
private
  type T_MyType_Private_Part;
  type T_MyType_Private_Part_Access is access T_MyType_Pirvate_Part;
  type T_MyType is tagged record
    Toto : Boolean;
  end record
end MyPackage;

MyFile.adb :

package body MyPackage is
   type T_MyType_Private_Part is record
     Private_Toto : Boolean;
   end record
end MyPackage;

But when an other package do MyVar.Toto where MyVar is T_MyType I have the error :

no selector "Toto" for type "T_MyType" defined at MyFile.ads

How can I fix this ?

โŒ