comp.lang.ada
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* Re: ALR unable to get many packages
  @ 2023-08-06 23:29  3%             ` Kenneth Wolcott
  0 siblings, 0 replies; 200+ results
From: Kenneth Wolcott @ 2023-08-06 23:29 UTC (permalink / raw)


Hi Simon;

An attempt to "get" aws follows along with all of my openssl installed packages from MacPorts.

alr --no-color get aws
Warning:
Warning:    New solution is incomplete.
Warning:    +i gnat     13.1.0 (new,installed,gnat_external)
Warning:    +  gnatcoll 23.0.0 (new)
Warning:    +  libgpr   23.0.0 (new,indirect)
Warning:    +  make     3.81.0 (new)
Warning:    +~ openssl  *      (new,external)
Warning:    +  xmlada   23.0.0 (new)
Warning:
Warning: Could not find a complete solution for aws=23.0.0
Build will fail unless externals are made available, do you want to continue?
[Y] Yes  [N] No  (default is No) y
Note: Deploying aws=23.0.0...
########################################################################################################################### 100.0%
warn: Generating possibly incomplete environment because of missing dependencies
Note: Deploying make=3.81.0...
Note: Deploying xmlada=23.0.0...
   -=O#-    #     #       #
Note: Running post_fetch actions for xmlada=23.0.0...
checking build system type... aarch64-apple-darwin22.6.0
checking host system type... aarch64-apple-darwin22.6.0
checking target system type... aarch64-apple-darwin22.6.0
checking whether gnat can build shared libs... yes
checking for a BSD-compatible install... /opt/local/bin/ginstall -c
checking whether ln -s works... yes
configure: creating ./config.status
config.status: creating xmlada_shared.gpr
config.status: creating Makefile
config.status: creating tests/dom/default.gpr
Note: Deploying libgpr=23.0.0...
   -=O#-    #     #       #
Note: Deploying gnatcoll=23.0.0...
   -=#=- #     #       #
Note: Running post_fetch actions for aws=23.0.0...
sed: illegal option -- s
usage: sed script [-Ealnru] [-i extension] [file ...]
	sed [-Ealnu] [-i extension] [-e script] ... [-f script_file] ... [file ...]
sed: illegal option -- s
usage: sed script [-Ealnru] [-i extension] [file ...]
	sed [-Ealnu] [-i extension] [-e script] ... [-f script_file] ... [file ...]
Bind
   [gprbind]      xoscons.bexch
   [Ada]          xoscons.ali
Link
   [link]         xoscons.adb
Setup OS specific definitions
aws-os_lib-tmplt.c:324:24: error: invalid operand for inline asm constraint 'i'
/*NOGEN*/ asm volatile("\n->CND:%0:" "SIN_FAMILY_OFFSET" ":%1:" "sin_family offset in record" : : "i" (324), "i" ((int) (uintptr_t)((uintptr_t)&sa.sin_family - (uintptr_t)&sa)));;
                       ^
aws-os_lib-tmplt.c:343:24: error: invalid operand for inline asm constraint 'i'
/*NOGEN*/ asm volatile("\n->CND:%0:" "AI_FAMILY_OFFSET" ":%1:" "???" : : "i" (343), "i" ((int) (uintptr_t)((uintptr_t)&ai.ai_family - (uintptr_t)&ai)));;
                       ^
aws-os_lib-tmplt.c:344:24: error: invalid operand for inline asm constraint 'i'
/*NOGEN*/ asm volatile("\n->CND:%0:" "AI_CANONNAME_OFFSET" ":%1:" "???" : : "i" (344), "i" ((int) (uintptr_t)((uintptr_t)&ai.ai_canonname - (uintptr_t)&ai)));;
                       ^
aws-os_lib-tmplt.c:345:24: error: invalid operand for inline asm constraint 'i'
/*NOGEN*/ asm volatile("\n->CND:%0:" "AI_ADDR_OFFSET" ":%1:" "???" : : "i" (345), "i" ((int) (uintptr_t)((uintptr_t)&ai.ai_addr - (uintptr_t)&ai)));;
                       ^
aws-os_lib-tmplt.c:233:17: error: unexpected token at start of statement
asm volatile("\n->TXT:%0:" "--  This is the version for " "arm64-apple-darwin22.6.0" : : "i" (233));
                ^
<inline asm>:2:1: note: instantiated into assembly here
->TXT:233:--  This is the version for arm64-apple-darwin22.6.0
^
aws-os_lib-tmplt.c:234:17: error: unexpected token at start of statement
asm volatile("\n->TXT:%0:" "" : : "i" (234));
                ^
<inline asm>:2:1: note: instantiated into assembly here
->TXT:234:
^
aws-os_lib-tmplt.c:240:17: error: unexpected token at start of statement
asm volatile("\n->TXT:%0:" "with Interfaces.C.Strings;" : : "i" (240));
                ^
<inline asm>:2:1: note: instantiated into assembly here
->TXT:240:with Interfaces.C.Strings;
^
aws-os_lib-tmplt.c:241:17: error: unexpected token at start of statement
asm volatile("\n->TXT:%0:" "with System;" : : "i" (241));
                ^
<inline asm>:2:1: note: instantiated into assembly here
->TXT:241:with System;
^
aws-os_lib-tmplt.c:243:17: error: unexpected token at start of statement
asm volatile("\n->TXT:%0:" "with GNAT.OS_Lib;" : : "i" (243));
                ^
<inline asm>:2:1: note: instantiated into assembly here
->TXT:243:with GNAT.OS_Lib;
^
aws-os_lib-tmplt.c:272:17: error: unexpected token at start of statement
asm volatile("\n->C:%0:" "Target_OS" ":" "OS_Type" ":" "Other_OS" ":" "" : : "i" (272));
                ^
<inline asm>:2:1: note: instantiated into assembly here
->C:272:Target_OS:OS_Type:Other_OS:
^
aws-os_lib-tmplt.c:281:17: error: unexpected token at start of statement
asm volatile("\n->C:%0:" "Target_Name" ":" "String" ":" "arm64-apple-darwin22.6.0" ":" "" : : "i" (281));
                ^
<inline asm>:2:1: note: instantiated into assembly here
->C:281:Target_Name:String:arm64-apple-darwin22.6.0:
^
aws-os_lib-tmplt.c:310:17: error: unexpected token at start of statement
asm volatile("\n->CND:%0:" "SIZEOF_unsigned_int" ":%1:" "Size of unsigned int" : : "i" (310), "i" ((int) sizeof (unsigned int)));
                ^
<inline asm>:2:1: note: instantiated into assembly here
->CND:310:SIZEOF_unsigned_int:4:Size of unsigned int
^
aws-os_lib-tmplt.c:313:17: error: unexpected token at start of statement
asm volatile("\n->CND:%0:" "SIZEOF_fd_set" ":%1:" "fd_set" : : "i" (313), "i" ((int) (sizeof (fd_set))));;
                ^
<inline asm>:2:1: note: instantiated into assembly here
->CND:313:SIZEOF_fd_set:128:fd_set
^
aws-os_lib-tmplt.c:314:17: error: unexpected token at start of statement
asm volatile("\n->CND:%0:" "FD_SETSIZE" ":%1:" "Max fd value" : : "i" (314), "i" ((int) 1024));;
                ^
<inline asm>:2:1: note: instantiated into assembly here
->CND:314:FD_SETSIZE:1024:Max fd value
^
aws-os_lib-tmplt.c:320:17: error: unexpected token at start of statement
asm volatile("\n->CND:%0:" "SIZEOF_sin_family" ":%1:" "Size of sa.sin_family" : : "i" (320), "i" ((int) sizeof (sa.sin_family) * 8));;
                ^
<inline asm>:2:1: note: instantiated into assembly here
->CND:320:SIZEOF_sin_family:8:Size of sa.sin_family
^
aws-os_lib-tmplt.c:353:17: error: unexpected token at start of statement
asm volatile("\n->CND:%0:" "SIZEOF_nfds_t" ":%1:" "Size of nfds_t" : : "i" (353), "i" ((int) sizeof (nfds_t) * 8));;
                ^
<inline asm>:2:1: note: instantiated into assembly here
->CND:353:SIZEOF_nfds_t:32:Size of nfds_t
^
aws-os_lib-tmplt.c:362:17: error: unexpected token at start of statement
asm volatile("\n->CND:%0:" "SIZEOF_pollfd_events" ":%1:" "Size of pollfd.events" : : "i" (362), "i" ((int) sizeof (v_pollfd.events) * 8));;
                ^
<inline asm>:2:1: note: instantiated into assembly here
->CND:362:SIZEOF_pollfd_events:16:Size of pollfd.events
^
aws-os_lib-tmplt.c:373:17: error: unexpected token at start of statement
asm volatile("\n->CND:%0:" "SIZEOF_fd_type" ":%1:" "Size of socket fd" : : "i" (373), "i" ((int) sizeof (v_pollfd.fd) * 8));;
                ^
<inline asm>:2:1: note: instantiated into assembly here
->CND:373:SIZEOF_fd_type:32:Size of socket fd
^
aws-os_lib-tmplt.c:381:17: error: unexpected token at start of statement
asm volatile("\n->CND:%0:" "SIZEOF_socklen_t" ":%1:" "Size of socklen_t" : : "i" (381), "i" ((int) sizeof (socklen_t) * 8));;
                ^
<inline asm>:2:1: note: instantiated into assembly here
->CND:381:SIZEOF_socklen_t:32:Size of socklen_t
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
raised raised ADA.IO_EXCEPTIONS.NAME_ERROR : aws-os_lib-tmplt.s: No such file or directory

make[1]: *** [../.build/arm64-apple-darwin22.6.0/debug/../setup/src/aws-os_lib.ads] Error 1
make: *** [config_setup] Error 2
ERROR: A post-fetch action failed, re-run with -vv -d for details

-----------------------------------------------
port installed | grep openssl
  openssl @3_8
  openssl @3_9
  openssl @3_9+universal
  openssl @3_10+universal
  openssl @3_10
  openssl @3_11
  openssl @3_12 (active)
  openssl3 @3.0.7_0+legacy
  openssl3 @3.0.7_2+legacy
  openssl3 @3.0.8_1+legacy
  openssl3 @3.0.8_1+legacy+universal
  openssl3 @3.1.0_0+universal
  openssl3 @3.1.0_1
  openssl3 @3.1.0_1+universal
  openssl3 @3.1.0_2+universal
  openssl3 @3.1.0_3+universal
  openssl3 @3.1.0_3
  openssl3 @3.1.1_0
  openssl3 @3.1.2_0 (active)
  openssl10 @1.0.2u_4 (active)
  openssl11 @1.1.1s_0
  openssl11 @1.1.1t_0
  openssl11 @1.1.1t_1
  openssl11 @1.1.1u_1
  openssl11 @1.1.1v_1 (active)
  py310-openssl @21.0.0_0
  py310-openssl @22.1.0_0
  py310-openssl @23.0.0_0
  py310-openssl @23.2.0_0 (active)
  py311-openssl @23.0.0_0
  py311-openssl @23.2.0_0 (active)
  qt5-qtbase @5.15.6_1+openssl
  qt5-qtbase @5.15.8_0+openssl
  qt5-qtbase @5.15.8_1+openssl
  qt5-qtbase @5.15.9_0+openssl
  qt5-qtbase @5.15.10_0+openssl (active)
  qt6-qtbase @6.4.3_1+openssl (active)
-----------------------------------------------

That reminds me, I need to uninstall those "universal" packages...

Thanks, 
Ken

^ permalink raw reply	[relevance 3%]

* Re: Plugin with controlled variable for initialization.
  2022-02-02 17:21  5% Plugin with controlled variable for initialization hreba
@ 2022-02-02 18:05  0% ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2022-02-02 18:05 UTC (permalink / raw)


On 2022-02-02 18:21, hreba wrote:
> For the plugin scheme in my actual program I worked along the 
> corresponding gnat example, but while the original works, mine doesn't. 
> So I boiled it down to a minimum.
> 
> plugin.ads
> ----------
> 
> package Plugin is
>     procedure Empty;
> end Plugin;
> 
> plugin.adb
> ----------
> with Ada.Finalization;
> with Ada.Text_IO;
> 
> package body Plugin is
> 
>     type Life_Controller is new Ada.Finalization.Limited_Controlled with 
> null record;
>     overriding procedure Initialize (lc: in out Life_Controller);
>     overriding procedure Finalize (lc: in out Life_Controller);
> 
>     procedure Empty is
>     begin
>        null;
>     end Empty;
> 
>     overriding procedure Initialize (lc: in out Life_Controller) is
>     begin
>        Ada.Text_IO.Put_Line("Hello world!");
>     end Initialize;
> 
>     overriding procedure Finalize (lc: in out Life_Controller) is
>     begin
>        Ada.Text_IO.Put_Line("Bye world!");
>     end Finalize;
> 
>     lc:    Life_Controller;
> 
> end Plugin;
> 
> main.adb
> --------
> with System;
> with Interfaces.C.Strings;
> with Ada.Text_IO;
> 
> procedure Main is
> 
>     use type System.Address;
>     RTLD_LAZY:    constant := 1;
>     handle:    System.Address;
> 
>     function dlopen (Lib_Name: String; Mode: Interfaces.C.int)
>             return System.Address;
>     pragma Import (C, dlopen, "dlopen");
> 
> begin
>     handle:= dlopen ("../Plugin/lib/libplugin.so" & ASCII.NUL, RTLD_LAZY);
>     if handle = System.Null_Address then
>        Ada.Text_IO.Put_Line("unable to load plugin");
>     end if;
> end Main;
> 
> 
> Main executes without any output. My understanding is the following:
> 
>   - When plugin loading with dlopen fails, I get an error message.
>   - Otherwise, the controlled variable lc in plugin.adb comes to life and
>     I get an output from the Initialize procedure.
> 
> Where is my misconception?

Probably, you do not have automatic initialization of the Ada run-time.

    for Library_Auto_Init use "False";

Which is good, because under Windows would deadlock.

What you should do is:

1. Add an entry point to the library. Call it in order to return the 
expected minimum version of Main. It would add resilience. The 
implementation must be simple and not to require initialization. E.g.

    function get_required_version return Interfaces.C.unsigned;
    pragma Convention (C, get_required_version);

Use dlsym to get the address:

    type get_required_version_ptr is
       function return Interfaces.C.unsigned;
    pragma Convention (C, get_required_version_ptr);
    function dlsym
             (  handle : System.Address;
                symbol : char_array := "get_required_version" & NUL
             )  return get_required_version_ptr;
    pragma Import (C, dlsym);

2. Add another entry point like My_DLL_Init to call after version check. 
 From there first call to Ada run-time initialization. I believe it is named

    <library-name>init

After that you could do plug-in bookkeeping, calling registering 
subprograms etc.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Plugin with controlled variable for initialization.
@ 2022-02-02 17:21  5% hreba
  2022-02-02 18:05  0% ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: hreba @ 2022-02-02 17:21 UTC (permalink / raw)


For the plugin scheme in my actual program I worked along the 
corresponding gnat example, but while the original works, mine doesn't. 
So I boiled it down to a minimum.

plugin.ads
----------

package Plugin is
    procedure Empty;
end Plugin;

plugin.adb
----------
with Ada.Finalization;
with Ada.Text_IO;

package body Plugin is

    type Life_Controller is new Ada.Finalization.Limited_Controlled with 
null record;
    overriding procedure Initialize (lc: in out Life_Controller);
    overriding procedure Finalize (lc: in out Life_Controller);

    procedure Empty is
    begin
       null;
    end Empty;

    overriding procedure Initialize (lc: in out Life_Controller) is
    begin
       Ada.Text_IO.Put_Line("Hello world!");
    end Initialize;

    overriding procedure Finalize (lc: in out Life_Controller) is
    begin
       Ada.Text_IO.Put_Line("Bye world!");
    end Finalize;

    lc:	Life_Controller;

end Plugin;

main.adb
--------
with System;
with Interfaces.C.Strings;
with Ada.Text_IO;

procedure Main is

    use type System.Address;
    RTLD_LAZY:	constant := 1;
    handle:	System.Address;

    function dlopen (Lib_Name: String; Mode: Interfaces.C.int)
		   return System.Address;
    pragma Import (C, dlopen, "dlopen");

begin
    handle:= dlopen ("../Plugin/lib/libplugin.so" & ASCII.NUL, RTLD_LAZY);
    if handle = System.Null_Address then
       Ada.Text_IO.Put_Line("unable to load plugin");
    end if;
end Main;


Main executes without any output. My understanding is the following:

  - When plugin loading with dlopen fails, I get an error message.
  - Otherwise, the controlled variable lc in plugin.adb comes to life and
    I get an output from the Initialize procedure.

Where is my misconception?
-- 
Frank Hrebabetzky, Kronach	+49 / 9261 / 950 0565

^ permalink raw reply	[relevance 5%]

* Re: Getting the 3 letter time zone abbreviation
  @ 2020-05-02 12:46  7%           ` Bob Goddard
  0 siblings, 0 replies; 200+ results
From: Bob Goddard @ 2020-05-02 12:46 UTC (permalink / raw)


Here goes...

On Linux and the various BSD's, the tm structure has been extended to include:

  long int tm_gmtoff;           /* Seconds east of UTC.  */
  const char *tm_zone;          /* Timezone abbreviation.  */

When you make a call to localtime_r, these are filled in with the correct into, at least on Linux.

The other big iron Unix's do not have this extension, and neither does Windows.

Windows also does not have localtime_r, instead it has localtime_s plus its 32 & 64 versions.

On the other Unix's & Windows, a call made to tzset (_tzset on Windows), which fills in tzname (_tzname under Windows). This should contain 2 record for non-saving & saving timezone name. and the correct entry can be garnered by way of tm_isdst.

To set another timezone, external var TZ should be set.

And don't test an example time of 1234 seconds past epoch for the UK expecting GMT. The UK was in fact in daylight saving time and double time (I think) for a few years. In my defence, I was only about 7yo and totally forgot about it.

There, clear as mud.

This works on Linux, the tm_zone is filled in by the call automatically...


with System;
with Interfaces;
with Interfaces.C;
with Interfaces.C.Strings;

package Unix is
   type tm is record
      tm_sec    : Interfaces.C.int;
      tm_min    : Interfaces.C.int;
      tm_hour   : Interfaces.C.int;
      tm_day    : Interfaces.C.int;
      tm_mon    : Interfaces.C.int;
      tm_year   : Interfaces.C.int;
      tm_wday   : Interfaces.C.int;
      tm_yday   : Interfaces.C.int;
      tm_isdst  : Interfaces.C.int;
      tm_gmtoff : Interfaces.C.long;
      tm_zone   : Interfaces.C.Strings.chars_ptr;
   end record;
   pragma Convention (C_Pass_By_Copy, tm);
   
   procedure localtime_r (T : System.Address; TM_Struct : System.Address);
   pragma Import (C, localtime_r, "localtime_r");
end Unix;

^ permalink raw reply	[relevance 7%]

* Re: differences between Ada and C in gnat forcing me to use C instead of Ada
  @ 2019-04-04  0:51  5%     ` matthewbrentmccarty
  0 siblings, 0 replies; 200+ results
From: matthewbrentmccarty @ 2019-04-04  0:51 UTC (permalink / raw)


Hi all:

OK!  I was looking at this again with fresh eyes and with a little tweaking, I got Dmitry's example working with the following code:



with Text_Io; use Text_io;
with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;

procedure foo3 is

   subtype SANE_Word is int;  -- /usr/include/sane/sane.h:43
   subtype SANE_Bool is SANE_Word;  -- /usr/include/sane/sane.h:44

   type SANE_Status is
     (SANE_STATUS_GOOD,
      SANE_STATUS_UNSUPPORTED,
      SANE_STATUS_CANCELLED,
      SANE_STATUS_DEVICE_BUSY,
      SANE_STATUS_INVAL,
      SANE_STATUS_EOF,
      SANE_STATUS_JAMMED,
      SANE_STATUS_NO_DOCS,
      SANE_STATUS_COVER_OPEN,
      SANE_STATUS_IO_ERROR,
      SANE_STATUS_NO_MEM,
      SANE_STATUS_ACCESS_DENIED);
   pragma Convention (C, SANE_Status);  -- /usr/include/sane/sane.h:71

   subtype SANE_Char is char;  -- /usr/include/sane/sane.h:46
   subtype SANE_Int is SANE_Word;  -- /usr/include/sane/sane.h:45
   type SANE_String_Const is access all SANE_Char;  -- /usr/include/sane/sane.h:48

   type SANE_Auth_Callback is access procedure
        (arg1 : SANE_String_Const;
         arg2 : access SANE_Char;
         arg3 : access SANE_Char);
   pragma Convention (C, SANE_Auth_Callback);  -- /usr/include/sane/sane.h:214

    type SANE_Device is record
      name   : chars_ptr;
      vendor : chars_ptr;
      model  : chars_ptr;
      c_type : chars_ptr;
    end record;
    pragma Convention (C, SANE_Device);
    type SANE_Device_Ptr is access all SANE_Device;
    pragma Convention (C, SANE_Device_Ptr);

       -- Flat array of devices
    type SANE_Device_Array is array (size_t) of SANE_Device_Ptr;
    pragma Convention (C, SANE_Device_Array);
    type SANE_Device_Array_Ptr is access all SANE_Device_Array;
    pragma Convention (C, SANE_Device_Array_Ptr);

    function sane_get_devices
             (  device_list :  in out  SANE_Device_Array_Ptr;
                local_only  : SANE_Bool
             )  return SANE_Status;
   pragma Import (C, sane_get_devices, "sane_get_devices");

   function sane_init (version_code : access SANE_Int; authorize : SANE_Auth_Callback) return SANE_Status;  -- /usr/include/sane/sane.h:218
   pragma Import (C, sane_init, "sane_init");

   procedure sane_exit;  -- /usr/include/sane/sane.h:220
   pragma Import (C, sane_exit, "sane_exit");

---------------------------------

   List_Ptr : SANE_Device_Array_Ptr;
   stat : SANE_Status := SANE_STATUS_GOOD;
   version_code : access SANE_Int :=  new SANE_Int;


begin
    stat := sane_init(version_code, null);

    stat := sane_get_devices (List_Ptr, 0);
    declare
       List : SANE_Device_Array renames List_Ptr.all;
    begin
       for Index in List'Range loop      -- "Infinite" loop
          exit when List (Index) = null; -- Null-terminated
         Text_Io.Put_Line ("Name: " & Value (List (Index).name));
         Text_Io.Put_Line ("Vendor: " & Value (List (Index).vendor));
         Text_Io.Put_Line ("Model: " & Value (List (Index).model));
         Text_Io.Put_Line ("C_Type: " & Value (List (Index).c_type));
         
       end loop;
   end;

   sane_exit;
end Foo3;


Now, if I knew that it was possible to interface to C using "sane_get_devices" with a parameter of "device_list :  in out  SANE_Device_Array_Ptr;" instead of the generated "System.Address" parameter, then I would have been delighted to use that method instead of the generated version from "%g++ -c -fdump-ada-spec-slim".  For some reason, I thought the generated version was more accurate.  But I much rather use the SANE_Device_Array_Ptr version since it more accurately matches the documented API calls as explained in the manual.  I had to remove the "not null" on the parameter since it was causing "raised CONSTRAINT_ERROR : foo3.adb:74 access check failed" and it is null when you first call it.  And I still get garbage when passing the 'Address of the first element of my array in my version of the code.  Thanks for the assistance!

Regards,
Matthew McCarty

^ permalink raw reply	[relevance 5%]

* Re: differences between Ada and C in gnat forcing me to use C instead of Ada
  2019-03-25  5:46  5% differences between Ada and C in gnat forcing me to use C instead of Ada matthewbrentmccarty
  2019-03-25  5:58  0% ` Jere
@ 2019-03-25 14:09  4% ` matthewbrentmccarty
    2 siblings, 0 replies; 200+ results
From: matthewbrentmccarty @ 2019-03-25 14:09 UTC (permalink / raw)


Hi all:
"gnat-gps" on my machine Windows 10 (debian subsystem for Linux) (see https://docs.microsoft.com/en-us/windows/wsl/install-win10 ) gives me "raised STORAGE_ERROR : s-intman.adb:139 explicit raise" yet the same software works fine on my "real" debian machine. The compiler works but gant-gps doesn't. 


For some reason when I call sane_get_devices as in:

      type Sane_Device_Ptr is access all sane_sane_h.SANE_Device;
      for Sane_Device_Ptr'Size use Standard'Address_Size;
      pragma Convention (C, Sane_Device_Ptr);

      type Device_Array is array (Integer range <>) of aliased Sane_Device_Ptr;
      pragma Convention (C, Device_Array);
      ...
      devices :  aliased  Device_Array (1..5);
      Status := sane_sane_h.sane_get_devices (devices(1)'Address, sane_sane_h.SANE_Bool(SANE_TRUE));

I get back garbage but in C, it works. Oh, now that makes sense about 'Size returning bits and sizeof in C returning bytes. 256 bits is indeed 32 bytes. I wonder why I'm getting back garbage. InterfaceS.C.Strings.chars_ptr'Size=64 and sizeof(char *)=8 are equivalent.

Thanks. I guess I got some more digging to do as to my garbage.

Regards,
Matthew McCarty


^ permalink raw reply	[relevance 4%]

* Re: differences between Ada and C in gnat forcing me to use C instead of Ada
  2019-03-25  5:46  5% differences between Ada and C in gnat forcing me to use C instead of Ada matthewbrentmccarty
@ 2019-03-25  5:58  0% ` Jere
  2019-03-25 14:09  4% ` matthewbrentmccarty
    2 siblings, 0 replies; 200+ results
From: Jere @ 2019-03-25  5:58 UTC (permalink / raw)


On Monday, March 25, 2019 at 1:46:07 AM UTC-4, matthewbr...@gmail.com wrote:
> Hi all:
> 
> I really want to use Ada.  But gnat is forcing me to use C.  Basically, I wanted to interface with my scanner using SANE (Scanner Access Now Easy).  Using my "real" Debian machine since gnat doesn't work under Windows 10 (Debian subsystem for Linux), I created the ada specs from the C headers and the sizes in C and Ada are different.  For example:
> 
> In C, this code:
> printf("sizeof(char *)=%d\n", sizeof(char *));
> 
> prints "sizeof(char *)=8"
> 
> 
> and this code:
> printf("sizeof(SANE_Device)=%d\n", sizeof(SANE_Device));
> 
> prints "sizeof(SANE_Device)=32".  In C, the header defines it this way:
> 
> typedef char SANE_Char;
> typedef const SANE_Char *SANE_String_Const;
> 
> typedef struct
>   {
>     SANE_String_Const name;	/* unique device name */
>     SANE_String_Const vendor;	/* device vendor string */
>     SANE_String_Const model;	/* device model name */
>     SANE_String_Const type;	/* device type (e.g., "flatbed scanner") */
>   }
> SANE_Device;
> 
> which makes sense to me since 8*4 = 32 (sizeof(char *) * 4 elements in the record.  But on the Ada side, I get the following code:
> 
> Text_Io.Put_Line ("sane_sane_h.SANE_Device'Size=>" & 
>     Integer'Image (sane_sane_h.SANE_Device'Size));
> 
> to print "sane_sane_h.SANE_Device'Size=> 256"
> 
> And sure enough "Integer'Image (InterfaceS.C.Strings.chars_ptr'Size))" prints out 64.  Now, how can we interface to a C library passing around the 'Address of an array of pointers to records if the elements in the record are different sizes.  No wonder, I get back garbage when calling sane_get_devices. How is it that "sizeof(char *) is 8 in C and InterfaceS.C.Strings.chars_ptr'Size is 64 in Ada.  When I try to rep spec it, I get

So when you do sizeof() in C it returns the number of bytes. When
you do 'Size in Ada, it gives the number of bits.  8bits * 8bytes
is 64 bits, so everything looks correct. They are returning the same
effective size in both C and Ada.


^ permalink raw reply	[relevance 0%]

* differences between Ada and C in gnat forcing me to use C instead of Ada
@ 2019-03-25  5:46  5% matthewbrentmccarty
  2019-03-25  5:58  0% ` Jere
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: matthewbrentmccarty @ 2019-03-25  5:46 UTC (permalink / raw)


Hi all:

I really want to use Ada.  But gnat is forcing me to use C.  Basically, I wanted to interface with my scanner using SANE (Scanner Access Now Easy).  Using my "real" Debian machine since gnat doesn't work under Windows 10 (Debian subsystem for Linux), I created the ada specs from the C headers and the sizes in C and Ada are different.  For example:

In C, this code:
printf("sizeof(char *)=%d\n", sizeof(char *));

prints "sizeof(char *)=8"


and this code:
printf("sizeof(SANE_Device)=%d\n", sizeof(SANE_Device));

prints "sizeof(SANE_Device)=32".  In C, the header defines it this way:

typedef char SANE_Char;
typedef const SANE_Char *SANE_String_Const;

typedef struct
  {
    SANE_String_Const name;	/* unique device name */
    SANE_String_Const vendor;	/* device vendor string */
    SANE_String_Const model;	/* device model name */
    SANE_String_Const type;	/* device type (e.g., "flatbed scanner") */
  }
SANE_Device;

which makes sense to me since 8*4 = 32 (sizeof(char *) * 4 elements in the record.  But on the Ada side, I get the following code:

Text_Io.Put_Line ("sane_sane_h.SANE_Device'Size=>" & 
    Integer'Image (sane_sane_h.SANE_Device'Size));

to print "sane_sane_h.SANE_Device'Size=> 256"

And sure enough "Integer'Image (InterfaceS.C.Strings.chars_ptr'Size))" prints out 64.  Now, how can we interface to a C library passing around the 'Address of an array of pointers to records if the elements in the record are different sizes.  No wonder, I get back garbage when calling sane_get_devices. How is it that "sizeof(char *) is 8 in C and InterfaceS.C.Strings.chars_ptr'Size is 64 in Ada.  When I try to rep spec it, I get

   --size for "SANE_String_Const" too small, minimum allowed is 64
   --
   --for SANE_String_Const'Size use 8;

and

--for SANE_Device'Size use 32;                                     
-- causes compiler error "size for "SANE_Device" too small, minimum allowed is 256 
--       for SANE_Device use record
--          name at 0 range 0 .. 7;
--          vendor at 1 range 0 .. 7;
--          model at 2 range 0 .. 7;
--          c_type at 3 range 0 .. 7;
--       end record;

And sure enough Standard'Address_Size is  64.  Sorry to be so long winded. I guess I'll write C code.  Arggggh!

Regards,
Matthew McCarty

PS: Here are the steps.

So, I installed the development libraries using:

%apt-get install sane sane-utils libsane-extras xsane

which gave me

/usr/include/sane/sane.h


I then ran

%g++ -c -fdump-ada-spec -C /usr/include/sane/sane.h

which includes the following types and record:


with Interfaces.C; use Interfaces.C;
...
...
subtype SANE_Char is char;  -- /usr/include/sane/sane.h:46
...
type SANE_String is access all SANE_Char;  -- /usr/include/sane/sane.h:47
...
-- unique device name  
type SANE_Device is record
   name : SANE_String_Const;  -- /usr/include/sane/sane.h:104
   vendor : SANE_String_Const;  -- /usr/include/sane/sane.h:105
   model : SANE_String_Const;  -- /usr/include/sane/sane.h:106
   c_type : SANE_String_Const;  -- /usr/include/sane/sane.h:107
end record;
pragma Convention (C_Pass_By_Copy, SANE_Device);  -- /usr/include/sane/sane.h:109

function sane_get_devices (device_list : System.Address; local_only : SANE_Bool) return SANE_Status;  -- /usr/include/sane/sane.h:221
pragma Import (C, sane_get_devices, "sane_get_devices");

^ permalink raw reply	[relevance 5%]

* Re: How to bind this properly, C ** which is an array
  @ 2019-03-01 22:02  7%     ` Per Sandberg
  0 siblings, 0 replies; 200+ results
From: Per Sandberg @ 2019-03-01 22:02 UTC (permalink / raw)


 From the source provided i would guss that the folowing is a correct 
spec-file.
------------------------------------------------------------
pragma Ada_2012;
pragma Style_Checks (Off);

with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings;

package xx_h is

    type mpc_state_ti is record
       null;
    end record
    with Convention => C_Pass_By_Copy;  -- xx.h:1

    subtype mpc_state_t is mpc_state_ti;  -- xx.h:1

    type mpc_ast_t;
    type mpc_ast_t_access is access all  mpc_ast_t;
    type mpc_ast_t is record
       tag : Interfaces.C.Strings.chars_ptr;  -- xx.h:4
       contents : Interfaces.C.Strings.chars_ptr;  -- xx.h:5
       state : aliased mpc_state_t;  -- xx.h:6
       children_num : aliased int;  -- xx.h:7
       children : access mpc_ast_t_access;  -- xx.h:8
    end record
    with Convention => C_Pass_By_Copy;  -- xx.h:3

end xx_h;
------------------------------------------------------------
/P

On 3/1/19 9:25 PM, Lucretia wrote:
> On Friday, 1 March 2019 19:57:17 UTC, Per Sandberg  wrote:
>> Well i would start with:
>>
>> gcc -c -fdump-ada-spec ${headerfile} [-fada-spec-parent=${a-good-root}]
>>
>> to have the compiler do all the tricky work, if the headers are "bad"
>> you might need to do som touch-ups but that could usually be done with
>> some simple sed-scripts.
> 
> I already did, it just generates what I originally had, Address.
> 

^ permalink raw reply	[relevance 7%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-05-31 22:25  7%       ` Randy Brukardt
@ 2018-06-05 12:42  8%         ` Alejandro R. Mosteo
  0 siblings, 0 replies; 200+ results
From: Alejandro R. Mosteo @ 2018-06-05 12:42 UTC (permalink / raw)


On 01/06/2018 00:25, Randy Brukardt wrote:
> "Alejandro R. Mosteo" <alejandro@mosteo.com> wrote in message
> news:peoj3f$8ti$1@dont-email.me...
>> On 30/05/2018 21:56, Randy Brukardt wrote:
> ...
>>>> Is the in-place built limited tagged type guaranteed to live during the
>>>> call to the C function? (In other words, is the pointer safe (as long as
>>>> the C side does not make a copy, of course)?
>>>
>>> That depends on the master of the parameter. I believe that the master of
>>> a
>>> parameter is that of the call (each call being it's own master for the
>>> parameters) -- you'd have to look in 7.6.1 to be sure. So they stay
>>> around
>>> as long as the call.
>>
>> Might that be 6.4.1? 7 deals with packages (in 2012).
> 
> No. The rules for masters are defined with finalization in 7.6, and
> specifically in 7.6.1(3/2). The single middle sentence in that paragraph (a
> classic RM run-on sentence) defines completely where every object in an Ada
> program is finalized -- and also defines large parts of the accessibility
> and tasking models (which mainly follow the same master rules).

I was a bit thrown off by the use of finalization in the non-controlled 
sense.

>> Although it was too dense for me anyway :(
> 
> That's why I didn't want to give you a definitive answer. It takes a lot of
> mental effort to do that, and I need to save that effort for things people
> pay me to do. ;-)
> 
> ...
>>>        Foo (Bar (Ugh (...))
>>>
>>> The result of Ugh is finalized when the call to Bar ends, so if it is
>>> somehow in the result of Bar, you could get trouble in Foo. You can avoid
>>> that by declaring the parameter "aliased" (those belong to the *result*
>>> of
>>> the function, so they stick around longer).
>>
>> The parameter is actually aliased already. So I hope your impressions are
>> right and I'm on firm ground then, a pleasant surprise.
> 
> Turns out I was wrong: 7.6.1(3/2) says that only the outer function call is
> a master. So there is no problem in even the case I suggested.

Thanks again. And for doing it for free ;-)

Alex.

> 
>                                                     Randy.
> 
> 


^ permalink raw reply	[relevance 8%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-06-04  7:06  8%       ` Dmitry A. Kazakov
@ 2018-06-04  7:47  8%         ` ytomino
  0 siblings, 0 replies; 200+ results
From: ytomino @ 2018-06-04  7:47 UTC (permalink / raw)


On Monday, June 4, 2018 at 4:06:56 PM UTC+9, Dmitry A. Kazakov wrote:
> On 2018-06-03 10:03 PM, ytomino wrote:
> > On Monday, June 4, 2018 at 4:33:20 AM UTC+9, Dmitry A. Kazakov wrote:
> >> On 2018-06-03 20:31, ytomino wrote:
> >>> Perhaps, malloc is better than New_String in this case.
> >>>
> >>>    function malloc (s : Interfaces.C.size_t) return Interfaces.C.Strings.chars_ptr
> >>>       with Import, Convention => C;
> >>
> >> I had a case when that caused the application crashed.
> >>
> >> I guess it was because of mixed Visual Studio and GCC run-times. The
> >> pointer returned by the malloc from one was freed in a third-party C
> >> library by another.
> >>
> >> -- 
> >> Regards,
> >> Dmitry A. Kazakov
> >> http://www.dmitry-kazakov.de
> > 
> > What!?
> > 
> > New_String calls malloc in the end, too, in mingw runtime.
> > (It calls Memory_Alloc, Memory_Alloc is _gnat_malloc, and __gnat_malloc calls malloc.)
> > https://gcc.gnu.org/svn/gcc/trunk/gcc/ada/libgnat/i-cstrin.adb
> > https://gcc.gnu.org/svn/gcc/trunk/gcc/ada/libgnat/s-parame.ads
> > https://gcc.gnu.org/svn/gcc/trunk/gcc/ada/libgnat/s-memory__mingw.adb
> > 
> > If Interfaces.C.Strings.Free (malloc) is crashed, New_String would be same.
> 
> No, not this free but the one called from the third-party library 
> because the pointer was passed there to handle.
> 
> Of course it is safe to call malloc-free or New_String-Free pairs. Other 
> combinations can be unsafe.
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

> Of course it is safe to call malloc-free or New_String-Free pairs. Other 
> combinations can be unsafe.

That is only talking on the standard, probably is not the cause of the crash.

^ permalink raw reply	[relevance 8%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-06-03 20:03 12%     ` ytomino
@ 2018-06-04  7:06  8%       ` Dmitry A. Kazakov
  2018-06-04  7:47  8%         ` ytomino
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2018-06-04  7:06 UTC (permalink / raw)


On 2018-06-03 10:03 PM, ytomino wrote:
> On Monday, June 4, 2018 at 4:33:20 AM UTC+9, Dmitry A. Kazakov wrote:
>> On 2018-06-03 20:31, ytomino wrote:
>>> Perhaps, malloc is better than New_String in this case.
>>>
>>>    function malloc (s : Interfaces.C.size_t) return Interfaces.C.Strings.chars_ptr
>>>       with Import, Convention => C;
>>
>> I had a case when that caused the application crashed.
>>
>> I guess it was because of mixed Visual Studio and GCC run-times. The
>> pointer returned by the malloc from one was freed in a third-party C
>> library by another.
>>
>> -- 
>> Regards,
>> Dmitry A. Kazakov
>> http://www.dmitry-kazakov.de
> 
> What!?
> 
> New_String calls malloc in the end, too, in mingw runtime.
> (It calls Memory_Alloc, Memory_Alloc is _gnat_malloc, and __gnat_malloc calls malloc.)
> https://gcc.gnu.org/svn/gcc/trunk/gcc/ada/libgnat/i-cstrin.adb
> https://gcc.gnu.org/svn/gcc/trunk/gcc/ada/libgnat/s-parame.ads
> https://gcc.gnu.org/svn/gcc/trunk/gcc/ada/libgnat/s-memory__mingw.adb
> 
> If Interfaces.C.Strings.Free (malloc) is crashed, New_String would be same.

No, not this free but the one called from the third-party library 
because the pointer was passed there to handle.

Of course it is safe to call malloc-free or New_String-Free pairs. Other 
combinations can be unsafe.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 8%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-06-03 19:33  8%   ` Dmitry A. Kazakov
  2018-06-03 20:03 12%     ` ytomino
@ 2018-06-03 20:37  8%     ` ytomino
  1 sibling, 0 replies; 200+ results
From: ytomino @ 2018-06-03 20:37 UTC (permalink / raw)


On Monday, June 4, 2018 at 4:33:20 AM UTC+9, Dmitry A. Kazakov wrote:
> On 2018-06-03 20:31, ytomino wrote:
> > Perhaps, malloc is better than New_String in this case.
> > 
> >   function malloc (s : Interfaces.C.size_t) return Interfaces.C.Strings.chars_ptr
> >      with Import, Convention => C;
> 
> I had a case when that caused the application crashed.
> 
> I guess it was because of mixed Visual Studio and GCC run-times. The 
> pointer returned by the malloc from one was freed in a third-party C 
> library by another.
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

By my intuition, the crash is caused by not free but Update.
Because malloc does not set NUL.
So maybe is the length-checking in Update crashed?
If that is so, "Check => False" should be inserted into the first Update.

 Update (..., Check => False);

^ permalink raw reply	[relevance 8%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-06-03 19:33  8%   ` Dmitry A. Kazakov
@ 2018-06-03 20:03 12%     ` ytomino
  2018-06-04  7:06  8%       ` Dmitry A. Kazakov
  2018-06-03 20:37  8%     ` ytomino
  1 sibling, 1 reply; 200+ results
From: ytomino @ 2018-06-03 20:03 UTC (permalink / raw)


On Monday, June 4, 2018 at 4:33:20 AM UTC+9, Dmitry A. Kazakov wrote:
> On 2018-06-03 20:31, ytomino wrote:
> > Perhaps, malloc is better than New_String in this case.
> > 
> >   function malloc (s : Interfaces.C.size_t) return Interfaces.C.Strings.chars_ptr
> >      with Import, Convention => C;
> 
> I had a case when that caused the application crashed.
> 
> I guess it was because of mixed Visual Studio and GCC run-times. The 
> pointer returned by the malloc from one was freed in a third-party C 
> library by another.
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

What!?

New_String calls malloc in the end, too, in mingw runtime.
(It calls Memory_Alloc, Memory_Alloc is _gnat_malloc, and __gnat_malloc calls malloc.)
https://gcc.gnu.org/svn/gcc/trunk/gcc/ada/libgnat/i-cstrin.adb
https://gcc.gnu.org/svn/gcc/trunk/gcc/ada/libgnat/s-parame.ads
https://gcc.gnu.org/svn/gcc/trunk/gcc/ada/libgnat/s-memory__mingw.adb

If Interfaces.C.Strings.Free (malloc) is crashed, New_String would be same.


^ permalink raw reply	[relevance 12%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-06-03 18:31 14% ` ytomino
@ 2018-06-03 19:33  8%   ` Dmitry A. Kazakov
  2018-06-03 20:03 12%     ` ytomino
  2018-06-03 20:37  8%     ` ytomino
  0 siblings, 2 replies; 200+ results
From: Dmitry A. Kazakov @ 2018-06-03 19:33 UTC (permalink / raw)


On 2018-06-03 20:31, ytomino wrote:
> Perhaps, malloc is better than New_String in this case.
> 
>   function malloc (s : Interfaces.C.size_t) return Interfaces.C.Strings.chars_ptr
>      with Import, Convention => C;

I had a case when that caused the application crashed.

I guess it was because of mixed Visual Studio and GCC run-times. The 
pointer returned by the malloc from one was freed in a third-party C 
library by another.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 8%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-05-25 22:22  6% Interfaces.C.Strings chars_ptr memory management strategy NiGHTS
  2018-05-26  2:52  8% ` Shark8
  2018-05-30 13:10  7% ` Alejandro R. Mosteo
@ 2018-06-03 18:31 14% ` ytomino
  2018-06-03 19:33  8%   ` Dmitry A. Kazakov
  2 siblings, 1 reply; 200+ results
From: ytomino @ 2018-06-03 18:31 UTC (permalink / raw)


Perhaps, malloc is better than New_String in this case.

 function malloc (s : Interfaces.C.size_t) return Interfaces.C.Strings.chars_ptr
    with Import, Convention => C;

^ permalink raw reply	[relevance 14%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-05-31 10:34  8%     ` Alejandro R. Mosteo
@ 2018-05-31 22:25  7%       ` Randy Brukardt
  2018-06-05 12:42  8%         ` Alejandro R. Mosteo
  0 siblings, 1 reply; 200+ results
From: Randy Brukardt @ 2018-05-31 22:25 UTC (permalink / raw)


"Alejandro R. Mosteo" <alejandro@mosteo.com> wrote in message 
news:peoj3f$8ti$1@dont-email.me...
> On 30/05/2018 21:56, Randy Brukardt wrote:
...
>>> Is the in-place built limited tagged type guaranteed to live during the
>>> call to the C function? (In other words, is the pointer safe (as long as
>>> the C side does not make a copy, of course)?
>>
>> That depends on the master of the parameter. I believe that the master of 
>> a
>> parameter is that of the call (each call being it's own master for the
>> parameters) -- you'd have to look in 7.6.1 to be sure. So they stay 
>> around
>> as long as the call.
>
> Might that be 6.4.1? 7 deals with packages (in 2012).

No. The rules for masters are defined with finalization in 7.6, and 
specifically in 7.6.1(3/2). The single middle sentence in that paragraph (a 
classic RM run-on sentence) defines completely where every object in an Ada 
program is finalized -- and also defines large parts of the accessibility 
and tasking models (which mainly follow the same master rules).

> Although it was too dense for me anyway :(

That's why I didn't want to give you a definitive answer. It takes a lot of 
mental effort to do that, and I need to save that effort for things people 
pay me to do. ;-)

...
>>       Foo (Bar (Ugh (...))
>>
>> The result of Ugh is finalized when the call to Bar ends, so if it is
>> somehow in the result of Bar, you could get trouble in Foo. You can avoid
>> that by declaring the parameter "aliased" (those belong to the *result* 
>> of
>> the function, so they stick around longer).
>
> The parameter is actually aliased already. So I hope your impressions are 
> right and I'm on firm ground then, a pleasant surprise.

Turns out I was wrong: 7.6.1(3/2) says that only the outer function call is 
a master. So there is no problem in even the case I suggested.

                                                   Randy.



^ permalink raw reply	[relevance 7%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-05-30 19:56  6%   ` Randy Brukardt
@ 2018-05-31 10:34  8%     ` Alejandro R. Mosteo
  2018-05-31 22:25  7%       ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: Alejandro R. Mosteo @ 2018-05-31 10:34 UTC (permalink / raw)


On 30/05/2018 21:56, Randy Brukardt wrote:
> "Alejandro R. Mosteo" <alejandro@mosteo.com> wrote in message
> news:pem7s0$go4$1@dont-email.me...
>> On 26/05/2018 00:22, NiGHTS wrote:
>>> I am creating a binding to a C library that requires me to repeat the
>>> same function but with a string parameter that changes on each call. I
>>> don't want to have to keep creating and destroying string memory for all
>>> of these function calls. I would like to create the memory for the string
>>> once, allocate enough space so it doesn't need to grow, and reuse that
>>> memory for the function call every time I need to pass a new string to
>>> it.
>>
>> I'm currently using this:
>>
>> https://github.com/mosteo/cstrings
>>
>> which is not what you want since it allocates on every instance (although
>> on the stack). Still, it might give you some ideas.
>>
>> I'm still unsure if that's 100% guaranteed to be safe; for the experts out
>> here, the question is, in a call to a C function like this:
>>
>> Call_To_C_Function
>>     (Function_That_Returns_A_Limited_Tagged_Type (...)
>>        .Subprogram_That_Returns_A_C_Pointer_To_Data_In_The_Tagged_Type);
>>
>> Is the in-place built limited tagged type guaranteed to live during the
>> call to the C function? (In other words, is the pointer safe (as long as
>> the C side does not make a copy, of course)?
> 
> That depends on the master of the parameter. I believe that the master of a
> parameter is that of the call (each call being it's own master for the
> parameters) -- you'd have to look in 7.6.1 to be sure. So they stay around
> as long as the call.

Might that be 6.4.1? 7 deals with packages (in 2012).

Although it was too dense for me anyway :(

> If that wasn't true, passing an aggregate could have the temporary object
> freed/finalized before the call ended, which would be a disaster.
> 
>> My suspicion is that once the subprogram returns the pointer, the limited
>> type can be optimized away before the call to the C side. It's not what
>> I'm seeing now, but I don't want to depend on an erroneous assumption.
> 
>   Don't think this is a problem in general -- and the result of a function
> does *not* belong to the master of the call but rather the enclosing one
> (else you couldn't use it before it went away). You might be able to get it
> with nested calls:
> 
>       Foo (Bar (Ugh (...))
> 
> The result of Ugh is finalized when the call to Bar ends, so if it is
> somehow in the result of Bar, you could get trouble in Foo. You can avoid
> that by declaring the parameter "aliased" (those belong to the *result* of
> the function, so they stick around longer).

The parameter is actually aliased already. So I hope your impressions are 
right and I'm on firm ground then, a pleasant surprise.

Thanks,
Alex.

> 
>                                                            Randy.
> 
> 


^ permalink raw reply	[relevance 8%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-05-30 13:10  7% ` Alejandro R. Mosteo
@ 2018-05-30 19:56  6%   ` Randy Brukardt
  2018-05-31 10:34  8%     ` Alejandro R. Mosteo
  0 siblings, 1 reply; 200+ results
From: Randy Brukardt @ 2018-05-30 19:56 UTC (permalink / raw)


"Alejandro R. Mosteo" <alejandro@mosteo.com> wrote in message 
news:pem7s0$go4$1@dont-email.me...
> On 26/05/2018 00:22, NiGHTS wrote:
>> I am creating a binding to a C library that requires me to repeat the 
>> same function but with a string parameter that changes on each call. I 
>> don't want to have to keep creating and destroying string memory for all 
>> of these function calls. I would like to create the memory for the string 
>> once, allocate enough space so it doesn't need to grow, and reuse that 
>> memory for the function call every time I need to pass a new string to 
>> it.
>
> I'm currently using this:
>
> https://github.com/mosteo/cstrings
>
> which is not what you want since it allocates on every instance (although 
> on the stack). Still, it might give you some ideas.
>
> I'm still unsure if that's 100% guaranteed to be safe; for the experts out 
> here, the question is, in a call to a C function like this:
>
> Call_To_C_Function
>    (Function_That_Returns_A_Limited_Tagged_Type (...)
>       .Subprogram_That_Returns_A_C_Pointer_To_Data_In_The_Tagged_Type);
>
> Is the in-place built limited tagged type guaranteed to live during the 
> call to the C function? (In other words, is the pointer safe (as long as 
> the C side does not make a copy, of course)?

That depends on the master of the parameter. I believe that the master of a 
parameter is that of the call (each call being it's own master for the 
parameters) -- you'd have to look in 7.6.1 to be sure. So they stay around 
as long as the call.

If that wasn't true, passing an aggregate could have the temporary object 
freed/finalized before the call ended, which would be a disaster.

> My suspicion is that once the subprogram returns the pointer, the limited 
> type can be optimized away before the call to the C side. It's not what 
> I'm seeing now, but I don't want to depend on an erroneous assumption.

 Don't think this is a problem in general -- and the result of a function 
does *not* belong to the master of the call but rather the enclosing one 
(else you couldn't use it before it went away). You might be able to get it 
with nested calls:

     Foo (Bar (Ugh (...))

The result of Ugh is finalized when the call to Bar ends, so if it is 
somehow in the result of Bar, you could get trouble in Foo. You can avoid 
that by declaring the parameter "aliased" (those belong to the *result* of 
the function, so they stick around longer).

                                                          Randy.



^ permalink raw reply	[relevance 6%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-05-25 22:22  6% Interfaces.C.Strings chars_ptr memory management strategy NiGHTS
  2018-05-26  2:52  8% ` Shark8
@ 2018-05-30 13:10  7% ` Alejandro R. Mosteo
  2018-05-30 19:56  6%   ` Randy Brukardt
  2018-06-03 18:31 14% ` ytomino
  2 siblings, 1 reply; 200+ results
From: Alejandro R. Mosteo @ 2018-05-30 13:10 UTC (permalink / raw)


On 26/05/2018 00:22, NiGHTS wrote:
> I am creating a binding to a C library that requires me to repeat the same function but with a string parameter that changes on each call. I don't want to have to keep creating and destroying string memory for all of these function calls. I would like to create the memory for the string once, allocate enough space so it doesn't need to grow, and reuse that memory for the function call every time I need to pass a new string to it.

I'm currently using this:

https://github.com/mosteo/cstrings

which is not what you want since it allocates on every instance (although 
on the stack). Still, it might give you some ideas.

I'm still unsure if that's 100% guaranteed to be safe; for the experts 
out here, the question is, in a call to a C function like this:

Call_To_C_Function
    (Function_That_Returns_A_Limited_Tagged_Type (...)
       .Subprogram_That_Returns_A_C_Pointer_To_Data_In_The_Tagged_Type);

Is the in-place built limited tagged type guaranteed to live during the 
call to the C function? (In other words, is the pointer safe (as long as 
the C side does not make a copy, of course)?

My suspicion is that once the subprogram returns the pointer, the limited 
type can be optimized away before the call to the C side. It's not what 
I'm seeing now, but I don't want to depend on an erroneous assumption.

Alex.

> 
> The trick here is that whatever strategy I use must be compatible with C, so for instance using a storage pool would not be directly compatible with the C binding.
> 
> Here is just a quick and sloppy idea I had on how to tackle my problem.
> 
> str : chars_ptr := New_String ("                                     ");
> ...
> Update (Item => str, Offset => 0, Str => "Some Param");
> ...
> Update (Item => str, Offset => 0, Str => "Some Other Param");
> ...
> Free (str);
> 
> I find the first line quite ugly. I'm sure there is an easier way to create a large empty string but I can't seem to come up with an elegant way to do it.
> 
> As far as the Update commands, will it act like strcpy() in C? If so I'd guess that this is an efficient technique.
> 
> Thanks for your help!
> 

^ permalink raw reply	[relevance 7%]

* Re: Strings with discriminated records
  2018-05-27 22:44  0%     ` NiGHTS
  2018-05-28  7:29  6%       ` Dmitry A. Kazakov
@ 2018-05-28  7:42  4%       ` Simon Wright
  1 sibling, 0 replies; 200+ results
From: Simon Wright @ 2018-05-28  7:42 UTC (permalink / raw)


NiGHTS <nights@unku.us> writes:

> I confirmed with an Ada.Text_IO.Put_Line() that Finalize was called
> three times. I then disabled Finalize and created an explicitly called
> Finalize2 function and it worked fine. It's weird though because my
> program only elaborated the object once, so why did it finalize three
> times?

You need to read ARM7.6, in particular (17):
http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-7-6.html#p17

Disregarding for the moment any "assignment" that might happen in
computing the result of Create, & looking at
   
   declare
      M : Nights.Message := Nights.Create ("Hello World");
   begin
      null;
   end;

First, the Create call makes an anonymous object.

Then, M is in theory finalized, but this is likely optimised away.

Then, the bits of the anonymous object are copied into M. This is a
"shallow copy". [***]

Then, the anonymous object is finalized, which frees
<anonymous>.Cstr. HOWEVER, M.Cstr still contains the same value, which
means it's pointing to deallocated memory.

Then, on exit from the declare block, M is finalized, and Finalize tries
to free M.Cstr again. Oops.

This is always going to happen if you make a shallow copy of something
which contains plain allocated memory.

As Dmitry said upthread, you need an Adjust, which makes a deep copy of
the plain allocated memory, immediately after [***] above:

   procedure Adjust (M : in out Message) is
      use Interfaces.C.Strings;
   begin
      M.Cstr := New_Char_Array (Value (M.Cstr));
   end Adjust;

> I tried wrapping the body of finalize in a condition to force it to
> run only once, yet it still managed to run it again ignoring the
> boolean.

If the boolean was in Message, the same argument as above applies.

>          I'm perplexed. Not sure if I should ever trust
> Ada.Finalization.Controlled.

As with most things, not until you know how to use it.

^ permalink raw reply	[relevance 4%]

* Re: Strings with discriminated records
  2018-05-27 22:44  0%     ` NiGHTS
@ 2018-05-28  7:29  6%       ` Dmitry A. Kazakov
  2018-05-28  7:42  4%       ` Simon Wright
  1 sibling, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2018-05-28  7:29 UTC (permalink / raw)


On 2018-05-28 00:44, NiGHTS wrote:

> I confirmed with an Ada.Text_IO.Put_Line() that Finalize was called three times.

It is called for three different objects.

> I then disabled Finalize and created an explicitly called Finalize2 function and it worked fine. It's weird though because my program only elaborated the object once, so why did it finalize three times?

Because you have three copies of the controlled object. Here is a fixed 
implementation with Adjust:
-------------------------------------------------------
with Ada.Text_IO;          use Ada.Text_IO;
with Interfaces.C;         use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;

with Ada.Finalization;

procedure Test is

    package P is
       type C_String is new Ada.Finalization.Controlled with private;
       function Create (Text : String) return C_String;
       overriding procedure Adjust (Text : in out C_String);
       overriding procedure Finalize (Text : in out C_String);
    private
       type C_String is new Ada.Finalization.Controlled with record
          Ptr : chars_ptr;
       end record;
    end P;

    package body P is
       function Create (Text : String) return C_String is
       begin
          Put_Line ("Creating:" & Text);
          return (Ada.Finalization.Controlled with New_String (Text));
       end Create;

       procedure Adjust (Text : in out C_String) is
       begin
          if Text.Ptr = Null_Ptr then
             Put_Line ("Copying null string:");
          else
             Put_Line ("Copying:" & Value (Text.Ptr));
             Text.Ptr := New_String (Value (Text.Ptr));
          end if;
       end Adjust;

       procedure Finalize (Text : in out C_String) is
       begin
          if Text.Ptr = Null_Ptr then
             Put_Line ("Finalizing null string:");
          else
             Put_Line ("Finalizing:" & Value (Text.Ptr));
             Free (Text.Ptr);
          end if;
       end Finalize;
    end P;

    use P;
    S1 : C_String := Create ("Hello");
begin
    null;
end Test;
-------------------------------------------------
It prints:

Creating:Hello
Copying:Hello
Finalizing:Hello
Copying:Hello
Finalizing:Hello
Finalizing:Hello

Now the meaning of this:

Creating:Hello   -- Create
Copying:Hello    -- Copy local object (aggregate?) in Create
Finalizing:Hello -- Finalize the local object in Create
Copying:Hello    -- Copy result of Create to S1
Finalizing:Hello -- Finalize the result of Create
Finalizing:Hello -- Finalize S1

> I tried wrapping the body of finalize in a condition to force it to run only once, yet it still managed to run it again ignoring the boolean. I'm perplexed. Not sure if I should ever trust Ada.Finalization.Controlled.

Yes, see the example.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 6%]

* Re: Strings with discriminated records
  2018-05-28  1:44  0%       ` Jere
@ 2018-05-28  3:05  0%         ` NiGHTS
  0 siblings, 0 replies; 200+ results
From: NiGHTS @ 2018-05-28  3:05 UTC (permalink / raw)


On Sunday, May 27, 2018 at 9:44:22 PM UTC-4, Jere wrote:
> On Sunday, May 27, 2018 at 7:08:03 PM UTC-4, NiGHTS wrote:
> > On Sunday, May 27, 2018 at 2:07:37 PM UTC-4, Simon Wright wrote:
> > > 
> > > > I've expanded my example to include a strange run-time crash I am getting.
> > > >
> > > > Type Message (Length : Positive) is new Ada.Finalization.Controlled with record
> > > >     Text  :  String (1 .. Length);
> > > >     Cstr  :  Interfaces.C.Strings.chars_ptr;
> > > > end record;
> > > >        
> > > > function Create (Value : String) return Message is
> > > > begin
> > > >     return (
> > > >         Ada.Finalization.Controlled with Length => Value'Length, 
> > > >         Text => Value, 
> > > >         Cstr => Interfaces.C.Strings.New_String (Value) 
> > > >     );
> > > > end Create; 
> > > >
> > > > procedure Finalize (
> > > >     M : in out Message
> > > > ) is
> > > > begin
> > > >     Interfaces.C.Strings.Free ( M.Cstr ); -- Crashes here
> > > > end;
> > > >
> > > > declare
> > > >     M : Message := Create ("Hello World");
> > > > begin
> > > >     null;
> > > > end; 
> > > >
> > > > Why does my program crash on Finalization?
> > > 
> > > Maybe Finalize is getting called twice? You should set M.Cstr to
> > > Null_Ptr after freeing it.
> > 
> > It doesn't work. On each automatic call of Finalize, the object data is reset. Its very strange.
> 
> It won't work unless you have an appropriate Adjust.  Since your object is
> controlled (and not limited controlled), the compiler is making temporaries,
> each with their own copy of the pointer (someone else mentioned this above).
> Each temporary will be finalized and each will have their own copy of
> the pointer, so nulling it only nulls that objects copy and not the others.
> 
> As stated above by someone else, you'll either have to do a clone with
> separately allocated memory or some sort of reference count that only 
> allows finalize to call free when the last copy calls finalize (and
> ignores the others calls).
> 
> Dmitry has an example of how to do this with an intrusive reference
> count with his handles/objects library (see his website).
> 
> Making the type limited controlled is also a solution since it cannot
> make temporaries for one like it can a regular controlled object.

Yes, I understand now. I will do some tests and see what works for me. Thank you.


^ permalink raw reply	[relevance 0%]

* Re: Strings with discriminated records
  2018-05-27 23:08  0%     ` NiGHTS
@ 2018-05-28  1:44  0%       ` Jere
  2018-05-28  3:05  0%         ` NiGHTS
  0 siblings, 1 reply; 200+ results
From: Jere @ 2018-05-28  1:44 UTC (permalink / raw)


On Sunday, May 27, 2018 at 7:08:03 PM UTC-4, NiGHTS wrote:
> On Sunday, May 27, 2018 at 2:07:37 PM UTC-4, Simon Wright wrote:
> > 
> > > I've expanded my example to include a strange run-time crash I am getting.
> > >
> > > Type Message (Length : Positive) is new Ada.Finalization.Controlled with record
> > >     Text  :  String (1 .. Length);
> > >     Cstr  :  Interfaces.C.Strings.chars_ptr;
> > > end record;
> > >        
> > > function Create (Value : String) return Message is
> > > begin
> > >     return (
> > >         Ada.Finalization.Controlled with Length => Value'Length, 
> > >         Text => Value, 
> > >         Cstr => Interfaces.C.Strings.New_String (Value) 
> > >     );
> > > end Create; 
> > >
> > > procedure Finalize (
> > >     M : in out Message
> > > ) is
> > > begin
> > >     Interfaces.C.Strings.Free ( M.Cstr ); -- Crashes here
> > > end;
> > >
> > > declare
> > >     M : Message := Create ("Hello World");
> > > begin
> > >     null;
> > > end; 
> > >
> > > Why does my program crash on Finalization?
> > 
> > Maybe Finalize is getting called twice? You should set M.Cstr to
> > Null_Ptr after freeing it.
> 
> It doesn't work. On each automatic call of Finalize, the object data is reset. Its very strange.

It won't work unless you have an appropriate Adjust.  Since your object is
controlled (and not limited controlled), the compiler is making temporaries,
each with their own copy of the pointer (someone else mentioned this above).
Each temporary will be finalized and each will have their own copy of
the pointer, so nulling it only nulls that objects copy and not the others.

As stated above by someone else, you'll either have to do a clone with
separately allocated memory or some sort of reference count that only 
allows finalize to call free when the last copy calls finalize (and
ignores the others calls).

Dmitry has an example of how to do this with an intrusive reference
count with his handles/objects library (see his website).

Making the type limited controlled is also a solution since it cannot
make temporaries for one like it can a regular controlled object.

^ permalink raw reply	[relevance 0%]

* Re: Strings with discriminated records
  2018-05-27 18:07  0%   ` Simon Wright
@ 2018-05-27 23:08  0%     ` NiGHTS
  2018-05-28  1:44  0%       ` Jere
  0 siblings, 1 reply; 200+ results
From: NiGHTS @ 2018-05-27 23:08 UTC (permalink / raw)


On Sunday, May 27, 2018 at 2:07:37 PM UTC-4, Simon Wright wrote:
> 
> > I've expanded my example to include a strange run-time crash I am getting.
> >
> > Type Message (Length : Positive) is new Ada.Finalization.Controlled with record
> >     Text  :  String (1 .. Length);
> >     Cstr  :  Interfaces.C.Strings.chars_ptr;
> > end record;
> >        
> > function Create (Value : String) return Message is
> > begin
> >     return (
> >         Ada.Finalization.Controlled with Length => Value'Length, 
> >         Text => Value, 
> >         Cstr => Interfaces.C.Strings.New_String (Value) 
> >     );
> > end Create; 
> >
> > procedure Finalize (
> >     M : in out Message
> > ) is
> > begin
> >     Interfaces.C.Strings.Free ( M.Cstr ); -- Crashes here
> > end;
> >
> > declare
> >     M : Message := Create ("Hello World");
> > begin
> >     null;
> > end; 
> >
> > Why does my program crash on Finalization?
> 
> Maybe Finalize is getting called twice? You should set M.Cstr to
> Null_Ptr after freeing it.

It doesn't work. On each automatic call of Finalize, the object data is reset. Its very strange.

^ permalink raw reply	[relevance 0%]

* Re: Strings with discriminated records
  2018-05-27 18:25  0%   ` Dmitry A. Kazakov
@ 2018-05-27 22:44  0%     ` NiGHTS
  2018-05-28  7:29  6%       ` Dmitry A. Kazakov
  2018-05-28  7:42  4%       ` Simon Wright
  0 siblings, 2 replies; 200+ results
From: NiGHTS @ 2018-05-27 22:44 UTC (permalink / raw)


On Sunday, May 27, 2018 at 2:25:02 PM UTC-4, Dmitry A. Kazakov wrote:
> On 2018-05-27 19:11, NiGHTS wrote:
> > I've expanded my example to include a strange run-time crash I am getting.
> > 
> > Type Message (Length : Positive) is new Ada.Finalization.Controlled with record
> >      Text  :  String (1 .. Length);
> >      Cstr  :  Interfaces.C.Strings.chars_ptr;
> > end record;
> >         
> > function Create (Value : String) return Message is
> > begin
> >      return (
> >          Ada.Finalization.Controlled with Length => Value'Length,
> >          Text => Value,
> >          Cstr => Interfaces.C.Strings.New_String (Value)
> >      );
> > end Create;
> > 
> > procedure Finalize (
> >      M : in out Message
> > ) is
> > begin
> >      Interfaces.C.Strings.Free ( M.Cstr ); -- Crashes here
> > end;
> > 
> > declare
> >      M : Message := Create ("Hello World");
> > begin
> >      null;
> > end;
> > 
> > Why does my program crash on Finalization?
> 
> Because it is wrong.
> 
> You have a controlled object which gets copied all the time. It means 
> that the pointer Cstr is shared by all copies and is freed multiple 
> times. Either
> 
> 1. You must override Adjust and make a new string for the result.
> 
> or
> 
> 2. You could deploy some reference counting schema cloning the content 
> when the string at the pointer is updated. This is how dynamic strings 
> are usually implemented.
> 
> P.S. If you want C-compatible strings use char_array, it is exactly the 
> thing you need.
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

I confirmed with an Ada.Text_IO.Put_Line() that Finalize was called three times. I then disabled Finalize and created an explicitly called Finalize2 function and it worked fine. It's weird though because my program only elaborated the object once, so why did it finalize three times? 

I tried wrapping the body of finalize in a condition to force it to run only once, yet it still managed to run it again ignoring the boolean. I'm perplexed. Not sure if I should ever trust Ada.Finalization.Controlled.


^ permalink raw reply	[relevance 0%]

* Re: Strings with discriminated records
  2018-05-27 17:11  7% ` NiGHTS
  2018-05-27 18:07  0%   ` Simon Wright
@ 2018-05-27 18:25  0%   ` Dmitry A. Kazakov
  2018-05-27 22:44  0%     ` NiGHTS
  1 sibling, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2018-05-27 18:25 UTC (permalink / raw)


On 2018-05-27 19:11, NiGHTS wrote:
> I've expanded my example to include a strange run-time crash I am getting.
> 
> Type Message (Length : Positive) is new Ada.Finalization.Controlled with record
>      Text  :  String (1 .. Length);
>      Cstr  :  Interfaces.C.Strings.chars_ptr;
> end record;
>         
> function Create (Value : String) return Message is
> begin
>      return (
>          Ada.Finalization.Controlled with Length => Value'Length,
>          Text => Value,
>          Cstr => Interfaces.C.Strings.New_String (Value)
>      );
> end Create;
> 
> procedure Finalize (
>      M : in out Message
> ) is
> begin
>      Interfaces.C.Strings.Free ( M.Cstr ); -- Crashes here
> end;
> 
> declare
>      M : Message := Create ("Hello World");
> begin
>      null;
> end;
> 
> Why does my program crash on Finalization?

Because it is wrong.

You have a controlled object which gets copied all the time. It means 
that the pointer Cstr is shared by all copies and is freed multiple 
times. Either

1. You must override Adjust and make a new string for the result.

or

2. You could deploy some reference counting schema cloning the content 
when the string at the pointer is updated. This is how dynamic strings 
are usually implemented.

P.S. If you want C-compatible strings use char_array, it is exactly the 
thing you need.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 0%]

* Re: Strings with discriminated records
  2018-05-27 17:11  7% ` NiGHTS
@ 2018-05-27 18:07  0%   ` Simon Wright
  2018-05-27 23:08  0%     ` NiGHTS
  2018-05-27 18:25  0%   ` Dmitry A. Kazakov
  1 sibling, 1 reply; 200+ results
From: Simon Wright @ 2018-05-27 18:07 UTC (permalink / raw)


NiGHTS <nights@unku.us> writes:

> I've expanded my example to include a strange run-time crash I am getting.
>
> Type Message (Length : Positive) is new Ada.Finalization.Controlled with record
>     Text  :  String (1 .. Length);
>     Cstr  :  Interfaces.C.Strings.chars_ptr;
> end record;
>        
> function Create (Value : String) return Message is
> begin
>     return (
>         Ada.Finalization.Controlled with Length => Value'Length, 
>         Text => Value, 
>         Cstr => Interfaces.C.Strings.New_String (Value) 
>     );
> end Create; 
>
> procedure Finalize (
>     M : in out Message
> ) is
> begin
>     Interfaces.C.Strings.Free ( M.Cstr ); -- Crashes here
> end;
>
> declare
>     M : Message := Create ("Hello World");
> begin
>     null;
> end; 
>
> Why does my program crash on Finalization?

Maybe Finalize is getting called twice? You should set M.Cstr to
Null_Ptr after freeing it.

^ permalink raw reply	[relevance 0%]

* Re: Strings with discriminated records
  @ 2018-05-27 17:11  7% ` NiGHTS
  2018-05-27 18:07  0%   ` Simon Wright
  2018-05-27 18:25  0%   ` Dmitry A. Kazakov
  0 siblings, 2 replies; 200+ results
From: NiGHTS @ 2018-05-27 17:11 UTC (permalink / raw)


I've expanded my example to include a strange run-time crash I am getting.

Type Message (Length : Positive) is new Ada.Finalization.Controlled with record
    Text  :  String (1 .. Length);
    Cstr  :  Interfaces.C.Strings.chars_ptr;
end record;
       
function Create (Value : String) return Message is
begin
    return (
        Ada.Finalization.Controlled with Length => Value'Length, 
        Text => Value, 
        Cstr => Interfaces.C.Strings.New_String (Value) 
    );
end Create; 

procedure Finalize (
    M : in out Message
) is
begin
    Interfaces.C.Strings.Free ( M.Cstr ); -- Crashes here
end;

declare
    M : Message := Create ("Hello World");
begin
    null;
end; 

Why does my program crash on Finalization?


^ permalink raw reply	[relevance 7%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-05-26 12:44  8%   ` NiGHTS
@ 2018-05-26 13:56  8%     ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2018-05-26 13:56 UTC (permalink / raw)


On Saturday, May 26, 2018 at 6:45:01 AM UTC-6, NiGHTS wrote:
> On Friday, May 25, 2018 at 10:52:55 PM UTC-4, Shark8 wrote:
> > On Friday, May 25, 2018 at 4:22:13 PM UTC-6, NiGHTS wrote:
> > > 
> > > Here is just a quick and sloppy idea I had on how to tackle my problem.
> > > 
> > > str : chars_ptr := New_String ("                                     ");
> > > 
> > > I find the first line quite ugly. I'm sure there is an easier way to create a large empty string but I can't seem to come up with an elegant way to do it.
> > 
> > 
> > Something like this?
> > Big_String : chars_ptr := New_String( (1..200 => ' ') );
> 
> Thanks, It was on the tip of my brain I just for some reason couldn't put it together quite right.

It happens.
If you're going to be using this a lot I'd recommend a generic-wrapper something like:

GENERIC
  Max_Size : Natural;
FUNCTION Buffer_String Return Chars_Ptr;
FUNCTION Buffer_String Return Chars_Ptr IS
( New_String( (1..Max_Size => ' ') ) );

Or maybe a package.

^ permalink raw reply	[relevance 8%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-05-26  2:52  8% ` Shark8
@ 2018-05-26 12:44  8%   ` NiGHTS
  2018-05-26 13:56  8%     ` Shark8
  0 siblings, 1 reply; 200+ results
From: NiGHTS @ 2018-05-26 12:44 UTC (permalink / raw)


On Friday, May 25, 2018 at 10:52:55 PM UTC-4, Shark8 wrote:
> On Friday, May 25, 2018 at 4:22:13 PM UTC-6, NiGHTS wrote:
> > 
> > Here is just a quick and sloppy idea I had on how to tackle my problem.
> > 
> > str : chars_ptr := New_String ("                                     ");
> > 
> > I find the first line quite ugly. I'm sure there is an easier way to create a large empty string but I can't seem to come up with an elegant way to do it.
> 
> 
> Something like this?
> Big_String : chars_ptr := New_String( (1..200 => ' ') );

Thanks, It was on the tip of my brain I just for some reason couldn't put it together quite right.

^ permalink raw reply	[relevance 8%]

* Re: Interfaces.C.Strings chars_ptr memory management strategy
  2018-05-25 22:22  6% Interfaces.C.Strings chars_ptr memory management strategy NiGHTS
@ 2018-05-26  2:52  8% ` Shark8
  2018-05-26 12:44  8%   ` NiGHTS
  2018-05-30 13:10  7% ` Alejandro R. Mosteo
  2018-06-03 18:31 14% ` ytomino
  2 siblings, 1 reply; 200+ results
From: Shark8 @ 2018-05-26  2:52 UTC (permalink / raw)


On Friday, May 25, 2018 at 4:22:13 PM UTC-6, NiGHTS wrote:
> 
> Here is just a quick and sloppy idea I had on how to tackle my problem.
> 
> str : chars_ptr := New_String ("                                     ");
> 
> I find the first line quite ugly. I'm sure there is an easier way to create a large empty string but I can't seem to come up with an elegant way to do it.


Something like this?
Big_String : chars_ptr := New_String( (1..200 => ' ') );


^ permalink raw reply	[relevance 8%]

* Interfaces.C.Strings chars_ptr memory management strategy
@ 2018-05-25 22:22  6% NiGHTS
  2018-05-26  2:52  8% ` Shark8
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: NiGHTS @ 2018-05-25 22:22 UTC (permalink / raw)


I am creating a binding to a C library that requires me to repeat the same function but with a string parameter that changes on each call. I don't want to have to keep creating and destroying string memory for all of these function calls. I would like to create the memory for the string once, allocate enough space so it doesn't need to grow, and reuse that memory for the function call every time I need to pass a new string to it.

The trick here is that whatever strategy I use must be compatible with C, so for instance using a storage pool would not be directly compatible with the C binding.

Here is just a quick and sloppy idea I had on how to tackle my problem.

str : chars_ptr := New_String ("                                     ");
...
Update (Item => str, Offset => 0, Str => "Some Param");
...
Update (Item => str, Offset => 0, Str => "Some Other Param");
...
Free (str);

I find the first line quite ugly. I'm sure there is an easier way to create a large empty string but I can't seem to come up with an elegant way to do it.

As far as the Update commands, will it act like strcpy() in C? If so I'd guess that this is an efficient technique.

Thanks for your help!

^ permalink raw reply	[relevance 6%]

* Re: non-local pointer cannot point to local object
  2018-02-23  8:54  7% non-local pointer cannot point to local object artium
@ 2018-02-23  9:22  0% ` J-P. Rosen
  0 siblings, 0 replies; 200+ results
From: J-P. Rosen @ 2018-02-23  9:22 UTC (permalink / raw)


Le 23/02/2018 à 09:54, artium@nihamkin.com a écrit :
> Can someone explain why I get "non-local pointer cannot point to
> local object" error, even though it looks like "Arr" and "Arr_Access"
> have the same accessibility level?

> Can I overcome the problem without dynamically allocating memory and without using "Unchecked_Access"?
> 
> with Interfaces.C;
> with Interfaces.C.Strings;
> 
> procedure X is
> 
>    type Integer_Access is access all Integer;
> 
>    Arr_Access : Interfaces.C.Strings.char_array_access;
>    Arr : aliased Interfaces.C.char_array := Interfaces.C.To_C ("From");
> 
>    A : Integer_Access;
>    I : aliased Integer := 6;
> 
> begin
> 
>    Arr_Access := Arr'Access;
>    A := I'Access;
> 
> end X;
> 
What counts for accessibility is the place where the type of the object
is declared, not where the object itself is declared. In your case,
char_array_access is a global type, therefore you cannot assign a
pointer to a local variable.  Otherwise, Arr_Access could later be
assigned to some global variable, and you would end up with a global
variable pointing to a local object. Using Unchecked_Access means that
you swear that you don't do such evil things.

Ada has this nice property that no object can survive to its type (no,
it's not obvious; I think this is not guaranteed by C++ - can anyone
confirm?). Therefore, when you exit the scope of an access type, you are
guaranteed that there is no more value of this type hanging around.



-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr


^ permalink raw reply	[relevance 0%]

* non-local pointer cannot point to local object
@ 2018-02-23  8:54  7% artium
  2018-02-23  9:22  0% ` J-P. Rosen
  0 siblings, 1 reply; 200+ results
From: artium @ 2018-02-23  8:54 UTC (permalink / raw)


I am cross costing a question from SO since it looks like all the Ada experts are here and not there :)

https://stackoverflow.com/questions/48939845/non-local-pointer-cannot-point-to-local-object


Can someone explain why I get "non-local pointer cannot point to local object" error, even though it looks like "Arr" and "Arr_Access" have the same accessibility level?

Can I overcome the problem without dynamically allocating memory and without using "Unchecked_Access"?


with Interfaces.C;
with Interfaces.C.Strings;

procedure X is

   type Integer_Access is access all Integer;

   Arr_Access : Interfaces.C.Strings.char_array_access;
   Arr : aliased Interfaces.C.char_array := Interfaces.C.To_C ("From");

   A : Integer_Access;
   I : aliased Integer := 6;

begin

   Arr_Access := Arr'Access;
   A := I'Access;

end X;



Thank you,
Artium

^ permalink raw reply	[relevance 7%]

* Re: Convert between C "void*" pointer and an access
  2017-10-11 23:12  6%   ` Victor Porton
@ 2017-10-12  1:01  3%     ` Victor Porton
  0 siblings, 0 replies; 200+ results
From: Victor Porton @ 2017-10-12  1:01 UTC (permalink / raw)


Victor Porton wrote:

> Victor Porton wrote:
> 
>> Victor Porton wrote:
>> 
>>> What is the right way to convert between C "void*" pointer and an access
>>> to a tagged or class-wide type?
>>> 
>>> Ada.Unchecked_Conversion seems to be what I need, but the access type
>>> may be "fat" and thus have another format than void*.
>>> 
>>> I caught myself doing such unchecked conversions, but now I feel I did
>>> an error.
>>> 
>>> For example, let
>>> 
>>> type X_Type is abstract tagged null record;
>>> 
>>> How to store X_Type'Class pointer in "void*" and convert them back and
>>> forth?
>> 
>> It seems I've found a right solution of my problem. (Check if Ada RM
>> warrants that it works with every compiler!)
>> 
>> Well, why it is not a standard package?! Why I need to invent something
>> "smart" every time I need to code?
> 
> The package body was with a bug. Here there is corrected code:

[snip] (see code above in the thread)

Now I will prove that it works without errors with every conforming 
compilers.

The below will describe how my package Convert_Void works. If in doubt, 
consult the package source code.

First I should formulate the problem exactly:

Having an Ada object (we can restrict to tagged and class-wide types and 
benefit from the fact that such objects 'Address "should produce a useful 
result" (RM 13.3.16)), we need to transform it to C void pointer and pass to 
C code; the C code should be able to call Ada code (e.g. through subprogram 
access) and pass the pointer back and the Ada code should be able to work 
with the original Ada object.

In other words, we need to define two functions: To_Pointer which converts 
all access values for a certain type (tagged or class-wide, at least) into 
void pointers and To_Access which converts void pointers obtained by 
To_Pointer back into the original access value.

In other words, we need two mutually inverse bijections between every set of 
values of 'Unchecked_Access of values of a type (tagged or class-wide, at 
least) and a subset of C void pointers.

We also need map null access to NULL pointer and vice versa.

We will use chars_ptr from Interfaces.C.Strings to represent void pointers. 
It is valid because C11, 6.2.5, 28 (draft N1548): "A pointer to void shall 
have the same representation and alignment requirements as a pointer to a 
character type."

This problem is solved in my generic package Convert_Void:

-- "with" and "use" skipped
generic
    type Object(<>) is limited private;
package Convert_Void is

   package Address_Conversions is new
     System.Address_To_Access_Conversions(Object);
   
   subtype Object_Pointer is Address_Conversions.Object_Pointer;
   
   function To_Access (Void_Pointer: chars_ptr) return Object_Pointer;
   
   function To_C_Pointer (Pointer: Object_Pointer) return chars_ptr;
   
end Convert_Void;

We define in Convert_Void body:

type My_Char_Pointer is access all char with Convention=>C;
package Char_Address_Conversions is new
  System.Address_To_Access_Conversions(char);

One of the steps of implementing the functions To_Pointer and To_Access is 
to convert between chars_ptr and My_Char_Pointer. This is trivially done 
with Ada.Unchecked_Conversion because they are by definition the same C type 
char* and thus have the same representation.

So our task is reduced to conversion between My_Char_Pointer an Ada object 
access.

We do this conversion (in both directions) like:

Char_Address_Conversions.To_Pointer(Address_Conversions.To_Address(...))

Address_Conversions.To_Pointer(Char_Address_Conversions.To_Address(...))

The thing to prove is that this is an injective function from object 
pointers to My_Char_Pointer values and that backward conversion is really 
its inversion.

But it is just my understanding of "The To_Pointer and To_Address 
subprograms convert back and forth between values of types Object_Pointer 
and Address." (RM 13.7.2 5/2)

That null access are mapped into NULL pointers and vice versa is left as an 
exercise to the reader.

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 3%]

* Re: Convert between C "void*" pointer and an access
  2017-10-11 22:58  6% ` Victor Porton
@ 2017-10-11 23:12  6%   ` Victor Porton
  2017-10-12  1:01  3%     ` Victor Porton
  0 siblings, 1 reply; 200+ results
From: Victor Porton @ 2017-10-11 23:12 UTC (permalink / raw)


Victor Porton wrote:

> Victor Porton wrote:
> 
>> What is the right way to convert between C "void*" pointer and an access
>> to a tagged or class-wide type?
>> 
>> Ada.Unchecked_Conversion seems to be what I need, but the access type may
>> be "fat" and thus have another format than void*.
>> 
>> I caught myself doing such unchecked conversions, but now I feel I did an
>> error.
>> 
>> For example, let
>> 
>> type X_Type is abstract tagged null record;
>> 
>> How to store X_Type'Class pointer in "void*" and convert them back and
>> forth?
> 
> It seems I've found a right solution of my problem. (Check if Ada RM
> warrants that it works with every compiler!)
> 
> Well, why it is not a standard package?! Why I need to invent something
> "smart" every time I need to code?

The package body was with a bug. Here there is corrected code:


with System.Address_To_Access_Conversions;
with Interfaces.C.Strings; use Interfaces.C.Strings;

-- C11, 6.2.5, 28 (draft N1548):
-- A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.
-- So we can use chars_ptr to mean void pointer in C.

generic
    type Object(<>) is limited private;
package Convert_Void is

   package Address_Conversions is new System.Address_To_Access_Conversions(Object);

   subtype Object_Pointer is Address_Conversions.Object_Pointer;

   function To_Access (Void_Pointer: chars_ptr) return Object_Pointer;

   function To_C_Pointer (Pointer: Object_Pointer) return chars_ptr;

end Convert_Void;


with Ada.Unchecked_Conversion;

package body Convert_Void is

   type My_Char_Pointer is access all char with Convention=>C;

   function From_My_Char_Pointer is new Ada.Unchecked_Conversion(My_Char_Pointer, chars_ptr);
   function From_Chars_Ptr is new Ada.Unchecked_Conversion(chars_ptr, My_Char_Pointer);

   package Char_Address_Conversions is new System.Address_To_Access_Conversions(char);

   function To_Access (Void_Pointer: chars_ptr) return Object_Pointer is
      P: constant My_Char_Pointer := From_Chars_Ptr(Void_Pointer);
      A: constant System.Address :=
        Char_Address_Conversions.To_Address(Char_Address_Conversions.Object_Pointer(P));
   begin
      return Address_Conversions.To_Pointer(A);
   end;

   function To_C_Pointer (Pointer: Object_Pointer) return chars_ptr is
      A: constant System.Address := Address_Conversions.To_Address(Pointer);
      P: constant My_Char_Pointer :=
        My_Char_Pointer(Char_Address_Conversions.To_Pointer(A));
   begin
      return From_My_Char_Pointer(P);
   end;

end Convert_Void;

-- 
Victor Porton - http://portonvictor.org


^ permalink raw reply	[relevance 6%]

* Re: Convert between C "void*" pointer and an access
  @ 2017-10-11 22:58  6% ` Victor Porton
  2017-10-11 23:12  6%   ` Victor Porton
  0 siblings, 1 reply; 200+ results
From: Victor Porton @ 2017-10-11 22:58 UTC (permalink / raw)


Victor Porton wrote:

> What is the right way to convert between C "void*" pointer and an access
> to a tagged or class-wide type?
> 
> Ada.Unchecked_Conversion seems to be what I need, but the access type may
> be "fat" and thus have another format than void*.
> 
> I caught myself doing such unchecked conversions, but now I feel I did an
> error.
> 
> For example, let
> 
> type X_Type is abstract tagged null record;
> 
> How to store X_Type'Class pointer in "void*" and convert them back and
> forth?

It seems I've found a right solution of my problem. (Check if Ada RM
warrants that it works with every compiler!)

Well, why it is not a standard package?! Why I need to invent something
"smart" every time I need to code?

with System.Address_To_Access_Conversions;
with Interfaces.C.Strings; use Interfaces.C.Strings;

-- C11, 6.2.5, 28 (draft N1548):
-- A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.
-- So we can use chars_ptr to mean void pointer in C.

generic
    type Object(<>) is limited private;
package Convert_Void is

   package Address_Conversions is new System.Address_To_Access_Conversions(Object);

   subtype Object_Pointer is Address_Conversions.Object_Pointer;

   function To_Access (Void_Pointer: chars_ptr) return Object_Pointer;

   function To_C_Pointer (Pointer: Object_Pointer) return chars_ptr;

end Convert_Void;


with Ada.Unchecked_Conversion;

package body Convert_Void is

   type My_Char_Pointer is access all char with Convention=>C;

   function From_My_Char_Pointer is new Ada.Unchecked_Conversion(My_Char_Pointer, chars_ptr);
   function From_Chars_Ptr is new Ada.Unchecked_Conversion(chars_ptr, My_Char_Pointer);

   package Char_Address_Conversions is new System.Address_To_Access_Conversions(char);

   function To_Access (Void_Pointer: chars_ptr) return Object_Pointer is
   begin
      return Address_Conversions.To_Pointer(From_Chars_Ptr(Void_Pointer)'Address);
   end;

   function To_C_Pointer (Pointer: Object_Pointer) return chars_ptr is
      A: constant System.Address := Address_Conversions.To_Address(Pointer);
      P: constant My_Char_Pointer :=
        My_Char_Pointer(Char_Address_Conversions.To_Pointer(A));
   begin
      return From_My_Char_Pointer(P);
   end;

end Convert_Void;

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 6%]

* Re: Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders
  @ 2017-09-23  9:16  5%           ` Jeffrey R. Carter
  0 siblings, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2017-09-23  9:16 UTC (permalink / raw)


On 09/23/2017 10:09 AM, Dmitry A. Kazakov wrote:
> On 2017-09-23 00:15, Victor Porton wrote:
>>
>> In my opinion, it would be better to change RM phrasing from "null string"
>> to "empty string", because in some other languages (notably C) NULL means
>> something other. It is just confusing.
> 
> The adjective null and the noun null are distinct parts of speech. C's noun null 
> is an abbreviation of null pointer. If pointers can be null so strings can.

Another way to look at it: Ada has the formal concepts of:

* null access value ARM 4.2(9)
* null array 3.6.1(7)
* null constraint 3.2(7/2)
* null_exclusion 3.10(5.1/2)
* null extension 3.9.1(4.1/2)
* null procedure 6.7(3/3)
* null range 3.5(4)
* null record 3.8(15)
* null slice 4.1.2(7)
* null string literal 2.6(6)
* null value (of an access type) 3.10(13/2)
* null_statement 5.1(6)

not to mention the language-defined identifiers

Null_Address
    in System   13.7(12)
Null_Bounded_String
    in Ada.Strings.Bounded   A.4.4(7)
Null_Id
    in Ada.Exceptions   11.4.1(2/2)
Null_Occurrence
    in Ada.Exceptions   11.4.1(3/2)
Null_Ptr
    in Interfaces.C.Strings   B.3.1(7)
Null_Set
    in Ada.Strings.Maps   A.4.2(5)
    in Ada.Strings.Wide_Maps   A.4.7(5)
    in Ada.Strings.Wide_Wide_Maps   A.4.8(5/2)
Null_Task_Id
    in Ada.Task_Identification   C.7.1(2/2)
Null_Unbounded_String
    in Ada.Strings.Unbounded   A.4.5(5)

(Just look under N in the index.)

It's called overloading. Many of these cases refer to things that can have 
components and mean one with zero components: a null record has no components, a 
null array has no components ('Length = 0), a null string literal has no 
characters, a null set has no members, ... It should not be confusing.

-- 
Jeff Carter
"You cheesy lot of second-hand electric donkey-bottom biters."
Monty Python & the Holy Grail
14

^ permalink raw reply	[relevance 5%]

* Re: Convert an access to constant to access to variable
  @ 2017-08-07 23:16  6%     ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2017-08-07 23:16 UTC (permalink / raw)


"Victor Porton" <porton@narod.ru> wrote in message 
news:om500e$3iv$1@gioia.aioe.org...
...
> I need chars_ptr for interfacing with C.
>
> There is no constant_chars_ptr.
>
> (I need to generate chars_ptr from a char_array or rather from constant
> char_array.)

We did all of this sort of stuff just using Interfaces.C.To_Ada and various 
types with convention C. I don't think I've ever used Interfaces.C.Strings 
and Interfaces.C.Pointers outside of testing them. I think you are seeing 
why...

                                       Randy.


^ permalink raw reply	[relevance 6%]

* Re: Need a way to convert a constant to a variable
  2017-08-05 13:41  6% Need a way to convert a constant to a variable Victor Porton
  2017-08-05 14:48  0% ` Dmitry A. Kazakov
  2017-08-05 15:41  7% ` Jeffrey R. Carter
@ 2017-08-05 17:59  0% ` Per Sandberg
  2 siblings, 0 replies; 200+ results
From: Per Sandberg @ 2017-08-05 17:59 UTC (permalink / raw)


????
A constant shall never ever change its value since the compiler is free 
to use the value in compile time to optimize the code if possible.

So the whole suggestion is screaming "I want to do a very bad design".

/P


Den 2017-08-05 kl. 15:41, skrev Victor Porton:
> I've sent the following email to ada-comment mailing list. I duplicate it
> here.
> 
> !topic Need a way to convert a constant to a variable
> !reference Ada 2012 RM
> !from Victor Porton 17-08-05
> !keywords constant, variable, view, conversion
> !discussion
> 
> Sometimes one needs to convert a constant view into variable view (I am
> fully conscious that after this the programmer should take care not to
> change the object of the view).
> 
> In the following (not compilable with GNAT 7.1.0) code I present my
> best attempt to solve the following problem:
> 
> Write a function with an "in" indefinite holder with a string, return
> chars_ptr corresponding to the string.
> 
> It looks like there is no solution of this in Ada 2012 :-(
> 
> with Interfaces.C; use Interfaces.C;
> with Interfaces.C.Strings; use Interfaces.C.Strings;
> with Ada.Containers.Indefinite_Holders;
> 
> procedure Conv is
> 
>     package Char_Array_Holders is
>        new Ada.Containers.Indefinite_Holders(char_array);
> 
>     type C_String_Holder is new Char_Array_Holders.Holder
>        with null record;
>     
>     function To_C_String (Object: C_String_Holder) return chars_ptr is
>        Value: char_array renames Constant_Reference(Object).Element.all;
>        Value2: aliased Char_Array(Value'Range) with Import;
>        for Value2'Address use Value'Address;
>     begin
>        return To_Chars_Ptr(Char_Array_Access'(Value2'Access));
>     end;
> begin
>     null;
> end;
> 
> $ gnatgcc -c conv.adb -c conv.adb
> conv.adb:13:07: warning: aliased object has explicit bounds
> conv.adb:13:07: warning: declare without bounds (and with explicit
> initialization)
> conv.adb:13:07: warning: for use with unconstrained access
> conv.adb:16:46: object subtype must statically match designated subtype
> 
> My current workaround is to define my own "indefinite holder" type to
> use it in my software instead of Ada.Containers.Indefinite_Holders.
> 
> I propose the following language change:
> 
> Please add 'Unchecked_Variable attribute.
> 
> There are two possible meanings (of which we should choose one) of the
> attribute:
> 
> 1. C'Unchecked_Variable returns a variable view of a constant C.
> 
> 2. A'Unchecked_Variable returns the corresponding access to a variable
> for an access A to constant.
> 
> Both variants seem to solve the trouble.
> 
> Can any problem with different representation of constant and variables
> appear?
> 

^ permalink raw reply	[relevance 0%]

* Re: Need a way to convert a constant to a variable
  2017-08-05 15:41  7% ` Jeffrey R. Carter
@ 2017-08-05 16:25  0%   ` Victor Porton
  0 siblings, 0 replies; 200+ results
From: Victor Porton @ 2017-08-05 16:25 UTC (permalink / raw)


Jeffrey R. Carter wrote:

> On 08/05/2017 03:41 PM, Victor Porton wrote:
>> 
>> Write a function with an "in" indefinite holder with a string, return
>> chars_ptr corresponding to the string.
> 
> Your requirements are for an indefinite holder with a string, but your
> attempted solution is for an indefinite holder with a char_array. I will
> assume you meant an indefinite holder with a char_array.

Yes, my typo. I am about an indefinite holder with a char_array.

>> It looks like there is no solution of this in Ada 2012 :-(
> 
> with Ada.Containers.Indefinite_Holders;
> with Interfaces.C.Strings;
> 
> package Conv is
>     package C_Str_Holders is new Ada.Containers.Indefinite_Holders
>        (Element_Type => Interfaces.C.Char_Array, "=" => Interfaces.C."=");
> 
>     function To_Chars_Ptr (Item : C_Str_Holders.Holder)
>                         return Interfaces.C.Strings.Chars_Ptr is
>        (Interfaces.C.Strings.New_Char_Array (Item.Element) );
> end Conv;
> 
> This compiles fine, so clearly there is a way to do this without a
> language change.

Your code allocates a new string which requires to be freed later.

I want a function, which would return a pointer to the (not necessarily nul-
terminated) string hold in the indefinite holder, so that deallocation would 
be not required and code would be more efficient (not requiring to copy the 
char_array).

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 0%]

* Re: Need a way to convert a constant to a variable
  2017-08-05 13:41  6% Need a way to convert a constant to a variable Victor Porton
  2017-08-05 14:48  0% ` Dmitry A. Kazakov
@ 2017-08-05 15:41  7% ` Jeffrey R. Carter
  2017-08-05 16:25  0%   ` Victor Porton
  2017-08-05 17:59  0% ` Per Sandberg
  2 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2017-08-05 15:41 UTC (permalink / raw)


On 08/05/2017 03:41 PM, Victor Porton wrote:
> 
> Write a function with an "in" indefinite holder with a string, return
> chars_ptr corresponding to the string.

Your requirements are for an indefinite holder with a string, but your attempted 
solution is for an indefinite holder with a char_array. I will assume you meant 
an indefinite holder with a char_array.

> It looks like there is no solution of this in Ada 2012 :-(

with Ada.Containers.Indefinite_Holders;
with Interfaces.C.Strings;

package Conv is
    package C_Str_Holders is new Ada.Containers.Indefinite_Holders
       (Element_Type => Interfaces.C.Char_Array, "=" => Interfaces.C."=");

    function To_Chars_Ptr (Item : C_Str_Holders.Holder)
                        return Interfaces.C.Strings.Chars_Ptr is
       (Interfaces.C.Strings.New_Char_Array (Item.Element) );
end Conv;

This compiles fine, so clearly there is a way to do this without a language change.

-- 
Jeff Carter
"He didn't get that nose from playing ping-pong."
Never Give a Sucker an Even Break
110

---
This email has been checked for viruses by AVG.
http://www.avg.com


^ permalink raw reply	[relevance 7%]

* Re: Need a way to convert a constant to a variable
  2017-08-05 14:48  0% ` Dmitry A. Kazakov
@ 2017-08-05 15:11  0%   ` Victor Porton
  0 siblings, 0 replies; 200+ results
From: Victor Porton @ 2017-08-05 15:11 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> On 2017-08-05 15:41, Victor Porton wrote:
>> I've sent the following email to ada-comment mailing list. I duplicate it
>> here.
>> 
>> !topic Need a way to convert a constant to a variable
>> !reference Ada 2012 RM
>> !from Victor Porton 17-08-05
>> !keywords constant, variable, view, conversion
>> !discussion
>> 
>> Sometimes one needs to convert a constant view into variable view (I am
>> fully conscious that after this the programmer should take care not to
>> change the object of the view).
>> 
>> In the following (not compilable with GNAT 7.1.0) code I present my
>> best attempt to solve the following problem:
>> 
>> Write a function with an "in" indefinite holder with a string, return
>> chars_ptr corresponding to the string.
>> 
>> It looks like there is no solution of this in Ada 2012 :-(
>> 
>> with Interfaces.C; use Interfaces.C;
>> with Interfaces.C.Strings; use Interfaces.C.Strings;
>> with Ada.Containers.Indefinite_Holders;
>> 
>> procedure Conv is
>> 
>>     package Char_Array_Holders is
>>        new Ada.Containers.Indefinite_Holders(char_array);
>> 
>>     type C_String_Holder is new Char_Array_Holders.Holder
>>        with null record;
>>     
>>     function To_C_String (Object: C_String_Holder) return chars_ptr is
>>        Value: char_array renames Constant_Reference(Object).Element.all;
>>        Value2: aliased Char_Array(Value'Range) with Import;
>>        for Value2'Address use Value'Address;
>>     begin
>>        return To_Chars_Ptr(Char_Array_Access'(Value2'Access));
>>     end;
>> begin
>>     null;
>> end;
> 
> AFAIK, Ada.Containers.Indefinite_Holders was designed in a way to
> prevent specifically what you want.
> 
>> Can any problem with different representation of constant and variables
>> appear?
> 
> 1. Don't use Ada.Containers.Indefinite_Holders?
> 
> 2. Don't use char_array. It has restricted use when interfacing C. You
> probably need chars_ptr put into a controlled type if you want safe C
> strings. This is basically same as Holder internally is, except that you
> are in full control.

I do use char_array for interfacing with C.

It is a pity that I need to reimplement Indefinite_Holders for this task.

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 0%]

* Re: Need a way to convert a constant to a variable
  2017-08-05 13:41  6% Need a way to convert a constant to a variable Victor Porton
@ 2017-08-05 14:48  0% ` Dmitry A. Kazakov
  2017-08-05 15:11  0%   ` Victor Porton
  2017-08-05 15:41  7% ` Jeffrey R. Carter
  2017-08-05 17:59  0% ` Per Sandberg
  2 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2017-08-05 14:48 UTC (permalink / raw)


On 2017-08-05 15:41, Victor Porton wrote:
> I've sent the following email to ada-comment mailing list. I duplicate it
> here.
> 
> !topic Need a way to convert a constant to a variable
> !reference Ada 2012 RM
> !from Victor Porton 17-08-05
> !keywords constant, variable, view, conversion
> !discussion
> 
> Sometimes one needs to convert a constant view into variable view (I am
> fully conscious that after this the programmer should take care not to
> change the object of the view).
> 
> In the following (not compilable with GNAT 7.1.0) code I present my
> best attempt to solve the following problem:
> 
> Write a function with an "in" indefinite holder with a string, return
> chars_ptr corresponding to the string.
> 
> It looks like there is no solution of this in Ada 2012 :-(
> 
> with Interfaces.C; use Interfaces.C;
> with Interfaces.C.Strings; use Interfaces.C.Strings;
> with Ada.Containers.Indefinite_Holders;
> 
> procedure Conv is
> 
>     package Char_Array_Holders is
>        new Ada.Containers.Indefinite_Holders(char_array);
> 
>     type C_String_Holder is new Char_Array_Holders.Holder
>        with null record;
>     
>     function To_C_String (Object: C_String_Holder) return chars_ptr is
>        Value: char_array renames Constant_Reference(Object).Element.all;
>        Value2: aliased Char_Array(Value'Range) with Import;
>        for Value2'Address use Value'Address;
>     begin
>        return To_Chars_Ptr(Char_Array_Access'(Value2'Access));
>     end;
> begin
>     null;
> end;

AFAIK, Ada.Containers.Indefinite_Holders was designed in a way to 
prevent specifically what you want.

> Can any problem with different representation of constant and variables
> appear?

1. Don't use Ada.Containers.Indefinite_Holders?

2. Don't use char_array. It has restricted use when interfacing C. You 
probably need chars_ptr put into a controlled type if you want safe C 
strings. This is basically same as Holder internally is, except that you 
are in full control.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Need a way to convert a constant to a variable
@ 2017-08-05 13:41  6% Victor Porton
  2017-08-05 14:48  0% ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Victor Porton @ 2017-08-05 13:41 UTC (permalink / raw)


I've sent the following email to ada-comment mailing list. I duplicate it 
here.

!topic Need a way to convert a constant to a variable
!reference Ada 2012 RM
!from Victor Porton 17-08-05
!keywords constant, variable, view, conversion
!discussion

Sometimes one needs to convert a constant view into variable view (I am
fully conscious that after this the programmer should take care not to
change the object of the view).

In the following (not compilable with GNAT 7.1.0) code I present my
best attempt to solve the following problem:

Write a function with an "in" indefinite holder with a string, return
chars_ptr corresponding to the string.

It looks like there is no solution of this in Ada 2012 :-(

with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;
with Ada.Containers.Indefinite_Holders;

procedure Conv is

   package Char_Array_Holders is
      new Ada.Containers.Indefinite_Holders(char_array);

   type C_String_Holder is new Char_Array_Holders.Holder
      with null record;
   
   function To_C_String (Object: C_String_Holder) return chars_ptr is
      Value: char_array renames Constant_Reference(Object).Element.all;
      Value2: aliased Char_Array(Value'Range) with Import;
      for Value2'Address use Value'Address;
   begin
      return To_Chars_Ptr(Char_Array_Access'(Value2'Access));
   end;
begin
   null;
end;

$ gnatgcc -c conv.adb -c conv.adb 
conv.adb:13:07: warning: aliased object has explicit bounds
conv.adb:13:07: warning: declare without bounds (and with explicit
initialization)
conv.adb:13:07: warning: for use with unconstrained access
conv.adb:16:46: object subtype must statically match designated subtype

My current workaround is to define my own "indefinite holder" type to
use it in my software instead of Ada.Containers.Indefinite_Holders.

I propose the following language change:

Please add 'Unchecked_Variable attribute.

There are two possible meanings (of which we should choose one) of the
attribute:

1. C'Unchecked_Variable returns a variable view of a constant C.

2. A'Unchecked_Variable returns the corresponding access to a variable
for an access A to constant.

Both variants seem to solve the trouble.

Can any problem with different representation of constant and variables
appear?

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 6%]

* Re: Convert chars_ptr to Ada String
  2017-07-10 12:41  6%               ` Mark Lorenzen
@ 2017-07-10 14:24  0%                 ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2017-07-10 14:24 UTC (permalink / raw)


On 10/07/2017 14:41, Mark Lorenzen wrote:
> On Monday, July 10, 2017 at 11:48:29 AM UTC+2, Dmitry A. Kazakov wrote:
>> On 10/07/2017 11:31, Victor Porton wrote:
>>
>>> Read description of Value() carefully. It stops at first NUL.
>>
>>      if Ptr = Null_Ptr then
>>         return "";
>>      else
>>         return To_Ada (Value (Ptr, Length), False);
>>      end if;
> 
> I don't think that it will work as (if I understand it correctly) the
> string the OP tries to convert may contain NULL characters that are
> not to be interpreted as string terminators.
I see, it seems that Value is broken in ARM B.3.1(35). The semantics 
specified is:

"If Item = Null_Ptr, then Value propagates Dereference_Error. Otherwise, 
Value returns the shorter of two arrays, either the first Length chars 
pointed to by Item, or Value(Item). The lower bound of the result is 0. 
If Length is 0, then Value propagates Constraint_Error."

which is if not useless then incomplete. There must be Trim_Nul or 
Ignore_Nul parameter as in To_Ada and Length=0 must be OK.

> I think the problem is, that the OP is confused about the difference
> between C strings and C arrays of characters and tries to use
> Interfaces.C.Strings to manipulate C arrays of characters thar are not
> be interpreted as C strings but as simple arrays of characters.

There is no such difference. Some C functions use NUL some ignore it. 
The OP's request is absolutely reasonable.

> Maybe Interfaces.C.Pointers is more appropriate?

Yes. There seems no way other than to use Interfaces.C.Pointers and 
convert each character individually.

I would suggest the OP to post a change request to ARG.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Re: Convert chars_ptr to Ada String
  @ 2017-07-10 12:41  6%               ` Mark Lorenzen
  2017-07-10 14:24  0%                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Mark Lorenzen @ 2017-07-10 12:41 UTC (permalink / raw)


On Monday, July 10, 2017 at 11:48:29 AM UTC+2, Dmitry A. Kazakov wrote:
> On 10/07/2017 11:31, Victor Porton wrote:
> 
> > Read description of Value() carefully. It stops at first NUL.
> 
>     if Ptr = Null_Ptr then
>        return "";
>     else
>        return To_Ada (Value (Ptr, Length), False);
>     end if;
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

I don't think that it will work as (if I understand it correctly) the string the OP tries to convert may contain NULL characters that are not to be interpreted as string terminators.

I think the problem is, that the OP is confused about the difference between C strings and C arrays of characters and tries to use Interfaces.C.Strings to manipulate C arrays of characters thar are not be interpreted as C strings but as simple arrays of characters.

Maybe Interfaces.C.Pointers is more appropriate?

Regards,

Mark L


^ permalink raw reply	[relevance 6%]

* Re: Convert chars_ptr to Ada String
  2017-07-10  4:58  5%         ` Anh Vo
@ 2017-07-10  9:31  0%           ` Victor Porton
    0 siblings, 1 reply; 200+ results
From: Victor Porton @ 2017-07-10  9:31 UTC (permalink / raw)


Anh Vo wrote:

> On Saturday, July 8, 2017 at 11:49:34 PM UTC-7, Victor Porton wrote:
>> Anh Vo wrote:
>> 
>> > On Friday, July 7, 2017 at 3:49:20 PM UTC-7, Victor Porton wrote:
>> >> Anh Vo wrote:
>> >> 
>> >> > On Friday, July 7, 2017 at 2:03:32 PM UTC-7, Victor Porton wrote:
>> >> >> Remind me how to convert a pair of Ptr: chars_ptr and Size: size_t
>> >> >> to an Ada string.
>> >> >> 
>> >> >> Ptr may contain NULs and this should not influence the length of
>> >> >> the resulting string.
>> >> > 
>> >> > Look at APIs defined in package Interfaces.C.Strings.
>> >> 
>> >> I've done it:
>> >> 
>> >> https://github.com/vporton/redland-bindings/blob/ada2012/ada/src/rdf-auxiliary-convert.adb
>> >> 
>> >> It requires not only Interfaces.C.Strings but also
>> >> Interfaces.C.Pointers to make things more confusing.
>> > 
>> > Why make it more confusing while it is actually simpler as shown below.
>> > 
>> > with Interfaces.C.Strings; use Interfaces.C.Strings;
>> > 
>> > package body RDF.Auxiliary.Convert is
>> > 
>> >    function Value_With_Possible_NULs (Item:
>> >    RDF.Auxiliary.C_Pointers.Pointer; Length: size_t) return String is
>> >    begin
>> >       return To_Ada(Item, Length);
>> 
>> I see no such two-argument To_Ada in Interfaces.C.
>> 
>> Or where to import such To_Ada from?
> 
> Oops! I meant function value which is defined in Interfaces.C.Strings.

Read description of Value() carefully. It stops at first NUL.

-- 
Victor Porton - http://portonvictor.org


^ permalink raw reply	[relevance 0%]

* Re: Convert chars_ptr to Ada String
  2017-07-09  6:49  0%       ` Victor Porton
@ 2017-07-10  4:58  5%         ` Anh Vo
  2017-07-10  9:31  0%           ` Victor Porton
  0 siblings, 1 reply; 200+ results
From: Anh Vo @ 2017-07-10  4:58 UTC (permalink / raw)


On Saturday, July 8, 2017 at 11:49:34 PM UTC-7, Victor Porton wrote:
> Anh Vo wrote:
> 
> > On Friday, July 7, 2017 at 3:49:20 PM UTC-7, Victor Porton wrote:
> >> Anh Vo wrote:
> >> 
> >> > On Friday, July 7, 2017 at 2:03:32 PM UTC-7, Victor Porton wrote:
> >> >> Remind me how to convert a pair of Ptr: chars_ptr and Size: size_t to
> >> >> an Ada string.
> >> >> 
> >> >> Ptr may contain NULs and this should not influence the length of the
> >> >> resulting string.
> >> > 
> >> > Look at APIs defined in package Interfaces.C.Strings.
> >> 
> >> I've done it:
> >> 
> >> https://github.com/vporton/redland-bindings/blob/ada2012/ada/src/rdf-auxiliary-convert.adb
> >> 
> >> It requires not only Interfaces.C.Strings but also Interfaces.C.Pointers
> >> to make things more confusing.
> > 
> > Why make it more confusing while it is actually simpler as shown below.
> > 
> > with Interfaces.C.Strings; use Interfaces.C.Strings;
> > 
> > package body RDF.Auxiliary.Convert is
> > 
> >    function Value_With_Possible_NULs (Item:
> >    RDF.Auxiliary.C_Pointers.Pointer; Length: size_t) return String is
> >    begin
> >       return To_Ada(Item, Length);
> 
> I see no such two-argument To_Ada in Interfaces.C.
> 
> Or where to import such To_Ada from?

Oops! I meant function value which is defined in Interfaces.C.Strings.


^ permalink raw reply	[relevance 5%]

* Re: Convert chars_ptr to Ada String
  2017-07-07 23:14  6%     ` Anh Vo
@ 2017-07-09  6:49  0%       ` Victor Porton
  2017-07-10  4:58  5%         ` Anh Vo
  0 siblings, 1 reply; 200+ results
From: Victor Porton @ 2017-07-09  6:49 UTC (permalink / raw)


Anh Vo wrote:

> On Friday, July 7, 2017 at 3:49:20 PM UTC-7, Victor Porton wrote:
>> Anh Vo wrote:
>> 
>> > On Friday, July 7, 2017 at 2:03:32 PM UTC-7, Victor Porton wrote:
>> >> Remind me how to convert a pair of Ptr: chars_ptr and Size: size_t to
>> >> an Ada string.
>> >> 
>> >> Ptr may contain NULs and this should not influence the length of the
>> >> resulting string.
>> > 
>> > Look at APIs defined in package Interfaces.C.Strings.
>> 
>> I've done it:
>> 
>> https://github.com/vporton/redland-bindings/blob/ada2012/ada/src/rdf-auxiliary-convert.adb
>> 
>> It requires not only Interfaces.C.Strings but also Interfaces.C.Pointers
>> to make things more confusing.
> 
> Why make it more confusing while it is actually simpler as shown below.
> 
> with Interfaces.C.Strings; use Interfaces.C.Strings;
> 
> package body RDF.Auxiliary.Convert is
> 
>    function Value_With_Possible_NULs (Item:
>    RDF.Auxiliary.C_Pointers.Pointer; Length: size_t) return String is
>    begin
>       return To_Ada(Item, Length);

I see no such two-argument To_Ada in Interfaces.C.

Or where to import such To_Ada from?

>    end;
> 
> end RDF.Auxiliary.Convert;

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 0%]

* Re: Convert chars_ptr to Ada String
  2017-07-07 22:48  6%   ` Victor Porton
@ 2017-07-07 23:14  6%     ` Anh Vo
  2017-07-09  6:49  0%       ` Victor Porton
  0 siblings, 1 reply; 200+ results
From: Anh Vo @ 2017-07-07 23:14 UTC (permalink / raw)


On Friday, July 7, 2017 at 3:49:20 PM UTC-7, Victor Porton wrote:
> Anh Vo wrote:
> 
> > On Friday, July 7, 2017 at 2:03:32 PM UTC-7, Victor Porton wrote:
> >> Remind me how to convert a pair of Ptr: chars_ptr and Size: size_t to an
> >> Ada string.
> >> 
> >> Ptr may contain NULs and this should not influence the length of the
> >> resulting string.
> > 
> > Look at APIs defined in package Interfaces.C.Strings.
> 
> I've done it:
> 
> https://github.com/vporton/redland-bindings/blob/ada2012/ada/src/rdf-auxiliary-convert.adb
> 
> It requires not only Interfaces.C.Strings but also Interfaces.C.Pointers
> to make things more confusing.

Why make it more confusing while it is actually simpler as shown below.

with Interfaces.C.Strings; use Interfaces.C.Strings;

package body RDF.Auxiliary.Convert is

   function Value_With_Possible_NULs (Item: RDF.Auxiliary.C_Pointers.Pointer; Length: size_t) return String is
   begin
      return To_Ada(Item, Length);
   end;

end RDF.Auxiliary.Convert;


^ permalink raw reply	[relevance 6%]

* Re: Convert chars_ptr to Ada String
  2017-07-07 22:23  5% ` Anh Vo
@ 2017-07-07 22:48  6%   ` Victor Porton
  2017-07-07 23:14  6%     ` Anh Vo
  0 siblings, 1 reply; 200+ results
From: Victor Porton @ 2017-07-07 22:48 UTC (permalink / raw)


Anh Vo wrote:

> On Friday, July 7, 2017 at 2:03:32 PM UTC-7, Victor Porton wrote:
>> Remind me how to convert a pair of Ptr: chars_ptr and Size: size_t to an
>> Ada string.
>> 
>> Ptr may contain NULs and this should not influence the length of the
>> resulting string.
> 
> Look at APIs defined in package Interfaces.C.Strings.

I've done it:

https://github.com/vporton/redland-bindings/blob/ada2012/ada/src/rdf-auxiliary-convert.adb

It requires not only Interfaces.C.Strings but also Interfaces.C.Pointers
to make things more confusing.

-- 
Victor Porton - http://portonvictor.org


^ permalink raw reply	[relevance 6%]

* Re: Convert chars_ptr to Ada String
  @ 2017-07-07 22:23  5% ` Anh Vo
  2017-07-07 22:48  6%   ` Victor Porton
  0 siblings, 1 reply; 200+ results
From: Anh Vo @ 2017-07-07 22:23 UTC (permalink / raw)


On Friday, July 7, 2017 at 2:03:32 PM UTC-7, Victor Porton wrote:
> Remind me how to convert a pair of Ptr: chars_ptr and Size: size_t to an Ada 
> string. 
> 
> Ptr may contain NULs and this should not influence the length of the 
> resulting string.

Look at APIs defined in package Interfaces.C.Strings.

Anh Vo


^ permalink raw reply	[relevance 5%]

* Re: How to use/obtain output from system commands (in an Ada program) ?
  2016-06-19  7:23  0% ` Dmitry A. Kazakov
@ 2016-06-20  8:34  0%   ` reinkor
  0 siblings, 0 replies; 200+ results
From: reinkor @ 2016-06-20  8:34 UTC (permalink / raw)


Thanks a lot,

any hint about rpm/repository for gtkada on OpenSuse (Leap) ?

reinert


On Sunday, June 19, 2016 at 9:24:16 AM UTC+2, Dmitry A. Kazakov wrote:
> On 2016-06-19 08:08, reinkor wrote:
> 
> > I am looking for a simple way to obtain output from "xmessage"
> > (or dialog/kdialog) in my Ada program. Any good hints?
> 
> The package System.OS_Lib has procedures Spawn that are much more 
> comfortable to use than system().
> 
> If you use GtkAda you can start xmessage or any other process with 
> pipe-lined input/output/error. Then you will have callbacks to process 
> them. It is also possible to use Gtk_Text_Buffer instead of callbacks.
> 
> http://www.dmitry-kazakov.de/ada/gtkada_contributions.htm#10.1
> 
> > A trivial way is to output to a file like in this test procedure:
> >
> > with Interfaces.C;
> > with Interfaces.C.Strings;
> > with Ada.Text_IO, Text_IO;
> >
> > procedure Test7 is
> >    package C renames Interfaces.C;
> >    use type C.char_array;
> >    procedure system (Source : in  C.char_array);
> >    pragma Import(C, system, "system");
> >    use Ada.Text_IO, Text_IO;
> >    file1 : File_Type;
> > begin
> >      system("xmessage -center Box1  -buttons label1:X,label2:y -print > choice_file1");
> 
> Add terminating ASCII NUL here.
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 0%]

* Re: How to use/obtain output from system commands (in an Ada program) ?
  2016-06-19  6:08  6% How to use/obtain output from system commands (in an Ada program) ? reinkor
@ 2016-06-19  7:23  0% ` Dmitry A. Kazakov
  2016-06-20  8:34  0%   ` reinkor
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2016-06-19  7:23 UTC (permalink / raw)


On 2016-06-19 08:08, reinkor wrote:

> I am looking for a simple way to obtain output from "xmessage"
> (or dialog/kdialog) in my Ada program. Any good hints?

The package System.OS_Lib has procedures Spawn that are much more 
comfortable to use than system().

If you use GtkAda you can start xmessage or any other process with 
pipe-lined input/output/error. Then you will have callbacks to process 
them. It is also possible to use Gtk_Text_Buffer instead of callbacks.

http://www.dmitry-kazakov.de/ada/gtkada_contributions.htm#10.1

> A trivial way is to output to a file like in this test procedure:
>
> with Interfaces.C;
> with Interfaces.C.Strings;
> with Ada.Text_IO, Text_IO;
>
> procedure Test7 is
>    package C renames Interfaces.C;
>    use type C.char_array;
>    procedure system (Source : in  C.char_array);
>    pragma Import(C, system, "system");
>    use Ada.Text_IO, Text_IO;
>    file1 : File_Type;
> begin
>      system("xmessage -center Box1  -buttons label1:X,label2:y -print > choice_file1");

Add terminating ASCII NUL here.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 0%]

* How  to use/obtain output from system commands (in an Ada program) ?
@ 2016-06-19  6:08  6% reinkor
  2016-06-19  7:23  0% ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: reinkor @ 2016-06-19  6:08 UTC (permalink / raw)


Hi,

I am looking for a simple way to obtain output from "xmessage"
(or dialog/kdialog) in my Ada program. Any good hints?

A trivial way is to output to a file like in this test procedure:

with Interfaces.C;
with Interfaces.C.Strings;
with Ada.Text_IO, Text_IO;

procedure Test7 is
   package C renames Interfaces.C;
   use type C.char_array;
   procedure system (Source : in  C.char_array);
   pragma Import(C, system, "system");
   use Ada.Text_IO, Text_IO;
   file1 : File_Type;
begin
     system("xmessage -center Box1  -buttons label1:X,label2:y -print > choice_file1");
     Open(file1,In_File,"choice_file1");
     declare
      A : String := Get_Line(file1);
     begin
      Put(" Choice: " & A);
     end;
     Close(file1);
end Test7;

Are there more direct/better ways?

** By the way: when I run this program on Raspberry Pi 
(lastest Raspbian jessie) i get, as expected, created the file "choice_file1".
Under OpenSuse Leap 42.1, gnat-5, i get produced a file named:
"choice_file1choice_file1test7.adb". Strange?

reinert

^ permalink raw reply	[relevance 6%]

* ANN: Cortex GNAT RTS 20160522
@ 2016-05-22 14:20  4% Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2016-05-22 14:20 UTC (permalink / raw)


Available at
https://sourceforge.net/projects/cortex-gnat-rts/files/20160522/

This release includes GNAT Ada Run Time Systems (RTSs) based
on FreeRTOS (http://www.freertos.org) and targeted at boards with
Cortex-M3, -M4, -M4F MCUs (Arduino Due from http://www.arduino.org,
the STM32F4-series evaluation boards from STMicroelectronics at
http://www.st.com).

In each case, the board support for the RTS (configuration for size
and location of Flash, RAM; clock initialization; interrupt naming) is
in $RTS/adainclude. Support for the on-chip peripherals is also
included, in Ada spec files generated by SVD2Ada
(https://github.com/AdaCore/svd2ada).

The Ada source is either original or based on FSF GCC (mainly 4.9.1,
some later releases too).

(1) arduino-due is a Ravenscar-style RTOS based on FreeRTOS from
    http://www.freertos.org for the Arduino Due.

    See arduino-due/COPYING* for licensing terms.

    On-chip peripheral support in atsam3x8e/.

    Tests in test-arduino-due/.

(2) stm32f4 is a Ravenscar-style RTOS based on FreeRTOS from
    http://www.freertos.org for the STM32F4-DISC* board.

    See stm32f4/COPYING* for licensing terms.

    On-chip peripheral support in stm32f40x/.

    Tests in test-stm32f4/.

(3) stm32f429i is a Ravenscar-style RTOS based on FreeRTOS from
    http://www.freertos.org for the STM32F429I-DISC* board.

    See stm32f429i/COPYING* for licensing terms.

    On-chip peripheral support in stm32f429x/.

    Tests in test-stm32f429i/.

In this release,

* There is no longer any dependence on the STMicroelectronics'
  STM32Cube package.

* The support for on-chip peripherals is limited to the
  SVD2Ada-generated spec files. The AdaCore 'bareboard' software
  (currently https://github.com/AdaCore/bareboard, but a name change
  is under consideration) supports the STM32 line.

* Tasking no longer requires an explicit start
  (https://sourceforge.net/p/cortex-gnat-rts/tickets/5/).

* Locking in interrupt-handling protected objects no longer inhibits
  all interrupts, only those of equal or lower priority
  (https://sourceforge.net/p/cortex-gnat-rts/tickets/18/).

The standard packages included (there are more, implementation-specific,
ones) are:

Ada
Ada.Containers
Ada.Containers.Bounded_Hashed_Maps
Ada.Containers.Bounded_Vectors
Ada.Exceptions
Ada.IO_Exceptions
Ada.Interrupts
Ada.Interrupts.Names
Ada.Iterator_Interfaces
Ada.Real_Time
Ada.Streams
Ada.Synchronous_Task_Control
Ada.Tags
Ada.Task_Identification
Interfaces
Interfaces.C
Interfaces.C.Strings
System
System.Assertions
System.Address_To_Access_Conversions
System.Storage_Elements
GNAT
GNAT.Source_Info


^ permalink raw reply	[relevance 4%]

* Re: A suggestion about interfacing with C
  2016-05-02 16:45  5% A suggestion about interfacing with C mockturtle
  2016-05-02 19:07  0% ` Jeffrey R. Carter
@ 2016-05-02 19:40  0% ` Per Sandberg
  1 sibling, 0 replies; 200+ results
From: Per Sandberg @ 2016-05-02 19:40 UTC (permalink / raw)


Well
I would have done it in two steps
1) generate a full low-level interface using -fdump-ada-spec
2) Do the high level interface using the generated specs in the private 
part.
I usually use a script like the following:
##################################################################################
#!/bin/bash
mkdir -p .gen
rm -rf src/gen
mkdir -p src/gen

(cd /usr/include/ ; find libnl3/ -type f -name "*.h")  | \
		grep -v -e qdisc/hfsc.h  \
				-e netlink/hashtable.h \
				-e route/link/info-api.h \
				-e route/link/sit.h \
				-e route/tc-api.h \
				-e route/link/api.h \
				-e route/link/ip6tnl.h \
				-e netlink/cache-api.h | sed -e "s-^-#include <-" -e "s-\$->-" | 
while read i ; do
	echo $i >.gen/gen.cpp
	(cd .gen; gcc -I /usr/include/libnl3/ -c -fdump-ada-spec gen.cpp)
done

# patch up all standard stuff (size_t, int32, uint32, ...)
# Get rid of dependencies to bits_*.h ctype.h ans alike.
sed -f sed sed/all.sed .gen/*.ads -i

# And file specific patches.
for i in sed/*.sed ; do
	name=$(basename $i .sed).ads
	echo .gen/$name
	if [[ -e ${name} ]] ; then
		sed -f $i -i ${name}
	fi
done

cp .gen/libnl3_* src/gen
##################################################################################

Den 2016-05-02 kl. 18:45, skrev mockturtle:
> Dear all,
> I need to interface with a C library (libnl, for using Netlink in Linux).  The library provides a "socket" represented by a struct nl_sock, but the user (the library user, that is, myself) sees only a pointer to nl_sock, since the library provides constructors, destructors and everything is needed to manipulate the socket. In a sense, the user can consider the pointer just as an "opaque handler" rather than a pointer. (I must say that my first impression of the API is definitively positive).
>
> In Ada I would like to provide a slightly thick package that hides the C type behind a, say, Netlink_Socket type that could be a record holding the pointer to nl_sock. Note that since libnl uses said pointer as an opaque handle, I just need to store the "bitstring" representing its value, in order to pass it to the C library.
>
> I was wandering about the best way to implement the Ada "view"  of the pointer to nl_sock.
>
> * I could use Interfaces.C.Pointers, but it seems me an overkill since I do not need to do pointer arithmetic.  Moreover, I would need to define a record equivalento to struct nl_sock (although maybe in my case a null record could suffice)
>
> * I could convert it in C to a char* and then using Interfaces.C.Strings.  (A bit dirty, but not too much...)
>
> * I could convert it to an integer... (no, definitively too dirty)
>
> * others?
>
> What would you suggest?
>
> Keep in mind that the software will run on Linux only (Netlink is specific to Linux, as long as I know) and at 99.99% only on x86 and similar.
>
> Thank you in advance for your help
>
> Riccardo
>

^ permalink raw reply	[relevance 0%]

* Re: A suggestion about interfacing with C
  2016-05-02 16:45  5% A suggestion about interfacing with C mockturtle
@ 2016-05-02 19:07  0% ` Jeffrey R. Carter
  2016-05-02 19:40  0% ` Per Sandberg
  1 sibling, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2016-05-02 19:07 UTC (permalink / raw)


On 05/02/2016 09:45 AM, mockturtle wrote:
>
> I need to interface with a C library (libnl, for using Netlink in Linux).  The library provides a "socket" represented by a struct nl_sock, but the user (the library user, that is, myself) sees only a pointer to nl_sock, since the library provides constructors, destructors and everything is needed to manipulate the socket. In a sense, the user can consider the pointer just as an "opaque handler" rather than a pointer. (I must say that my first impression of the API is definitively positive).
>
> In Ada I would like to provide a slightly thick package that hides the C type behind a, say, Netlink_Socket type that could be a record holding the pointer to nl_sock. Note that since libnl uses said pointer as an opaque handle, I just need to store the "bitstring" representing its value, in order to pass it to the C library.

The 1st question is, "How many objects of this type are there in a typical 
application?" Very often in C, you find a type like this even though it makes no 
sense to have more than one of them, because the language lacks modules. If this 
is one of those cases where there will only be one of them, then the Ada 
implementation would be a pkg providing only operations, with the C pointer 
hidden in the body.

This doesn't address your low-level question, which is

> I was wandering about the best way to implement the Ada "view"  of the pointer to nl_sock.
>
> * I could use Interfaces.C.Pointers, but it seems me an overkill since I do not need to do pointer arithmetic.  Moreover, I would need to define a record equivalento to struct nl_sock (although maybe in my case a null record could suffice)
>
> * I could convert it in C to a char* and then using Interfaces.C.Strings.  (A bit dirty, but not too much...)
>
> * I could convert it to an integer... (no, definitively too dirty)
>
> * others?

This kind of opaque pointer is very common in C libraries. Some use "void*" to 
further hide the implementation details. I think you're over thinking things 
here. I usually do something like

type C_Socket is null record;
pragma Convention (C, C_Socket);

type Socket_Ptr is access all C_Socket;
pragma Convention (C, Socket_Ptr);

If you're hiding this in the pkg body, then you're done. If you're exposing the 
type, then these would be in the private part and you'll have

type Socket [(...)] is limited private;

in the public part. Also in the private part you'd have

type Socket [(...)] is limited record
    Ptr : Socket_Ptr;
end record;

or maybe even

function New_Socket [(...)] return Socket_Ptr;
pragma Import (C, New_Socket, ...);

type Socket [(...)] is limited record
    Ptr : Socket_Ptr := New_Socket [(...)];
end record;

Of course, if finalization is needed, this becomes a little more complex, as 
does initialization that needs parameters that can't be discriminants.

-- 
Jeff Carter
"When Roman engineers built a bridge, they had to stand under it
while the first legion marched across. If programmers today
worked under similar ground rules, they might well find
themselves getting much more interested in Ada!"
Robert Dewar
62


^ permalink raw reply	[relevance 0%]

* A suggestion about interfacing with C
@ 2016-05-02 16:45  5% mockturtle
  2016-05-02 19:07  0% ` Jeffrey R. Carter
  2016-05-02 19:40  0% ` Per Sandberg
  0 siblings, 2 replies; 200+ results
From: mockturtle @ 2016-05-02 16:45 UTC (permalink / raw)


Dear all,
I need to interface with a C library (libnl, for using Netlink in Linux).  The library provides a "socket" represented by a struct nl_sock, but the user (the library user, that is, myself) sees only a pointer to nl_sock, since the library provides constructors, destructors and everything is needed to manipulate the socket. In a sense, the user can consider the pointer just as an "opaque handler" rather than a pointer. (I must say that my first impression of the API is definitively positive). 

In Ada I would like to provide a slightly thick package that hides the C type behind a, say, Netlink_Socket type that could be a record holding the pointer to nl_sock. Note that since libnl uses said pointer as an opaque handle, I just need to store the "bitstring" representing its value, in order to pass it to the C library.

I was wandering about the best way to implement the Ada "view"  of the pointer to nl_sock.  

* I could use Interfaces.C.Pointers, but it seems me an overkill since I do not need to do pointer arithmetic.  Moreover, I would need to define a record equivalento to struct nl_sock (although maybe in my case a null record could suffice)

* I could convert it in C to a char* and then using Interfaces.C.Strings.  (A bit dirty, but not too much...)

* I could convert it to an integer... (no, definitively too dirty)

* others? 

What would you suggest?

Keep in mind that the software will run on Linux only (Netlink is specific to Linux, as long as I know) and at 99.99% only on x86 and similar.

Thank you in advance for your help

Riccardo


^ permalink raw reply	[relevance 5%]

* ANN: Cortex GNAT RTS 20160314
@ 2016-03-14 17:42  5% Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2016-03-14 17:42 UTC (permalink / raw)


At https://sourceforge.net/projects/cortex-gnat-rts/files/20160314/.

This release includes

* an RTS for the Arduino Due, arduino-due, and a minimal BSP,
  arduino-due-bsp.

* an RTS for the STM32F429I-DISCO, stm32f429i-disco-rtos, based on
  STMicroelectronics' STM32Cube package and FreeRTOS, and a
  corresponding partial BSP, stm32f429i-disco-bsp.

* an RTS for the STM32F429I-DISCO, stm32f429i, based on FreeRTOS, with
  a set of peripheral definition packages created by SVD2Ada.

In this release,

* the Containers support generalized iteration ("for all E of C
  loop"). Note, this is achieved by removing tampering checks. While
  tampering errors are rare, it would be as well to check algorithms
  using a fully-featured desktop compiler.

The standard packages included (there are more, implementation-specific,
ones) are:

Ada
Ada.Containers
Ada.Containers.Bounded_Hashed_Maps
Ada.Containers.Bounded_Vectors
Ada.Exceptions
Ada.IO_Exceptions
Ada.Interrupts
Ada.Interrupts.Names
Ada.Iterator_Interfaces
Ada.Real_Time
Ada.Streams
Ada.Synchronous_Task_Control
Ada.Tags
Ada.Task_Identification
Interfaces
Interfaces.C
Interfaces.C.Strings
System
System.Assertions
System.Address_To_Access_Conversions
System.Storage_Elements
GNAT
GNAT.Source_Info


^ permalink raw reply	[relevance 5%]

* ANN: Cortex GNAT RTS 20160207
@ 2016-02-07 22:45  5% Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2016-02-07 22:45 UTC (permalink / raw)


This release is at Sourceforge[1].

This release includes an RTS for the Arduino Due, arduino-due, and a
minimal BSP, arduino-due-bsp.

For the STM32F429I-DISCO, there is one RTS, stm32f429i-disco-rtos, and
one BSP, stm32f429i-disco-bsp.

In this release,

* the Containers support generalized iteration ("for all E of C
  loop"). Note, this is achieved by removing tampering checks. While
  tampering errors are rare, it would be as well to check algorithms
  using a fully-featured desktop compiler.

* FreeRTOS is configured to detect stack overflow (if it is detected,
  the RTS loops inside vApplicationStackOverflowHook()).

The standard packages included (there are more,
implementation-specific, ones) are:

   Ada
   Ada.Containers
   Ada.Containers.Bounded_Hashed_Maps
   Ada.Containers.Bounded_Vectors
   Ada.Exceptions
   Ada.IO_Exceptions
   Ada.Interrupts
   Ada.Interrupts.Names
   Ada.Iterator_Interfaces
   Ada.Real_Time
   Ada.Streams
   Ada.Synchronous_Task_Control
   Ada.Tags
   Ada.Task_Identification
   Interfaces
   Interfaces.C
   Interfaces.C.Strings
   System
   System.Assertions
   System.Address_To_Access_Conversions
   System.Storage_Elements
   GNAT
   GNAT.Source_Info

The software is supplied built with for debugging (-g) and with suitable
optimisation (-Og), using GNAT GPL 2015 on Mac OS X (it should work
out of the box with a Linux-hosted GNAT GPL 2015 cross-compiler, but
will need recompiling for another compiler version).

[1] https://sourceforge.net/projects/cortex-gnat-rts/files/20160207/


^ permalink raw reply	[relevance 5%]

* Can I get rid of C libraries dependencies?
@ 2015-09-16 12:55  7% Leff Ivanov
  0 siblings, 0 replies; 200+ results
From: Leff Ivanov @ 2015-09-16 12:55 UTC (permalink / raw)


Okey, so I wrote this code:

pragma No_Run_Time;

with Interfaces.C.Strings;
use  Interfaces.C.Strings;
with Interfaces.C;
use  Interfaces.C;

procedure Main is
   procedure cputs(str:Char_Array);
   pragma Import(C, cputs, "puts");
   
   procedure cexit(code:Integer);
   pragma Import(C, cexit, "exit");
begin
   cputs("Hello World!");
   cexit(0);
end Main;

What I want to achive is a tiny 2kb binary executable 
with a single function called as entry point (which is 
defined in Ada and called Main procedure). The pragma 
on top let me get rid of the huge RTL code that is written
in Ada. However I'm still getting a lot of code linked 
in from C libraries, so...

1) Can I get rid of the C code linked in?
2) What is implemented in thoose C libraries?
3) Can I use Ada's RTL library without the C 
   support code, if I use some Restrictions?

^ permalink raw reply	[relevance 7%]

* Re: Returning a string from C
  2015-07-23  2:20  5% Returning a string from C NiGHTS
  2015-07-23  4:48  0% ` Jeffrey R. Carter
@ 2015-07-23  7:17  6% ` Dmitry A. Kazakov
  1 sibling, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2015-07-23  7:17 UTC (permalink / raw)


On Wed, 22 Jul 2015 19:20:34 -0700 (PDT), NiGHTS wrote:

> I am having some difficulty with returning a string from a C function.
> 
> Say I have the following C function:
> 
>     void Return_Hello (char *inout_Test_String ) {
>         strcpy( inout_Test_String, "Hello World" );
>     }

[...]

> What am I doing wrong here?

When you pass a string to C, use To_C from Interfaces.C that returns
char_array

 When you receive a string from C, use Chars_Ptr and Value from
Interfaces.C.Strings. E.g.

   function Foo (Text : String) return String is
      function Internal (S : char_array) return Chars_Ptr;
      pragma Import (C, Internal, "c_stuff");
      Result : Chars_Ptr;
   begin
      Result := Internal (To_C (Text));
      if Result /= Null_Ptr then
         return Value (Result);
      else
         return "";
      end if;
   end Foo;

When C side allocates a new string and your side is responsible for
deallocating it, use Free on Chars_Ptr from Interfaces.C.Strings.

If you want in-place string modified by C, pass char_array, maximum size,
actual length to C.

Never ever use strcpy, always strncpy.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 6%]

* Re: Returning a string from C
  2015-07-23  2:20  5% Returning a string from C NiGHTS
@ 2015-07-23  4:48  0% ` Jeffrey R. Carter
  2015-07-23  7:17  6% ` Dmitry A. Kazakov
  1 sibling, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2015-07-23  4:48 UTC (permalink / raw)


On 07/22/2015 07:20 PM, NiGHTS wrote:
> 
> Say I have the following C function:
> 
>     void Return_Hello (char *inout_Test_String ) {
>         strcpy( inout_Test_String, "Hello World" );
>     }
> 
> This function will use the string memory generated on the Ada side and return a simple string "Hello World". Here is how I would interface with it:
> 
>     procedure Return_Hello ( Test_String : in out chars_ptr );
>     pragma Import (C, Return_Hello, "Return_Hello");
> 
> And this is how I would use it.
> 
>     use Interfaces.C;
>     use Interfaces.C.Strings;
> 
>     declare
> 
>         Test_String      : String (1 .. 100);
>         Test_String_Char : chars_ptr := New_String (Test_String);
> 
>     begin
>     
>         Return_Hello ( Test_String_Char );
>         Test_String := Value ( Test_String_Char ) ;
>         Ada.Text_IO.Put_Line ( Test_String );
>         Free (Test_String_Char);
>   
>     end;
> 
> When I run the program I get a runtime error "length check failed" on the line "Test_String := Value ( Test_String_Char );".
> 
> What am I doing wrong here?

Well, for one thing, you're thinking like a C person and using unnecessary
pointers. I'd import the procedure as

procedure Return_Hello (Test_String : out Char_Array);

and call it with

Test_String : Char_Array (1 .. 100);

Return_Hello (Test_String => Test_String);
Ada.Text_IO.Put_Line (Item => To_Ada (Test_String) );

As for the exception you get, Value returns the string pointed to by Item up to
but not including the terminating NUL, which is 11 characters. Test_String is
100 characters, so the lengths don't match.

-- 
Jeff Carter
"Sir Robin the not-quite-so-brave-as-Sir-Lancelot,
who had nearly fought the Dragon of Angnor,
who nearly stood up to the vicious Chicken of Bristol,
and who had personally wet himself at the
Battle of Badon Hill."
Monty Python & the Holy Grail
68


^ permalink raw reply	[relevance 0%]

* Returning a string from C
@ 2015-07-23  2:20  5% NiGHTS
  2015-07-23  4:48  0% ` Jeffrey R. Carter
  2015-07-23  7:17  6% ` Dmitry A. Kazakov
  0 siblings, 2 replies; 200+ results
From: NiGHTS @ 2015-07-23  2:20 UTC (permalink / raw)


I am having some difficulty with returning a string from a C function.

Say I have the following C function:

    void Return_Hello (char *inout_Test_String ) {
        strcpy( inout_Test_String, "Hello World" );
    }

This function will use the string memory generated on the Ada side and return a simple string "Hello World". Here is how I would interface with it:

    procedure Return_Hello ( Test_String : in out chars_ptr );
    pragma Import (C, Return_Hello, "Return_Hello");

And this is how I would use it.

    use Interfaces.C;
    use Interfaces.C.Strings;

    declare

        Test_String      : String (1 .. 100);
        Test_String_Char : chars_ptr := New_String (Test_String);

    begin
    
        Return_Hello ( Test_String_Char );
        Test_String := Value ( Test_String_Char ) ;
        Ada.Text_IO.Put_Line ( Test_String );
        Free (Test_String_Char);
  
    end;

When I run the program I get a runtime error "length check failed" on the line "Test_String := Value ( Test_String_Char );".

What am I doing wrong here?

^ permalink raw reply	[relevance 5%]

* ANN: STM32F4 GNAT Run Time Systems 20150406
@ 2015-04-06 17:27  5% Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2015-04-06 17:27 UTC (permalink / raw)


This is the fourth release of a GNAT RTS with the GCC Runtime Library
exception for STM32F4 boards.

(a) Tasking is implemented using FreeRTOS[3], which STMicroelectronics
    provide a copy of with their BSP.

(b) I've included a BSP with minimal higher-level Ada interfaces to the
    board hardware: clock, buttons, LEDs, LCD. In addition, there's a
    machine-generated translation of STMicroelectronics' type-specific
    header in stm32f429xx_h.ads, for low-level interfacing.

The release is at
https://sourceforge.net/projects/stm32f4-gnat-rts/files/20150406/.

From its README,

20150406
========

This release has been reorganised from previous releases.

There is one RTS, stm32f4-disco-rtos, and one BSP, stm32f4-disco-bsp.

Changes to the RTS from the previous release:
---------------------------------------------

These units (and supporting units) are now included:

  Ada.Containers.Bounded_Vectors (*)
  Ada.Containers.Bounded_Hashed_Maps (*)
  Ada.Containers.Generic_Array_Sort
  Ada.Containers.Generic_Constrained_Array_Sort
  Ada.IO_Exceptions
  Ada.Streams
  Ada.Task_Identification
  Interfaces.C
  Interfaces.C.Strings
  System.Assertions

  (*) The new iterators (for some F in Foo loop ...) are NOT supported
      (they require finalization).

The STM32F429I_Discovery tree has been moved to the BSP.

The following tickets have been fixed:

  2  Protected spec hides package Interfaces
  14 Last_Chance_Handler doesn’t stop tasking

Tasking is started by calling Start_FreeRTOS_Scheduler.

^ permalink raw reply	[relevance 5%]

* Re: silly ravenscar question
  @ 2015-02-24 16:52  4%       ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2015-02-24 16:52 UTC (permalink / raw)


Brad Moore <brad.moore@shaw.ca> writes:

> You might be thinking of the restriction, No_Implicit_Heap_Allocations
> which is part of the Ravenscar Profile. That restricts the runtime
> from making allocations from the heap, but it does not restrict
> application code from using the heap to allocate objecs.

From a hobbyist point of view, the Ravenscar approach to _tasking_ makes
a lot of sense, because full Ada tasking is very hairy (the restricted
tasking in GNAT's Ravenscar is hairy enough).

But some of the other restrictions, like this one, are less appropriate
outside the critical area.

OK, so far the only user-visible effect I see is in packages like
Interfaces.C.Strings, where it's obvious to you and me that
New_Char_Array and New_String are going to allocate memory, but
No_Implicit_Heap_Allocations prevents 'new' (I used FreeRTOS's memory
management routines instead), and in Containers, where you're restricted
to the Bounded versions (no great problem there).

^ permalink raw reply	[relevance 4%]

* Did I find mamory leak in Generic Image Decoder (GID) ?
@ 2015-02-02  5:50  4% reinkor
  0 siblings, 0 replies; 200+ results
From: reinkor @ 2015-02-02  5:50 UTC (permalink / raw)


Dear All,

I tried out GID (Generic Image Decoder) from

http://sourceforge.net/projects/gen-img-dec/

The point was to read jpeg-images from my Ada program
"wrapped" in a function:

  function  read_jpg(cfile_jpg : String) return image1.imgc_t;

The source code is below. However, this function seems to eat memory
during (say 200) repeated calls to it (large images, 2000x1800 pixels each).

I did something very very stupid ?

reinert

----------------------------------------------------------------------

Here is the actual code:

with Ada.Streams.Stream_IO;
use Ada.Streams.Stream_IO;

with Ada.Characters.Latin_1;

with Interfaces.C;
with Interfaces.C.Strings;

with system;
with Ada.Unchecked_Conversion;
with Interfaces;

with GID;
with Ada.Calendar;
with Ada.Characters.Handling;           use Ada.Characters.Handling;
with Ada.Text_IO;                       use Ada.Text_IO;
with Ada.Unchecked_Deallocation;

with Text_IO; use Text_IO;




package body file_handling3 is

  package Int_Io is new Text_IO.Integer_Io (Integer);
  use Int_Io;

  use Interfaces;

  type Byte_Array is array(Integer range <>) of Unsigned_8;
  type p_Byte_Array is access Byte_Array;
  procedure Dispose is new Ada.Unchecked_Deallocation(Byte_Array, p_Byte_Array);


  img_buf: p_Byte_Array := null;

  procedure Free_buf is new Ada.Unchecked_Deallocation(Object => Byte_Array, Name => p_Byte_Array);

  procedure Load_raw_image(
    image : in out GID.Image_descriptor;
    buffer: in out p_Byte_Array;
    next_frame: out Ada.Calendar.Day_Duration
  )
  is
    subtype Primary_color_range is Unsigned_8;
    image_width : constant Positive:= GID.Pixel_Width(image);
    image_height: constant Positive:= GID.Pixel_height(image);
    idx: Natural;
    --
    procedure Set_X_Y (x, y: Natural) is
    begin
      idx:= 3 * (x + image_width * (image_height - 1 - y));
    end Set_X_Y;
    --
    procedure Put_Pixel (
      red, green, blue : Primary_color_range;
      alpha            : Primary_color_range
    )
    is
    pragma Warnings(off, alpha); -- alpha is just ignored
    begin
      buffer(idx..idx+2):= (red, green, blue);
      idx:= idx + 3;
      -- ^ GID requires us to look to next pixel on the right for next time.
    end Put_Pixel;

    stars: Natural:= 0;
    procedure Feedback(percents: Natural) is
      so_far: constant Natural:= percents / 5;
    begin
      for i in stars+1..so_far loop
        Put( Standard_Error, '*');
      end loop;
      stars:= so_far;
    end Feedback;

    procedure Load_image is
      new GID.Load_image_contents(
        Primary_color_range, Set_X_Y,
        Put_Pixel, Feedback, GID.fast
      );

  begin
    Dispose(buffer);
    buffer:= new Byte_Array(0..3 * image_width * image_height - 1);
    Load_image(image, next_frame);
  end Load_raw_image;



 function read_jpg(cfile_jpg : String) return image1.imgc_t is
    f: Ada.Streams.Stream_IO.File_Type;
    i: GID.Image_descriptor;
    name : String := cfile_jpg;
    up_name: constant String:= To_Upper(name);
    next_frame, current_frame: Ada.Calendar.Day_Duration:= 0.0;
    isx,isy : Integer;
 begin

    Open(f, In_File, name);
    GID.Load_image_header(
      i,
      Stream(f).all,
      try_tga =>
        name'Length >= 4 and then
        up_name(up_name'Last-3..up_name'Last) = ".TGA"
    );
    Load_raw_image(i, img_buf, next_frame);
    Close(f);
    isx := GID.Pixel_Width(i);
    isy := GID.Pixel_Height(i);
    New_line;
    Put(" isx,isy: ");Put(Integer'Image(isx));Put(Integer'Image(isy));
    New_line;

    declare
      img1 : image1.imgc_t(1..isx,1..isy) := (others => (others => image1.Black));
      Index : Positive;
    begin
      Index := img_buf'First;
      for j in img1'Range (2) loop
          for i in img1'Range (1) loop
              img1(i,isy - j + 1).red   := image1.Short_I(img_buf (Index + 0));
              img1(i,isy - j + 1).green := image1.Short_I(img_buf (Index + 1));
              img1(i,isy - j + 1).blue  := image1.Short_I(img_buf (Index + 2));
              Index := Index + 3;
          end loop;
      end loop;
      Free_buf(img_buf);

      return img1;
    end;
 end read_jpg;

end file_handling3;

^ permalink raw reply	[relevance 4%]

* Re: Interface with C codes
  2014-10-19  4:33  6%     ` Anh Vo
  2014-10-19  9:24  0%       ` Simon Clubley
@ 2014-10-19 11:46  0%       ` Brian Drummond
  1 sibling, 0 replies; 200+ results
From: Brian Drummond @ 2014-10-19 11:46 UTC (permalink / raw)


On Sat, 18 Oct 2014 21:33:03 -0700, Anh Vo wrote:

> On Saturday, October 18, 2014 11:33:32 AM UTC-7, Stephen Leake wrote:
>> Anh Vo <anhvofrcaus@gmail.com> writes:
>> > On Friday, October 17, 2014 4:22:15 PM UTC-7, Anh Vo wrote:
>> >>  
>> >> char *  bootStringToStruct (char * bootString,  BOOT_PARAMS *
>> >> pBootParams);
>> >  
>> > Should this one work?
>> >
>> > function Boot_String_To_Type (
>> >            Boot_String : Interfaces.C.Strings.chars_ptr;
>> >            Boot_Params : Boot_Parameter_Type_Access)
>> >                              return Interfaces.C.Strings.chars_ptr;
>> > pragma Import (C, Boot_String_To_Type, "bootStringToStruct");
>> 
>> Looks good. but give -fdump-ada-spec a try.
> 
> Yes, I tried and the result is below.
(C++ snipped)

Use gcc -fdump-ada-spec instead of g++ -fdump-ada-spec

- Brian

^ permalink raw reply	[relevance 0%]

* Re: Interface with C codes
  2014-10-19  4:33  6%     ` Anh Vo
@ 2014-10-19  9:24  0%       ` Simon Clubley
  2014-10-19 11:46  0%       ` Brian Drummond
  1 sibling, 0 replies; 200+ results
From: Simon Clubley @ 2014-10-19  9:24 UTC (permalink / raw)


On 2014-10-19, Anh Vo <anhvofrcaus@gmail.com> wrote:
> On Saturday, October 18, 2014 11:33:32 AM UTC-7, Stephen Leake wrote:
>> Anh Vo <anhvofrcaus@gmail.com> writes:
>> > On Friday, October 17, 2014 4:22:15 PM UTC-7, Anh Vo wrote:
>> >>  
>> >> char *  bootStringToStruct (char * bootString,  BOOT_PARAMS * pBootParams); 
>> >  
>> > Should this one work?
>> >
>> > function Boot_String_To_Type (
>> >            Boot_String : Interfaces.C.Strings.chars_ptr;
>> >            Boot_Params : Boot_Parameter_Type_Access) 
>> >                              return Interfaces.C.Strings.chars_ptr; 
>> > pragma Import (C, Boot_String_To_Type, "bootStringToStruct");
>> 
>> Looks good. but give -fdump-ada-spec a try.
>
> Yes, I tried and the result is below.
>
> function bootStringToStruct (bootString : Interfaces.C.Strings.chars_ptr;
>                                 pBootParams : access BOOT_PARAMS)
>                                    return Interfaces.C.Strings.chars_ptr;
> pragma Import (CPP, bootStringToStruct,  "_Z18bootStringToStructPcP11BOOT_PARAMS");
>
> Why was "_Z18bootStringToStructPcP11BOOT_PARAMS" generated for third parameter of pragma Import? I thought it should be "bootStringToStruct".
>

It's known as a mangled symbol and is required with C++ (notice your
latter example is using "CPP" and not "C" on the pragma Import).

The "Name mangling in C++" section of the following might be useful:

http://en.wikipedia.org/wiki/Name_mangling

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world


^ permalink raw reply	[relevance 0%]

* Re: Interface with C codes
  2014-10-18 18:33  0%   ` Stephen Leake
@ 2014-10-19  4:33  6%     ` Anh Vo
  2014-10-19  9:24  0%       ` Simon Clubley
  2014-10-19 11:46  0%       ` Brian Drummond
  0 siblings, 2 replies; 200+ results
From: Anh Vo @ 2014-10-19  4:33 UTC (permalink / raw)


On Saturday, October 18, 2014 11:33:32 AM UTC-7, Stephen Leake wrote:
> Anh Vo <anhvofrcaus@gmail.com> writes:
> > On Friday, October 17, 2014 4:22:15 PM UTC-7, Anh Vo wrote:
> >>  
> >> char *  bootStringToStruct (char * bootString,  BOOT_PARAMS * pBootParams); 
> >  
> > Should this one work?
> >
> > function Boot_String_To_Type (
> >            Boot_String : Interfaces.C.Strings.chars_ptr;
> >            Boot_Params : Boot_Parameter_Type_Access) 
> >                              return Interfaces.C.Strings.chars_ptr; 
> > pragma Import (C, Boot_String_To_Type, "bootStringToStruct");
> 
> Looks good. but give -fdump-ada-spec a try.

Yes, I tried and the result is below.

function bootStringToStruct (bootString : Interfaces.C.Strings.chars_ptr;
                                pBootParams : access BOOT_PARAMS)
                                   return Interfaces.C.Strings.chars_ptr;
pragma Import (CPP, bootStringToStruct,  "_Z18bootStringToStructPcP11BOOT_PARAMS");

Why was "_Z18bootStringToStructPcP11BOOT_PARAMS" generated for third parameter of pragma Import? I thought it should be "bootStringToStruct".

A. Vo
 


^ permalink raw reply	[relevance 6%]

* Re: Interface with C codes
  2014-10-17 23:30  6% ` Anh Vo
@ 2014-10-18 18:33  0%   ` Stephen Leake
  2014-10-19  4:33  6%     ` Anh Vo
  0 siblings, 1 reply; 200+ results
From: Stephen Leake @ 2014-10-18 18:33 UTC (permalink / raw)


Anh Vo <anhvofrcaus@gmail.com> writes:

> On Friday, October 17, 2014 4:22:15 PM UTC-7, Anh Vo wrote:
>>  
>> char *  bootStringToStruct (char * bootString,  BOOT_PARAMS * pBootParams); 
>  
>> Anh Vo
>
> Should this one work?
>
> function Boot_String_To_Type (
>            Boot_String : Interfaces.C.Strings.chars_ptr;
>            Boot_Params : Boot_Parameter_Type_Access) 
>                              return Interfaces.C.Strings.chars_ptr;
> pragma Import (C, Boot_String_To_Type, "bootStringToStruct");

Looks good. but give -fdump-ada-spec a try.

-- 
-- Stephe

^ permalink raw reply	[relevance 0%]

* Re: Interface with C codes
  2014-10-18  2:20  6% ` Jeffrey Carter
@ 2014-10-18 17:00  0%   ` Anh Vo
  0 siblings, 0 replies; 200+ results
From: Anh Vo @ 2014-10-18 17:00 UTC (permalink / raw)


On Friday, October 17, 2014 7:20:45 PM UTC-7, Jeffrey Carter wrote:
> On 10/17/2014 04:22 PM, Anh Vo wrote:
> 
> > What Ada spec should be for the following C prototype where BOOT_PARAMS is a struct and responding Ada type is 
> >  
> > type Boot_Parameter_Type is 
> >    record 
> >       Boot_Dev : Interfaces.C.Strings.Chars_Ptr; 
> This doesn't match the C quoted below. Use
>                    Interfaces.C.Char_Array (0 .. 19);

Thanks for that.
> 
> >       -- ...
> 
> >    end record;
> > pragma Convention (C, Boot_Parameter_Type); 
> >  
> > type Boot_Parameter_Type_Access is access Boot_Parameter_Type; 
> > pragma Convention (C, Boot_Parameter_Type_Access);
> 
> You don't need this access type.
> 
> > char *  bootStringToStruct (char * bootString,  BOOT_PARAMS * pBootParams);
> 
> I would probably use

> function To_Record 
> (Boot_String : Intefaces.C.Char_Array; Boot_Parameter : Boot_Parameter_Type) 
> return Interfaces.C.Strings.Chars_Ptr;

> and rely on the advice in B.3(69-70): both parameters will be passed by reference.

Thanks again. I have enough info to test it out. 

Anh Vo

^ permalink raw reply	[relevance 0%]

* Re: Interface with C codes
  2014-10-17 23:22  5% Interface with C codes Anh Vo
                   ` (2 preceding siblings ...)
  2014-10-18  2:20  6% ` Jeffrey Carter
@ 2014-10-18  6:27  0% ` Per Sandberg
  3 siblings, 0 replies; 200+ results
From: Per Sandberg @ 2014-10-18  6:27 UTC (permalink / raw)


Ask the compiler
g++ -fdump-ada-spec ${header}
/Per

On 18.10.2014 01:22, Anh Vo wrote:
> What Ada spec should be for the following C prototype where BOOT_PARAMS is a struct and responding Ada type is
>
> type Boot_Parameter_Type is
>     record
>        Boot_Dev : Interfaces.C.Strings.Chars_Ptr;
>        -- ...
>     end record;
> pragma Convention (C, Boot_Parameter_Type);
>
> type Boot_Parameter_Type_Access is access Boot_Parameter_Type;
> pragma Convention (C, Boot_Parameter_Type_Access);
>
>
> typedef struct           /* BOOT_PARAMS */
>      {
>      char bootDev [20];  /* boot device code */
>      * ... *
>      } BOOT_PARAMS;
>
> Note that I can not use Ada 2012 yet.
>
>
> char *  bootStringToStruct (char * bootString,  BOOT_PARAMS * pBootParams);
>
>
> Anh Vo
>

^ permalink raw reply	[relevance 0%]

* Re: Interface with C codes
  2014-10-17 23:22  5% Interface with C codes Anh Vo
  2014-10-17 23:30  6% ` Anh Vo
  2014-10-17 23:49  0% ` Adam Beneschan
@ 2014-10-18  2:20  6% ` Jeffrey Carter
  2014-10-18 17:00  0%   ` Anh Vo
  2014-10-18  6:27  0% ` Per Sandberg
  3 siblings, 1 reply; 200+ results
From: Jeffrey Carter @ 2014-10-18  2:20 UTC (permalink / raw)


On 10/17/2014 04:22 PM, Anh Vo wrote:
> What Ada spec should be for the following C prototype where BOOT_PARAMS is a struct and responding Ada type is
> 
> type Boot_Parameter_Type is
>    record
>       Boot_Dev : Interfaces.C.Strings.Chars_Ptr;

This doesn't match the C quoted below. Use

                   Interfaces.C.Char_Array (0 .. 19);

>       -- ...
>    end record;
> pragma Convention (C, Boot_Parameter_Type);
> 
> type Boot_Parameter_Type_Access is access Boot_Parameter_Type;
> pragma Convention (C, Boot_Parameter_Type_Access);

You don't need this access type.

> char *  bootStringToStruct (char * bootString,  BOOT_PARAMS * pBootParams);

I would probably use

function To_Record
(Boot_String : Intefaces.C.Char_Array; Boot_Parameter : Boot_Parameter_Type)
return Interfaces.C.Strings.Chars_Ptr;

and rely on the advice in B.3(69-70): both parameters will be passed by reference.

-- 
Jeff Carter
"Whatever it is, I'm against it."
Horse Feathers
46


^ permalink raw reply	[relevance 6%]

* Re: Interface with C codes
  2014-10-18  0:04  0%   ` Anh Vo
@ 2014-10-18  1:04  6%     ` Anh Vo
  0 siblings, 0 replies; 200+ results
From: Anh Vo @ 2014-10-18  1:04 UTC (permalink / raw)


On Friday, October 17, 2014 5:04:17 PM UTC-7, Anh Vo wrote:
> On Friday, October 17, 2014 4:49:04 PM UTC-7, Adam Beneschan wrote:
> 
> > On Friday, October 17, 2014 4:22:15 PM UTC-7, Anh Vo wrote:
> > 
> > > What Ada spec should be for the following C prototype where BOOT_PARAMS is a struct and responding Ada type is
> 
> > > type Boot_Parameter_Type is
> > >    record
> > >       Boot_Dev : Interfaces.C.Strings.Chars_Ptr;
> > >       -- ...
> > >    end record;
> > > pragma Convention (C, Boot_Parameter_Type);
> > 
> > > type Boot_Parameter_Type_Access is access Boot_Parameter_Type;
> > > pragma Convention (C, Boot_Parameter_Type_Access);
> > 
> > > typedef struct           /* BOOT_PARAMS */
> > >     {
> > >     char bootDev [20];  /* boot device code */
> > >     * ... *
> > >     } BOOT_PARAMS;
> > 
> > > Note that I can not use Ada 2012 yet.
> > 
> > > char *  bootStringToStruct (char * bootString,  BOOT_PARAMS * pBootParams); 
> > 
> > I'm confused.  You've defined an Ada record Boot_Parameter_Type that has a pointer in it, and a C struct that does not have a pointer. 
> 
> > 
> The second parameter of the function prototype use pointer, BOOT_PARAMS * pBootParams.
> 

How this one.

function Boot_String_To_Type (
           Boot_String : Interfaces.C.Strings.chars_ptr;
           Boot_Params : System.Address) 
                             return Interfaces.C.Strings.chars_ptr;
pragma Import (C, Boot_String_To_Type, "bootStringToStruct");

^ permalink raw reply	[relevance 6%]

* Re: Interface with C codes
  2014-10-17 23:49  0% ` Adam Beneschan
@ 2014-10-18  0:04  0%   ` Anh Vo
  2014-10-18  1:04  6%     ` Anh Vo
  0 siblings, 1 reply; 200+ results
From: Anh Vo @ 2014-10-18  0:04 UTC (permalink / raw)


On Friday, October 17, 2014 4:49:04 PM UTC-7, Adam Beneschan wrote:
> On Friday, October 17, 2014 4:22:15 PM UTC-7, Anh Vo wrote:
> 
> > What Ada spec should be for the following C prototype where BOOT_PARAMS is a struct and responding Ada type is
> 
> > 
> 
> > type Boot_Parameter_Type is
> 
> >    record
> 
> >       Boot_Dev : Interfaces.C.Strings.Chars_Ptr;
> 
> >       -- ...
> 
> >    end record;
> 
> > 
> 
> > pragma Convention (C, Boot_Parameter_Type);
> 
> > 
> 
> > type Boot_Parameter_Type_Access is access Boot_Parameter_Type;
> 
> > pragma Convention (C, Boot_Parameter_Type_Access);
> 
> 
> 
> > typedef struct           /* BOOT_PARAMS */
> 
> >     {
> 
> >     char bootDev [20];  /* boot device code */
> 
> >     * ... *
> 
> >     } BOOT_PARAMS;
> 
> > 
> 
> > Note that I can not use Ada 2012 yet.
> 
> > 
> 
> > char *  bootStringToStruct (char * bootString,  BOOT_PARAMS * pBootParams);
> 
> > 
> 
> > Anh Vo
> 
> I'm confused.  You've defined an Ada record Boot_Parameter_Type that has a pointer in it, and a C struct that does not have a pointer. 
> 

The second parameter of the function prototype use pointer, BOOT_PARAMS * pBootParams.

Anh Vo


^ permalink raw reply	[relevance 0%]

* Re: Interface with C codes
  2014-10-17 23:22  5% Interface with C codes Anh Vo
  2014-10-17 23:30  6% ` Anh Vo
@ 2014-10-17 23:49  0% ` Adam Beneschan
  2014-10-18  0:04  0%   ` Anh Vo
  2014-10-18  2:20  6% ` Jeffrey Carter
  2014-10-18  6:27  0% ` Per Sandberg
  3 siblings, 1 reply; 200+ results
From: Adam Beneschan @ 2014-10-17 23:49 UTC (permalink / raw)


On Friday, October 17, 2014 4:22:15 PM UTC-7, Anh Vo wrote:
> What Ada spec should be for the following C prototype where BOOT_PARAMS is a struct and responding Ada type is
> 
> type Boot_Parameter_Type is
>    record
>       Boot_Dev : Interfaces.C.Strings.Chars_Ptr;
>       -- ...
>    end record;
> 
> pragma Convention (C, Boot_Parameter_Type);
> 
> type Boot_Parameter_Type_Access is access Boot_Parameter_Type;
> pragma Convention (C, Boot_Parameter_Type_Access);

> typedef struct           /* BOOT_PARAMS */
>     {
>     char bootDev [20];  /* boot device code */
>     * ... *
>     } BOOT_PARAMS;
> 
> Note that I can not use Ada 2012 yet.
> 
> char *  bootStringToStruct (char * bootString,  BOOT_PARAMS * pBootParams);
> 
> Anh Vo

I'm confused.  You've defined an Ada record Boot_Parameter_Type that has a pointer in it, and a C struct that does not have a pointer. 

                                -- Adam



^ permalink raw reply	[relevance 0%]

* Re: Interface with C codes
  2014-10-17 23:22  5% Interface with C codes Anh Vo
@ 2014-10-17 23:30  6% ` Anh Vo
  2014-10-18 18:33  0%   ` Stephen Leake
  2014-10-17 23:49  0% ` Adam Beneschan
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 200+ results
From: Anh Vo @ 2014-10-17 23:30 UTC (permalink / raw)


On Friday, October 17, 2014 4:22:15 PM UTC-7, Anh Vo wrote:
> What Ada spec should be for the following C prototype where BOOT_PARAMS is a struct and responding Ada type is
>  
> 
> type Boot_Parameter_Type is
> 
>    record 
>       Boot_Dev : Interfaces.C.Strings.Chars_Ptr; 
>       -- ... 
>    end record;
> 
> pragma Convention (C, Boot_Parameter_Type);
>  
> 
> type Boot_Parameter_Type_Access is access Boot_Parameter_Type;
> 
> pragma Convention (C, Boot_Parameter_Type_Access);
>  
> typedef struct           /* BOOT_PARAMS */ 
>     { 
>     char bootDev [20];  /* boot device code */ 
>     * ... * 
>     } BOOT_PARAMS;
>   
> Note that I can not use Ada 2012 yet.
>  
> char *  bootStringToStruct (char * bootString,  BOOT_PARAMS * pBootParams); 
 
> Anh Vo

Should this one work?

function Boot_String_To_Type (
           Boot_String : Interfaces.C.Strings.chars_ptr;
           Boot_Params : Boot_Parameter_Type_Access) 
                             return Interfaces.C.Strings.chars_ptr;
pragma Import (C, Boot_String_To_Type, "bootStringToStruct");

^ permalink raw reply	[relevance 6%]

* Interface with C codes
@ 2014-10-17 23:22  5% Anh Vo
  2014-10-17 23:30  6% ` Anh Vo
                   ` (3 more replies)
  0 siblings, 4 replies; 200+ results
From: Anh Vo @ 2014-10-17 23:22 UTC (permalink / raw)


What Ada spec should be for the following C prototype where BOOT_PARAMS is a struct and responding Ada type is

type Boot_Parameter_Type is
   record
      Boot_Dev : Interfaces.C.Strings.Chars_Ptr;
      -- ...
   end record;
pragma Convention (C, Boot_Parameter_Type);

type Boot_Parameter_Type_Access is access Boot_Parameter_Type;
pragma Convention (C, Boot_Parameter_Type_Access);


typedef struct           /* BOOT_PARAMS */
    {
    char bootDev [20];  /* boot device code */
    * ... *
    } BOOT_PARAMS;

Note that I can not use Ada 2012 yet.


char *  bootStringToStruct (char * bootString,  BOOT_PARAMS * pBootParams);


Anh Vo

^ permalink raw reply	[relevance 5%]

* Re: Ada.Containers.Indefinite_Holders in GNAT and Ada2012
  2014-08-10 13:06  5%   ` Victor Porton
@ 2014-08-10 15:32  0%     ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2014-08-10 15:32 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> One (real World!) usage for this: Interfaces.C.Strings.To_Chars_Ptr
> applied to an element in an indefinite holder of type char_array.

I don't know what your actual usage is, but I'd prefer in general to
keep to Ada types in the application, and only do interfacing at the
edges.

^ permalink raw reply	[relevance 0%]

* Re: Ada.Containers.Indefinite_Holders in GNAT and Ada2012
  @ 2014-08-10 13:06  5%   ` Victor Porton
  2014-08-10 15:32  0%     ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: Victor Porton @ 2014-08-10 13:06 UTC (permalink / raw)


Victor Porton wrote:

> Victor Porton wrote:
> 
>> I tried to write:
>> 
>> Element(Object)'Access;
>> 
>> for "Object" being a value of an instance of
>> Ada.Containers.Indefinite_Holders.
>> 
>> This does not work because the return type of Element is not aliased.
> 
> By the way, does it makes sense in the next Ada specification to make the
> return type of "Element" function aliased?

Hm, my idea was wrong: Element may return a copy instead of the actual 
element.

However I propose to add Element_Access to next RM which would return access 
to the element in the container.

One (real World!) usage for this: Interfaces.C.Strings.To_Chars_Ptr applied 
to an element in an indefinite holder of type char_array.

>> Then I tried:
>> 
>> Reference(Object).all'Access;
>> 
>> This does not work because in GNAT 4.9 a-coinho.ads source file is not up
>> to date with Ada2012 and there are no Reference function here.
>> 
>> My questions:
>> 
>> 1. How long to wait for GNAT to work with this? (in which GNAT version?)
>> 
>> 2. In a conforming Ada2012 compiler `Reference(Object).all'Access;` is
>> semantically correct, isn't it?
>> 
>> In the meantime, I need to write for my private use a container similar
>> to Ada.Containers.Indefinite_Holders for aliased objects by myself :-(

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 5%]

* AUnit question
@ 2014-08-04 11:28  6% Victor Porton
  0 siblings, 0 replies; 200+ results
From: Victor Porton @ 2014-08-04 11:28 UTC (permalink / raw)


In the below source every test requires an object of type World_Type.

Wouldn't it better to move the `World: World_Type` object into the test case
object and not create it anew in every test procedure?

But how to do this? Test functions receive Test_Cases.Test_Case'Class, not
my type of test case. Should I manually do type conversion in every test
function? or is there a better way?

with AUnit, AUnit.Test_Cases, AUnit.Test_Results; use AUnit, AUnit.Test_Cases, AUnit.Test_Results;
--  with RDF.Raptor.World;

package Iostreams_Test is

   type Test_Case is new AUnit.Test_Cases.Test_Case with null record;

   procedure Register_Tests (T : in out Test_Case);
   --  Register routines to be run

   function Name (T : Test_Case)
                  return Test_String;
   --  Returns name identifying the test case

end Iostreams_Test;

with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;
with AUnit.Test_Cases;
with AUnit.Assertions; use AUnit.Assertions;
with RDF.Raptor.World;
with RDF.Raptor.Iostream; use RDF.Raptor.Iostream;
with Ada.Text_IO;

package body Iostreams_Test is

   procedure Test_Sinks(T : in out Test_Cases.Test_Case'Class) is
      World: RDF.Raptor.World.World_Type;
      Str: aliased char_array := "qqq";
      In_Sink:  Stream_Type := From_Sink (World);
      Out_Sink: Stream_Type := To_Sink (World);
   begin
      Assert (Read_Bytes (To_Chars_Ptr (Str'Unchecked_Access), 10, 10, In_Sink) = 0, "Read zero bytes from a sink");
      Write ("XYZ", Out_Sink); -- does nothing
   end;

   procedure Test_Strings(T : in out Test_Cases.Test_Case'Class) is
      World: RDF.Raptor.World.World_Type;
      Str  : String := "xqqq";
      Buf: aliased char_array := (1..99=>'w', 100=>NUL);
      In_String: Stream_From_String := Open_From_String (World, Str);
      Out_String: Stream_To_String := Open (World);
      Bytes_Read: size_t;
   begin
      Bytes_Read := Read_Bytes (To_Chars_Ptr (Buf'Unchecked_Access), 1, 100, In_String);
      Assert (Bytes_Read = 4, "Read 4 bytes from string");
      Assert (To_Ada (Buf(1..4), Trim_Nul=>False) = Str, "Compare read string");
      Write(Str, Out_String);
      Write("QQ", Out_String);
      Assert (Value (Out_String) = Str & "QQ", "Compare written string");
   end;

   function Name (T : Test_Case)
                  return Test_String is
   begin
      return Format ("Streams");
   end Name;

   procedure Register_Tests (T : in out Test_Case) is
      use AUnit.Test_Cases.Registration;
   begin
      Register_Routine (T, Test_Sinks'Access, "Testing sinks"); -- FIXME: uncomment
      Register_Routine (T, Test_Strings'Access, "Testing string streams");
   end Register_Tests;

end Iostreams_Test;


-- 
Victor Porton - http://portonvictor.org


^ permalink raw reply	[relevance 6%]

* Re: Troubles with C strings
  2014-07-26 19:09  0%     ` Victor Porton
@ 2014-08-01 22:16  0%       ` Victor Porton
  0 siblings, 0 replies; 200+ results
From: Victor Porton @ 2014-08-01 22:16 UTC (permalink / raw)


Victor Porton wrote:

> Peter Chapin wrote:
> 
>> On 2014-07-26 11:15, Shark8 wrote:
>> 
>>> On 26-Jul-14 08:13, Victor Porton wrote:
>>>> Also: It seems that in Interfaces.C.Strings there is no function which
>>>> creates an Ada string of specified length from a chars_ptr (without
>>>> checking for NUL).
>>> 
>>> Such a function cannot exist: to determine the length of a C-style
>>> string you *must* scan through it for the terminating NULL. What you
>>> describe would be a "substring" method that can read beyond the
>>> string-bounds without raising an error... and I see no way that would
>>> end well.
>> 
>> Well the function could exist; it would just require an additional
>> parameter to specify how much should be copied. While such an approach
>> might be contrary to the sensibilities of Ada programmers, I don't think
>> C programmers would find it shocking.
>> 
>> Of course we are talking about an Ada interface here so adding a
>> function that by its nature could easily lead to undefined behave...
>> er... erroneous execution probably wouldn't be great.
> 
> Jut call this function *_Unchecked or *_Unsafe and it would turn it safe.
> :-)

Hey, anyone!

Could we add this *_Unchecked or *_Unsafe to Ada202x?

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 0%]

* Re: Troubles with C strings
  2014-07-26 19:06  0%   ` Peter Chapin
@ 2014-07-26 19:09  0%     ` Victor Porton
  2014-08-01 22:16  0%       ` Victor Porton
  0 siblings, 1 reply; 200+ results
From: Victor Porton @ 2014-07-26 19:09 UTC (permalink / raw)


Peter Chapin wrote:

> On 2014-07-26 11:15, Shark8 wrote:
> 
>> On 26-Jul-14 08:13, Victor Porton wrote:
>>> Also: It seems that in Interfaces.C.Strings there is no function which
>>> creates an Ada string of specified length from a chars_ptr (without
>>> checking for NUL).
>> 
>> Such a function cannot exist: to determine the length of a C-style
>> string you *must* scan through it for the terminating NULL. What you
>> describe would be a "substring" method that can read beyond the
>> string-bounds without raising an error... and I see no way that would
>> end well.
> 
> Well the function could exist; it would just require an additional
> parameter to specify how much should be copied. While such an approach
> might be contrary to the sensibilities of Ada programmers, I don't think
> C programmers would find it shocking.
> 
> Of course we are talking about an Ada interface here so adding a
> function that by its nature could easily lead to undefined behave...
> er... erroneous execution probably wouldn't be great.

Jut call this function *_Unchecked or *_Unsafe and it would turn it safe. 
:-)

-- 
Victor Porton - http://portonvictor.org


^ permalink raw reply	[relevance 0%]

* Re: Troubles with C strings
  2014-07-26 15:15  0% ` Shark8
  2014-07-26 15:52  0%   ` Victor Porton
@ 2014-07-26 19:06  0%   ` Peter Chapin
  2014-07-26 19:09  0%     ` Victor Porton
  1 sibling, 1 reply; 200+ results
From: Peter Chapin @ 2014-07-26 19:06 UTC (permalink / raw)


On 2014-07-26 11:15, Shark8 wrote:

> On 26-Jul-14 08:13, Victor Porton wrote:
>> Also: It seems that in Interfaces.C.Strings there is no function which
>> creates an Ada string of specified length from a chars_ptr (without
>> checking for NUL).
> 
> Such a function cannot exist: to determine the length of a C-style
> string you *must* scan through it for the terminating NULL. What you
> describe would be a "substring" method that can read beyond the
> string-bounds without raising an error... and I see no way that would
> end well.

Well the function could exist; it would just require an additional
parameter to specify how much should be copied. While such an approach
might be contrary to the sensibilities of Ada programmers, I don't think
C programmers would find it shocking.

Of course we are talking about an Ada interface here so adding a
function that by its nature could easily lead to undefined behave...
er... erroneous execution probably wouldn't be great.

^ permalink raw reply	[relevance 0%]

* Re: Allocating a C string without heap
  2014-07-26 16:30  0%   ` Victor Porton
@ 2014-07-26 18:38  0%     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2014-07-26 18:38 UTC (permalink / raw)


On Sat, 26 Jul 2014 19:30:16 +0300, Victor Porton wrote:

> Dmitry A. Kazakov wrote:
> 
>> On Sat, 26 Jul 2014 19:01:20 +0300, Victor Porton wrote:
>> 
>>> Let we have an Ada String.
>>> 
>>> I need to pass it converted to a C string into a C library function.
>>> 
>>> Now I do it with Interfaces.C.Strings.New_String. But it is slow as it
>>> uses the heap and requires (not to forget incidentally!) further
>>> Interfaces.C.Strings.Free.
>>> 
>>> Is there a better way to do this? I mean that we would probably create a
>>> nul-terminated char_array (not on the heap but on the stack!) and pass
>>> the pointer to its first element.
>> 
>> The canonical method is this (Ada 95):
>> 
>>    procedure Foo (Text : String) is
>>       procedure Internal (Text : char_array);
>>       pragma Convention (C, Internal, "foo");
>>    begin
>>       Internal (To_C (Text));
>>    end Foo;
> 
> Why Internal (Text : char_array); not Internal (Text : char_array_access);?

char_array_access is an Ada side type. You should not pass it to C.

If you want to pass an Ada-managed array down to C it is char_array (Ada
knows how to pass arrays and record types). If you want to pass a C-managed
array it is chars_ptr.

There is no safe way to know which side manages the array. C does not make
any distinction because it is always a pointer in C. Each time you should
read the documentation carefully.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[relevance 0%]

* Re: Allocating a C string without heap
  2014-07-26 16:20  0% ` Dmitry A. Kazakov
@ 2014-07-26 16:30  0%   ` Victor Porton
  2014-07-26 18:38  0%     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Victor Porton @ 2014-07-26 16:30 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> On Sat, 26 Jul 2014 19:01:20 +0300, Victor Porton wrote:
> 
>> Let we have an Ada String.
>> 
>> I need to pass it converted to a C string into a C library function.
>> 
>> Now I do it with Interfaces.C.Strings.New_String. But it is slow as it
>> uses the heap and requires (not to forget incidentally!) further
>> Interfaces.C.Strings.Free.
>> 
>> Is there a better way to do this? I mean that we would probably create a
>> nul-terminated char_array (not on the heap but on the stack!) and pass
>> the pointer to its first element.
> 
> The canonical method is this (Ada 95):
> 
>    procedure Foo (Text : String) is
>       procedure Internal (Text : char_array);
>       pragma Convention (C, Internal, "foo");
>    begin
>       Internal (To_C (Text));
>    end Foo;

Why Internal (Text : char_array); not Internal (Text : char_array_access);?

-- 
Victor Porton - http://portonvictor.org


^ permalink raw reply	[relevance 0%]

* Re: Allocating a C string without heap
  2014-07-26 16:01  6% Allocating a C string without heap Victor Porton
@ 2014-07-26 16:20  0% ` Dmitry A. Kazakov
  2014-07-26 16:30  0%   ` Victor Porton
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2014-07-26 16:20 UTC (permalink / raw)


On Sat, 26 Jul 2014 19:01:20 +0300, Victor Porton wrote:

> Let we have an Ada String.
> 
> I need to pass it converted to a C string into a C library function.
> 
> Now I do it with Interfaces.C.Strings.New_String. But it is slow as it uses 
> the heap and requires (not to forget incidentally!) further 
> Interfaces.C.Strings.Free.
> 
> Is there a better way to do this? I mean that we would probably create a 
> nul-terminated char_array (not on the heap but on the stack!) and pass the 
> pointer to its first element.

The canonical method is this (Ada 95):

   procedure Foo (Text : String) is
      procedure Internal (Text : char_array);
      pragma Convention (C, Internal, "foo");
   begin
      Internal (To_C (Text));
   end Foo;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Allocating a C string without heap
@ 2014-07-26 16:01  6% Victor Porton
  2014-07-26 16:20  0% ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Victor Porton @ 2014-07-26 16:01 UTC (permalink / raw)


Let we have an Ada String.

I need to pass it converted to a C string into a C library function.

Now I do it with Interfaces.C.Strings.New_String. But it is slow as it uses 
the heap and requires (not to forget incidentally!) further 
Interfaces.C.Strings.Free.

Is there a better way to do this? I mean that we would probably create a 
nul-terminated char_array (not on the heap but on the stack!) and pass the 
pointer to its first element.

This would be both safer an faster.

Can you elaborate on this?

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 6%]

* Re: Troubles with C strings
  2014-07-26 15:15  0% ` Shark8
@ 2014-07-26 15:52  0%   ` Victor Porton
  2014-07-26 19:06  0%   ` Peter Chapin
  1 sibling, 0 replies; 200+ results
From: Victor Porton @ 2014-07-26 15:52 UTC (permalink / raw)


Shark8 wrote:

> On 26-Jul-14 08:13, Victor Porton wrote:
>> Also: It seems that in Interfaces.C.Strings there is no function which
>> creates an Ada string of specified length from a chars_ptr (without
>> checking for NUL). Addition of such a function would be good, because it
>> can be very fast (on some platforms it can be implemented as memcpy).
> 
> Such a function cannot exist: to determine the length of a C-style
> string you *must* scan through it for the terminating NULL. What you
> describe would be a "substring" method that can read beyond the
> string-bounds without raising an error... and I see no way that would
> end well.

It can. The length of the string may be "scanned" earlier and be stored, so 
that we could later use it efficiently.

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 0%]

* Re: Troubles with C strings
  2014-07-26 14:13  5% Troubles with C strings Victor Porton
@ 2014-07-26 15:15  0% ` Shark8
  2014-07-26 15:52  0%   ` Victor Porton
  2014-07-26 19:06  0%   ` Peter Chapin
  0 siblings, 2 replies; 200+ results
From: Shark8 @ 2014-07-26 15:15 UTC (permalink / raw)


On 26-Jul-14 08:13, Victor Porton wrote:
> Also: It seems that in Interfaces.C.Strings there is no function which
> creates an Ada string of specified length from a chars_ptr (without checking
> for NUL). Addition of such a function would be good, because it can be very
> fast (on some platforms it can be implemented as memcpy).

Such a function cannot exist: to determine the length of a C-style 
string you *must* scan through it for the terminating NULL. What you 
describe would be a "substring" method that can read beyond the 
string-bounds without raising an error... and I see no way that would 
end well.

^ permalink raw reply	[relevance 0%]

* Troubles with C strings
@ 2014-07-26 14:13  5% Victor Porton
  2014-07-26 15:15  0% ` Shark8
  0 siblings, 1 reply; 200+ results
From: Victor Porton @ 2014-07-26 14:13 UTC (permalink / raw)


RM2012 B.3.1:

39 function Value (Item : in chars_ptr; Length : in size_t)
   return String;
40/1 Equivalent to To_Ada(Value(Item, Length) & nul, Trim_Nul=>True).

Isn't the function Value improperly recursively defined through itself?! 
Please explain.

Also: It seems that in Interfaces.C.Strings there is no function which 
creates an Ada string of specified length from a chars_ptr (without checking 
for NUL). Addition of such a function would be good, because it can be very 
fast (on some platforms it can be implemented as memcpy).

-- 
Victor Porton - http://portonvictor.org

^ permalink raw reply	[relevance 5%]

* Re: How to convert a C "char *" value to Ada string?
    2014-07-22  0:19  5% ` Victor Porton
@ 2014-07-22  0:28  7% ` Randy Brukardt
  1 sibling, 0 replies; 200+ results
From: Randy Brukardt @ 2014-07-22  0:28 UTC (permalink / raw)


"Victor Porton" <porton@narod.ru> wrote in message 
news:lqk8lm$hss$1@speranza.aioe.org...
> How to convert a C "char *" value to Ada string?
>
> There is
>
>   function To_Ada (Item     : in char_array;
>                    Trim_Nul : in Boolean := True)
>      return String;
>
> in package Interfaces.C, but it receives an array not a pointer (= 
> access).
>
> So I don't understand how to do this simple thing.

You didn't look far enough in the RM. Look at Interfaces.C.Strings and/or 
Interfaces.C.Pointers (B.3.1 and B.3.2, respectively). You probably want 
Interfaces.C.Strings.

                     Randy. 


^ permalink raw reply	[relevance 7%]

* Re: How to convert a C "char *" value to Ada string?
  @ 2014-07-22  0:19  5% ` Victor Porton
  2014-07-22  0:28  7% ` Randy Brukardt
  1 sibling, 0 replies; 200+ results
From: Victor Porton @ 2014-07-22  0:19 UTC (permalink / raw)


Victor Porton wrote:

> How to convert a C "char *" value to Ada string?
> 
> There is
> 
>    function To_Ada (Item     : in char_array;
>                     Trim_Nul : in Boolean := True)
>       return String;
> 
> in package Interfaces.C, but it receives an array not a pointer (=
> access).
> 
> So I don't understand how to do this simple thing.

Oh, Interfaces.C.Strings.

-- 
Victor Porton - http://portonvictor.org


^ permalink raw reply	[relevance 5%]

* Re: Ada's ranking of popularity at IEEE Spectrum
  @ 2014-07-09  2:30  4%       ` Shark8
  0 siblings, 0 replies; 200+ results
From: Shark8 @ 2014-07-09  2:30 UTC (permalink / raw)


On 08-Jul-14 17:03, sbelmont700@gmail.com wrote:
> So we, as a community, cannot easily divide up the work in a component like manner,
> and are usually forced to start all way down at the O/S interface level *for every
> single project*.

Why would we need to start at the OS level for TLS? Yes, I realize we'll 
need to depend on X.509 and ASN.1, but I don't see why we cannot write 
[at least those] in a generally platform-independent manner.

In fact, given Ada's reputation as being highly-portable, wouldn't 
writing theses basic [fundamental, not simple] components be a /good/ thing?

> And again, even if you do manage to create an elegant Ada interface to OpenSSL,
> it's not going to be OpenSSL, because OpenSSL is an untyped C API that is anathema
> to everything Ada.  The better you make it, the further away from the standard you
> get, and the less people are going to want to use it.

I said TLS, not OpenSSL.
But even so, what's stopping someone from taking a formally-verified TLS 
component and wrapping/exporting it for C [and OpenSSL] compatibility? 
How would that be buying into C's type-system?

e.g. what is stopping us from exporting to C-interface if we have a 
string-date package? Sure values and such won't be protected on the 
C-side, but we know about out Ada side, no?

Package Date_String is

     -- Date-String format: ####-##-##
     Subtype Date_String is String(1..10)
     with Dynamic_Predicate =>
       (for all Index in Date_String'Range =>
          (case Index is
             when 5|8  => Date_String(Index) = '-',
           when others => Date_String(Index) in '0'..'9'
          )
       ) and then -- short-circut boolean, ensures the above first
       (case Month(Date_String) is
          when 1 | 3 | 5 | 7 | 8 | 10 | 12 => Day(Date_String)'Valid,
          when 4 | 6 | 9 | 11              => Day(Date_String) in 1..30,
          when 2 => (if Is_Leap_Year(Date_String) then Day(Date_String) 
in 1..30
                     else Day(Date_String) in 1..29)
       );

     SUBTYPE C_Date_String is Interfaces.C.Strings.char_array_access with
       Dynamic_Predicate =>
           Interfaces.C.To_Ada(C_Date_String.All) in Date_String;

     -- Whatever procedures we need to export.

Private

        Subtype Month_Type is Natural range 1..12;
        subtype Day_Type   is Natural range 1..31;

     Function Year ( Input : String ) Return Natural is
       ( Natural'Value(Input(Input'First..Input'First+3)) );
     Function Month( Input : String ) Return Month_Type is
       ( Natural'Value(Input(Input'First+5..Input'First+6)) );
     Function Day  ( Input : String ) Return Day_Type is
       ( Natural'Value(Input(Input'Last-1..Input'Last)) );

     -- METHOD FOR DETERMINING LEAP-YEAR:
     -- (1) If the year is evenly divisible by 4, go to step 2.
     --     Otherwise, go to step 5.
     -- (2) If the year is evenly divisible by 100, go to step 3.
     --     Otherwise, go to step 4.
     -- (3) If the year is evenly divisible by 400, go to step 4.
     --     Otherwise, go to step 5.
     -- (4) The year is a leap year (it has 366 days).
     -- (5) The year is not a leap year (it has 365 days).
     --
     -- CONCISELY:
     --     Year Mod 400 = 0 or (Year Mod 4 = 0 and Year Mod 100 /= 0)
     Function Is_Leap_Year( Year : Natural ) Return Boolean is
       (Year Mod 400 = 0 or (Year Mod 4 = 0 and Year Mod 100 /= 0));
     Function Is_Leap_Year( Input : String  ) Return Boolean is
       ( Is_Leap_Year(Year(Input)) );

End Date_String;


^ permalink raw reply	[relevance 4%]

* Re: How to import C pointers to structures?
  2014-05-20  0:10  0%     ` Shark8
@ 2014-05-20  0:22  0%       ` Adam Beneschan
  0 siblings, 0 replies; 200+ results
From: Adam Beneschan @ 2014-05-20  0:22 UTC (permalink / raw)


On Monday, May 19, 2014 5:10:14 PM UTC-7, Shark8 wrote:
> On 19-May-14 16:44, Adam Beneschan wrote:
> 
> >> You generally *can't*  do a real/meaningful import w/o knowing the
> >> layout.
> 
> > I'm not sure that's quite true ... there are lots of situations
> > where you simply want to "pass through" a pointer, e.g. in
> > callback situations, where a function sets up a callback and says
> > "when you do the callback, please pass this pointer to it"; and
> > whoever registers the callback will take the pointer, store it
> > somewhere, and use it when it's needed, without ever trying to
> > look at what it points to.
> 
> While those are /common/ cases, I would be hesitant to call them 
> /general/ cases.
> 
> > Unfortunately, I don't see the equivalent of "void *" anywhere in
> > Interfaces.C, which is what the sort of thing you'd want.  You
> > could probably use Interfaces.C.Strings.chars_ptr (the equivalent
> > of "char *").
> 
> Instantiate Interfaces.C.Pointers on a null-record or, perhaps, 
> System.Address?

I wouldn't trust System.Address; there's no guarantee that the Ada implementation of this Ada type is represented the same way as a C pointer, an Ada access object, or anything else.  The first idea, to instantiate Interfaces.C.Pointers, should be trustworthy--that's an excellent idea.

                               -- Adam

^ permalink raw reply	[relevance 0%]

* Re: How to import C pointers to structures?
  2014-05-19 22:44  5%   ` Adam Beneschan
@ 2014-05-20  0:10  0%     ` Shark8
  2014-05-20  0:22  0%       ` Adam Beneschan
  0 siblings, 1 reply; 200+ results
From: Shark8 @ 2014-05-20  0:10 UTC (permalink / raw)


On 19-May-14 16:44, Adam Beneschan wrote:
>> You generally *can't*  do a real/meaningful import w/o knowing the
>> layout.
>
> I'm not sure that's quite true ... there are lots of situations
> where you simply want to "pass through" a pointer, e.g. in
> callback situations, where a function sets up a callback and says
> "when you do the callback, please pass this pointer to it"; and
> whoever registers the callback will take the pointer, store it
> somewhere, and use it when it's needed, without ever trying to
> look at what it points to.

While those are /common/ cases, I would be hesitant to call them 
/general/ cases.

> Unfortunately, I don't see the equivalent of "void *" anywhere in
> Interfaces.C, which is what the sort of thing you'd want.  You
> could probably use Interfaces.C.Strings.chars_ptr (the equivalent
> of "char *").

Instantiate Interfaces.C.Pointers on a null-record or, perhaps, 
System.Address?

^ permalink raw reply	[relevance 0%]

* Re: How to import C pointers to structures?
  @ 2014-05-19 22:44  5%   ` Adam Beneschan
  2014-05-20  0:10  0%     ` Shark8
  0 siblings, 1 reply; 200+ results
From: Adam Beneschan @ 2014-05-19 22:44 UTC (permalink / raw)


On Monday, May 19, 2014 3:33:56 PM UTC-7, Shark8 wrote:
> On 19-May-14 16:26, Victor Porton wrote:
> 
> > How to import it to Ada? We don't know struct_t layout.
> 
> You generally *can't* do a real/meaningful import w/o knowing the 
> layout. 

I'm not sure that's quite true ... there are lots of situations where you simply want to "pass through" a pointer, e.g. in callback situations, where a function sets up a callback and says "when you do the callback, please pass this pointer to it"; and whoever registers the callback will take the pointer, store it somewhere, and use it when it's needed, without ever trying to look at what it points to.

Unfortunately, I don't see the equivalent of "void *" anywhere in Interfaces.C, which is what the sort of thing you'd want.  You could probably use Interfaces.C.Strings.chars_ptr (the equivalent of "char *").  Your suggestion:

> You /can/ have an importation of the pointer itself, though 
> that's not particularly helpful w/o the structure; something like:
> 
> Type Structure_Stub is null record
> with Convention => C;
> 
> Type Structure_Pointer is access Structure_Stub
> with Convention => C;

should work too.

                                 -- Adam


^ permalink raw reply	[relevance 5%]

* gprbuild and Linker_Options bug?
@ 2014-03-31 23:21  7% Qun-Ying
  0 siblings, 0 replies; 200+ results
From: Qun-Ying @ 2014-03-31 23:21 UTC (permalink / raw)


With gnat 2013, GPRBUILD GPL 2013 (20130314) (x86_64-pc-linux-gnu)

For this simple program:

a.gpr:
--------
project A is

    for Main use ("main.adb");

    package Linker is
       for Linker_Options use ("-lgs");
    end Linker;

end A;

main.adb:
----------
with Interfaces.C; use Interfaces.C;
with b; use b;

procedure Main is
    revision: aliased revision_t;
    ret : int;
begin
    ret := b.revision (revision'Access, revision'Size / 8);
end Main;

b.ads
---------
-- simple single function binding for gs to illustrate the bug
with Interfaces.C;         use Interfaces.C;
with Interfaces.C.Strings;
with System;

package b is
    type revision_t is limited private;
    function revision (pr : access revision_t; len : int) return int;
    pragma Import (C, revision, "gsapi_revision");

private
    type revision_t is limited record
       product      : Interfaces.C.Strings.chars_ptr;
       copyright    : Interfaces.C.Strings.chars_ptr;
       revision     : long;
       revisiondate : long;
    end record;
    pragma Convention (C_Pass_By_Copy, revision_t);
end b;

When running under gprbuild -P a, It will failed with the following message:
gcc main.o -o main
main.o: In function `_ada_main':
main.adb:(.text+0x21): undefined reference to `gsapi_revision'
collect2: error: ld returned 1 exit status
gprbuild: link of main.adb failed

Where it fails to use the Linker_Options defined in the project file.
But "gnatmake -P a" will build the program without problem.

Is this a known problem? Or something I have missed?

If  added a line of 'pragma Linker_Options ("-lgs")' in b.ads, then
gprbuild could build without problem.

^ permalink raw reply	[relevance 7%]

* Re: Is there some way of calling a system command?
  2013-11-26 16:10  0%     ` adambeneschan
@ 2013-11-26 18:54  0%       ` tolkamp
  0 siblings, 0 replies; 200+ results
From: tolkamp @ 2013-11-26 18:54 UTC (permalink / raw)


Op dinsdag 26 november 2013 17:10:32 UTC+1 schreef adambe...@gmail.com:
> On Tuesday, November 26, 2013 7:35:26 AM UTC-8, tolkamp wrote:
> 
> > Op zondag 11 juni 2006 15:19:12 UTC+2 schreef jimmaure...@worldnet.att.net:
> 
> 
> 
> > > The easiest way is to simply call the C system command.
> 
> > > The example below was run on my Windows XP system.
> 
> > 
> 
> > > with Interfaces.C.Strings;
> 
> > > use Interfaces.C.Strings;
> 
> > 
> 
> > > procedure System_Example is
> 
> > >    function System_Call(Command : Chars_Ptr) return Interfaces.C.Int;
> 
> > >    pragma Import(Convention => C, Entity => System_Call,
> 
> > >       External_Name => "system");
> 
> > >    Rc : Interfaces.C.Int;
> 
> > 
> 
> > > begin
> 
> > >    Rc := System_Call(New_String("dir"));
> 
> > > end System_Example;
> 
> 
> 
> > > The important part of the example is the creation of a function
> 
> > > specification I have named System_Call. That function specification
> 
> > > take a parameter of Chars_Ptr, which corresponds to a C char *.
> 
> > > The function specification is used as the Ada interface to the C
> 
> > > system call. The compiler is notified of that association through 
> 
> > > the pragma Import. That pragma causes the compiler to link the C
> 
> > > system command and call it whenever System_Call is called in the
> 
> > > Ada code.
> 
> 
> 
> > Thank you for your reaction.
> 
> > For me this is not very understandable.
> 
> > Where must I put the directory path to the executable?
> 
> > Is this "dir" in  Rc := System_Call(New_String("dir"));?
> 
> 
> 
> No, "dir" is the command.  The effect of this statement is that it will execute the "dir" command just as if a user had typed it into the Command Prompt window.  On Windows, "dir" causes a directory listing to appear on the screen.
> 
> 
> 
> System_Call (that is, the C system() routine) more or less requires a string that is something the user would type in a shell or a Command Prompt window.  So if you want to include the directory path, just include it as part of the command, same as you would if you typed it in yourself:
> 
> 
> 
>    Rc := System_Call(New_String("c:\users\abc\subdirectory\mytool"));
> 
> 
> 
> or use the Ada.Directories and possibly Ada.Directories.Hierarchical_File_Names to create the file name:
> 
> 
> 
>    Dir : constant String := "c:\users\abc\subdirectory";
> 
>    
> 
>    Rc := System.Call(New_String(Ada.Directories.Compose(Dir, "mytool")));
> 
> 
> 
>                                    -- Adam

Thank you for your explanation. Now it works, the extra program is started. 
The only disadvantage is that the Ada code below the procedure System_Example is suspended untill the extra started program is terminated. Is there a possibility that the Ada program continues while the extra program runs?

^ permalink raw reply	[relevance 0%]

* Re: Is there some way of calling a system command?
  2013-11-26 15:35  0%   ` tolkamp
  2013-11-26 16:10  0%     ` adambeneschan
@ 2013-11-26 18:24  0%     ` Per Sandberg
  1 sibling, 0 replies; 200+ results
From: Per Sandberg @ 2013-11-26 18:24 UTC (permalink / raw)


Why not just 
	GNAT.OS_Lib.spawn
or
	GNAT.Expect.*
?
/Persan


On Tue, 26 Nov 2013 07:35:26 -0800 (PST)
tolkamp <f.tolkamp@gmail.com> wrote:

> Op zondag 11 juni 2006 15:19:12 UTC+2 schreef
> jimmaure...@worldnet.att.net:
> > Aldebaran wrote:
> > > I am a newbie Ada-programmer and need help with this topic.
> > > In C one can launch a system command, for instance through
> > >  the following function.
> > >
> > >  system("ls ");
> > >
> > > or in JAVA
> > >
> > >  exec("ls");
> > >
> > > Is there some similar  way of calling a system command in ADA?
> > 
> > The easiest way is to simply call the C system command.
> > The example below was run on my Windows XP system.
> > 
> > with Interfaces.C.Strings;
> > use Interfaces.C.Strings;
> > 
> > procedure System_Example is
> >    function System_Call(Command : Chars_Ptr) return
> > Interfaces.C.Int; pragma Import(Convention => C, Entity =>
> > System_Call, External_Name => "system");
> >    Rc : Interfaces.C.Int;
> > 
> > begin
> >    Rc := System_Call(New_String("dir"));
> > 
> > end System_Example;
> > 
> > The important part of the example is the creation of a function
> > specification I have named System_Call. That function specification
> > take a parameter of Chars_Ptr, which corresponds to a C char *.
> > The function specification is used as the Ada interface to the C
> > system call. The compiler is notified of that association through
> > the pragma Import. That pragma causes the compiler to link the C
> > system command and call it whenever System_Call is called in the
> > Ada code.
> > 
> > Jim Rogers
> 
> Thank you for your reaction.
> For me this is not very understandable.
> Where must I put the directory path to the executable?
> Is this "dir" in  Rc := System_Call(New_String("dir"));?
> 


^ permalink raw reply	[relevance 0%]

* Re: Is there some way of calling a system command?
  2013-11-26 15:35  0%   ` tolkamp
@ 2013-11-26 16:10  0%     ` adambeneschan
  2013-11-26 18:54  0%       ` tolkamp
  2013-11-26 18:24  0%     ` Per Sandberg
  1 sibling, 1 reply; 200+ results
From: adambeneschan @ 2013-11-26 16:10 UTC (permalink / raw)


On Tuesday, November 26, 2013 7:35:26 AM UTC-8, tolkamp wrote:
> Op zondag 11 juni 2006 15:19:12 UTC+2 schreef jimmaure...@worldnet.att.net:

> > The easiest way is to simply call the C system command.
> > The example below was run on my Windows XP system.
> 
> > with Interfaces.C.Strings;
> > use Interfaces.C.Strings;
> 
> > procedure System_Example is
> >    function System_Call(Command : Chars_Ptr) return Interfaces.C.Int;
> >    pragma Import(Convention => C, Entity => System_Call,
> >       External_Name => "system");
> >    Rc : Interfaces.C.Int;
> 
> > begin
> >    Rc := System_Call(New_String("dir"));
> > end System_Example;

> > The important part of the example is the creation of a function
> > specification I have named System_Call. That function specification
> > take a parameter of Chars_Ptr, which corresponds to a C char *.
> > The function specification is used as the Ada interface to the C
> > system call. The compiler is notified of that association through 
> > the pragma Import. That pragma causes the compiler to link the C
> > system command and call it whenever System_Call is called in the
> > Ada code.

> Thank you for your reaction.
> For me this is not very understandable.
> Where must I put the directory path to the executable?
> Is this "dir" in  Rc := System_Call(New_String("dir"));?

No, "dir" is the command.  The effect of this statement is that it will execute the "dir" command just as if a user had typed it into the Command Prompt window.  On Windows, "dir" causes a directory listing to appear on the screen.

System_Call (that is, the C system() routine) more or less requires a string that is something the user would type in a shell or a Command Prompt window.  So if you want to include the directory path, just include it as part of the command, same as you would if you typed it in yourself:

   Rc := System_Call(New_String("c:\users\abc\subdirectory\mytool"));

or use the Ada.Directories and possibly Ada.Directories.Hierarchical_File_Names to create the file name:

   Dir : constant String := "c:\users\abc\subdirectory";
   
   Rc := System.Call(New_String(Ada.Directories.Compose(Dir, "mytool")));

                                   -- Adam
 

^ permalink raw reply	[relevance 0%]

* Re: Is there some way of calling a system command?
  2006-06-11 13:19  7% ` jimmaureenrogers
  2006-06-15 14:03  0%   ` Michel Simeon
@ 2013-11-26 15:35  0%   ` tolkamp
  2013-11-26 16:10  0%     ` adambeneschan
  2013-11-26 18:24  0%     ` Per Sandberg
  1 sibling, 2 replies; 200+ results
From: tolkamp @ 2013-11-26 15:35 UTC (permalink / raw)


Op zondag 11 juni 2006 15:19:12 UTC+2 schreef jimmaure...@worldnet.att.net:
> Aldebaran wrote:
> > I am a newbie Ada-programmer and need help with this topic.
> > In C one can launch a system command, for instance through
> >  the following function.
> >
> >  system("ls ");
> >
> > or in JAVA
> >
> >  exec("ls");
> >
> > Is there some similar  way of calling a system command in ADA?
> 
> The easiest way is to simply call the C system command.
> The example below was run on my Windows XP system.
> 
> with Interfaces.C.Strings;
> use Interfaces.C.Strings;
> 
> procedure System_Example is
>    function System_Call(Command : Chars_Ptr) return Interfaces.C.Int;
>    pragma Import(Convention => C, Entity => System_Call,
>       External_Name => "system");
>    Rc : Interfaces.C.Int;
> 
> begin
>    Rc := System_Call(New_String("dir"));
> 
> end System_Example;
> 
> The important part of the example is the creation of a function
> specification I have named System_Call. That function specification
> take a parameter of Chars_Ptr, which corresponds to a C char *.
> The function specification is used as the Ada interface to the C
> system call. The compiler is notified of that association through
> the pragma Import. That pragma causes the compiler to link the C
> system command and call it whenever System_Call is called in the
> Ada code.
> 
> Jim Rogers

Thank you for your reaction.
For me this is not very understandable.
Where must I put the directory path to the executable?
Is this "dir" in  Rc := System_Call(New_String("dir"));?

^ permalink raw reply	[relevance 0%]

* Re: library/binding for sftp?
  @ 2013-08-22  5:53  7%                                           ` Per Sandberg
  0 siblings, 0 replies; 200+ results
From: Per Sandberg @ 2013-08-22  5:53 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 1389 bytes --]


gcc -fdump-ada-spec =>

It requires a wrapper to be Ada not C written in Ada but anyway.

/Per

On Wed, 21 Aug 2013 09:46:55 -0700 (PDT)
Alan Jump <alan.jump@gmail.com> wrote:

> On Wednesday, August 21, 2013 12:27:30 AM UTC-7,
> Stefan...@uni-weimar.de wrote:
> > On Tue, 20 Aug 2013, Randy Brukardt wrote:
> > 
> [snip] 
> > 
> > ------  I  love  the  taste  of  Cryptanalysis  in  the morning!
> > ------
> 
> One final thought which goes directly back to the OP's questions.
> 
> I'd love to see an Ada binding for SFTP or a similar
> relatively-secure transfer protocol released to an open-source
> repository. It would certainly relieve in-house developers from
> having to come up with their own implementations, and by placing such
> in an open-source repository, it would invite inspection from outside
> which may reveal dangerous flaws prior to widespread deployment.
> 
> Even though data transfers may be monitored, and with sufficient
> effort the contents of the packets extracted, there's absolutely
> nothing that says one can't implement one or more additional
> encryption layers prior to transmission. Think "belt and suspenders".
> Or, in a more relevant comparison, encrypting an email using GPG,
> Enigma, one-time pad, or whatever, then sending it via an encrypted
> VPN tunnel.
> 
> Just my 2p worth. Save up the change for a pint.
> 
> - -
> 73 de N5ILN
> Alan


[-- Attachment #2: libssh2_h.ads --]
[-- Type: text/x-adasrc, Size: 47013 bytes --]

pragma Ada_2005;
pragma Style_Checks (Off);

with Interfaces.C; use Interfaces.C;
with Interfaces.C.Extensions;
with Interfaces.C.Strings;
with System;

package libssh2_h is
   package time_h is

      subtype clock_t is long;  -- time.h:60

      subtype time_t is long;  -- time.h:76

      subtype clockid_t is int;  -- time.h:92

      subtype timer_t is System.Address;  -- time.h:104

      type timespec is record
         tv_sec : aliased long;  -- time.h:122
         tv_nsec : aliased long;  -- time.h:123
      end record;
      pragma Convention (C_Pass_By_Copy, timespec);  -- time.h:120

   end time_h;


   package bits_stat_h is

      --  unsupported macro: st_atime st_atim.tv_sec
      --  unsupported macro: st_mtime st_mtim.tv_sec
      --  unsupported macro: st_ctime st_ctim.tv_sec

      UTIME_NOW : constant := ((2 ** 30) - 1);  --  bits/stat.h:209
      UTIME_OMIT : constant := ((2 ** 30) - 2);  --  bits/stat.h:210

      type stat_uu_unused_array is array (0 .. 2) of aliased long;
      type stat is record
         st_dev : aliased unsigned_long;  -- bits/stat.h:48
         st_ino : aliased unsigned_long;  -- bits/stat.h:53
         st_nlink : aliased unsigned_long;  -- bits/stat.h:61
         st_mode : aliased unsigned;  -- bits/stat.h:62
         st_uid : aliased unsigned;  -- bits/stat.h:64
         st_gid : aliased unsigned;  -- bits/stat.h:65
         uu_pad0 : aliased int;  -- bits/stat.h:67
         st_rdev : aliased unsigned_long;  -- bits/stat.h:69
         st_size : aliased long;  -- bits/stat.h:74
         st_blksize : aliased long;  -- bits/stat.h:78
         st_blocks : aliased long;  -- bits/stat.h:80
         st_atim : aliased time_h.timespec;  -- bits/stat.h:91
         st_mtim : aliased time_h.timespec;  -- bits/stat.h:92
         st_ctim : aliased time_h.timespec;  -- bits/stat.h:93
         uu_unused : aliased stat_uu_unused_array;  -- bits/stat.h:106
      end record;
      pragma Convention (C_Pass_By_Copy, stat);  -- bits/stat.h:46

      type stat64_uu_unused_array is array (0 .. 2) of aliased long;
      type stat64 is record
         st_dev : aliased unsigned_long;  -- bits/stat.h:121
         st_ino : aliased unsigned_long;  -- bits/stat.h:123
         st_nlink : aliased unsigned_long;  -- bits/stat.h:124
         st_mode : aliased unsigned;  -- bits/stat.h:125
         st_uid : aliased unsigned;  -- bits/stat.h:132
         st_gid : aliased unsigned;  -- bits/stat.h:133
         uu_pad0 : aliased int;  -- bits/stat.h:135
         st_rdev : aliased unsigned_long;  -- bits/stat.h:136
         st_size : aliased long;  -- bits/stat.h:137
         st_blksize : aliased long;  -- bits/stat.h:143
         st_blocks : aliased long;  -- bits/stat.h:144
         st_atim : aliased time_h.timespec;  -- bits/stat.h:152
         st_mtim : aliased time_h.timespec;  -- bits/stat.h:153
         st_ctim : aliased time_h.timespec;  -- bits/stat.h:154
         uu_unused : aliased stat64_uu_unused_array;  -- bits/stat.h:167
      end record;
      pragma Convention (C_Pass_By_Copy, stat64);  -- bits/stat.h:119

   end bits_stat_h;

   LIBSSH2_H : constant := 1;  --  libssh2.h:41

   LIBSSH2_COPYRIGHT : aliased constant String := "2004-2010 The libssh2 project and its contributors." & ASCII.NUL;  --  libssh2.h:43

   LIBSSH2_VERSION : aliased constant String := "1.2.7" & ASCII.NUL;  --  libssh2.h:49

   LIBSSH2_VERSION_MAJOR : constant := 1;  --  libssh2.h:53
   LIBSSH2_VERSION_MINOR : constant := 2;  --  libssh2.h:54
   LIBSSH2_VERSION_PATCH : constant := 7;  --  libssh2.h:55

   LIBSSH2_VERSION_NUM : constant := 16#010207#;  --  libssh2.h:72

   LIBSSH2_TIMESTAMP : aliased constant String := "Tue Aug 17 21:11:33 UTC 2010" & ASCII.NUL;  --  libssh2.h:83
   --  unsupported macro: LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION
   --  unsupported macro: LIBSSH2_SSH_DEFAULT_BANNER LIBSSH2_SSH_BANNER
   --  unsupported macro: LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF LIBSSH2_SSH_DEFAULT_BANNER "\r\n"

   LIBSSH2_DH_GEX_MINGROUP : constant := 1024;  --  libssh2.h:142
   LIBSSH2_DH_GEX_OPTGROUP : constant := 1536;  --  libssh2.h:143
   LIBSSH2_DH_GEX_MAXGROUP : constant := 2048;  --  libssh2.h:144

   LIBSSH2_TERM_WIDTH : constant := 80;  --  libssh2.h:147
   LIBSSH2_TERM_HEIGHT : constant := 24;  --  libssh2.h:148
   LIBSSH2_TERM_WIDTH_PX : constant := 0;  --  libssh2.h:149
   LIBSSH2_TERM_HEIGHT_PX : constant := 0;  --  libssh2.h:150

   LIBSSH2_SOCKET_POLL_UDELAY : constant := 250000;  --  libssh2.h:153

   LIBSSH2_SOCKET_POLL_MAXLOOPS : constant := 120;  --  libssh2.h:155

   LIBSSH2_PACKET_MAXCOMP : constant := 32000;  --  libssh2.h:159

   LIBSSH2_PACKET_MAXDECOMP : constant := 40000;  --  libssh2.h:163

   LIBSSH2_PACKET_MAXPAYLOAD : constant := 40000;  --  libssh2.h:167
   --  arg-macro: procedure LIBSSH2_ALLOC_FUNC (name)
   --    void *name(size_t count, void **abstract)
   --  arg-macro: procedure LIBSSH2_REALLOC_FUNC (name)
   --    void *name(void *ptr, size_t count, void **abstract)
   --  arg-macro: procedure LIBSSH2_FREE_FUNC (name)
   --    void name(void *ptr, void **abstract)
   --  arg-macro: procedure LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC (name)
   --    int name(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract)
   --  arg-macro: procedure LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC (name_)
   --    void name_(const char* name, int name_len, const char* instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract)
   --  arg-macro: procedure LIBSSH2_IGNORE_FUNC (name)
   --    void name(LIBSSH2_SESSION *session, const char *message, int message_len, void **abstract)
   --  arg-macro: procedure LIBSSH2_DEBUG_FUNC (name)
   --    void name(LIBSSH2_SESSION *session, int always_display, const char *message, int message_len, const char *language, int language_len, void **abstract)
   --  arg-macro: procedure LIBSSH2_DISCONNECT_FUNC (name)
   --    void name(LIBSSH2_SESSION *session, int reason, const char *message, int message_len, const char *language, int language_len, void **abstract)
   --  arg-macro: procedure LIBSSH2_PASSWD_CHANGEREQ_FUNC (name)
   --    void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, void **abstract)
   --  arg-macro: procedure LIBSSH2_MACERROR_FUNC (name)
   --    int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, void **abstract)
   --  arg-macro: procedure LIBSSH2_X11_OPEN_FUNC (name)
   --    void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, const char *shost, int sport, void **abstract)
   --  arg-macro: procedure LIBSSH2_CHANNEL_CLOSE_FUNC (name)
   --    void name(LIBSSH2_SESSION *session, void **session_abstract, LIBSSH2_CHANNEL *channel, void **channel_abstract)

   LIBSSH2_CALLBACK_IGNORE : constant := 0;  --  libssh2.h:232
   LIBSSH2_CALLBACK_DEBUG : constant := 1;  --  libssh2.h:233
   LIBSSH2_CALLBACK_DISCONNECT : constant := 2;  --  libssh2.h:234
   LIBSSH2_CALLBACK_MACERROR : constant := 3;  --  libssh2.h:235
   LIBSSH2_CALLBACK_X11 : constant := 4;  --  libssh2.h:236

   LIBSSH2_METHOD_KEX : constant := 0;  --  libssh2.h:239
   LIBSSH2_METHOD_HOSTKEY : constant := 1;  --  libssh2.h:240
   LIBSSH2_METHOD_CRYPT_CS : constant := 2;  --  libssh2.h:241
   LIBSSH2_METHOD_CRYPT_SC : constant := 3;  --  libssh2.h:242
   LIBSSH2_METHOD_MAC_CS : constant := 4;  --  libssh2.h:243
   LIBSSH2_METHOD_MAC_SC : constant := 5;  --  libssh2.h:244
   LIBSSH2_METHOD_COMP_CS : constant := 6;  --  libssh2.h:245
   LIBSSH2_METHOD_COMP_SC : constant := 7;  --  libssh2.h:246
   LIBSSH2_METHOD_LANG_CS : constant := 8;  --  libssh2.h:247
   LIBSSH2_METHOD_LANG_SC : constant := 9;  --  libssh2.h:248

   LIBSSH2_FLAG_SIGPIPE : constant := 16#00000001#;  --  libssh2.h:251

   LIBSSH2_POLLFD_SOCKET : constant := 1;  --  libssh2.h:274
   LIBSSH2_POLLFD_CHANNEL : constant := 2;  --  libssh2.h:275
   LIBSSH2_POLLFD_LISTENER : constant := 3;  --  libssh2.h:276

   LIBSSH2_POLLFD_POLLIN : constant := 16#0001#;  --  libssh2.h:281

   LIBSSH2_POLLFD_POLLPRI : constant := 16#0002#;  --  libssh2.h:284

   LIBSSH2_POLLFD_POLLEXT : constant := 16#0002#;  --  libssh2.h:286

   LIBSSH2_POLLFD_POLLOUT : constant := 16#0004#;  --  libssh2.h:288

   LIBSSH2_POLLFD_POLLERR : constant := 16#0008#;  --  libssh2.h:291
   LIBSSH2_POLLFD_POLLHUP : constant := 16#0010#;  --  libssh2.h:292
   LIBSSH2_POLLFD_SESSION_CLOSED : constant := 16#0010#;  --  libssh2.h:293
   LIBSSH2_POLLFD_POLLNVAL : constant := 16#0020#;  --  libssh2.h:294

   LIBSSH2_POLLFD_POLLEX : constant := 16#0040#;  --  libssh2.h:296

   LIBSSH2_POLLFD_CHANNEL_CLOSED : constant := 16#0080#;  --  libssh2.h:298
   LIBSSH2_POLLFD_LISTENER_CLOSED : constant := 16#0080#;  --  libssh2.h:299

   LIBSSH2_SESSION_BLOCK_INBOUND : constant := 16#0001#;  --  libssh2.h:303
   LIBSSH2_SESSION_BLOCK_OUTBOUND : constant := 16#0002#;  --  libssh2.h:304

   LIBSSH2_HOSTKEY_HASH_MD5 : constant := 1;  --  libssh2.h:307
   LIBSSH2_HOSTKEY_HASH_SHA1 : constant := 2;  --  libssh2.h:308

   LIBSSH2_HOSTKEY_TYPE_UNKNOWN : constant := 0;  --  libssh2.h:311
   LIBSSH2_HOSTKEY_TYPE_RSA : constant := 1;  --  libssh2.h:312
   LIBSSH2_HOSTKEY_TYPE_DSS : constant := 2;  --  libssh2.h:313

   SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT : constant := 1;  --  libssh2.h:316
   SSH_DISCONNECT_PROTOCOL_ERROR : constant := 2;  --  libssh2.h:317
   SSH_DISCONNECT_KEY_EXCHANGE_FAILED : constant := 3;  --  libssh2.h:318
   SSH_DISCONNECT_RESERVED : constant := 4;  --  libssh2.h:319
   SSH_DISCONNECT_MAC_ERROR : constant := 5;  --  libssh2.h:320
   SSH_DISCONNECT_COMPRESSION_ERROR : constant := 6;  --  libssh2.h:321
   SSH_DISCONNECT_SERVICE_NOT_AVAILABLE : constant := 7;  --  libssh2.h:322
   SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED : constant := 8;  --  libssh2.h:323
   SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE : constant := 9;  --  libssh2.h:324
   SSH_DISCONNECT_CONNECTION_LOST : constant := 10;  --  libssh2.h:325
   SSH_DISCONNECT_BY_APPLICATION : constant := 11;  --  libssh2.h:326
   SSH_DISCONNECT_TOO_MANY_CONNECTIONS : constant := 12;  --  libssh2.h:327
   SSH_DISCONNECT_AUTH_CANCELLED_BY_USER : constant := 13;  --  libssh2.h:328
   SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE : constant := 14;  --  libssh2.h:329
   SSH_DISCONNECT_ILLEGAL_USER_NAME : constant := 15;  --  libssh2.h:330

   LIBSSH2_ERROR_NONE : constant := 0;  --  libssh2.h:333
   LIBSSH2_ERROR_SOCKET_NONE : constant := -1;  --  libssh2.h:334
   LIBSSH2_ERROR_BANNER_NONE : constant := -2;  --  libssh2.h:335
   LIBSSH2_ERROR_BANNER_SEND : constant := -3;  --  libssh2.h:336
   LIBSSH2_ERROR_INVALID_MAC : constant := -4;  --  libssh2.h:337
   LIBSSH2_ERROR_KEX_FAILURE : constant := -5;  --  libssh2.h:338
   LIBSSH2_ERROR_ALLOC : constant := -6;  --  libssh2.h:339
   LIBSSH2_ERROR_SOCKET_SEND : constant := -7;  --  libssh2.h:340
   LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE : constant := -8;  --  libssh2.h:341
   LIBSSH2_ERROR_TIMEOUT : constant := -9;  --  libssh2.h:342
   LIBSSH2_ERROR_HOSTKEY_INIT : constant := -10;  --  libssh2.h:343
   LIBSSH2_ERROR_HOSTKEY_SIGN : constant := -11;  --  libssh2.h:344
   LIBSSH2_ERROR_DECRYPT : constant := -12;  --  libssh2.h:345
   LIBSSH2_ERROR_SOCKET_DISCONNECT : constant := -13;  --  libssh2.h:346
   LIBSSH2_ERROR_PROTO : constant := -14;  --  libssh2.h:347
   LIBSSH2_ERROR_PASSWORD_EXPIRED : constant := -15;  --  libssh2.h:348
   LIBSSH2_ERROR_FILE : constant := -16;  --  libssh2.h:349
   LIBSSH2_ERROR_METHOD_NONE : constant := -17;  --  libssh2.h:350
   LIBSSH2_ERROR_AUTHENTICATION_FAILED : constant := -18;  --  libssh2.h:351
   --  unsupported macro: LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED LIBSSH2_ERROR_AUTHENTICATION_FAILED

   LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED : constant := -19;  --  libssh2.h:353
   LIBSSH2_ERROR_CHANNEL_OUTOFORDER : constant := -20;  --  libssh2.h:354
   LIBSSH2_ERROR_CHANNEL_FAILURE : constant := -21;  --  libssh2.h:355
   LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED : constant := -22;  --  libssh2.h:356
   LIBSSH2_ERROR_CHANNEL_UNKNOWN : constant := -23;  --  libssh2.h:357
   LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED : constant := -24;  --  libssh2.h:358
   LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED : constant := -25;  --  libssh2.h:359
   LIBSSH2_ERROR_CHANNEL_CLOSED : constant := -26;  --  libssh2.h:360
   LIBSSH2_ERROR_CHANNEL_EOF_SENT : constant := -27;  --  libssh2.h:361
   LIBSSH2_ERROR_SCP_PROTOCOL : constant := -28;  --  libssh2.h:362
   LIBSSH2_ERROR_ZLIB : constant := -29;  --  libssh2.h:363
   LIBSSH2_ERROR_SOCKET_TIMEOUT : constant := -30;  --  libssh2.h:364
   LIBSSH2_ERROR_SFTP_PROTOCOL : constant := -31;  --  libssh2.h:365
   LIBSSH2_ERROR_REQUEST_DENIED : constant := -32;  --  libssh2.h:366
   LIBSSH2_ERROR_METHOD_NOT_SUPPORTED : constant := -33;  --  libssh2.h:367
   LIBSSH2_ERROR_INVAL : constant := -34;  --  libssh2.h:368
   LIBSSH2_ERROR_INVALID_POLL_TYPE : constant := -35;  --  libssh2.h:369
   LIBSSH2_ERROR_PUBLICKEY_PROTOCOL : constant := -36;  --  libssh2.h:370
   LIBSSH2_ERROR_EAGAIN : constant := -37;  --  libssh2.h:371
   LIBSSH2_ERROR_BUFFER_TOO_SMALL : constant := -38;  --  libssh2.h:372
   LIBSSH2_ERROR_BAD_USE : constant := -39;  --  libssh2.h:373
   LIBSSH2_ERROR_COMPRESS : constant := -40;  --  libssh2.h:374
   LIBSSH2_ERROR_OUT_OF_BOUNDARY : constant := -41;  --  libssh2.h:375
   LIBSSH2_ERROR_AGENT_PROTOCOL : constant := -42;  --  libssh2.h:376

   LIBSSH2_INIT_NO_CRYPTO : constant := 16#0001#;  --  libssh2.h:379
   --  arg-macro: procedure libssh2_session_init ()
   --    libssh2_session_init_ex(NULL, NULL, NULL, NULL)
   --  arg-macro: procedure libssh2_session_disconnect (session, descrilibssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, (description), "")
   --    libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, (description), "")
   --  arg-macro: procedure libssh2_userauth_password (session, usernalibssh2_userauth_password_ex((session), (username), strlen(username), (password), strlen(password), NULL)
   --    libssh2_userauth_password_ex((session), (username), strlen(username), (password), strlen(password), NULL)
   --  arg-macro: procedure libssh2_userauth_publickey_fromfile (session, usernalibssh2_userauth_publickey_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase))
   --    libssh2_userauth_publickey_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase))
   --  arg-macro: procedure libssh2_userauth_hostbased_fromfile (session, usernalibssh2_userauth_hostbased_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase), (hostname), strlen(hostname), (username), strlen(username))
   --    libssh2_userauth_hostbased_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase), (hostname), strlen(hostname), (username), strlen(username))
   --  arg-macro: procedure libssh2_userauth_keyboard_interactive (session, usernalibssh2_userauth_keyboard_interactive_ex((session), (username), strlen(username), (response_callback))
   --    libssh2_userauth_keyboard_interactive_ex((session), (username), strlen(username), (response_callback))

   LIBSSH2_CHANNEL_WINDOW_DEFAULT : constant := 65536;  --  libssh2.h:529
   LIBSSH2_CHANNEL_PACKET_DEFAULT : constant := 32768;  --  libssh2.h:530
   LIBSSH2_CHANNEL_MINADJUST : constant := 1024;  --  libssh2.h:531

   LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL : constant := 0;  --  libssh2.h:534
   LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : constant := 1;  --  libssh2.h:535
   LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE : constant := 2;  --  libssh2.h:536

   SSH_EXTENDED_DATA_STDERR : constant := 1;  --  libssh2.h:538
   --  unsupported macro: LIBSSH2CHANNEL_EAGAIN LIBSSH2_ERROR_EAGAIN
   --  arg-macro: procedure libssh2_channel_open_session (session)
   --    libssh2_channel_open_ex((session), "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0)
   --  arg-macro: procedure libssh2_channel_direct_tcpip (session, host, libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22)
   --    libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22)
   --  arg-macro: procedure libssh2_channel_forward_listen (session, port)
   --    libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16)
   --  arg-macro: procedure libssh2_channel_setenv (channel, varnamlibssh2_channel_setenv_ex((channel), (varname), strlen(varname), (value), strlen(value))
   --    libssh2_channel_setenv_ex((channel), (varname), strlen(varname), (value), strlen(value))
   --  arg-macro: procedure libssh2_channel_request_pty (channel, term)
   --    libssh2_channel_request_pty_ex((channel), (term), strlen(term), NULL, 0, LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX)
   --  arg-macro: procedure libssh2_channel_request_pty_size (channel, width,libssh2_channel_request_pty_size_ex( (channel), (width), (height), 0, 0)
   --    libssh2_channel_request_pty_size_ex( (channel), (width), (height), 0, 0)
   --  arg-macro: procedure libssh2_channel_x11_req (channel, screenlibssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number))
   --    libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number))
   --  arg-macro: procedure libssh2_channel_shell (channel)
   --    libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, NULL, 0)
   --  arg-macro: procedure libssh2_channel_exec (channel, commanlibssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, (command), strlen(command))
   --    libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, (command), strlen(command))
   --  arg-macro: procedure libssh2_channel_subsystem (channel, subsyslibssh2_channel_process_startup((channel), "subsystem", sizeof("subsystem") - 1, (subsystem), strlen(subsystem))
   --    libssh2_channel_process_startup((channel), "subsystem", sizeof("subsystem") - 1, (subsystem), strlen(subsystem))
   --  arg-macro: procedure libssh2_channel_read (channel, buf, blibssh2_channel_read_ex((channel), 0, (buf), (buflen))
   --    libssh2_channel_read_ex((channel), 0, (buf), (buflen))
   --  arg-macro: procedure libssh2_channel_read_stderr (channel, buf, blibssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
   --    libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
   --  arg-macro: procedure libssh2_channel_window_read (channel)
   --    libssh2_channel_window_read_ex((channel), NULL, NULL)
   --  arg-macro: procedure libssh2_channel_write (channel, buf, blibssh2_channel_write_ex((channel), 0, (buf), (buflen))
   --    libssh2_channel_write_ex((channel), 0, (buf), (buflen))
   --  arg-macro: procedure libssh2_channel_write_stderr (channel, buf, blibssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
   --    libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
   --  arg-macro: procedure libssh2_channel_window_write (channel)
   --    libssh2_channel_window_write_ex((channel), NULL)
   --  arg-macro: procedure libssh2_channel_ignore_extended_data (channel, ignorelibssh2_channel_handle_extended_data((channel), (ignore) ? LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL )
   --    libssh2_channel_handle_extended_data((channel), (ignore) ? LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL )

   LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA : constant := -1;  --  libssh2.h:696
   LIBSSH2_CHANNEL_FLUSH_ALL : constant := -2;  --  libssh2.h:697
   --  arg-macro: procedure libssh2_channel_flush (channel)
   --    libssh2_channel_flush_ex((channel), 0)
   --  arg-macro: procedure libssh2_channel_flush_stderr (channel)
   --    libssh2_channel_flush_ex((channel), SSH_EXTENDED_DATA_STDERR)
   --  arg-macro: procedure libssh2_scp_send (session, path, libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0)
   --    libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0)

   HAVE_LIBSSH2_KNOWNHOST_API : constant := 16#010101#;  --  libssh2.h:733
   HAVE_LIBSSH2_VERSION_API : constant := 16#010100#;  --  libssh2.h:734

   LIBSSH2_KNOWNHOST_TYPE_MASK : constant := 16#ffff#;  --  libssh2.h:776
   LIBSSH2_KNOWNHOST_TYPE_PLAIN : constant := 1;  --  libssh2.h:777
   LIBSSH2_KNOWNHOST_TYPE_SHA1 : constant := 2;  --  libssh2.h:778
   LIBSSH2_KNOWNHOST_TYPE_CUSTOM : constant := 3;  --  libssh2.h:779
   --  unsupported macro: LIBSSH2_KNOWNHOST_KEYENC_MASK (3<<16)

   LIBSSH2_KNOWNHOST_KEYENC_RAW : constant := (2**16);  --  libssh2.h:783
   --  unsupported macro: LIBSSH2_KNOWNHOST_KEYENC_BASE64 (2<<16)
   --  unsupported macro: LIBSSH2_KNOWNHOST_KEY_MASK (3<<18)

   LIBSSH2_KNOWNHOST_KEY_SHIFT : constant := 18;  --  libssh2.h:788
   LIBSSH2_KNOWNHOST_KEY_RSA1 : constant := (2**18);  --  libssh2.h:789
   --  unsupported macro: LIBSSH2_KNOWNHOST_KEY_SSHRSA (2<<18)
   --  unsupported macro: LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18)

   LIBSSH2_KNOWNHOST_CHECK_MATCH : constant := 0;  --  libssh2.h:854
   LIBSSH2_KNOWNHOST_CHECK_MISMATCH : constant := 1;  --  libssh2.h:855
   LIBSSH2_KNOWNHOST_CHECK_NOTFOUND : constant := 2;  --  libssh2.h:856
   LIBSSH2_KNOWNHOST_CHECK_FAILURE : constant := 3;  --  libssh2.h:857

   LIBSSH2_KNOWNHOST_FILE_OPENSSH : constant := 1;  --  libssh2.h:917

   HAVE_LIBSSH2_AGENT_API : constant := 16#010202#;  --  libssh2.h:972

   LIBSSH2_TRACE_TRANS : constant := (2**1);  --  libssh2.h:1093
   LIBSSH2_TRACE_KEX : constant := (2**2);  --  libssh2.h:1094
   LIBSSH2_TRACE_AUTH : constant := (2**3);  --  libssh2.h:1095
   LIBSSH2_TRACE_CONN : constant := (2**4);  --  libssh2.h:1096
   LIBSSH2_TRACE_SCP : constant := (2**5);  --  libssh2.h:1097
   LIBSSH2_TRACE_SFTP : constant := (2**6);  --  libssh2.h:1098
   LIBSSH2_TRACE_ERROR : constant := (2**7);  --  libssh2.h:1099
   LIBSSH2_TRACE_PUBLICKEY : constant := (2**8);  --  libssh2.h:1100
   LIBSSH2_TRACE_SOCKET : constant := (2**9);  --  libssh2.h:1101

   subtype libssh2_uint64_t is Extensions.unsigned_long_long;  -- libssh2.h:130

   subtype libssh2_int64_t is Long_Long_Integer;  -- libssh2.h:131

   type u_LIBSSH2_USERAUTH_KBDINT_PROMPT is record
      text : Interfaces.C.Strings.chars_ptr;  -- libssh2.h:177
      length : aliased unsigned;  -- libssh2.h:178
      echo : aliased unsigned_char;  -- libssh2.h:179
   end record;
   pragma Convention (C_Pass_By_Copy, u_LIBSSH2_USERAUTH_KBDINT_PROMPT);  -- libssh2.h:175

   subtype LIBSSH2_USERAUTH_KBDINT_PROMPT is u_LIBSSH2_USERAUTH_KBDINT_PROMPT;

   type u_LIBSSH2_USERAUTH_KBDINT_RESPONSE is record
      text : Interfaces.C.Strings.chars_ptr;  -- libssh2.h:184
      length : aliased unsigned;  -- libssh2.h:185
   end record;
   pragma Convention (C_Pass_By_Copy, u_LIBSSH2_USERAUTH_KBDINT_RESPONSE);  -- libssh2.h:182

   subtype LIBSSH2_USERAUTH_KBDINT_RESPONSE is u_LIBSSH2_USERAUTH_KBDINT_RESPONSE;

   --  skipped empty struct u_LIBSSH2_SESSION

   --  skipped empty struct LIBSSH2_SESSION

   --  skipped empty struct u_LIBSSH2_CHANNEL

   --  skipped empty struct LIBSSH2_CHANNEL

   --  skipped empty struct u_LIBSSH2_LISTENER

   --  skipped empty struct LIBSSH2_LISTENER

   --  skipped empty struct u_LIBSSH2_KNOWNHOSTS

   --  skipped empty struct LIBSSH2_KNOWNHOSTS

   --  skipped empty struct u_LIBSSH2_AGENT

   --  skipped empty struct LIBSSH2_AGENT

   type anon_14 (discr : unsigned := 0) is record
      case discr is
         when 0 =>
            socket : aliased int;  -- libssh2.h:263
         when 1 =>
            channel : System.Address;  -- libssh2.h:264
         when others =>
            listener : System.Address;  -- libssh2.h:265
      end case;
   end record;
   pragma Convention (C_Pass_By_Copy, anon_14);
   pragma Unchecked_Union (anon_14);
   type u_LIBSSH2_POLLFD is record
      c_type : aliased unsigned_char;  -- libssh2.h:260
      fd : anon_14;  -- libssh2.h:267
      events : aliased unsigned_long;  -- libssh2.h:269
      revents : aliased unsigned_long;  -- libssh2.h:270
   end record;
   pragma Convention (C_Pass_By_Copy, u_LIBSSH2_POLLFD);  -- libssh2.h:259

   subtype LIBSSH2_POLLFD is u_LIBSSH2_POLLFD;

   function libssh2_init (flags : int) return int;  -- libssh2.h:395
   pragma Import (C, libssh2_init, "libssh2_init");

   procedure libssh2_exit;  -- libssh2.h:402
   pragma Import (C, libssh2_exit, "libssh2_exit");

   function libssh2_session_init_ex
     (my_alloc : access function (arg1 : size_t; arg2 : System.Address) return System.Address;
      my_free : access procedure (arg1 : System.Address; arg2 : System.Address);
      my_realloc : access function
        (arg1 : System.Address;
         arg2 : size_t;
         arg3 : System.Address) return System.Address;
      c_abstract : System.Address) return System.Address;  -- libssh2.h:406
   pragma Import (C, libssh2_session_init_ex, "libssh2_session_init_ex");

   function libssh2_session_abstract (session : System.Address) return System.Address;  -- libssh2.h:411
   pragma Import (C, libssh2_session_abstract, "libssh2_session_abstract");

   function libssh2_session_callback_set
     (session : System.Address;
      cbtype : int;
      callback : System.Address) return System.Address;  -- libssh2.h:413
   pragma Import (C, libssh2_session_callback_set, "libssh2_session_callback_set");

   function libssh2_banner_set (session : System.Address; banner : Interfaces.C.Strings.chars_ptr) return int;  -- libssh2.h:415
   pragma Import (C, libssh2_banner_set, "libssh2_banner_set");

   function libssh2_session_startup (session : System.Address; sock : int) return int;  -- libssh2.h:418
   pragma Import (C, libssh2_session_startup, "libssh2_session_startup");

   function libssh2_session_disconnect_ex
     (session : System.Address;
      reason : int;
      description : Interfaces.C.Strings.chars_ptr;
      lang : Interfaces.C.Strings.chars_ptr) return int;  -- libssh2.h:419
   pragma Import (C, libssh2_session_disconnect_ex, "libssh2_session_disconnect_ex");

   function libssh2_session_free (session : System.Address) return int;  -- libssh2.h:427
   pragma Import (C, libssh2_session_free, "libssh2_session_free");

   function libssh2_hostkey_hash (session : System.Address; hash_type : int) return Interfaces.C.Strings.chars_ptr;  -- libssh2.h:429
   pragma Import (C, libssh2_hostkey_hash, "libssh2_hostkey_hash");

   function libssh2_session_hostkey
     (session : System.Address;
      len : access size_t;
      c_type : access int) return Interfaces.C.Strings.chars_ptr;  -- libssh2.h:432
   pragma Import (C, libssh2_session_hostkey, "libssh2_session_hostkey");

   function libssh2_session_method_pref
     (session : System.Address;
      method_type : int;
      prefs : Interfaces.C.Strings.chars_ptr) return int;  -- libssh2.h:435
   pragma Import (C, libssh2_session_method_pref, "libssh2_session_method_pref");

   function libssh2_session_methods (session : System.Address; method_type : int) return Interfaces.C.Strings.chars_ptr;  -- libssh2.h:438
   pragma Import (C, libssh2_session_methods, "libssh2_session_methods");

   function libssh2_session_last_error
     (session : System.Address;
      errmsg : System.Address;
      errmsg_len : access int;
      want_buf : int) return int;  -- libssh2.h:440
   pragma Import (C, libssh2_session_last_error, "libssh2_session_last_error");

   function libssh2_session_last_errno (session : System.Address) return int;  -- libssh2.h:443
   pragma Import (C, libssh2_session_last_errno, "libssh2_session_last_errno");

   function libssh2_session_block_directions (session : System.Address) return int;  -- libssh2.h:444
   pragma Import (C, libssh2_session_block_directions, "libssh2_session_block_directions");

   function libssh2_session_flag
     (session : System.Address;
      flag : int;
      value : int) return int;  -- libssh2.h:446
   pragma Import (C, libssh2_session_flag, "libssh2_session_flag");

   function libssh2_userauth_list
     (session : System.Address;
      username : Interfaces.C.Strings.chars_ptr;
      username_len : unsigned) return Interfaces.C.Strings.chars_ptr;  -- libssh2.h:450
   pragma Import (C, libssh2_userauth_list, "libssh2_userauth_list");

   function libssh2_userauth_authenticated (session : System.Address) return int;  -- libssh2.h:453
   pragma Import (C, libssh2_userauth_authenticated, "libssh2_userauth_authenticated");

   function libssh2_userauth_password_ex
     (session : System.Address;
      username : Interfaces.C.Strings.chars_ptr;
      username_len : unsigned;
      password : Interfaces.C.Strings.chars_ptr;
      password_len : unsigned;
      passwd_change_cb : access procedure
        (arg1 : System.Address;
         arg2 : System.Address;
         arg3 : access int;
         arg4 : System.Address)) return int;  -- libssh2.h:455
   pragma Import (C, libssh2_userauth_password_ex, "libssh2_userauth_password_ex");

   function libssh2_userauth_publickey_fromfile_ex
     (session : System.Address;
      username : Interfaces.C.Strings.chars_ptr;
      username_len : unsigned;
      publickey : Interfaces.C.Strings.chars_ptr;
      privatekey : Interfaces.C.Strings.chars_ptr;
      passphrase : Interfaces.C.Strings.chars_ptr) return int;  -- libssh2.h:467
   pragma Import (C, libssh2_userauth_publickey_fromfile_ex, "libssh2_userauth_publickey_fromfile_ex");

   function libssh2_userauth_publickey
     (session : System.Address;
      username : Interfaces.C.Strings.chars_ptr;
      pubkeydata : access unsigned_char;
      pubkeydata_len : size_t;
      sign_callback : access function
        (arg1 : System.Address;
         arg2 : System.Address;
         arg3 : access size_t;
         arg4 : access unsigned_char;
         arg5 : size_t;
         arg6 : System.Address) return int;
      c_abstract : System.Address) return int;  -- libssh2.h:481
   pragma Import (C, libssh2_userauth_publickey, "libssh2_userauth_publickey");

   function libssh2_userauth_hostbased_fromfile_ex
     (session : System.Address;
      username : Interfaces.C.Strings.chars_ptr;
      username_len : unsigned;
      publickey : Interfaces.C.Strings.chars_ptr;
      privatekey : Interfaces.C.Strings.chars_ptr;
      passphrase : Interfaces.C.Strings.chars_ptr;
      hostname : Interfaces.C.Strings.chars_ptr;
      hostname_len : unsigned;
      local_username : Interfaces.C.Strings.chars_ptr;
      local_username_len : unsigned) return int;  -- libssh2.h:489
   pragma Import (C, libssh2_userauth_hostbased_fromfile_ex, "libssh2_userauth_hostbased_fromfile_ex");

   function libssh2_userauth_keyboard_interactive_ex
     (session : System.Address;
      username : Interfaces.C.Strings.chars_ptr;
      username_len : unsigned;
      response_callback : access procedure
        (arg1 : Interfaces.C.Strings.chars_ptr;
         arg2 : int;
         arg3 : Interfaces.C.Strings.chars_ptr;
         arg4 : int;
         arg5 : int;
         arg6 : System.Address;
         arg7 : access LIBSSH2_USERAUTH_KBDINT_RESPONSE;
         arg8 : System.Address)) return int;  -- libssh2.h:515
   pragma Import (C, libssh2_userauth_keyboard_interactive_ex, "libssh2_userauth_keyboard_interactive_ex");

   function libssh2_poll
     (fds : access LIBSSH2_POLLFD;
      nfds : unsigned;
      timeout : long) return int;  -- libssh2.h:525
   pragma Import (C, libssh2_poll, "libssh2_poll");

   function libssh2_channel_open_ex
     (session : System.Address;
      channel_type : Interfaces.C.Strings.chars_ptr;
      channel_type_len : unsigned;
      window_size : unsigned;
      packet_size : unsigned;
      message : Interfaces.C.Strings.chars_ptr;
      message_len : unsigned) return System.Address;  -- libssh2.h:544
   pragma Import (C, libssh2_channel_open_ex, "libssh2_channel_open_ex");

   function libssh2_channel_direct_tcpip_ex
     (session : System.Address;
      host : Interfaces.C.Strings.chars_ptr;
      port : int;
      shost : Interfaces.C.Strings.chars_ptr;
      sport : int) return System.Address;  -- libssh2.h:555
   pragma Import (C, libssh2_channel_direct_tcpip_ex, "libssh2_channel_direct_tcpip_ex");

   function libssh2_channel_forward_listen_ex
     (session : System.Address;
      host : Interfaces.C.Strings.chars_ptr;
      port : int;
      bound_port : access int;
      queue_maxsize : int) return System.Address;  -- libssh2.h:561
   pragma Import (C, libssh2_channel_forward_listen_ex, "libssh2_channel_forward_listen_ex");

   function libssh2_channel_forward_cancel (listener : System.Address) return int;  -- libssh2.h:566
   pragma Import (C, libssh2_channel_forward_cancel, "libssh2_channel_forward_cancel");

   function libssh2_channel_forward_accept (listener : System.Address) return System.Address;  -- libssh2.h:569
   pragma Import (C, libssh2_channel_forward_accept, "libssh2_channel_forward_accept");

   function libssh2_channel_setenv_ex
     (channel : System.Address;
      varname : Interfaces.C.Strings.chars_ptr;
      varname_len : unsigned;
      value : Interfaces.C.Strings.chars_ptr;
      value_len : unsigned) return int;  -- libssh2.h:571
   pragma Import (C, libssh2_channel_setenv_ex, "libssh2_channel_setenv_ex");

   function libssh2_channel_request_pty_ex
     (channel : System.Address;
      term : Interfaces.C.Strings.chars_ptr;
      term_len : unsigned;
      modes : Interfaces.C.Strings.chars_ptr;
      modes_len : unsigned;
      width : int;
      height : int;
      width_px : int;
      height_px : int) return int;  -- libssh2.h:581
   pragma Import (C, libssh2_channel_request_pty_ex, "libssh2_channel_request_pty_ex");

   function libssh2_channel_request_pty_size_ex
     (channel : System.Address;
      width : int;
      height : int;
      width_px : int;
      height_px : int) return int;  -- libssh2.h:593
   pragma Import (C, libssh2_channel_request_pty_size_ex, "libssh2_channel_request_pty_size_ex");

   function libssh2_channel_x11_req_ex
     (channel : System.Address;
      single_connection : int;
      auth_proto : Interfaces.C.Strings.chars_ptr;
      auth_cookie : Interfaces.C.Strings.chars_ptr;
      screen_number : int) return int;  -- libssh2.h:600
   pragma Import (C, libssh2_channel_x11_req_ex, "libssh2_channel_x11_req_ex");

   function libssh2_channel_process_startup
     (channel : System.Address;
      request : Interfaces.C.Strings.chars_ptr;
      request_len : unsigned;
      message : Interfaces.C.Strings.chars_ptr;
      message_len : unsigned) return int;  -- libssh2.h:608
   pragma Import (C, libssh2_channel_process_startup, "libssh2_channel_process_startup");

   function libssh2_channel_read_ex
     (channel : System.Address;
      stream_id : int;
      buf : Interfaces.C.Strings.chars_ptr;
      buflen : size_t) return long;  -- libssh2.h:624
   pragma Import (C, libssh2_channel_read_ex, "libssh2_channel_read_ex");

   function libssh2_poll_channel_read (channel : System.Address; extended : int) return int;  -- libssh2.h:632
   pragma Import (C, libssh2_poll_channel_read, "libssh2_poll_channel_read");

   function libssh2_channel_window_read_ex
     (channel : System.Address;
      read_avail : access unsigned_long;
      window_size_initial : access unsigned_long) return unsigned_long;  -- libssh2.h:636
   pragma Import (C, libssh2_channel_window_read_ex, "libssh2_channel_window_read_ex");

   function libssh2_channel_receive_window_adjust
     (channel : System.Address;
      adjustment : unsigned_long;
      force : unsigned_char) return unsigned_long;  -- libssh2.h:644
   pragma Import (C, libssh2_channel_receive_window_adjust, "libssh2_channel_receive_window_adjust");

   function libssh2_channel_receive_window_adjust2
     (channel : System.Address;
      adjustment : unsigned_long;
      force : unsigned_char;
      storewindow : access unsigned) return int;  -- libssh2.h:649
   pragma Import (C, libssh2_channel_receive_window_adjust2, "libssh2_channel_receive_window_adjust2");

   function libssh2_channel_write_ex
     (channel : System.Address;
      stream_id : int;
      buf : Interfaces.C.Strings.chars_ptr;
      buflen : size_t) return long;  -- libssh2.h:654
   pragma Import (C, libssh2_channel_write_ex, "libssh2_channel_write_ex");

   function libssh2_channel_window_write_ex (channel : System.Address; window_size_initial : access unsigned_long) return unsigned_long;  -- libssh2.h:664
   pragma Import (C, libssh2_channel_window_write_ex, "libssh2_channel_window_write_ex");

   procedure libssh2_session_set_blocking (session : System.Address; blocking : int);  -- libssh2.h:669
   pragma Import (C, libssh2_session_set_blocking, "libssh2_session_set_blocking");

   function libssh2_session_get_blocking (session : System.Address) return int;  -- libssh2.h:671
   pragma Import (C, libssh2_session_get_blocking, "libssh2_session_get_blocking");

   procedure libssh2_channel_set_blocking (channel : System.Address; blocking : int);  -- libssh2.h:673
   pragma Import (C, libssh2_channel_set_blocking, "libssh2_channel_set_blocking");

   procedure libssh2_channel_handle_extended_data (channel : System.Address; ignore_mode : int);  -- libssh2.h:677
   pragma Import (C, libssh2_channel_handle_extended_data, "libssh2_channel_handle_extended_data");

   function libssh2_channel_handle_extended_data2 (channel : System.Address; ignore_mode : int) return int;  -- libssh2.h:679
   pragma Import (C, libssh2_channel_handle_extended_data2, "libssh2_channel_handle_extended_data2");

   function libssh2_channel_flush_ex (channel : System.Address; streamid : int) return int;  -- libssh2.h:698
   pragma Import (C, libssh2_channel_flush_ex, "libssh2_channel_flush_ex");

   function libssh2_channel_get_exit_status (channel : System.Address) return int;  -- libssh2.h:704
   pragma Import (C, libssh2_channel_get_exit_status, "libssh2_channel_get_exit_status");

   function libssh2_channel_send_eof (channel : System.Address) return int;  -- libssh2.h:705
   pragma Import (C, libssh2_channel_send_eof, "libssh2_channel_send_eof");

   function libssh2_channel_eof (channel : System.Address) return int;  -- libssh2.h:706
   pragma Import (C, libssh2_channel_eof, "libssh2_channel_eof");

   function libssh2_channel_wait_eof (channel : System.Address) return int;  -- libssh2.h:707
   pragma Import (C, libssh2_channel_wait_eof, "libssh2_channel_wait_eof");

   function libssh2_channel_close (channel : System.Address) return int;  -- libssh2.h:708
   pragma Import (C, libssh2_channel_close, "libssh2_channel_close");

   function libssh2_channel_wait_closed (channel : System.Address) return int;  -- libssh2.h:709
   pragma Import (C, libssh2_channel_wait_closed, "libssh2_channel_wait_closed");

   function libssh2_channel_free (channel : System.Address) return int;  -- libssh2.h:710
   pragma Import (C, libssh2_channel_free, "libssh2_channel_free");

   function libssh2_scp_recv
     (session : System.Address;
      path : Interfaces.C.Strings.chars_ptr;
      sb : access bits_stat_h.stat) return System.Address;  -- libssh2.h:712
   pragma Import (C, libssh2_scp_recv, "libssh2_scp_recv");

   function libssh2_scp_send_ex
     (session : System.Address;
      path : Interfaces.C.Strings.chars_ptr;
      mode : int;
      size : size_t;
      mtime : long;
      atime : long) return System.Address;  -- libssh2.h:715
   pragma Import (C, libssh2_scp_send_ex, "libssh2_scp_send_ex");

   function libssh2_scp_send64
     (session : System.Address;
      path : Interfaces.C.Strings.chars_ptr;
      mode : int;
      size : libssh2_int64_t;
      mtime : time_h.time_t;
      atime : time_h.time_t) return System.Address;  -- libssh2.h:720
   pragma Import (C, libssh2_scp_send64, "libssh2_scp_send64");

   function libssh2_base64_decode
     (session : System.Address;
      dest : System.Address;
      dest_len : access unsigned;
      src : Interfaces.C.Strings.chars_ptr;
      src_len : unsigned) return int;  -- libssh2.h:726
   pragma Import (C, libssh2_base64_decode, "libssh2_base64_decode");

   function get_libssh2_version (req_version_num : int) return Interfaces.C.Strings.chars_ptr;  -- libssh2.h:731
   pragma Import (C, get_libssh2_version, "libssh2_version");

   type libssh2_knownhost is record
      magic : aliased unsigned;  -- libssh2.h:737
      node : System.Address;  -- libssh2.h:738
      name : Interfaces.C.Strings.chars_ptr;  -- libssh2.h:739
      key : Interfaces.C.Strings.chars_ptr;  -- libssh2.h:740
      typemask : aliased int;  -- libssh2.h:741
   end record;
   pragma Convention (C_Pass_By_Copy, libssh2_knownhost);  -- libssh2.h:736

   function libssh2_knownhost_init (session : System.Address) return System.Address;  -- libssh2.h:751
   pragma Import (C, libssh2_knownhost_init, "libssh2_knownhost_init");

   function libssh2_knownhost_add
     (hosts : System.Address;
      host : Interfaces.C.Strings.chars_ptr;
      salt : Interfaces.C.Strings.chars_ptr;
      key : Interfaces.C.Strings.chars_ptr;
      keylen : size_t;
      typemask : int;
      store : System.Address) return int;  -- libssh2.h:794
   pragma Import (C, libssh2_knownhost_add, "libssh2_knownhost_add");

   function libssh2_knownhost_addc
     (hosts : System.Address;
      host : Interfaces.C.Strings.chars_ptr;
      salt : Interfaces.C.Strings.chars_ptr;
      key : Interfaces.C.Strings.chars_ptr;
      keylen : size_t;
      comment : Interfaces.C.Strings.chars_ptr;
      commentlen : size_t;
      typemask : int;
      store : System.Address) return int;  -- libssh2.h:828
   pragma Import (C, libssh2_knownhost_addc, "libssh2_knownhost_addc");

   function libssh2_knownhost_check
     (hosts : System.Address;
      host : Interfaces.C.Strings.chars_ptr;
      key : Interfaces.C.Strings.chars_ptr;
      keylen : size_t;
      typemask : int;
      knownhost : System.Address) return int;  -- libssh2.h:860
   pragma Import (C, libssh2_knownhost_check, "libssh2_knownhost_check");

   function libssh2_knownhost_checkp
     (hosts : System.Address;
      host : Interfaces.C.Strings.chars_ptr;
      port : int;
      key : Interfaces.C.Strings.chars_ptr;
      keylen : size_t;
      typemask : int;
      knownhost : System.Address) return int;  -- libssh2.h:868
   pragma Import (C, libssh2_knownhost_checkp, "libssh2_knownhost_checkp");

   function libssh2_knownhost_del (hosts : System.Address; c_entry : access libssh2_knownhost) return int;  -- libssh2.h:882
   pragma Import (C, libssh2_knownhost_del, "libssh2_knownhost_del");

   procedure libssh2_knownhost_free (hosts : System.Address);  -- libssh2.h:892
   pragma Import (C, libssh2_knownhost_free, "libssh2_knownhost_free");

   function libssh2_knownhost_readline
     (hosts : System.Address;
      line : Interfaces.C.Strings.chars_ptr;
      len : size_t;
      c_type : int) return int;  -- libssh2.h:903
   pragma Import (C, libssh2_knownhost_readline, "libssh2_knownhost_readline");

   function libssh2_knownhost_readfile
     (hosts : System.Address;
      filename : Interfaces.C.Strings.chars_ptr;
      c_type : int) return int;  -- libssh2.h:920
   pragma Import (C, libssh2_knownhost_readfile, "libssh2_knownhost_readfile");

   function libssh2_knownhost_writeline
     (hosts : System.Address;
      known : access libssh2_knownhost;
      buffer : Interfaces.C.Strings.chars_ptr;
      buflen : size_t;
      outlen : access size_t;
      c_type : int) return int;  -- libssh2.h:936
   pragma Import (C, libssh2_knownhost_writeline, "libssh2_knownhost_writeline");

   function libssh2_knownhost_writefile
     (hosts : System.Address;
      filename : Interfaces.C.Strings.chars_ptr;
      c_type : int) return int;  -- libssh2.h:952
   pragma Import (C, libssh2_knownhost_writefile, "libssh2_knownhost_writefile");

   function libssh2_knownhost_get
     (hosts : System.Address;
      store : System.Address;
      prev : access libssh2_knownhost) return int;  -- libssh2.h:968
   pragma Import (C, libssh2_knownhost_get, "libssh2_knownhost_get");

   type libssh2_agent_publickey is record
      magic : aliased unsigned;  -- libssh2.h:975
      node : System.Address;  -- libssh2.h:976
      blob : access unsigned_char;  -- libssh2.h:977
      blob_len : aliased size_t;  -- libssh2.h:978
      comment : Interfaces.C.Strings.chars_ptr;  -- libssh2.h:979
   end record;
   pragma Convention (C_Pass_By_Copy, libssh2_agent_publickey);  -- libssh2.h:974

   function libssh2_agent_init (session : System.Address) return System.Address;  -- libssh2.h:989
   pragma Import (C, libssh2_agent_init, "libssh2_agent_init");

   function libssh2_agent_connect (agent : System.Address) return int;  -- libssh2.h:999
   pragma Import (C, libssh2_agent_connect, "libssh2_agent_connect");

   function libssh2_agent_list_identities (agent : System.Address) return int;  -- libssh2.h:1009
   pragma Import (C, libssh2_agent_list_identities, "libssh2_agent_list_identities");

   function libssh2_agent_get_identity
     (agent : System.Address;
      store : System.Address;
      prev : access libssh2_agent_publickey) return int;  -- libssh2.h:1024
   pragma Import (C, libssh2_agent_get_identity, "libssh2_agent_get_identity");

   function libssh2_agent_userauth
     (agent : System.Address;
      username : Interfaces.C.Strings.chars_ptr;
      identity : access libssh2_agent_publickey) return int;  -- libssh2.h:1036
   pragma Import (C, libssh2_agent_userauth, "libssh2_agent_userauth");

   function libssh2_agent_disconnect (agent : System.Address) return int;  -- libssh2.h:1048
   pragma Import (C, libssh2_agent_disconnect, "libssh2_agent_disconnect");

   procedure libssh2_agent_free (agent : System.Address);  -- libssh2.h:1057
   pragma Import (C, libssh2_agent_free, "libssh2_agent_free");

   procedure libssh2_keepalive_config
     (session : System.Address;
      want_reply : int;
      interval : unsigned);  -- libssh2.h:1073
   pragma Import (C, libssh2_keepalive_config, "libssh2_keepalive_config");

   function libssh2_keepalive_send (session : System.Address; seconds_to_next : access int) return int;  -- libssh2.h:1085
   pragma Import (C, libssh2_keepalive_send, "libssh2_keepalive_send");

   function libssh2_trace (session : System.Address; bitmask : int) return int;  -- libssh2.h:1092
   pragma Import (C, libssh2_trace, "libssh2_trace");

   type libssh2_trace_handler_func is access procedure
     (arg1 : System.Address;
      arg2 : System.Address;
      arg3 : Interfaces.C.Strings.chars_ptr;
      arg4 : size_t);
   pragma Convention (C, libssh2_trace_handler_func);  -- libssh2.h:1103

   function libssh2_trace_sethandler
     (session : System.Address;
      context : System.Address;
      callback : libssh2_trace_handler_func) return int;  -- libssh2.h:1107
   pragma Import (C, libssh2_trace_sethandler, "libssh2_trace_sethandler");

end libssh2_h;

^ permalink raw reply	[relevance 7%]

* Re: Ada  "library only" compiler ?
  @ 2012-07-22 17:54  7%             ` Brian Drummond
  0 siblings, 0 replies; 200+ results
From: Brian Drummond @ 2012-07-22 17:54 UTC (permalink / raw)


On Sat, 21 Jul 2012 20:25:48 -0700, Patrick wrote:

> Hi Brian
> 
> Thanks for your feedback Yes, thankfully with the help of people on the
> list I can work in both directions with C and Ada now and as such could
> write code in Ada and export it as C for use with other languages like
> Lua.

I can now call Lua from Ada. 
Calling Ada from Lua ought to work, but I haven't tried it yet.

I downloaded Lua 5.21 today and tried this (c) example
http://lua-users.org/wiki/SimpleLuaApiExample

I needed to modify the compile process a little (linking with -ldl) to 
overcome missing "dlopen" etc functions; after that, it worked as 
expected. Then I made a basic port of the example to Ada.

This port uses a "thin binding", which can be (mostly) auto-generated by 
GCC, using the -fdump-ada-spec[-slim] option. (This assumes gcc4.6.1 or 
later)

gcc -fdump-ada-spec ../lua-5.2.1/install/include/lua.h
gcc -fdump-ada-spec ../lua-5.2.1/install/include/lauxlib.h
gcc -fdump-ada-spec ../lua-5.2.1/install/include/lualib.h

This builds package spec files (lua_h.ads, etc) for these header files. 
Without -slim, actually the transitive closure of all the headers they 
include, which can get VERY large. (This is not a problem with the tools, 
just a reflection of the disastrous character of C's #include mechanism)

It is probably better to use -slim, and collect the (few) missing 
dependencies into one small additional package. But for Lua, the closure 
only generated 11 files, so I didn't try for this experiment.

Now there are a few problems with this binding; two trivial, one large, 
because -fdump-ada-spec cannot parse everything in every header file.
I am detailing these below in case you want to reproduce the result.

Small problems (minimising the dependencies would eliminate these): 
(1) compiling lauxlib_h.ads reports 
"lauxlib_h.ads:289:25: "FILE" not declared in "stdio_h"
Workaround : comment out the problematic declaration (type luaL_Stream) 
in lauxlib_h.ads. (I can't see the problem)
(2) compiling libio_h.ads reports
libio_h.ads:49:28: "anon652_anon676_array" is undefined
libio_h.ads:58:27: "anon652_anon679_array" is undefined
which turns out to be missing declarations for fields in a record

   type u_IO_FILE is record
...
      u_shortbuf : aliased anon652_anon676_array;  
...
      u_unused2 : aliased anon652_anon679_array;  
   end record;

Considering that one of these fields is declared in C as
--------------------------------------------------------
  /* Make sure we don't get into trouble again.  */
  char _unused2[15 * sizeof (int) - 4 * sizeof (void *) 
	- sizeof (size_t)];
--------------------------------------------------------
I can't blame -fdump-ada-spec for failing to translate it!

Workaround : add subtype declarations ahead of the record decln in 
libio_h.ads, as follows... (size was experimentally determined)
subtype anon652_anon676_array is Interfaces.C.char_array (0 .. 0);
subtype anon652_anon679_array is Interfaces.C.char_array (0 .. 39);
   type u_IO_FILE is record ...

Bigger problem : -fdump-ada-spec can't translate macros; they just don't 
have enough context to define their meaning.

I have resolved this by adding a new package, lua_macros (below), to 
define constants, procedures and functions to replace the missing macros. 
(There are probably 150 missing macros; I have only replaced enough to 
run this example, but the remainder are mostly boilerplate)

Then a straight port of the test program (below) works as expected.
I have left all the gory details explicit in the source; a few "use" 
clauses would make it much more readable.

A better approach would be a thick binding, another package which uses 
these, but hides all the C interface details internally and provides a 
clean Ada interface to application code.

-------- output --------------------------------------------------
./test
The table the script received from the Ada main has:
1	2
2	4
3	6
4	8
5	10
Returning data back to Ada
Script returned: 3.00000E+01
Success

--------- source ---------------------------------------------------

with Interfaces.C.Strings; use Interfaces.C;

with lua_h;
with lauxlib_h;
with lua_macros;
with lualib_h; -- why didn't the C version need to #include lualib.h?

with Ada.Text_Io; use Ada.Text_Io;

-- http://lua-users.org/wiki/SimpleLuaApiExample

procedure test is
    status, result 	: Interfaces.C.int;
    sum 		: Interfaces.C.double;
    L	 		: lua_macros.lua_State_Ptr;

begin

    L := lauxlib_h.luaL_newstate;

    lualib_h.luaL_openlibs(L); -- /* Load Lua libraries */

    status := lua_macros.luaL_loadfile(L, 
				Strings.New_String("script.lua"));
    if status /= 0 then 
        -- If something went wrong, error is at the top of the stack 
        Put_Line("Couldn't load file: " & 
		Strings.Value(lua_macros.lua_tostring(L, -1)));
        raise Program_Error;
    end if;

    lua_macros.lua_newtable(L);

    for i in 1 .. 5 loop
        lua_h.lua_pushnumber(L, double(i));   	-- /* Push the table 
index */
        lua_h.lua_pushnumber(L, double(i*2)); 	-- /* Push the cell value 
*/
        lua_h.lua_rawset(L, -3);      		-- /* Stores the pair in 
the table */
    end loop;

    -- /* By what name is the script going to reference our table? */
    lua_h.lua_setglobal(L, Strings.New_String("foo"));

    -- /* Ask Lua to run our little script */
    result := lua_macros.lua_pcall(L, 0, lua_macros.LUA_MULTRET, 0);
    if result /= 0 then
        Put_Line("Failed to run script: "& 
		Strings.Value(lua_macros.lua_tostring(L, -1)));
        raise Program_Error;
    end if;

    -- /* Get the returned value at the top of the stack (index -1) */
    sum := lua_macros.lua_tonumber(L, -1);

    Put_Line("Script returned:"  & float'image(float(sum)));

    lua_macros.lua_pop(L, 1);  	-- /* Take returned value off stack */
    lua_h.lua_close(L);   	-- /* Cya, Lua */

    Put_Line("Success");

end test;

--------- macro spec ---------------------------------------------------
with lua_h;
with System;
with Interfaces.C.Strings;
use Interfaces.C;

package lua_macros is

-- missing macros from lua_h

   --  skipped empty struct lua_State ... lua.h
   subtype lua_State_Ptr is System.Address;

   -- /* option for multiple returns in 'lua_pcall' and 'lua_call' */
   -- #define LUA_MULTRET	(-1)
   LUA_MULTRET : constant Interfaces.C.Int := -1;

   -- #define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL)
   function lua_pcall (	L : lua_State_Ptr; 
			n : Interfaces.C.int;
			r : Interfaces.C.int;
			f : Interfaces.C.int ) 
   			return Interfaces.C.int;

   -- #define lua_pop(L,n)		lua_settop(L, -(n)-1)
   procedure lua_pop (L : lua_State_Ptr; n : Interfaces.C.int); 

   -- #define lua_tonumber(L,i)	lua_tonumberx(L,i,NULL)
   function lua_tonumber (L : lua_State_Ptr; i : Interfaces.C.int) 
	return lua_h.lua_Number; 

   -- #define lua_newtable(L)	lua_createtable(L, 0, 0)
   procedure lua_newtable (L : lua_State_Ptr);

   -- #define lua_tostring(L,i)	lua_tolstring(L, (i), NULL)
   function lua_tostring
     (L : lua_State_Ptr;
      i : Interfaces.C.int) return Interfaces.C.Strings.chars_ptr; 

-- missing macros from lauxlib_h

   -- #define luaL_loadfile(L,f)	luaL_loadfilex(L,f,NULL)
   function luaL_loadfile
     (L : lua_State_Ptr;
      f : Interfaces.C.Strings.chars_ptr ) return Interfaces.C.int;

end lua_macros;
--------- macro body ---------------------------------------------------
with lauxlib_h;
with lua_h;
with System;
with Interfaces.C;

package body lua_macros is

   function lua_pcall (	L : lua_State_Ptr; 
			n : Interfaces.C.int;
			r : Interfaces.C.int;
			f : Interfaces.C.int ) 
   			return Interfaces.C.int is
   begin
      return lua_h.lua_pcallk(L, n, r, f, 0, NULL);
   end lua_pcall;

   procedure lua_pop (L : lua_State_Ptr; n : Interfaces.C.int) is
   begin
      lua_h.lua_settop(L, -(n)-1);
   end lua_pop;

   function lua_tonumber (L : lua_State_Ptr; i : Interfaces.C.int) 
	return lua_h.lua_Number is
   begin
      return lua_h.lua_tonumberx(L, i, NULL);
   end lua_tonumber;

   procedure lua_newtable (L : lua_State_Ptr) is
   begin
      lua_h.lua_createtable(L, 0, 0);
   end lua_newtable;

   function lua_tostring
     (L : lua_State_Ptr;
      i : Interfaces.C.int) return Interfaces.C.Strings.chars_ptr is
   begin
      return lua_h.lua_tolstring(L, (i), NULL);
   end lua_tostring;

   function luaL_loadfile
     (L : lua_State_Ptr;
      f : Interfaces.C.Strings.chars_ptr ) return Interfaces.C.int is
   begin
   	return lauxlib_h.luaL_loadfilex
(L,f,Interfaces.C.Strings.Null_Ptr);
   end luaL_loadfile;

end lua_macros;
--------- end        ---------------------------------------------------




^ permalink raw reply	[relevance 7%]

* Re: Windows LDAP group-user checking in Ada 95
  2012-02-16 20:38  7% Windows LDAP group-user checking in Ada 95 Rego, P.
@ 2012-02-16 20:55  7% ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2012-02-16 20:55 UTC (permalink / raw)


On Thu, 16 Feb 2012 12:38:54 -0800 (PST), Rego, P. wrote:

> For getting the username, I have the function (in Ada 95):
> 
> function GetUsername return String is
>    function GetEnv (Variable : String) return Interfaces.C.Strings.chars_ptr;
>    pragma Import (C, GetEnv, "getenv");
> 
>    Command : constant String := "USERNAME";
>    Answer_Ptr : constant Interfaces.C.Strings.chars_ptr := GetEnv (Command);
>    Answer : constant String := Interfaces.C.Strings.Value (Answer_Ptr);
> begin
>    return Answer;
> end GetUsername;

This is wrong, you cannot pass String to a C program. Then the user name
variable is named USER.

with Interfaces.C.Strings;
use  Interfaces.C;
use  Interfaces.C.Strings;

function GetUsername return String is -- Constraint_Error when undefined
   function GetEnv (Variable : char_array) return chars_ptr;
   pragma Import (C, GetEnv, "getenv");
begin
   return Value (GetEnv (To_C ("USER")));
end GetUsername;

But you don't need that because there already exist the package
Ada.Environment_Variables.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 7%]

* Windows LDAP group-user checking in Ada 95
@ 2012-02-16 20:38  7% Rego, P.
  2012-02-16 20:55  7% ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Rego, P. @ 2012-02-16 20:38 UTC (permalink / raw)


I need a function in Ada 95 (or in C, which a pragma import can be used with no problem - I must not use the -gnat05 switch) to check if a user is present in a LDAP network group.

For getting the username, I have the function (in Ada 95):

function GetUsername return String is
   function GetEnv (Variable : String) return Interfaces.C.Strings.chars_ptr;
   pragma Import (C, GetEnv, "getenv");

   Command : constant String := "USERNAME";
   Answer_Ptr : constant Interfaces.C.Strings.chars_ptr := GetEnv (Command);
   Answer : constant String := Interfaces.C.Strings.Value (Answer_Ptr);
begin
   return Answer;
end GetUsername;

So I need a function Check_LDAP_Authentication (Username : String) return Boolean. How can I do it?

In stackoverflow someone suggested AWS or Savanna, but I think include them in the app could also include an unnecessary complexity to the system, because I don't have to use other network features, just a network group checking. 



^ permalink raw reply	[relevance 7%]

* Re: Interfaces.C.String.Update
  @ 2011-11-28 17:37  5%     ` Ludovic Brenta
  0 siblings, 0 replies; 200+ results
From: Ludovic Brenta @ 2011-11-28 17:37 UTC (permalink / raw)


awdorrin wrote on comp.lang.ada:
> Thanks for the confirmation and the suggestions.
>
> One followup question about Update and the use of Check=>True...
>
> If I'm understanding things properly, given the following scenario:
>
> Character array defined in C, initialized with a memset of nulls.
>
> Passing a char* to Ada, using the Chars_Ptr - Any attempt to use
> Update with Check=>True will raise an Update_Error, because Ada will
> see the string pointed to as zero length, right?

Right.

> So this requires us to disable the check and do some checking on both
> sides to make sure that we don't blow the char buffers.

Right.

> I think, updating these functions to pass in the buffer length (or
> 'cheating' by initializing the char arrays with spaces instead of
> nulls) would be safer, and allow me to take advantage of the
> Check=>True functionality.

In this case I would think it is easier to forget about C's notion
of a string (null-terminated, no length) and use Ada's notion on
both sides (length known at run time).  If you control the C side
of your system, you can easily make it allocate exactly the length
needed and pass the length explicitly.  Then on the Ada side you do
not need Interfaces.C.Strings anymore, just copy one char_array to
another.

--
Ludovic Brenta.
Our gut-feeling is that the stakeholders transition a progressive
trend across the board.



^ permalink raw reply	[relevance 5%]

* Re: Interfaces.C.String.Update
  2011-11-28 15:55  5% Interfaces.C.String.Update awdorrin
  2011-11-28 16:09  0% ` Interfaces.C.String.Update Adam Beneschan
@ 2011-11-28 16:22  0% ` Ludovic Brenta
    1 sibling, 1 reply; 200+ results
From: Ludovic Brenta @ 2011-11-28 16:22 UTC (permalink / raw)


awdorrin wrote on comp.lang.ada:
> What is the suggested method to null terminate an Ada string being
> passed back to C via Interfaces.C.Strings.Update() ?
>
> I've been looking at the code for i-cstrin.adb, and it seems that by
> default that the procedure, when passing in an Ada String, uses To_C
> with Append_Null  set to False.
>
> I was trying to determine if I should manually place the null
> character, or instead call Update like:
>
> Update( cPtr, 0, To_C( AStr, Append_Nul => True), False);
>
> I haven't been able to find any discussions on this, so I'm just not
> sure what the 'best' approach for this would be.

I think you are correct, perhaps a more terse idiom would be:

Update( cPtr, 0, AStr & ASCII.NUL, False);

This is because, if Check is True,

procedure Update (Item   : in chars_ptr;
                  Offset : in size_t;
                  Chars  : in char_array;
                  Check  : Boolean := True);

assumes that Item is null-terminated on input in order to call
Strlen (Item), but does not require Chars to be null-terminated
because
Chars is a char_array with known bounds.  If Item is not null-
terminated
before you call Update, you're in for C-style trouble :)

If Check is False, all bets are off, so you'd better null-terminate
Item manually.

--
Ludovic Brenta.
The synchronized executive talents result in the functional successful
execution.



^ permalink raw reply	[relevance 0%]

* Re: Interfaces.C.String.Update
  2011-11-28 15:55  5% Interfaces.C.String.Update awdorrin
@ 2011-11-28 16:09  0% ` Adam Beneschan
  2011-11-28 16:22  0% ` Interfaces.C.String.Update Ludovic Brenta
  1 sibling, 0 replies; 200+ results
From: Adam Beneschan @ 2011-11-28 16:09 UTC (permalink / raw)


On Nov 28, 7:55 am, awdorrin <awdor...@gmail.com> wrote:
> What is the suggested method to null terminate an Ada string being
> passed back to C via Interfaces.C.Strings.Update() ?
>
> I've been looking at the code for i-cstrin.adb, and it seems that by
> default that the procedure, when passing in an Ada String, uses To_C
> with Append_Null  set to False.

Right, that's actually in the RM.  B.3.1(49-50):

[49] procedure Update (Item   : in chars_ptr;
                       Offset : in size_t;
                       Str    : in String;
                       Check  : in Boolean := True);

[50] Equivalent to Update(Item, Offset, To_C(Str, Append_Nul =>
False), Check).

Since that's the language used in the RM, it seems most appropriate to
me that if you want to do the same kind of Update but *with* a null
character appended, you'd use the same code shown in the RM but with
Append_Nul => True.  It probably doesn't matter except as a matter of
style, but that's what I'd do (unless execution speed is *very*
critical, in which case a function call such as To_C that returns an
unconstrained array could involve too much overhead.  I doubt that's
true in your case).

                  -- Adam



^ permalink raw reply	[relevance 0%]

* Interfaces.C.String.Update
@ 2011-11-28 15:55  5% awdorrin
  2011-11-28 16:09  0% ` Interfaces.C.String.Update Adam Beneschan
  2011-11-28 16:22  0% ` Interfaces.C.String.Update Ludovic Brenta
  0 siblings, 2 replies; 200+ results
From: awdorrin @ 2011-11-28 15:55 UTC (permalink / raw)


What is the suggested method to null terminate an Ada string being
passed back to C via Interfaces.C.Strings.Update() ?

I've been looking at the code for i-cstrin.adb, and it seems that by
default that the procedure, when passing in an Ada String, uses To_C
with Append_Null  set to False.

I was trying to determine if I should manually place the null
character, or instead call Update like:

Update( cPtr, 0, To_C( AStr, Append_Nul => True), False);

I haven't been able to find any discussions on this, so I'm just not
sure what the 'best' approach for this would be.



^ permalink raw reply	[relevance 5%]

* Re: Calling Ada Procedure from C - how to handle a char ptr/array
  2011-11-22 13:20  6%     ` awdorrin
@ 2011-11-22 13:28  0%       ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2011-11-22 13:28 UTC (permalink / raw)


awdorrin <awdorrin@gmail.com> writes:

> Had a chance to review the Interfaces.C.Strings package and I think
> that the Chars_Ptr will work out a lot better for what I need than
> passing around char_array types.
>
> The Interfaces.C.Strings package looks like it can replace the custom
> code that was written back in the early 90s for this project, with
> some very minor adaptations.

That's good. It seems likely that that's exactly why Interfaces.C.* were
written!



^ permalink raw reply	[relevance 0%]

* Re: Calling Ada Procedure from C - how to handle a char ptr/array
  2011-11-21 16:33  4%   ` awdorrin
@ 2011-11-22 13:20  6%     ` awdorrin
  2011-11-22 13:28  0%       ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: awdorrin @ 2011-11-22 13:20 UTC (permalink / raw)


Had a chance to review the Interfaces.C.Strings package and I think
that the Chars_Ptr will work out a lot better for what I need than
passing around char_array types.

The Interfaces.C.Strings package looks like it can replace the custom
code that was written back in the early 90s for this project, with
some very minor adaptations.



^ permalink raw reply	[relevance 6%]

* Re: Calling Ada Procedure from C - how to handle a char ptr/array
  @ 2011-11-21 16:33  4%   ` awdorrin
  2011-11-22 13:20  6%     ` awdorrin
  0 siblings, 1 reply; 200+ results
From: awdorrin @ 2011-11-21 16:33 UTC (permalink / raw)


I've been side-tracked on another task this morning so I haven't had a
chance to investigate this further, but wanted to respond with a
'Thanks' for the suggestions and the related information.

My familiarity with Ada is limited - I understand the basics but when
interfacing with C, I have a tendency to get myself confused - since
it seems that a lot of the 'constraint' information that Ada uses is
packed in different locations depending upon the compiler. The
original programmers of this code made some assumptions that do
appears to be entirely compiler dependent and are not portable moving
to GNAT.

It would seem that modifying my approach to use the
Interfaces.C.strings and char_ptr would make more sense.

Thanks!




^ permalink raw reply	[relevance 4%]

* Re: Calling Ada Procedure from C - how to handle a char ptr/array
  @ 2011-11-18 21:38  5%       ` Adam Beneschan
  0 siblings, 0 replies; 200+ results
From: Adam Beneschan @ 2011-11-18 21:38 UTC (permalink / raw)


On Nov 18, 12:41 pm, awdorrin <awdor...@gmail.com> wrote:
> Tried reworking the code into a function that returns a char_array,
> but got a STORAGE_ERROR with a stack overflow/erroneous memory access.
>
> function Get_Label return Interfaces.C.Char_array is
>   Label : String(1..8);
> begin
>   Label(1..8) := "12345678";
>
>   return Interfaces.C.To_C(Label);
> end;
>
> From the source code for To_C(), it allocates the char array, so I'm
> not sure why this error would be raised...

I just tried a small test case (written entirely in Ada) that declared
this function just the way you wrote it, then called it.  I compiled
using GNAT.  It didn't raise anything.  Also, I don't see anything
wrong with the function.  So I suspect the problem isn't occurring in
this function; it's occurring somewhere else.

Are you calling Get_Label directly from C?  If so, how is it declared
in your C code?

I don't agree with Jeff's suggestion to use a function that returns a
Char_Array.  The reason is that Char_Array is defined as an
unconstrained array, and the language says that implementations don't
have to support applying the C convention to functions that return
unconstrained arrays.  When I try this (writing a source that defines
Get_Label as above, and applying Export(C) to it), GNAT gives a
warning "foreign convention function Get_Label should not return
unconstrained array".  Are you using GNAT?  If so, do you get the same
warning?  If so, that's a good indication that things aren't going to
work.  When an Ada function returns an unconstrained array, it has to
arrange to return the bounds as well as the array data, and how it
does that will vary from one implementation to another.  Our compiler,
for example, treats this kind of function as a procedure with an
implicit OUT parameter that points to a record that will contain the
data pointer and the bounds, which the caller will interpret as the
function result.  I don't know how GNAT handles it.  Regardless, it
will probably not be the way that a C program will expect, so you're
likely to get mismatched parameters or something else that could
easily lead to a bad memory access.

From the warning you described in your original post, and from my
experience, I don't think GNAT handles an *unconstrained* char_array
as an OUT parameter.  But there are a couple ways to get around this.
One is to declare your own constrained subtype:

   subtype constrained_char_array is Interfaces.C.Char_Array
(Interfaces.C.Size_T);

which declares a constrained array whose bounds are the entire range
of Size_T.  Of course, those won't be the actual bounds, but it will
make GNAT think those are the actual bounds so that it doesn't
complain about bounds not being passed in, and it doesn't try to check
indexes against some bogus bound and get a Constraint_Error.

   procedure Get_Text (s : out constrained_char_array) is
   ...
       s := Interfaces.C.To_C (Label);       -- WRONG

This is wrong, because it will try to assign to all of s from indexes
Size_T'First to Size_T'Last.  Remember, that's what it thinks the
bounds are.  (In your original attempt, it had no idea what the bounds
were, so assigning "s :=" couldn't have worked either.)  Since the C
code isn't going to pass any bound information to Get_Text, you have
to help it by telling it what index range you're setting:

       s(Size_T'First .. Size_T'First + Label'Length) :=
Interfaces.C.To_C (Label);

The length of the left-hand slice is Label'Length + 1, but that's what
you want because To_C will stick a NUL character on the end of the
string.  Of course, if the character array in your C code isn't large
enough to handle this result, you will be screwed, but that's par for
the course in C.  It might be better to have the C function pass in
the sizeof() of the array as an extra parameter, which is how it's
done in some of the Unix system calls.  Then the Ada code could check
to make sure that Label'Length + 1 <= [the Size parameter], or raise
Constraint_Error if not.

Another possibility is to use chars_ptr and Update in the
Interfaces.C.Strings package.  I'll let you look those up.

Hope this helps,

                               -- Adam



^ permalink raw reply	[relevance 5%]

* Re: Read Windows login username in Ada 95
  2011-11-09 21:52  0%   ` Jeffrey Carter
@ 2011-11-10  1:21  0%     ` Rego, P.
  0 siblings, 0 replies; 200+ results
From: Rego, P. @ 2011-11-10  1:21 UTC (permalink / raw)


> This no doubt expects a NUL-terminated string. I would use Char_Array for the 
> parameter and To_C to convert an Ada string passed to it.
> 
> >     pragma Import (C, GetEnv, "getenv");
> >
> >     Command : constant String := "USERNAME";
> >     Answer_Ptr : constant Interfaces.C.Strings.chars_ptr := GetEnv (Command);
> 
> You're not giving it a NUL-terminated string.

You're right, I'm gonna check the result.

> Who is responsible for freeing Answer_Ptr?

If I included an Free(Answer_Ptr), would it solve this?

> As Obry suggested, Ada.Environment_Variables is an all-Ada way to do this.

That's the Ada 2005 problem I explained above.

Thank you.



^ permalink raw reply	[relevance 0%]

* Re: Read Windows login username in Ada 95
  2011-11-09 20:47  7% ` Rego, P.
@ 2011-11-09 21:52  0%   ` Jeffrey Carter
  2011-11-10  1:21  0%     ` Rego, P.
  0 siblings, 1 reply; 200+ results
From: Jeffrey Carter @ 2011-11-09 21:52 UTC (permalink / raw)


On 11/09/2011 01:47 PM, Rego, P. wrote:
>
> function GetUsername return String is
>     function GetEnv (Variable : String) return Interfaces.C.Strings.chars_ptr;

This no doubt expects a NUL-terminated string. I would use Char_Array for the 
parameter and To_C to convert an Ada string passed to it.

>     pragma Import (C, GetEnv, "getenv");
>
>     Command : constant String := "USERNAME";
>     Answer_Ptr : constant Interfaces.C.Strings.chars_ptr := GetEnv (Command);

You're not giving it a NUL-terminated string.

>     Answer : constant String := Interfaces.C.Strings.Value (Answer_Ptr);
> begin
>     return Answer;

Who is responsible for freeing Answer_Ptr?

> end GetUsername;

As Obry suggested, Ada.Environment_Variables is an all-Ada way to do this.

-- 
Jeff Carter
"Alms for an ex-leper!"
Monty Python's Life of Brian
75



^ permalink raw reply	[relevance 0%]

* Re: Read Windows login username in Ada 95
  @ 2011-11-09 20:47  7% ` Rego, P.
  2011-11-09 21:52  0%   ` Jeffrey Carter
  0 siblings, 1 reply; 200+ results
From: Rego, P. @ 2011-11-09 20:47 UTC (permalink / raw)


Well, answering myself, we could use

function GetUsername return String is
   function GetEnv (Variable : String) return Interfaces.C.Strings.chars_ptr;
   pragma Import (C, GetEnv, "getenv");

   Command : constant String := "USERNAME";
   Answer_Ptr : constant Interfaces.C.Strings.chars_ptr := GetEnv (Command);
   Answer : constant String := Interfaces.C.Strings.Value (Answer_Ptr);
begin
   return Answer;
end GetUsername;

Not pure Ada, but fits very well.
Thank to all suggestions.



^ permalink raw reply	[relevance 7%]

* ADA and Open GL
@ 2011-08-09 14:31  6% ldries46
  0 siblings, 0 replies; 200+ results
From: ldries46 @ 2011-08-09 14:31 UTC (permalink / raw)


I do have a program where I have to create an OpenGL window in a selected 
number of cases.
The routine in which that happens is:

procedure InitGlutWindow( argc : integer; argv : string; Xpos : integer; 
Ypos : integer; Width : integer; Height : integer;  WindowName : string ) is
   argca : aliased integer := argc;
   winna : aliased string := WindowName;
   pargv : Interfaces.C.Strings.chars_ptr;
   pwin  : GLubytePtr := Interfaces.C.Strings.New_String(WindowName);
begin
   pargv := Interfaces.C.Strings.New_String(argv);
   glutInit( argca'Access, pargv );
   glutInitDisplayMode (GLUT_DOUBLE);
   glLoadIdentity;
   gluLookAt(eyex, eyey, eyez, refx, refy, refz, dirx, diry, dirz);
   glutInitWindowSize( Width, Height );
   glutInitWindowPosition( Xpos, Ypos );
   glutCreateWindow( pwin );                   -- Create the Window PROBLEM
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity;
   glOrtho( -0.5*vOrtho, vOrtho, -0.5*vOrtho, 0.5*vOrtho, -0.5*vOrtho, 
0.5*vOrtho );
   glMatrixMode(GL_MODELVIEW);
end InitGlutWindow;

When compiling I get the error message:

cannot use function "glutCreateWindow" in a procedure call

when I create a function in stead of a procedure I get the same error 
message

What can I do to make this work.

L. Dries 




^ permalink raw reply	[relevance 6%]

* Re: GNAT.Serial_Communications
  2011-04-19 19:57  7%                               ` GNAT.Serial_Communications Alex Mentis
@ 2011-04-20 11:37  0%                                 ` tonyg
  0 siblings, 0 replies; 200+ results
From: tonyg @ 2011-04-20 11:37 UTC (permalink / raw)


On Apr 19, 8:57 pm, "Alex Mentis" <f...@invalid.invalid> wrote:
> Ludovic Brenta wrote:
> > I think you'll have to create a task-specific binding to ioctl(2) to
> > set the flow control options before writing to the port.  
>
>  ...
>
> > If you're not sure what arguments to pass to ioctl, maybe you can try:
>
> > strace stty --file=/dev/ttyUSB0 -crtscts
>
> Does anyone know if the code below would work? I don't have a Linux box
> handy here, so I can't test it myself. I'm just going off of some notes
> on forking Linux child processes I acquired -- I've never actually done
> this, myself....
>
> ** begin code **
>
> with Ada.Text_IO; use Ada.Text_IO;
> with Interfaces.C;
> with Interfaces.C.Strings;
>
> procedure Main is
>
>    procedure Config_Stty is
>
>       package C renames Interfaces.C;
>
>       -- create an array that contains each portion of the command
>       -- to be executed
>       -- array must contain a null pointer in the last element
>       Stty_Cmd : C.Strings.Chars_Ptr_Array :=
>                    (C.Strings.New_String ("stty"),
>                     C.Strings.New_String ("--file=/dev/ttyUSB0"),
>                     C.Strings.New_String ("-crtscts"),
>                     C.Strings.Null_Ptr);
>
>       -- create an Ada-style prototype as an interface to the C execvp
>       -- function and associate the two with an Import pragma
>       procedure Execvp (File : C.Strings.Chars_Ptr;
>                         Args : C.Strings.Chars_Ptr_Array);
>       pragma Import (C, Execvp, "execvp");
>
>       -- create an Ada-style prototype to the C fork function so
>       -- you can call execvp then resume this program's execution
>       function Fork return Long_Integer;
>       pragma Import (C, Fork, "fork");
>
>       -- create an Ada-style prototype to the C waitpid function so
>       -- the parent will wait until the forked process completes
>       procedure Waitpid (Pid : Long_Integer; Stat_Loc, Options :
> Integer);
>       pragma Import (C, Waitpid, "waitpid");
>
>       Pid : Long_Integer;
>
>    begin -- Config_Stty
>
>       Put_Line ("Configuring serial port...");
>
>       -- create child process
>       Pid := Fork;
>
>       if Pid = 0 then -- I'm the child process
>          -- call execvp with the stty command
>          Execvp (Stty_Cmd (Stty_Cmd'First), Stty_Cmd);
>          -- Execvp does not return unless there's an error;
>          -- should probably check for that here and raise exception on
> error
>       elsif Pid > 0 then -- I'm the parent process
>          Waitpid (Pid, 0, 0);
>          Put_Line ("Continuing execution...");
>       else -- if Fork returns -1, then it was unsuccessful
>          Put_Line ("Unable to create new process.");
>       end if;
>
>    end Config_Stty;
>
> begin -- Main
>
>    Config_Stty;
>
>    -- serial port's ready to go; do the rest of your stuff here...
>
> end Main;

I don't think this would work because the port's settings need to be
overwritten after it is opened, as Gnat sercom will open it with
control flow enabled. I suspect it may be best to modify the serial
communications package so that there is a control flow option within
the set port procedure. Or to make a copy of the sercom package, call
it something else, modify that and use it.



^ permalink raw reply	[relevance 0%]

* Re: GNAT.Serial_Communications
  @ 2011-04-19 19:57  7%                               ` Alex Mentis
  2011-04-20 11:37  0%                                 ` GNAT.Serial_Communications tonyg
  0 siblings, 1 reply; 200+ results
From: Alex Mentis @ 2011-04-19 19:57 UTC (permalink / raw)


Ludovic Brenta wrote:

> I think you'll have to create a task-specific binding to ioctl(2) to
> set the flow control options before writing to the port.  

 ...

> If you're not sure what arguments to pass to ioctl, maybe you can try:
> 
> strace stty --file=/dev/ttyUSB0 -crtscts

Does anyone know if the code below would work? I don't have a Linux box
handy here, so I can't test it myself. I'm just going off of some notes
on forking Linux child processes I acquired -- I've never actually done
this, myself....

** begin code **

with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.C;
with Interfaces.C.Strings;

procedure Main is
   
   procedure Config_Stty is
   
      package C renames Interfaces.C;

      -- create an array that contains each portion of the command
      -- to be executed
      -- array must contain a null pointer in the last element
      Stty_Cmd : C.Strings.Chars_Ptr_Array :=
                   (C.Strings.New_String ("stty"),
                    C.Strings.New_String ("--file=/dev/ttyUSB0"),
                    C.Strings.New_String ("-crtscts"),
                    C.Strings.Null_Ptr);

      -- create an Ada-style prototype as an interface to the C execvp
      -- function and associate the two with an Import pragma
      procedure Execvp (File : C.Strings.Chars_Ptr;
                        Args : C.Strings.Chars_Ptr_Array);
      pragma Import (C, Execvp, "execvp");
   
      -- create an Ada-style prototype to the C fork function so
      -- you can call execvp then resume this program's execution
      function Fork return Long_Integer;
      pragma Import (C, Fork, "fork");
   
      -- create an Ada-style prototype to the C waitpid function so
      -- the parent will wait until the forked process completes
      procedure Waitpid (Pid : Long_Integer; Stat_Loc, Options :
Integer);
      pragma Import (C, Waitpid, "waitpid");
   
      Pid : Long_Integer;
   
   begin -- Config_Stty
   
      Put_Line ("Configuring serial port...");
   
      -- create child process
      Pid := Fork;
   
      if Pid = 0 then -- I'm the child process
         -- call execvp with the stty command
         Execvp (Stty_Cmd (Stty_Cmd'First), Stty_Cmd);
         -- Execvp does not return unless there's an error;
         -- should probably check for that here and raise exception on
error
      elsif Pid > 0 then -- I'm the parent process
         Waitpid (Pid, 0, 0);
         Put_Line ("Continuing execution...");
      else -- if Fork returns -1, then it was unsuccessful
         Put_Line ("Unable to create new process.");
      end if;
   
   end Config_Stty;
   
begin -- Main
   
   Config_Stty;
   
   -- serial port's ready to go; do the rest of your stuff here...
   
end Main;



^ permalink raw reply	[relevance 7%]

* Re: problems with interfacing c
  2011-01-20 20:56  0% ` Dmitry A. Kazakov
  2011-01-20 21:31  0%   ` Yannick Duchêne (Hibou57)
@ 2011-01-28  0:39  0%   ` Stoik
  1 sibling, 0 replies; 200+ results
From: Stoik @ 2011-01-28  0:39 UTC (permalink / raw)


On Jan 20, 9:56 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Thu, 20 Jan 2011 12:21:08 -0800 (PST), Stoik wrote:
> > I need your help in finding a proper Ada code to simulate the behaviour of the
> > following lines in C:
> > char *bufor = (char*)malloc(100000);
> > fread(bufor, 1, 100000, stdin);
>
> That depends on what are going to achieve. Translating the above literally:
>
> [ with Ada.Text_IO.Text_Streams;
>   use Ada.Text_IO, Ada.Text_IO.Text_Streams; ]
>
>    Buffer : String (1..100_000);
> begin
>    String'Read (Stream (Standard_Input), Buffer);
>
> [ Which certainly nobody would do, but you didn't provide any information
> about the actual problem. ]
>
> > I need to do it from inside of the Ada code. I tried to import fread, use the package
> > interfaces.c.strings etc, but in the end I always get the same message:
> > raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION
> > Any ideas?
>
> You are using C bindings improperly and you need not C bindings in order to
> read the standard input.
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

Thanks for your suggestions and comments. The point is that I am
sending
a solution to a problem to a site managing programming contests, and
the stdin
is in fact redirected to some text file with data. I do not know how
big the data file
will be, I know only the upper limit. Quick reading of the data is the
key to success,
and the two lines of C work very well for the purpose. I have not
tried your solution,
is it not going to cause constraint_error when it meets the end of the
file?
The other question is - how to use the C bindings properly in such a
case?

Regards,
Staszek Goldstein



^ permalink raw reply	[relevance 0%]

* Re: problems with interfacing c
  2011-01-20 20:56  0% ` Dmitry A. Kazakov
@ 2011-01-20 21:31  0%   ` Yannick Duchêne (Hibou57)
  2011-01-28  0:39  0%   ` Stoik
  1 sibling, 0 replies; 200+ results
From: Yannick Duchêne (Hibou57) @ 2011-01-20 21:31 UTC (permalink / raw)


Le Thu, 20 Jan 2011 21:56:52 +0100, Dmitry A. Kazakov  
<mailbox@dmitry-kazakov.de> a écrit:

> On Thu, 20 Jan 2011 12:21:08 -0800 (PST), Stoik wrote:
>
>> I need your help in finding a proper Ada code to simulate the behaviour  
>> of the
>> following lines in C:
>> char *bufor = (char*)malloc(100000);
>> fread(bufor, 1, 100000, stdin);
>
> That depends on what are going to achieve. Translating the above  
> literally:
>
> [ with Ada.Text_IO.Text_Streams;
>   use Ada.Text_IO, Ada.Text_IO.Text_Streams; ]
>
>
>    Buffer : String (1..100_000);
> begin
>    String'Read (Stream (Standard_Input), Buffer);
>
> [ Which certainly nobody would do, but you didn't provide any information
> about the actual problem. ]

Some body do, for some kind of raw IO. Just that this may be more oftenly  
something like
    Character'Read (Standard_Input), C);
in a loop instead (always wondered if there is a more efficient way, I do  
not know one), because most of time the buffer size may vary in 1..n (I  
suppose it may vary for the OP matter too).

>> I need to do it from inside of the Ada code. I tried to import fread,  
>> use the package
>> interfaces.c.strings etc, but in the end I always get the same message:
>> raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION
>> Any ideas?
>
> You are using C bindings improperly and you need not C bindings in order  
> to
> read the standard input.
I feel the same. Strange to use C interface for an fread (however, for  
file mapping into memory or other specialized access, this would OK).


-- 
Si les chats miaulent et font autant de vocalises bizarres, c’est pas pour  
les chiens.

“I am fluent in ASCII” [Warren 2010]



^ permalink raw reply	[relevance 0%]

* Re: problems with interfacing c
  2011-01-20 20:21  5% problems with interfacing c Stoik
@ 2011-01-20 20:56  0% ` Dmitry A. Kazakov
  2011-01-20 21:31  0%   ` Yannick Duchêne (Hibou57)
  2011-01-28  0:39  0%   ` Stoik
  0 siblings, 2 replies; 200+ results
From: Dmitry A. Kazakov @ 2011-01-20 20:56 UTC (permalink / raw)


On Thu, 20 Jan 2011 12:21:08 -0800 (PST), Stoik wrote:

> I need your help in finding a proper Ada code to simulate the behaviour of the
> following lines in C:
> char *bufor = (char*)malloc(100000);
> fread(bufor, 1, 100000, stdin);

That depends on what are going to achieve. Translating the above literally:

[ with Ada.Text_IO.Text_Streams;
  use Ada.Text_IO, Ada.Text_IO.Text_Streams; ]


   Buffer : String (1..100_000);
begin
   String'Read (Stream (Standard_Input), Buffer);

[ Which certainly nobody would do, but you didn't provide any information
about the actual problem. ]

> I need to do it from inside of the Ada code. I tried to import fread, use the package
> interfaces.c.strings etc, but in the end I always get the same message:
> raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION
> Any ideas?

You are using C bindings improperly and you need not C bindings in order to
read the standard input.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 0%]

* problems with interfacing c
@ 2011-01-20 20:21  5% Stoik
  2011-01-20 20:56  0% ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Stoik @ 2011-01-20 20:21 UTC (permalink / raw)


I need your help in finding a proper Ada code to simulate the
behaviour of the
following lines in C:
char *bufor = (char*)malloc(100000);
fread(bufor, 1, 100000, stdin);
I need to do it from inside of the Ada code. I tried to import fread,
use the package
interfaces.c.strings etc, but in the end I always get the same
message:
raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION
Any ideas?



^ permalink raw reply	[relevance 5%]

* Re: Access Type
  2010-12-27 18:15  5%           ` Simon Wright
@ 2010-12-27 20:03  0%             ` Pascal Obry
  0 siblings, 0 replies; 200+ results
From: Pascal Obry @ 2010-12-27 20:03 UTC (permalink / raw)
  To: Simon Wright

Le 27/12/2010 19:15, Simon Wright a �crit :
> I guess I was thinking of Interfaces.C.Strings.chars_ptr.

No, there is no memory leak. To_C returns a standard array, there is no
dynamic allocation in sight.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|    http://www.obry.net  -  http://v2p.fr.eu.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver keys.gnupg.net --recv-key F949BD3B




^ permalink raw reply	[relevance 0%]

* Re: Access Type
  @ 2010-12-27 18:15  5%           ` Simon Wright
  2010-12-27 20:03  0%             ` Pascal Obry
  0 siblings, 1 reply; 200+ results
From: Simon Wright @ 2010-12-27 18:15 UTC (permalink / raw)


Ludovic Brenta <ludovic@ludovic-brenta.org> writes:

> Simon Wright writes on comp.lang.ada:
>> Ludovic Brenta <ludovic@ludovic-brenta.org> writes:
>>
>>>    C_Function (Interfaces.C.To_C ("Ada string"));
>>
>> Is there a potential memory leak lurking here?
>
> No, the char_array is on the stack and passed as a char* to the C
> function.

I guess I was thinking of Interfaces.C.Strings.chars_ptr.



^ permalink raw reply	[relevance 5%]

* Re: Access Type
  @ 2010-12-27  1:50  7%     ` Ludovic Brenta
    0 siblings, 1 reply; 200+ results
From: Ludovic Brenta @ 2010-12-27  1:50 UTC (permalink / raw)


kug1977 writes on comp.lang.ada:
> Pointers are an obstacle for most newbies and it takes some time to
> understand the principle in the first time. Now I've to learn it the
> Ada-way ...

The Ada way is not to use pointers at all... you can pass a string of
characters to a C function without pointers, like this:

with Interfaces.C;
procedure P is
   procedure C_Function (String : in Interfaces.C.char_array);
   pragma Import (C, C_Function, "foo");
begin
   C_Function (Interfaces.C.To_C ("Ada string"));
end P;

This will correctly append a null character to "Ada string" and pass the
address of the result to the C_Function.

Another idea: if you have a fixed number of service names, maybe you
should encapsulate them into a package of their own and only expose an
enumerated type and a getter function, like so:

with Interfaces.C;
package Services is

   type Service is (Open, ...);

   function Name (S : in Service) return Interfaces.C.char_array;

end Services;

with Interfaces.C.Strings;
package body Services is

   type String_Access is access String;

   All_Services : constant array (Service) of Interfaces.C.Strings.chars_ptr :=
     (Open => Interfaces.C.Strings.New_String ("open"),
      ...
     );

   function Name (S : in Service) return Interfaces.C.char_array is
   begin
      return Interfaces.C.Strings.Value (All_Services (S));
   end Name;

end Services;

HTH

-- 
Ludovic Brenta.



^ permalink raw reply	[relevance 7%]

* Re: The "black magic" of ioctl
  @ 2010-10-22 20:16  6%     ` michael bode
  0 siblings, 0 replies; 200+ results
From: michael bode @ 2010-10-22 20:16 UTC (permalink / raw)


Am 21.10.2010 13:31, schrieb Francesco Piraneo Giuliano:

> But my application still need to be written and has to run under linux
> so to collect some data about linux' framebuffer I have to use ioctl;
> the only solution is to write all low level interfacing (open the
> device, get informations about, map it into memory) in C then write
> the upper level in Ada?


Look here http://www.pegasoft.ca/resources/boblap/book.html for
information on how to program for Linux in Ada. You can call ioctl from
an Ada program, you only have to arrange the parameters. For example
this is part of a thin binding to Vide4Linux2 API:

with Posix.Io;
with Interfaces.C;
with Interfaces.C.Strings;

private package Video_4_Linux_2.Ioctls is

   package C renames Interfaces.C;
   VIDIOC_QUERYCAP : constant := -2140645888;

...

   type C_V4l2_Capability is record
      Driver       : C.Char_Array(0 .. 15);
      Card         : C.Char_Array(0 .. 31);
      Bus_Info     : C.Char_Array(0 .. 31);
      Version      : Unsigned32;
      Capabilities : Bits32;
      Reserved     : U32_Array(0 .. 3);
   end record;

   pragma Convention (C, C_V4l2_Capability);

   function Ioctl (Fd  : POSIX.IO.File_Descriptor;
                   Cmd : C.int;
                   Arg : access C_V4l2_Capability) return C.int;
   pragma Import (C, Ioctl, "ioctl");

And you use this ioctl like this:

   type Capability_array is array(Capability_Index) of boolean;

   type V4l2_Capability is record
      Driver : String(1 .. 16);
      Card : String(1 .. 32);
      Bus_Info : String(1 .. 32);
      Version : Natural;
      Capabilities : Capability_Array;
   end record;

   procedure Get_Capability (Device :     Video_Device;
                             Cap    : out V4l2_Capability)
   is
      C_Cap : aliased C_V4l2_Capability;
   begin
      if 0 = Ioctl (Device.Fd, VIDIOC_QUERYCAP, C_Cap'access) then
         Cap.Driver(1..C.To_Ada (C_Cap.Driver)'Length) :=
		C.To_Ada (C_Cap.Driver);
         Cap.Driver(C.To_Ada (C_Cap.Driver)'Length+1..16) :=
		(others => ' ');
...



^ permalink raw reply	[relevance 6%]

* Example GNAT Ada program for openGl
@ 2010-07-11  4:22  6% anon
  0 siblings, 0 replies; 200+ results
From: anon @ 2010-07-11  4:22 UTC (permalink / raw)


-- This program was converted from a C openGL sample program. June 2009
-- No comment because my "C to A" converter does not create comments 
-- But it should be easy to understand what going on.
--
-- System: One program file and a single support package (2files)
-- Requires: GNAT, adaopengl,  openGL engine

--
-- Spec
--

with openGL ;
with openGL.GLu ;
with openGL.GLut ;

use  openGL ;
use  openGL.GLu ;
use  openGL.GLut ;

package Bitmap_Sub is

  DoubleBuffer : Boolean := False ;

  type RGB_ARRAY is array ( Natural range <>,
                            Natural range <> ) of aliased GLfloat ;

  RGBMap : RGB_ARRAY := ( ( 0.0, 0.0, 0.0 ),
                          ( 1.0, 0.0, 0.0 ),
                          ( 0.0, 1.0, 0.0 ),
                          ( 1.0, 1.0, 0.0 ),
                          ( 0.0, 0.0, 1.0 ),
                          ( 1.0, 0.0, 1.0 ),
                          ( 0.0, 1.0, 1.0 ),
                          ( 1.0, 1.0, 1.0 ),
                          ( 0.5, 0.5, 0.5 )
                        ) ;

  End_Error : exception ;

-- ------------------------------------------------------------------------ --

  procedure Reshape ( width  : GLint ;
                      height : GLint ) ;

  procedure key ( key_value : GLubyte ;
                  x         : Integer ;
                  y         : Integer ) ;

  procedure Draw ;


end Bitmap_Sub ;

--
-- Body
--

with Interfaces.C ;
with Interfaces.C.Strings ;

with openGL ;
with openGL.GLu ;
with openGL.GLut ;

use  Interfaces.C ;
use  Interfaces.C.Strings ;

use  openGL ;
use  openGL.GLu ;
use  openGL.GLut ;

package body Bitmap_Sub is


  type GLubyte_Array is array ( Natural range <> ) of GLubyte ;

  type GLfloat_Array is array ( Natural range <> ) of aliased GLfloat ;



  OPENGL_WIDTH  : constant := 24.0 ;
  OPENGL_HEIGHT : constant := 13.0 ;

  boxA_Ary : GLfloat_Array := (    0.0,    0.0,    0.0 ) ;
  boxB_Ary : GLfloat_Array := ( -100.0,    0.0,    0.0 ) ;
  boxC_Ary : GLfloat_Array := (  100.0,    0.0,    0.0 ) ;
  boxD_Ary : GLfloat_Array := (    0.0,   95.0,    0.0 ) ;
  boxE_Ary : GLfloat_Array := (    0.0, -105.0,    0.0 ) ;

  boxA : GLfloatPtr := boxA_Ary ( 0 )'Access ;
  boxB : GLfloatPtr := boxB_Ary ( 0 )'Access ;
  boxC : GLfloatPtr := boxC_Ary ( 0 )'Access ;
  boxD : GLfloatPtr := boxD_Ary ( 0 )'Access ;
  boxE : GLfloatPtr := boxE_Ary ( 0 )'Access ;


  OpenGL_bits1_Ary : aliased char_array := ( char'val ( 16#00# ),
                                             char'val ( 16#03# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#7f# ),
                                             char'val ( 16#fb# ),
                                             char'val ( 16#ff# ),
                                             char'val ( 16#7f# ),
                                             char'val ( 16#fb# ),
                                             char'val ( 16#ff# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#03# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#3e# ),
                                             char'val ( 16#8f# ),
                                             char'val ( 16#b7# ),
                                             char'val ( 16#63# ),
                                             char'val ( 16#db# ),
                                             char'val ( 16#b0# ),
                                             char'val ( 16#63# ),
                                             char'val ( 16#db# ),
                                             char'val ( 16#b7# ),
                                             char'val ( 16#63# ),
                                             char'val ( 16#db# ),
                                             char'val ( 16#b6# ),
                                             char'val ( 16#63# ),
                                             char'val ( 16#8f# ),
                                             char'val ( 16#f3# ),
                                             char'val ( 16#63# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#63# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#63# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#3e# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#00# )
                                           ) ;

  OpenGL_bits1 : GLubytePtr := 
                             To_Chars_Ptr ( OpenGL_bits1_Ary'Access ) ;

  OpenGL_bits2_Ary : aliased char_array := ( char'val ( 16#00# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#ff# ),
                                             char'val ( 16#ff# ),
                                             char'val ( 16#01# ),
                                             char'val ( 16#ff# ),
                                             char'val ( 16#ff# ),
                                             char'val ( 16#01# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#f9# ),
                                             char'val ( 16#fc# ),
                                             char'val ( 16#01# ),
                                             char'val ( 16#8d# ),
                                             char'val ( 16#0d# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#8d# ),
                                             char'val ( 16#0d# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#8d# ),
                                             char'val ( 16#0d# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#cc# ),
                                             char'val ( 16#0d# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#0c# ),
                                             char'val ( 16#4c# ),
                                             char'val ( 16#0a# ),
                                             char'val ( 16#0c# ),
                                             char'val ( 16#4c# ),
                                             char'val ( 16#0e# ),
                                             char'val ( 16#8c# ),
                                             char'val ( 16#ed# ),
                                             char'val ( 16#0e# ),
                                             char'val ( 16#f8# ),
                                             char'val ( 16#0c# ),
                                             char'val ( 16#00# ),
                                             char'val ( 16#00# )
                                           ) ;

  OpenGL_bits2 : GLubytePtr := 
                             To_Chars_Ptr ( OpenGL_bits2_Ary'Access ) ;


  logo_bits_Ary : aliased char_array := ( char'val ( 16#00# ),
                                          char'val ( 16#66# ),
                                          char'val ( 16#66# ),
                                          char'val ( 16#ff# ),
                                          char'val ( 16#66# ),
                                          char'val ( 16#66# ),
                                          char'val ( 16#00# ),
                                          char'val ( 16#00# ),
                                          char'val ( 16#00# ),
                                          char'val ( 16#ff# ),
                                          char'val ( 16#3c# ),
                                          char'val ( 16#3c# ),
                                          char'val ( 16#00# ),
                                          char'val ( 16#42# ),
                                          char'val ( 16#40# ),
                                          char'val ( 16#ff# ),
                                          char'val ( 16#42# ),
                                          char'val ( 16#40# ),
                                          char'val ( 16#00# ),
                                          char'val ( 16#41# ),
                                          char'val ( 16#40# ),
                                          char'val ( 16#ff# ),
                                          char'val ( 16#21# ),
                                          char'val ( 16#20# ),
                                          char'val ( 16#00# ),
                                          char'val ( 16#2f# ),
                                          char'val ( 16#20# ),
                                          char'val ( 16#ff# ),
                                          char'val ( 16#20# ),
                                          char'val ( 16#20# ),
                                          char'val ( 16#00# ),
                                          char'val ( 16#10# ),
                                          char'val ( 16#90# ),
                                          char'val ( 16#ff# ),
                                          char'val ( 16#10# ),
                                          char'val ( 16#90# ),
                                          char'val ( 16#00# ),
                                          char'val ( 16#0f# ),
                                          char'val ( 16#10# ),
                                          char'val ( 16#ff# ),
                                          char'val ( 16#00# ),
                                          char'val ( 16#00# ),
                                          char'val ( 16#00# ),
                                          char'val ( 16#66# ),
                                          char'val ( 16#66# ),
                                          char'val ( 16#ff# ),
                                          char'val ( 16#66# ),
                                          char'val ( 16#66# ),
                                          char'val ( 16#00# )
                                        ) ;

  logo_bits : GLubytePtr := To_Chars_Ptr ( logo_bits_Ary'Access ) ;


  COLOR_BLACK   : constant := 0 ;
  COLOR_RED     : constant := 1 ;
  COLOR_GREEN   : constant := 2 ;
  COLOR_YELLOW  : constant := 3 ;
  COLOR_BLUE    : constant := 4 ;
  COLOR_MAGENTA : constant := 5 ;
  COLOR_CYAN    : constant := 6 ;
  COLOR_WHITE   : constant := 7 ;

-- ------------------------------------------------------------------------ --

  procedure Reshape ( width  : GLint ;
                      height : GLint ) is

    begin
      glViewport ( 0, 0, width, height ) ;

      glMatrixMode ( GL_PROJECTION ) ;
      glLoadIdentity ;
      gluOrtho2D ( -175.0, 175.0, -175.0, 175.0 ) ;
      glMatrixMode ( GL_MODELVIEW ) ;
    end Reshape ;

  procedure key ( key_value : GLubyte ;
                  x         : Integer ;
                  y         : Integer ) is


    begin
      case key_value is
        when 16#27# =>
          raise End_Error ;
        when others =>
          null ;
      end case ;
  end key ;


  procedure Draw is

      procedure SetColor ( C : Natural ) is
        begin
          if glutGet ( GLUT_WINDOW_RGBA ) = GL_TRUE then
            glColor3fv ( RGBMap ( C, 0 )'Access ) ;
        else
--          glIndexf ( GLfloat ( C ) ) ;
          glIndexi ( C ) ;
        end if ;
      end SetColor ;

      procedure Draw_Bits ( Color : Natural    ;
                            box   : GLfloatPtr ) is 
        begin
          SetColor ( Color ) ;
          glRasterPos3fv ( box ) ;
          glBitmap ( GLsizei ( OPENGL_WIDTH ), 
                     GLsizei ( OPENGL_HEIGHT ),
                     OPENGL_WIDTH, 0.0,
                     OPENGL_WIDTH, 0.0,
                     OpenGL_bits1 ) ;
          glBitmap ( GLsizei ( OPENGL_WIDTH ), 
                     GLsizei ( OPENGL_HEIGHT ),
                     OPENGL_WIDTH, 0.0,
                     OPENGL_WIDTH, 0.0,
                     OpenGL_bits2 ) ;
        end Draw_Bits ;

      mapI  : GLfloat_Array := ( 0.0, 1.0 ) ;
      mapIR : GLfloat_Array := ( 0.0, 0.0 ) ;
      mapIA : GLfloat_Array := ( 1.0, 1.0 ) ;

    begin
      glClear ( GL_COLOR_BUFFER_BIT ) ;

      glPixelMapfv ( GL_PIXEL_MAP_I_TO_R, 2,
                     mapIR ( 0 )'Unchecked_Access ) ;
      glPixelMapfv ( GL_PIXEL_MAP_I_TO_G, 2,
                     mapI ( 0 )'Unchecked_Access ) ;
      glPixelMapfv ( GL_PIXEL_MAP_I_TO_B, 2,
                     mapI ( 0 )'Unchecked_Access ) ;
      glPixelMapfv ( GL_PIXEL_MAP_I_TO_A, 2,
                     mapIA ( 0 )'Unchecked_Access ) ;
      glPixelTransferi ( GL_MAP_COLOR, GL_TRUE);

--      SetColor ( COLOR_White ) ;
      glRasterPos3fv ( boxA ) ;
      glPixelStorei ( GL_UNPACK_ROW_LENGTH, 24 ) ;
      glPixelStorei ( GL_UNPACK_SKIP_PIXELS, 8 ) ;
      glPixelStorei ( GL_UNPACK_SKIP_ROWS,   2 ) ;
      glPixelStorei ( GL_UNPACK_LSB_FIRST,   GL_FALSE ) ;
      glPixelStorei ( GL_UNPACK_ALIGNMENT,   1 ) ;
      glBitmap ( 16, 12, 16.0, 0.0, 16.0, 0.0, logo_bits ) ;

      glPixelStorei ( GL_UNPACK_ROW_LENGTH, 0 ) ;
      glPixelStorei ( GL_UNPACK_SKIP_PIXELS, 0 ) ;
      glPixelStorei ( GL_UNPACK_SKIP_ROWS, 0 ) ;
      glPixelStorei ( GL_UNPACK_LSB_FIRST, GL_TRUE ) ;
      glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 ) ;

      Draw_Bits ( COLOR_WHITE,  boxB ) ; 
      Draw_Bits ( COLOR_YELLOW, boxC ) ; 
      Draw_Bits ( COLOR_CYAN,   boxD ) ; 
      Draw_Bits ( COLOR_RED,    boxE ) ; 

      glFlush ;

      if DoubleBuffer then
        glutSwapBuffers ;
      end if ;
    end Draw ;

end Bitmap_Sub ;

---
--- main body 
---

with Ada.Command_Line ;
with Ada.Text_IO ;
with Interfaces.C ;
with Interfaces.C.Strings ;

with openGL ;
with openGL.GLu ;
with openGL.GLut ;

use  openGL ;
use  openGL.GLu ;
use  openGL.GLut ;

with Bitmap_Sub ;
use  Bitmap_Sub ;

procedure Bitmap is

  windType     : Interfaces.C.unsigned ;

  RGB          : Boolean := True ;

  End_Error : exception ;

-- ------------------------------------------------------------------------ --

  procedure Args is 

      use  Ada.Command_Line ;
      use  Ada.Text_IO;
      use  Interfaces.C ;

    begin
      windType := GLUT_RGB or GLUT_SINGLE ;

      for Index in 1..Argument_Count loop
        if Argument ( Index ) = "-ci" then
          RGB := False ;
          windType := GLUT_INDEX ;
        elsif Argument ( Index ) = "-rgb" then
          RGB := True ;
          windType := GLUT_RGB ;
        elsif Argument ( Index ) = "-sb" then
          DoubleBuffer := False ;
          windType := windType or GLUT_SINGLE ;
        elsif Argument ( Index ) = "-db" then
          DoubleBuffer := True ;
          windType := windType or GLUT_SINGLE ;
        elsif Argument ( Index ) = "-?" then
          Put_Line ( "Usage: bitmap2 [-ci|-rgb] [-sb|-db] [-?]" ) ;
          raise End_Error ;
        else
          Put_Line ( "Illegal command line opion: " & 
                     Argument ( Index ) ) ;
          raise End_Error ;
        end if ;         
    end loop ;
  end Args ;

  procedure InitMap is

    begin
      if not RGB then
        for Index in 0..8 loop 
          glutSetColor ( Index, RGBMap ( Index, 0 ), 
                                RGBMap ( Index, 1 ),
                                RGBMap ( Index, 2 ) ) ;
        end loop ;
      end if ;
    end InitMap ;

  procedure Init is

    begin
      glClearColor ( 0.0, 0.0, 0.0, 0.0 ) ;
      glClearIndex ( 0.0 ) ;
    end Init ;


-- ------------------------------------------------------------------------ --

  argc : aliased Integer;
    pragma Import ( C, argc, "gnat_argc" ) ;

  argv : GLubytePtr ;
    pragma Import ( C, argv, "gnat_argv" ) ;


  use  Ada.Text_IO;
  use  Interfaces.C.Strings ;

begin 
  Args ;

  glutInit ( argc'Access, argv ) ;

  glutInitDisplayMode ( windType ) ;
  glutInitWindowPosition ( 0, 0 ) ; 
  glutInitWindowSize ( 300, 300 ) ;

  if glutCreateWindow ( New_String ( "Bitmap" ) ) = GL_FALSE then
    Put_Line ( "glutCreateWindow Error" ) ;
    raise End_Error ;
  end if ;

  InitMap ;

  Init ;

  glutReshapeFunc ( Reshape'Access ) ;
  glutKeyboardFunc ( Key'Access ) ;
  glutDisplayFunc ( Draw'Access ) ;
  glutMainLoop ;

 exception 
  when End_Error =>
      null ;
  when others =>
      null ;

end Bitmap ;






^ permalink raw reply	[relevance 6%]

* Re: How to access this package written in C?
  @ 2010-04-27  0:20  4%         ` Robert A Duff
  0 siblings, 0 replies; 200+ results
From: Robert A Duff @ 2010-04-27  0:20 UTC (permalink / raw)


Keith Thompson <kst-u@mib.org> writes:

> Robert A Duff <bobduff@shell01.TheWorld.com> writes:
>> resander <kresander@gmail.com> writes:
>>
>>> On Apr 22, 10:12�pm, Keith Thompson <ks...@mib.org> wrote:
>>>> There is no guarantee that an int can hold the value of an address,
>>>> and there are common systems (including Linux systems) where it
>>>> can't. �Worse, you're not likely to get a warning if you convert
>>>> a pointer to int, even if there's a loss of information.
>>
>> Why?  I'd think if int is smaller than whatever*, then
>> a cast to int clearly deserves a warning.
>
> I made an assumption, thereby making an ass out of me and umption.

;-)

> In fact gcc does warn about converting a pointer to a smaller integer
> type:
>
>     warning: cast from pointer to integer of different size
>
> As the wording implies, it produces the same warning for a cast from a
> pointer to a larger integer type.

As well it should.

Thanks for checking gcc.  Of course I have a gcc at hand (which compiles
both Ada and C), but I was too lazy to try it.  Thanks!

> I haven't checked other C compilers.
>
> In many cases, though, C compilers tend to take a cast operator to mean
> "do this conversion and don't bother me, I know what I'm doing".

Ada is somewhat better, here, in that safer conversions
have a different syntax from unsafer conversions.

A cast, in C, might mean something fairly innocuous, or it might mean
"damn the torpedoes, full speed ahead!", and it's hard for a C compiler
to know which is which.

> [...]
>
>>> Thank you all for your concerns about using an int for passing an
>>> address. The interface actually uses a void * (could also be char * as
>>> that is what is needed), but I changed it for the post because I
>>> thought an all-int interface would be easier to handle at the Ada-to-C
>>> boundary. That seems to have backfired!
>>
>> You should look at section B (especially B.3) of the Ada RM.
>> There's a type char_star you can use.
>>
>> There's no void_star.  I'm not sure why -- probably this
>> part of Ada predates void* in C, and nobody bothered
>> to upgrade Ada to match the new C.
>
> As I recall, Ada 83 didn't have any of this; it was introduced in Ada
> 95.

Right.  Ada 83 just had pragma Interface (now called pragma Import),
and it just let implementations provide whatever interface-to-C
or interface-to-whatever they liked.  Ada 95, 2005, and 2012
offer much more.

> void* was introduced in the ANSI C standard in 1989 (reissued with
> cosmetic changes as the ISO C standard in 1990).
>
> But C still requires char* and void* to have the same representation.
>
> But in the Ada RM, I only see char_star in an example:
>
>     subtype Char_Star is Char_Ptrs.Pointer;

Yes, you're right.  My mistake -- there's no char_star in Ada.
You have to instantiate the C.Pointers generic package,
which is a bit of a pain.

On the other hand, Ada has the Interfaces.C.Strings package,
which has convenient things like char_array_access and
chars_ptr.

Note that GNAT tries pretty hard to make Ada types match
C types in representation, so if you're willing to stick
with gcc to compile your Ada and C programs, it works nicely.

> [snip]
>
> The document I'm looking at is "Ada Reference Manual, ISO/IEC
> 8652:2007(E) Ed. 3", "ISO/IEC 8652:1995(E) with Technical Corrigendum 1
> and Amendment 1".  Is that the most current version?

No.  The most current standard is here:

    http://www.ada-auth.org/

after you rummage aroung a bit.  Look for the Ada 2005 version.  The
most current future to-be-standardized version (for Ada 2012) is here:

    http://www.adaic.org/standards/ada1z.html

Note that this one has no official ISO status yet.

> A few comments on Interfaces.C:

Note that you can send comments on the Ada standard to
ada-comment@ada-auth.org.  I know you are an expert on
both C and Ada, so I think your comments about Ada-interfacing-to-C
should be taken very seriously.

> plain_char is a subtype of either unsigned_char or signed_char.  In C,
> plain char is actually a distinct type, though it has the same
> representation as either unsigned char or signed char.  It would be more
> consistent to have either
>     type plain_char is new signed_char;
> or
>     type plain_char is new unsigned_char;
> depending on the implementation.

I think I disagree with that, because "distinct type"
means different things in C versus Ada, because there
are different implicit conversions in the two languages.

In C, you can freely assign amongst these types (I think),
whereas Ada is more strict.

I'm not sure about that, but in any case, we're not going
to make incompatible changes (as subtype --> type surely
would be).

> There's no need for nul, wide_nul, and char32_nul to be
> implementation-defined; they're all zero by definition:
>
>     nul : constant char := char'val(0);
>     ...
>     wide_nul : constant wchar_t := wchar_t'val(0);
>     ...
>     char32_nul : constant char32_t := char32_t'val(0);

Yes, I think that makes sense.  See also AI95-00037.

> C doesn't actually have a type corresponding to char32_t; it has
> wchar_t, but its size is implementation-defined.

So what do you think it should say?

>     Execution of Free(X) is also erroneous if the chars_ptr X was not
>     returned by New_Char_Array or New_String.
>
> It should also be mentioned that calling Free twice on the same
> pointer value is erroneous (you can do this by saving a copy of the
> pointer before the first call to Free).

Yes, I agree.

- Bob



^ permalink raw reply	[relevance 4%]

* Re: This MIDI stuff, would someone be interested in reviewing my code?
  2010-03-08 11:40  5% This MIDI stuff, would someone be interested in reviewing my code? John McCabe
  2010-03-08 17:24  5% ` Jeffrey R. Carter
@ 2010-03-13  8:12  0% ` Christophe Chaumet
  1 sibling, 0 replies; 200+ results
From: Christophe Chaumet @ 2010-03-13  8:12 UTC (permalink / raw)


John McCabe a �crit :
> Hi
>
> It's still early days but, if I'm going to be using Ada to try to
> build this app I want, it would be nice to write it in a style that
> looks appropriate. I'm aware of the Q&S guide but I was hoping that
> someone could take a quick look at the code I've written (it's only 80
> lines or so, and it's down below) and see if there's anything
> obviously stupid I'm doing.
>
> My specific thoughts on this are:
>
> 1) Perhaps I should be using limited withs in some places to get
> access to the primitive operators/functions of the stuff in
> Interfaces.C/.strings and Win32 etc.
>
> 2) The for loops: for devId in Win32.UINT range 0..(NumOutputDevices -
> 1) etc. These are protected by a "if NumOutputDevices < 0" condition
> but before I realised my mistake I found that when NumOutputDevices is
> 0, the loop executes as many times as it can before it crashed. This
> was obviously because NumOutputDevices was 0, so the range
> "0..(NumOutputDevices - 1)" was 0..4929blahblah due to Win32.UINT
> being a modular type. I looked at the option to use something like:
>    for index in Win32.UINT range 1..NumOuputDevices loop
>       declare
>          devId : Win32.UINT := index - 1;
>       begin
>          ...
>       end;
>    end loop;
> but stuck with the original with the conditional round it.
>
> 3) Would it be more appropriate to use something like
> Win32.UINT'Image() instead of getting an instantiation of the
> Modular_IO package?
>
> Anyway - thanks to anyone who can be bothered to look at this. It will
> be much appreciated, and thanks for everyone's help so far.
>
> John
>
>
> ===================
> with Ada.Text_IO;
> with Ada.Unchecked_Deallocation;
>
> with Interfaces.C; use Interfaces.C;
> with Interfaces.C.Strings; use Interfaces.C.Strings;
>
> with Win32; use Win32;
> with Win32.Mmsystem; use Win32.Mmsystem;
>
> procedure MidiDevs is
>     NumInputDevices  : Win32.UINT;
>     NumOutputDevices : Win32.UINT;
>
>     res         : Win32.Mmsystem.MMRESULT;
>     midiInCaps  : Win32.Mmsystem.LPMIDIINCAPS;
>     midiOutCaps : Win32.Mmsystem.LPMIDIOUTCAPS;
>
>     package UINTText_IO is new Ada.Text_IO.Modular_IO(Win32.UINT);
>     package MMText_IO is new
> Ada.Text_IO.Modular_IO(Win32.Mmsystem.MMRESULT);
>
>     procedure Free is new
> Ada.Unchecked_Deallocation(Win32.Mmsystem.MIDIINCAPS,
> Win32.Mmsystem.LPMIDIINCAPS);
>     procedure Free is new
> Ada.Unchecked_Deallocation(Win32.Mmsystem.MIDIOUTCAPS,
> Win32.Mmsystem.LPMIDIOUTCAPS);
>
> begin
>    NumInputDevices := Win32.Mmsystem.midiInGetNumDevs;
>    NumOutputDevices := Win32.Mmsystem.midiOutGetNumDevs;
>    midiInCaps  := new Win32.Mmsystem.MIDIINCAPS;
>    midiOutCaps := new Win32.Mmsystem.MIDIOUTCAPS;
>
>    Ada.Text_IO.Put("There are ");
>    UINTText_IO.Put(NumInputDevices, 0);
>    Ada.Text_IO.Put(" input devices available, and ");
>    UINTText_IO.Put(NumOutputDevices, 0);
>    Ada.Text_IO.Put_Line(" output devices available.");
>
>    if NumInputDevices > 0
>    then
>       Ada.Text_IO.New_Line;
>       Ada.Text_IO.Put("The ");
>       UINTText_IO.Put(NumInputDevices, 0);
>       Ada.Text_IO.Put_Line(" input devices are:");
>       Ada.Text_IO.New_Line;
>
>       for devId in Win32.UINT range 0..(NumInputDevices - 1)
>       loop
>          res := Win32.Mmsystem.midiInGetDevCaps(devId,
>                                                 midiInCaps,
>
> (Win32.Mmsystem.MIDIINCAPS'size * Win32.BYTE'size));
>          UINTText_IO.Put(devId, 0);
>          Ada.Text_IO.Put(") ");
>          if res = Win32.Mmsystem.MMSYSERR_NOERROR
>          then
>             Ada.Text_IO.Put("szPname = ");
>             Ada.Text_IO.Put_Line(To_Ada(To_C(midiInCaps.szPname)));
>          else
>             Ada.Text_IO.Put("Query Failed. Returned ");
>             MMText_IO.Put(res, 0);
>          end if;
>          Ada.Text_IO.New_Line;
>       end loop;
>    end if;
>
>    if NumOutputDevices > 0
>    then
>       Ada.Text_IO.New_Line;
>       Ada.Text_IO.Put("The ");
>       UINTText_IO.Put(NumOutputDevices, 0);
>       Ada.Text_IO.Put_Line(" output devices are:");
>       Ada.Text_IO.New_Line;
>
>       for devId in Win32.UINT range 0..(NumOutputDevices - 1)
>       loop
>          res := Win32.Mmsystem.midiOutGetDevCaps(devId,
>                                                  midiOutCaps,
>
> (Win32.Mmsystem.MIDIOUTCAPS'size * Win32.BYTE'size));
>          UINTText_IO.Put(devId, 0);
>          Ada.Text_IO.Put(") ");
>          if res = Win32.Mmsystem.MMSYSERR_NOERROR
>          then
>             Ada.Text_IO.Put("szPname = ");
>             Ada.Text_IO.Put_Line(To_Ada(To_C(midiOutCaps.szPname)));
>          else
>             Ada.Text_IO.Put("Query Failed. Returned ");
>             MMText_IO.Put(res, 0);
>          end if;
>          Ada.Text_IO.New_Line;
>       end loop;
>    end if;
>
>    Free(midiInCaps);
>    Free(midiOutCaps);
>    
> end MidiDevs;
>
>   
Here is a working code: http://sourceforge.net/projects/canta/ written 
in Ada.



^ permalink raw reply	[relevance 0%]

* Re: This MIDI stuff, would someone be interested in reviewing my code?
  2010-03-08 17:24  5% ` Jeffrey R. Carter
@ 2010-03-09 10:21  0%   ` John McCabe
  0 siblings, 0 replies; 200+ results
From: John McCabe @ 2010-03-09 10:21 UTC (permalink / raw)


On Mon, 08 Mar 2010 10:24:26 -0700, "Jeffrey R. Carter"
<spam.jrcarter.not@spam.acm.org> wrote:

>John McCabe wrote:
>> 
>> 1) Perhaps I should be using limited withs in some places to get
>> access to the primitive operators/functions of the stuff in
>> Interfaces.C/.strings and Win32 etc.
>
>That's not what "limited with" is for.

>I notice that you "use" a lot of pkgs, but then refer to things using full 
>names. You should get rid of those "use" clauses, and add "use type" clauses in 
>your declarative part as needed.

Ah - thanks. I was getting confused there between limited with and use
type. You've clarified that for me.

>> 3) Would it be more appropriate to use something like
>> Win32.UINT'Image() instead of getting an instantiation of the
>> Modular_IO package?

>That's a matter of taste and needed functionality.

>My first comments would be to use common Ada naming conventions: Dev_ID, 
>Num_Input_Devices, and so on.

Ok - I'll see what I can do.

>I also prefer to see "loop" and "then" on the same line as "for" and "if". This 
>looks like a C-family person thinking they're equivalent to '{'.

I was thinking of them being more equivalent to Ada's begin for loops.
I like the idea of having a visual clue, be it a begin, loop, then, {
or whatever on a line on its own to show clearly that the following
code is indented because it's within that construct.

>I would make Numinputdevices and Numoutputdevices constants.

They're not constants though - they're discovered from the
midiInGetNumDevs and midiOutGetnumDevs functions.

>For this small 
>example, I would do the same with Midiincaps and Midioutcaps; there's really no 
>need to free them, since they're around for the entire program, and will be 
>freed when the program exits.

The point of allocating/freeing them was to get round the fact that,
when they were declared in the declarative part of the main function,
I seemed to have to use 'Unchecked_Access when passing them to
midiInGetDevCaps/midiOutGetDevCaps.

>> with Interfaces.C; use Interfaces.C;
>> with Interfaces.C.Strings; use Interfaces.C.Strings;
>
>"with Interfaces.C.Strings;" implies "with Interfaces; with Interfaces.C;", so 
>there's no reason to have both.

Ok - thanks.

>> with Win32; use Win32;
>> with Win32.Mmsystem; use Win32.Mmsystem;

>Ditto.

Ditto too :-)

>>       for devId in Win32.UINT range 0..(NumInputDevices - 1)
>>       loop
>
>These parentheses are unnecessary.

Yes, I agree. I like to make things obvious though :-)

>>          res := Win32.Mmsystem.midiInGetDevCaps(devId,
>>                                                 midiInCaps,
>> 
>> (Win32.Mmsystem.MIDIINCAPS'size * Win32.BYTE'size));
>
>So are the internal ones here.

True.

>You've already been warned about sprinkling OS-dependent stuff throughout your code.

Yip.

Thanks for those comments. Much appreciated.




^ permalink raw reply	[relevance 0%]

* Re: This MIDI stuff, would someone be interested in reviewing my code?
  2010-03-08 11:40  5% This MIDI stuff, would someone be interested in reviewing my code? John McCabe
@ 2010-03-08 17:24  5% ` Jeffrey R. Carter
  2010-03-09 10:21  0%   ` John McCabe
  2010-03-13  8:12  0% ` Christophe Chaumet
  1 sibling, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2010-03-08 17:24 UTC (permalink / raw)


John McCabe wrote:
> 
> 1) Perhaps I should be using limited withs in some places to get
> access to the primitive operators/functions of the stuff in
> Interfaces.C/.strings and Win32 etc.

That's not what "limited with" is for.

I notice that you "use" a lot of pkgs, but then refer to things using full 
names. You should get rid of those "use" clauses, and add "use type" clauses in 
your declarative part as needed.

> 3) Would it be more appropriate to use something like
> Win32.UINT'Image() instead of getting an instantiation of the
> Modular_IO package?

That's a matter of taste and needed functionality.

My first comments would be to use common Ada naming conventions: Dev_ID, 
Num_Input_Devices, and so on.

I also prefer to see "loop" and "then" on the same line as "for" and "if". This 
looks like a C-family person thinking they're equivalent to '{'.

I would make Numinputdevices and Numoutputdevices constants. For this small 
example, I would do the same with Midiincaps and Midioutcaps; there's really no 
need to free them, since they're around for the entire program, and will be 
freed when the program exits.

> with Interfaces.C; use Interfaces.C;
> with Interfaces.C.Strings; use Interfaces.C.Strings;

"with Interfaces.C.Strings;" implies "with Interfaces; with Interfaces.C;", so 
there's no reason to have both.

> with Win32; use Win32;
> with Win32.Mmsystem; use Win32.Mmsystem;

Ditto.

>       for devId in Win32.UINT range 0..(NumInputDevices - 1)
>       loop

These parentheses are unnecessary.

>          res := Win32.Mmsystem.midiInGetDevCaps(devId,
>                                                 midiInCaps,
> 
> (Win32.Mmsystem.MIDIINCAPS'size * Win32.BYTE'size));

So are the internal ones here.

You've already been warned about sprinkling OS-dependent stuff throughout your code.

-- 
Jeff Carter
"C's solution to this [variable-sized array parameters] has real
problems, and people who are complaining about safety definitely
have a point."
Dennis Ritchie
25



^ permalink raw reply	[relevance 5%]

* This MIDI stuff, would someone be interested in reviewing my code?
@ 2010-03-08 11:40  5% John McCabe
  2010-03-08 17:24  5% ` Jeffrey R. Carter
  2010-03-13  8:12  0% ` Christophe Chaumet
  0 siblings, 2 replies; 200+ results
From: John McCabe @ 2010-03-08 11:40 UTC (permalink / raw)


Hi

It's still early days but, if I'm going to be using Ada to try to
build this app I want, it would be nice to write it in a style that
looks appropriate. I'm aware of the Q&S guide but I was hoping that
someone could take a quick look at the code I've written (it's only 80
lines or so, and it's down below) and see if there's anything
obviously stupid I'm doing.

My specific thoughts on this are:

1) Perhaps I should be using limited withs in some places to get
access to the primitive operators/functions of the stuff in
Interfaces.C/.strings and Win32 etc.

2) The for loops: for devId in Win32.UINT range 0..(NumOutputDevices -
1) etc. These are protected by a "if NumOutputDevices < 0" condition
but before I realised my mistake I found that when NumOutputDevices is
0, the loop executes as many times as it can before it crashed. This
was obviously because NumOutputDevices was 0, so the range
"0..(NumOutputDevices - 1)" was 0..4929blahblah due to Win32.UINT
being a modular type. I looked at the option to use something like:
   for index in Win32.UINT range 1..NumOuputDevices loop
      declare
         devId : Win32.UINT := index - 1;
      begin
         ...
      end;
   end loop;
but stuck with the original with the conditional round it.

3) Would it be more appropriate to use something like
Win32.UINT'Image() instead of getting an instantiation of the
Modular_IO package?

Anyway - thanks to anyone who can be bothered to look at this. It will
be much appreciated, and thanks for everyone's help so far.

John


===================
with Ada.Text_IO;
with Ada.Unchecked_Deallocation;

with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;

with Win32; use Win32;
with Win32.Mmsystem; use Win32.Mmsystem;

procedure MidiDevs is
    NumInputDevices  : Win32.UINT;
    NumOutputDevices : Win32.UINT;

    res         : Win32.Mmsystem.MMRESULT;
    midiInCaps  : Win32.Mmsystem.LPMIDIINCAPS;
    midiOutCaps : Win32.Mmsystem.LPMIDIOUTCAPS;

    package UINTText_IO is new Ada.Text_IO.Modular_IO(Win32.UINT);
    package MMText_IO is new
Ada.Text_IO.Modular_IO(Win32.Mmsystem.MMRESULT);

    procedure Free is new
Ada.Unchecked_Deallocation(Win32.Mmsystem.MIDIINCAPS,
Win32.Mmsystem.LPMIDIINCAPS);
    procedure Free is new
Ada.Unchecked_Deallocation(Win32.Mmsystem.MIDIOUTCAPS,
Win32.Mmsystem.LPMIDIOUTCAPS);

begin
   NumInputDevices := Win32.Mmsystem.midiInGetNumDevs;
   NumOutputDevices := Win32.Mmsystem.midiOutGetNumDevs;
   midiInCaps  := new Win32.Mmsystem.MIDIINCAPS;
   midiOutCaps := new Win32.Mmsystem.MIDIOUTCAPS;

   Ada.Text_IO.Put("There are ");
   UINTText_IO.Put(NumInputDevices, 0);
   Ada.Text_IO.Put(" input devices available, and ");
   UINTText_IO.Put(NumOutputDevices, 0);
   Ada.Text_IO.Put_Line(" output devices available.");

   if NumInputDevices > 0
   then
      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put("The ");
      UINTText_IO.Put(NumInputDevices, 0);
      Ada.Text_IO.Put_Line(" input devices are:");
      Ada.Text_IO.New_Line;

      for devId in Win32.UINT range 0..(NumInputDevices - 1)
      loop
         res := Win32.Mmsystem.midiInGetDevCaps(devId,
                                                midiInCaps,

(Win32.Mmsystem.MIDIINCAPS'size * Win32.BYTE'size));
         UINTText_IO.Put(devId, 0);
         Ada.Text_IO.Put(") ");
         if res = Win32.Mmsystem.MMSYSERR_NOERROR
         then
            Ada.Text_IO.Put("szPname = ");
            Ada.Text_IO.Put_Line(To_Ada(To_C(midiInCaps.szPname)));
         else
            Ada.Text_IO.Put("Query Failed. Returned ");
            MMText_IO.Put(res, 0);
         end if;
         Ada.Text_IO.New_Line;
      end loop;
   end if;

   if NumOutputDevices > 0
   then
      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put("The ");
      UINTText_IO.Put(NumOutputDevices, 0);
      Ada.Text_IO.Put_Line(" output devices are:");
      Ada.Text_IO.New_Line;

      for devId in Win32.UINT range 0..(NumOutputDevices - 1)
      loop
         res := Win32.Mmsystem.midiOutGetDevCaps(devId,
                                                 midiOutCaps,

(Win32.Mmsystem.MIDIOUTCAPS'size * Win32.BYTE'size));
         UINTText_IO.Put(devId, 0);
         Ada.Text_IO.Put(") ");
         if res = Win32.Mmsystem.MMSYSERR_NOERROR
         then
            Ada.Text_IO.Put("szPname = ");
            Ada.Text_IO.Put_Line(To_Ada(To_C(midiOutCaps.szPname)));
         else
            Ada.Text_IO.Put("Query Failed. Returned ");
            MMText_IO.Put(res, 0);
         end if;
         Ada.Text_IO.New_Line;
      end loop;
   end if;

   Free(midiInCaps);
   Free(midiOutCaps);
   
end MidiDevs;




^ permalink raw reply	[relevance 5%]

* Re: Trouble writing Ada callback from C
  2009-09-12  5:28  5%   ` Jerry
@ 2009-09-12  8:44  6%     ` Georg Bauhaus
  0 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2009-09-12  8:44 UTC (permalink / raw)


Jerry wrote:

> Unfortunately, the C overlords are giving me a string of length 0--the
> first character is the null character. So Update quits with
> 
> raised INTERFACES.C.STRINGS.UPDATE_ERROR
> 
> as is expected since Update can't write before the null character.
> 
> I'm now (desperately) studying the GNAT code in i-cstrin.adb and
> attempting to make something like its Poke command, and then using it
> in a modified Update which I'm calling Unsafe_Update which is just
> like Update but with these lines deleted:
> 
>       if Check and then Offset + Chars'Length  > Strlen (Item) then
>          raise Update_Error;
>       end if;
> 
> I'm getting several errors which I'm trying to work through.

The following works---if I understand correctly what you
are trying to achieve.

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

extern void adainit(void);
extern void adafinal(void);
extern int geolocation_labeler(char*, size_t);

int main()
{
  char* buffer = calloc(2048, sizeof(char));

  adainit();

  assert(*(buffer + 112) == '\0');

  if (geolocation_labeler(buffer + 112, 40) >= 0)
    fputs(buffer + 112, stdout);
  else
    fputs("no label", stderr);

  adafinal();
  return 0;
}


with Interfaces.C.Strings; use Interfaces.C;

function Geolocation_Labeler
  (label : in Strings.chars_ptr; length : in size_t) return int;
pragma Export(C, Geolocation_Labeler, "geolocation_labeler");


function Geolocation_Labeler
  (label : in Strings.chars_ptr; length : in size_t) return int
is
   Result : constant String := " N"; -- or whatever
begin
   if Result'Length + 1 > Length then
      return -1;
   end if;

   Strings.Update (Item => label,
     Offset => 0,
     Chars => To_C (Result, Append_Nul => True),
     Check => False);
   return Result'Length;
exception
   when others =>
      return -2;
end geolocation_labeler;



^ permalink raw reply	[relevance 6%]

* Re: Trouble writing Ada callback from C
  2009-09-11  8:24  6% ` Ludovic Brenta
@ 2009-09-12  5:28  5%   ` Jerry
  2009-09-12  8:44  6%     ` Georg Bauhaus
  0 siblings, 1 reply; 200+ results
From: Jerry @ 2009-09-12  5:28 UTC (permalink / raw)


On Sep 11, 1:24 am, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote:
>
> I take it you mean "not known at compile time" because it is indeed
> "known at call time".
>
> C doesn't have proper strings; it has pointers to null-terminated
> arrays of characters, which do not carry bounds information. So, the
> specification of your callback is not "return a string in an array"
> but "write N characters starting where label points, where N+1 <
> a_length, followed by a null character (ASCII.NUL)".  Here is a
> possible implementation (not compiled or tested either):
>
> with Interfaces.C.Strings; use Interfaces.C.Strings;
> procedure geolocation_labeler (label : in chars_ptr; length : in
> size_t) is
>    Result : constant String := " N"; -- or whatever
> begin
>    Update (Item => label, Offset => 0, Str => To_C (Result), Check =>
> False);
>    -- See AARM B.3.1(43, 50.a/2)
> exception
>    when others =>
>       -- Important: callbacks must handle all exceptions because the C
> layer
>       -- calling us cannot propagate or handle them.
>       null; -- or report it.
> end geolocation_labeler;
>
> HTH
>
> --
> Ludovic Brenta.

Thanks, Ludovic.

Unfortunately, the C overlords are giving me a string of length 0--the
first character is the null character. So Update quits with

raised INTERFACES.C.STRINGS.UPDATE_ERROR

as is expected since Update can't write before the null character.

I'm now (desperately) studying the GNAT code in i-cstrin.adb and
attempting to make something like its Poke command, and then using it
in a modified Update which I'm calling Unsafe_Update which is just
like Update but with these lines deleted:

      if Check and then Offset + Chars'Length  > Strlen (Item) then
         raise Update_Error;
      end if;

I'm getting several errors which I'm trying to work through.

Jerry



^ permalink raw reply	[relevance 5%]

* Re: Trouble writing Ada callback from C
  @ 2009-09-11  8:24  6% ` Ludovic Brenta
  2009-09-12  5:28  5%   ` Jerry
  0 siblings, 1 reply; 200+ results
From: Ludovic Brenta @ 2009-09-11  8:24 UTC (permalink / raw)


On Sep 11, 9:57 am, Jerry <lancebo...@qwest.net> wrote:
> I have a problem with writing an Ada procedure, used as a callback
> from C, in which one of the arguments is an output char * (in the C
> version). The actual length of the returned "string" isn't known at
> calling time, even though the caller apparently allocates 40
> characters (see below). However, the actual number of characters
> returned by the C version is less than 40.
>
> My problem is how to pass probably a char_array back out which is the
> correct length, but which length is not known at the time the Ada
> callback is called from C.
>
> Here is a highly shortened version of one of many things that I have
> tried. I have not compiled or run this shortened version, but I
> believe that it contains the essence of the longer version:
>
> procedure geolocation_labeler
>    (label    : out char_array;
>     a_length : size_t);
> pragma Convention(C, geolocation_labeler);
>
> -- Highly shortened version.
> procedure geolocation_labeler
>    (label    : out char_array;
>     a_length : size_t)
> is
>     direction_label : Unbounded_String;
> begin
>     Put_Line("a_length = " & a_length'img); -- for testing
>     direction_label := To_Unbounded_String(" N"); -- not always length
> 2
>     label := To_C(To_String(direction_label), False);
> end geolocation_labeler;
>
> Of course, this fails with:
> raised CONSTRAINT_ERROR : blabla.adb:xxx length check failed
>
> Note that the Put_Line always prints 40, passed by the C caller.
>
> Here is a highly shortened version of the C callback. Note that PLINT
> is just an integer.
>
> /* Highly shortened version.*/
> void
> geolocation_labeler(char *label, PLINT length) {
>     const char *direction_label;
>
>     direction_label = " N";
>     snprintf(label, length, "%s", direction_label);
>     printf(label); /* for testing */
>
> }
>
> The printf(label) returns exactly <space>N (in this case) without \n.
> In particular, it is only 2 characters, not 40. (Presumably, length
> has a value of 40 here as well, although I have not tested that
> assumption.)
>
> I have tried things such as changing the type of label in the argument
> list then declaring e.g.
>
> label_as_char_array : aliased char_array := (0 .. whatever => ' ');
> label_as_char_array_ptr : char_array_access;
>
> then building the string in label_as_char_array, then doing
>
> label_as_char_array_ptr := label_as_char_array'Unchecked_Access;
>
> and then returning label_as_char_array_ptr. That also didn't work.
>
> So how do I mimic the char * behavior of C when the length of the
> output array is not known at call time?

I take it you mean "not known at compile time" because it is indeed
"known at call time".

C doesn't have proper strings; it has pointers to null-terminated
arrays of characters, which do not carry bounds information. So, the
specification of your callback is not "return a string in an array"
but "write N characters starting where label points, where N+1 <
a_length, followed by a null character (ASCII.NUL)".  Here is a
possible implementation (not compiled or tested either):

with Interfaces.C.Strings; use Interfaces.C.Strings;
procedure geolocation_labeler (label : in chars_ptr; length : in
size_t) is
   Result : constant String := " N"; -- or whatever
begin
   Update (Item => label, Offset => 0, Str => To_C (Result), Check =>
False);
   -- See AARM B.3.1(43, 50.a/2)
exception
   when others =>
      -- Important: callbacks must handle all exceptions because the C
layer
      -- calling us cannot propagate or handle them.
      null; -- or report it.
end geolocation_labeler;

HTH

--
Ludovic Brenta.



^ permalink raw reply	[relevance 6%]

* Enumeration of network shared under Windows (was: Interpretation of extensions different from Unix/Linux?)
  @ 2009-08-21 10:11  5%                                         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2009-08-21 10:11 UTC (permalink / raw)


On Thu, 20 Aug 2009 19:08:31 -0500, Randy Brukardt wrote:

> I disagree with everything you wrote on this topic. And there will be a way 
> to enumerate roots over my dead body, because it is not reliably 
> implementable on Windows (no matter how you define the roots).

Here is complete Ada program that enumerates Windows shares:

with Ada.Text_IO;           use Ada.Text_IO;
with Interfaces.C.Strings;  use Interfaces.C.Strings;
with Win32;                 use Win32;
with Win32.Windef;          use Win32.Windef;
with Win32.Winnetwk;        use Win32.Winnetwk;
with Win32.Winnt;           use Win32.Winnt;
with Win32.Winerror;        use Win32.Winerror;
with System;                use System;

with System.Address_To_Access_Conversions;

procedure Net_Share is
   Result      : DWORD;
   Count       : aliased DWORD;
   Size        : aliased DWORD;
   Enumeration : aliased HANDLE;
   Buffer      : String (1..10_000);
   use type DWORD;

   function WNetOpenEnumA             -- The standard version is
            (  dwScope       : DWORD; -- unusable for our purpose
               dwType        : DWORD;
               dwUsage       : DWORD;
               lpNetResource : Address;
               lphEnum       : access HANDLE
            )  return DWORD;
   pragma Import (Stdcall, WNETOPENENUMA, "WNetOpenEnumA");

   package Conversions is
      new System.Address_To_Access_Conversions (NETRESOURCEA);

begin
   Result :=
      WNetOpenEnumA
      (  RESOURCE_CONNECTED,
         RESOURCETYPE_DISK,
         0,
         Null_Address,
         Enumeration'Access
      );
   if Result /= NO_ERROR then
      Put_Line ("Error in WNetOpenEnumA" & DWORD'Image (Result));
   end if;
   loop
      Count  := 1;
      Size   := Buffer'Size / 8;
      Result :=
         WNetEnumResource
         (  Enumeration,
            Count'Unchecked_Access,
            Buffer'Address,
            Size'Unchecked_Access
         );
      exit when Result = ERROR_NO_MORE_ITEMS;
      if Result /= NO_ERROR then
         Put_Line ("Error in WNetEnumResource" & DWORD'Image (Result));
      end if;
      declare
         Resource : LPNETRESOURCEA :=
            Conversions.To_Pointer
            (  Buffer'Address
            ) .all'Unchecked_Access;
      begin
         Put_Line
         (  Value (To_Chars_Ptr (Resource.lpLocalName))
         &  " "
         &  Value (To_Chars_Ptr (Resource.lpRemoteName))
         );
      end;
   end loop;
   Result := WNetCloseEnum (Enumeration);
   if Result /= NO_ERROR then
      Put_Line ("Error in WNetCloseEnum" & DWORD'Image (Result));
   end if;
end Net_Share;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 5%]

* Re: Converting pointers to non nul-terminated C "strings" to Ada string
  2009-02-14 10:38  0%   ` xorquewasp
@ 2009-02-14 11:16  0%     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2009-02-14 11:16 UTC (permalink / raw)


On Sat, 14 Feb 2009 02:38:35 -0800 (PST), xorquewasp@googlemail.com wrote:

> Dmitry A. Kazakov wrote:
>>
>> I would suggest to use Interfaces.C.Pointers instead of
>> Interfaces.C.Strings:
> 
> That does mean going outside of the RM, which is a bit unfortunate.
> I'll keep it in mind, however.

What do you mean by that? Interfaces.C.Pointers is a part of the standard
Ada library.

>> Are you sure that get_data is char **, int * rather than void **, size_t *?
>> In the latter case I would consider Storage_Array instead of String on the
>> Ada side.
> 
> Well, the C function parameters are defined as char **, int * but do have
> a meaning closer to void **, size_t *. Storage_Array is probably more
> appropriate, as you state. That still leaves the question of
> converting from an address or access type to an unconstrained array (can't pass an
> unconstrained array or access to an unconstrained array to C code).

One technique is to declare a huge flat array:

   type Never_Instantiate_Me is array (size_t'range) of char;
   pragma Convention (C, Never_Instantiate_Me);

or else simply:

   subtype Never_Instantiate_Me is char_array (size_t'range);

Never_Instantiate_Me will have no dope.

   type Never_Instantiate_Me_Ptr is access all Never_Instantiate_Me;
   pragma Convention (C, Never_Instantiate_Me_Ptr);;

Then you go:

   function Get return String is
      procedure memory_data
                (  data   : out Never_Instantiate_Me_Ptr;
                   size   : out size_t
                );
      pragma Import (C, memory_data, "get_data");
      Data : Never_Instantiate_Me_Ptr;
      Size : size_t;
   begin
      memory_data (Data, Size);
      if Size = 0 then
         return "";
      else
         return
            To_Ada
            (  Data (size_t'First..size_t'First + Size - 1),
               False
            );
      end if;
   end Get;

Note Size = 0 check. When Size is zero, there is no way to construct an
empty char_array since size_t is modular.
 
-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 0%]

* Re: Converting pointers to non nul-terminated C "strings" to Ada string
  2009-02-14  9:26  6% ` Dmitry A. Kazakov
@ 2009-02-14 10:38  0%   ` xorquewasp
  2009-02-14 11:16  0%     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: xorquewasp @ 2009-02-14 10:38 UTC (permalink / raw)




Dmitry A. Kazakov wrote:
>
> I would suggest to use Interfaces.C.Pointers instead of
> Interfaces.C.Strings:
>

That does mean going outside of the RM, which is a bit unfortunate.
I'll keep it in mind, however.

>
> Are you sure that get_data is char **, int * rather than void **, size_t *?
> In the latter case I would consider Storage_Array instead of String on the
> Ada side.

Well, the C function parameters are defined as char **, int * but do
have
a meaning closer to void **, size_t *. Storage_Array is probably more
appropriate, as you state. That still leaves the question of
converting from
an address or access type to an unconstrained array (can't pass an
unconstrained array or access to an unconstrained array to C code).

>
> Yet another issue. It is not so frequent that C API allocated a data buffer
> and returned it to the caller, as your example suggests.

In this case, the library remains in complete control of the memory.

(It's one of the OpenSSL bio.h functions, if anyone's really curious).



^ permalink raw reply	[relevance 0%]

* Re: Converting pointers to non nul-terminated C "strings" to Ada string
  2009-02-14  6:58  6% Converting pointers to non nul-terminated C "strings" to Ada string xorquewasp
  2009-02-14  9:26  6% ` Dmitry A. Kazakov
  2009-02-14  9:28  6% ` sjw
@ 2009-02-14  9:33  0% ` likai3g
  2 siblings, 0 replies; 200+ results
From: likai3g @ 2009-02-14  9:33 UTC (permalink / raw)


On 2月14日, 下午2时58分, xorquew...@googlemail.com wrote:
> Hello.
>
> I have some C code that returns a pointer to a buffer of
> "data" (not a string, just raw data) and also returns the
> size of the buffer:
>
> void
> get_data (char **ptr, int *size);
>
> int size;
> char *ptr;
>
> get_data (&ptr, &size);
>
> The code is part of a library that I don't control, so I can't
> change the interface.
>
> I've defined the Ada equivalent as:
>
>     package CS renames Interfaces.C.Strings;
>     package C renames Interfaces.C;
>
>     procedure memory_data
>       (data   : out CS.chars_ptr;
>        size   : out C.int);
>     pragma Import (C, memory_data, "get_data");
>
> This works correctly, however I'm having trouble converting
> the chars_ptr type to an Ada string given that it's not nul-
> terminated.
>
> Attempts to do the following:
>
> return CS.Value (Item => data, Length => size);
>
> ... results in a String as long as the position of the first nul in
> the
> C string (the position is inevitably less than the length of the
> string).
>
> Is it possible to properly convert unterminated C strings or do I
> need to start messing about with raw System.Address types?
--try this....
   declare
      subtype Huge is String(Positive);
      type PHuge is access all Huge;
      type CString is record
	 Data: PHuge;
	 Size: Natural;
      end record;
      pragma Convention(C_Pass_By_Copy, CString);
      procedure Get_Data(S: out CString);
      pragma Import(C, Get_Data, "get_data");
      S: CString;
   begin
      Get_Data(S);
      Ada.Text_IO.Put_Line(S.Data(1..S.Size));
   end;



^ permalink raw reply	[relevance 0%]

* Re: Converting pointers to non nul-terminated C "strings" to Ada string
  2009-02-14  6:58  6% Converting pointers to non nul-terminated C "strings" to Ada string xorquewasp
  2009-02-14  9:26  6% ` Dmitry A. Kazakov
@ 2009-02-14  9:28  6% ` sjw
  2009-02-14  9:33  0% ` likai3g
  2 siblings, 0 replies; 200+ results
From: sjw @ 2009-02-14  9:28 UTC (permalink / raw)


On Feb 14, 6:58 am, xorquew...@googlemail.com wrote:

> Is it possible to properly convert unterminated C strings or do I
> need to start messing about with raw System.Address types?

I think you may need this from Interfaces.C (after all, what you're
looking at isn't a C string, which is what Interfaces.C.Strings is
for).

   function To_Ada
     (Item     : char_array;
      Trim_Nul : Boolean := True) return String;

You'll need to define your own pointer-to-Interfaces.C.char_array, I
think.



^ permalink raw reply	[relevance 6%]

* Re: Converting pointers to non nul-terminated C "strings" to Ada string
  2009-02-14  6:58  6% Converting pointers to non nul-terminated C "strings" to Ada string xorquewasp
@ 2009-02-14  9:26  6% ` Dmitry A. Kazakov
  2009-02-14 10:38  0%   ` xorquewasp
  2009-02-14  9:28  6% ` sjw
  2009-02-14  9:33  0% ` likai3g
  2 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2009-02-14  9:26 UTC (permalink / raw)


On Fri, 13 Feb 2009 22:58:55 -0800 (PST), xorquewasp@googlemail.com wrote:

> I have some C code that returns a pointer to a buffer of
> "data" (not a string, just raw data) and also returns the
> size of the buffer:
> 
> void
> get_data (char **ptr, int *size);
> 
> int size;
> char *ptr;
> 
> get_data (&ptr, &size);
> 
> The code is part of a library that I don't control, so I can't
> change the interface.
> 
> I've defined the Ada equivalent as:
> 
>     package CS renames Interfaces.C.Strings;
>     package C renames Interfaces.C;
> 
>     procedure memory_data
>       (data   : out CS.chars_ptr;
>        size   : out C.int);
>     pragma Import (C, memory_data, "get_data");
> 
> This works correctly, however I'm having trouble converting
> the chars_ptr type to an Ada string given that it's not nul-
> terminated.
> 
> Attempts to do the following:
> 
> return CS.Value (Item => data, Length => size);
> 
> ... results in a String as long as the position of the first nul in
> the
> C string (the position is inevitably less than the length of the
> string).
> 
> Is it possible to properly convert unterminated C strings or do I
> need to start messing about with raw System.Address types?

I would suggest to use Interfaces.C.Pointers instead of
Interfaces.C.Strings:

with Interfaces.C;           use Interfaces.C;
with Interfaces.C.Pointers;

package Char_Ptrs is
   new Interfaces.C.Pointers (size_t, char, char_array, Nul);
use Char_Ptrs;

function Get return String is
   procedure memory_data
             (  data   : out Pointer;
                size   : out ptrdiff_t  -- Really int as in your example?
             );
   pragma Import (C, memory_data, "get_data");
   Data : Pointer;
   Size : ptrdiff_t;
begin
   memory_data (Data, Size);
   return To_Ada (Value (Data, Size), False);
end Get;

Are you sure that get_data is char **, int * rather than void **, size_t *?
In the latter case I would consider Storage_Array instead of String on the
Ada side.

Yet another issue. It is not so frequent that C API allocated a data buffer
and returned it to the caller, as your example suggests. Usually it is the
caller who passes an array to the C callee specifying its maximal capacity.
In this case the code should be different. In the former case, the question
arise, who is responsible for feeing the buffer. Does Data point to some
statically allocated piece of memory inside C library, or else you have to
free Data after converting it to Ada array?

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 6%]

* Converting pointers to non nul-terminated C "strings" to Ada string
@ 2009-02-14  6:58  6% xorquewasp
  2009-02-14  9:26  6% ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: xorquewasp @ 2009-02-14  6:58 UTC (permalink / raw)


Hello.

I have some C code that returns a pointer to a buffer of
"data" (not a string, just raw data) and also returns the
size of the buffer:

void
get_data (char **ptr, int *size);

int size;
char *ptr;

get_data (&ptr, &size);

The code is part of a library that I don't control, so I can't
change the interface.

I've defined the Ada equivalent as:

    package CS renames Interfaces.C.Strings;
    package C renames Interfaces.C;

    procedure memory_data
      (data   : out CS.chars_ptr;
       size   : out C.int);
    pragma Import (C, memory_data, "get_data");

This works correctly, however I'm having trouble converting
the chars_ptr type to an Ada string given that it's not nul-
terminated.

Attempts to do the following:

return CS.Value (Item => data, Length => size);

... results in a String as long as the position of the first nul in
the
C string (the position is inevitably less than the length of the
string).

Is it possible to properly convert unterminated C strings or do I
need to start messing about with raw System.Address types?



^ permalink raw reply	[relevance 6%]

* Re: Directory Operations
  2008-11-04 12:57  0%   ` AndreiK
@ 2008-11-04 14:44  7%     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2008-11-04 14:44 UTC (permalink / raw)


On Tue, 4 Nov 2008 04:57:17 -0800 (PST), AndreiK wrote:

> On 3 яПНяПНяПНяПН, 19:33, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
> 
>> 2. Should you keep it non-Ada, then
>>
>> 2.a. how is this supposed to work?
>> 2.b. Where is the string allocated?
>> 2.c. Who will dispose it? When?
>> 2.d. What happens when called from multiple threads?
> 
> Yes I have to keep it in non-Ada, more exact I have to use it in the
> "NI LabVIEW"
> 2.a The LabVIEW calls the functions from DLL.
> 2.b,c LabVIEW allocates the string.
> 2.d --- I don't now

In this case it should be something like this. LabVIEW passes a buffer to
Ada (Path, equivalent to char *), and the length of the buffer (Length).
Then

with Ada.Characters.Latin_1;
with Ada.Directories;         use Ada.Directories;
with Interfaces.C;            use Interfaces.C;
with Interfaces.C.Strings;    use Interfaces.C.Strings;

procedure Pwd (Path : chars_ptr; Length : size_t) is
   Result : constant String := Current_Directory &
Ada.Characters.Latin_1.NUL;
begin
   if Result'Length > Length then
     ... -- What do you do when the buffer is too short?
   else
      Update (Path, 0, Result, False);
   end if;
end Pwd;

From C it is called like:

{
   char buffer [1024];

   pwd (buffer, sizeof (buffer));
   ...
}

However, you should really refer to LabVIEW documentation regarding the way
it passes strings around. Once you know it, you can interface Ada. The code
above is merely a wild guess about how the interface might look like.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 7%]

* Re: Directory Operations
  2008-11-03 17:33  0% ` Dmitry A. Kazakov
@ 2008-11-04 12:57  0%   ` AndreiK
  2008-11-04 14:44  7%     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: AndreiK @ 2008-11-04 12:57 UTC (permalink / raw)


On 3 нояб, 19:33, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Mon, 3 Nov 2008 08:27:36 -0800 (PST), andrei.krivos...@gmail.com wrote:
> > I have a problem.
> > I need to write a DLL with a function, which returns the path to a
> > current directory under Windows XP.
> > I have't any problem with DLL itself, but when I try to use some
> > function from the package "GNAT.Directory_Operations" or
> > "Ada.Directories", I get the unexecutable DLL.
> > NOTE! The executable file is working, I talk only about DLL variant!
>
> > Thanks!
>
> > The code listing of my program is
>
> > ========= Spec ============
> > with Interfaces.C.Strings; use Interfaces.C.Strings;
>
> > package FAD is
>
> >    procedure Pwd(Path_ptr: in out Chars_ptr );
>
> 1. Why don't you use Ada convention returning plain String?
>
>    function Pwd return String
>   [   renames Ada.Directories.Current_Directory; -- Work is done ]
>

Thank you for this advice.

> 2. Should you keep it non-Ada, then
>
> 2.a. how is this supposed to work?
> 2.b. Where is the string allocated?
> 2.c. Who will dispose it? When?
> 2.d. What happens when called from multiple threads?
>
>

Yes I have to keep it in non-Ada, more exact I have to use it in the
"NI LabVIEW"
2.a The LabVIEW calls the functions from DLL.
2.b,c LabVIEW allocates the string.
2.d --- I don't now

May be I can use plain String instead of pointers, but it seems, that
the problem is more abstract from the problem of String
representation.
For readability I will describe it in the next message.

> >    pragma Export(C, Pwd, "pwd");
>
> > end FAD;
>
> > ========= Body ============
> > --  with Ada.Directories;
> > with Ada.Strings;
> > with GNAT.Directory_Operations;
>
> > package body FAD is
> >    package DOP renames GNAT.Directory_Operations;
> >    use Ada.Strings;
>
> >    procedure Pwd(Path_ptr: in out Chars_ptr ) is
> > --        use Ada.Directories;
> >       CStr: Chars_ptr;
> >       Path: String (1 .. 1024);
> >    begin
> > --      Path: String := "custom test string";  -- with this code line,
> > the DLL is executable
> >       Path := DOP.Get_Current_Dir;  -- with this code line, the DLL is UNexecutable
>
> This cannot work, since Get_Current_Dir'Length may differ from 1024.
>
> >       CStr := Null_Ptr; -- Value for test purposes only
> >       Path_ptr := CStr;
>
> That will not work either because Path is allocated on the stack and
> destroyed upon return. See questions 2.a-d.
>
> >    end Pwd;
>
> > end FAD;
>
> C programming is substantially more difficult, even if occasionally spelt
> in Ada...
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

Thank you!



^ permalink raw reply	[relevance 0%]

* Re: Directory Operations
  2008-11-03 16:27  6% Directory Operations andrei.krivoshei
@ 2008-11-03 17:33  0% ` Dmitry A. Kazakov
  2008-11-04 12:57  0%   ` AndreiK
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2008-11-03 17:33 UTC (permalink / raw)


On Mon, 3 Nov 2008 08:27:36 -0800 (PST), andrei.krivoshei@gmail.com wrote:

> I have a problem.
> I need to write a DLL with a function, which returns the path to a
> current directory under Windows XP.
> I have't any problem with DLL itself, but when I try to use some
> function from the package "GNAT.Directory_Operations" or
> "Ada.Directories", I get the unexecutable DLL.
> NOTE! The executable file is working, I talk only about DLL variant!
> 
> Thanks!
> 
> The code listing of my program is
> 
> ========= Spec ============
> with Interfaces.C.Strings; use Interfaces.C.Strings;
> 
> package FAD is
> 
>    procedure Pwd(Path_ptr: in out Chars_ptr );

1. Why don't you use Ada convention returning plain String?

   function Pwd return String
  [   renames Ada.Directories.Current_Directory; -- Work is done ]

2. Should you keep it non-Ada, then

2.a. how is this supposed to work?
2.b. Where is the string allocated?
2.c. Who will dispose it? When?
2.d. What happens when called from multiple threads?

>    pragma Export(C, Pwd, "pwd");
> 
> end FAD;
> 
> ========= Body ============
> --  with Ada.Directories;
> with Ada.Strings;
> with GNAT.Directory_Operations;
> 
> package body FAD is
>    package DOP renames GNAT.Directory_Operations;
>    use Ada.Strings;
> 
>    procedure Pwd(Path_ptr: in out Chars_ptr ) is
> --        use Ada.Directories;
>       CStr: Chars_ptr;
>       Path: String (1 .. 1024);
>    begin
> --      Path: String := "custom test string";  -- with this code line,
> the DLL is executable
>       Path := DOP.Get_Current_Dir;  -- with this code line, the DLL is UNexecutable

This cannot work, since Get_Current_Dir'Length may differ from 1024.

>       CStr := Null_Ptr; -- Value for test purposes only
>       Path_ptr := CStr;

That will not work either because Path is allocated on the stack and
destroyed upon return. See questions 2.a-d.

>    end Pwd;
> 
> end FAD;

C programming is substantially more difficult, even if occasionally spelt
in Ada...

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 0%]

* Directory Operations
@ 2008-11-03 16:27  6% andrei.krivoshei
  2008-11-03 17:33  0% ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: andrei.krivoshei @ 2008-11-03 16:27 UTC (permalink / raw)


Hello.
I have a problem.
I need to write a DLL with a function, which returns the path to a
current directory under Windows XP.
I have't any problem with DLL itself, but when I try to use some
function from the package "GNAT.Directory_Operations" or
"Ada.Directories", I get the unexecutable DLL.
NOTE! The executable file is working, I talk only about DLL variant!

Thanks!

The code listing of my program is

========= Spec ============
with Interfaces.C.Strings; use Interfaces.C.Strings;

package FAD is

   procedure Pwd(Path_ptr: in out Chars_ptr );
   pragma Export(C, Pwd, "pwd");

end FAD;

========= Body ============
--  with Ada.Directories;
with Ada.Strings;
with GNAT.Directory_Operations;

package body FAD is
   package DOP renames GNAT.Directory_Operations;
   use Ada.Strings;

   procedure Pwd(Path_ptr: in out Chars_ptr ) is
--        use Ada.Directories;
      CStr: Chars_ptr;
      Path: String (1 .. 1024);
   begin
--      Path: String := "custom test string";  -- with this code line,
the DLL is executable
      Path := DOP.Get_Current_Dir;  -- with this code line, the DLL is
UNexecutable
      CStr := Null_Ptr; -- Value for test purposes only
      Path_ptr := CStr;
   end Pwd;

end FAD;



^ permalink raw reply	[relevance 6%]

* Re: Command Line on windows
  @ 2008-09-12 15:27  5%   ` Adam Beneschan
  0 siblings, 0 replies; 200+ results
From: Adam Beneschan @ 2008-09-12 15:27 UTC (permalink / raw)


On Sep 12, 8:18 am, "Jeffrey R. Carter"
<spam.jrcarter....@spam.acm.org> wrote:
> RasikaSriniva...@gmail.com wrote:
>
> > but it appears the wildcard is always "expanded to the list of file
> > names". for example, i create test_cli.adb with the following :
>
> This appears to be a "feature" of GNAT, apparently to make programs behave the
> same on Windows as on Linux, where wildcards are expanded by the shell.

You can get around this by calling GetCommandLine yourself; this will
get Windows to give you the original command line, unprocessed by
GNAT.  See

http://msdn.microsoft.com/en-us/library/ms683156(VS.85).aspx

But you'll have to deal with the null terminator yourself
(Interfaces.C.Strings should help here) and parse the arguments
yourself.

                               -- Adam






^ permalink raw reply	[relevance 5%]

* Re: C chars_ptr STORAGE_ERROR in Imported function
  2008-08-22 18:48  6% ` anon
@ 2008-08-23 10:11  7%   ` Niklas Holsti
  0 siblings, 0 replies; 200+ results
From: Niklas Holsti @ 2008-08-23 10:11 UTC (permalink / raw)


(Top posting by "anon" changed to bottom style...)

anon wrote:
 > In <g8ltqo$7ir$1@jacob-sparre.dk>, Kim Rostgaard Christensen
 > <krc@greenpc.dk> writes:
 >
 >>Hello there
 >>
 >>I am in progress of binding the pcap c library to ada, it is a
 >>part of a school project. And for that i need a funtion that 
 >>modifies a parameter to a function like so:
 >>
 >>char    *pcap_lookupdev(char *);
 >>
 >>I have figured out this much:
 >>
 >> function pcap_lookupdev(errbuff :
       Interfaces.C.Strings.Chars_Ptr)
 >> return Interfaces.C.Strings.Chars_Ptr;
 >> pragma Import (C, pcap_lookupdev, "pcap_lookupdev");
 >>
 >>This works in the sense that running it as root returns the
 >>device found, but when I run it as normal user I get
 >>raised STORAGE_ERROR : stack overflow (or erroneous memory
 >>access)
 >>
 >>Do I need to declare the buffer and then then pass its c pointer
 >>to the function?

anon wrote:
 > Because Char_Prt in "Interfaces.C.Strings" is a private Ada
 > type that  C function does not understand.

No, that's wrong. RM B.3.1(1) says that

...the private type chars_ptr corresponds to a common use of "char
*" in C programs, and an object of this type can be passed to a
subprogram to which pragma Import(C,...) has been applied, and for
which "char *" is the type of the argument of the C function.

I think Kim's choice of chars_ptr for this parameter is correct.
The error was firstly in the use of an uninitialized parameter of
this type (default initialized to Null_Ptr), and secondly in using
New_Char_Array on an uninitialized char_array, making
New_Char_Array allocate a smaller new buffer than was needed to
hold the error message from pcap_lookupdev(). Thus,
pcap_lookupdev() was called with incorrect values of its parameter,
not with an incorrect type of parameter. Similar errors could have
been made in a C function calling pcap_lookupdev() with a C
parameter of type "char *".

 > You need to use "Interfaces.C.Pointer"  package to build a C
 > Char_Ptr pointer package.

That might work, too, but Interfaces.C.Strings is the right tool
for pcap_lookupdev() since the parameter really is a NUL-terminated
C-style string.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



^ permalink raw reply	[relevance 7%]

* Re: C chars_ptr STORAGE_ERROR in Imported function
  2008-08-22  8:36  6% C chars_ptr STORAGE_ERROR in Imported function Kim Rostgaard Christensen
  @ 2008-08-22 18:48  6% ` anon
  2008-08-23 10:11  7%   ` Niklas Holsti
  1 sibling, 1 reply; 200+ results
From: anon @ 2008-08-22 18:48 UTC (permalink / raw)


Because Char_Prt in "Interfaces.C.Strings" is a private Ada type that 
C function does not understand. You need to use "Interfaces.C.Pointer" 
package to build a C Char_Ptr pointer package.  And use those functions, 
etc.

A possibility that most teachers may frown about, but it does work is to 
switch the Ada pointers to "System.Address" and pass to the C functions.. 
Check out the "Interfaces.C.Extensions.ads" to see how the "void" and 
"void *" are handled, if the teachers dislike the idea.


In <g8ltqo$7ir$1@jacob-sparre.dk>, Kim Rostgaard Christensen <krc@greenpc.dk> writes:
>Hello there
>
>I am in progress of binding the pcap c library to ada, it is a part of a
>school project. And for that i need a funtion that modifies a parameter 
>to a function like so:
>
>char    *pcap_lookupdev(char *);
>
>I have figured out this much:
>
>  function pcap_lookupdev(errbuff : Interfaces.C.Strings.Chars_Ptr) 
>return Interfaces.C.Strings.Chars_Ptr;
>  pragma Import (C, pcap_lookupdev, "pcap_lookupdev");
>
>This works in the sense that running it as root returns the device 
>found, but when I run it as normal user I get
>
>raised STORAGE_ERROR : stack overflow (or erroneous memory access)
>
>Do I need to declare the buffer and then then pass its c pointer to the 
>function?
>
>It is declared like this in a c example:
>char errbuf[PCAP_ERRBUF_SIZE];
>
>Best
>Kim Rostgaard Christensen




^ permalink raw reply	[relevance 6%]

* Re: C chars_ptr STORAGE_ERROR in Imported function
  2008-08-22  9:55  7%   ` Kim Rostgaard Christensen
@ 2008-08-22 11:43  5%     ` Niklas Holsti
  0 siblings, 0 replies; 200+ results
From: Niklas Holsti @ 2008-08-22 11:43 UTC (permalink / raw)


Kim Rostgaard Christensen wrote:
> Niklas Holsti wrote:
> 
>> Kim Rostgaard Christensen wrote:
>>
>>> Hello there
>>>
>>> I am in progress of binding the pcap c library to ada, it is a part of a
>>> school project. And for that i need a funtion that modifies a 
>>> parameter to a function like so:
>>>
>>> char    *pcap_lookupdev(char *);
>>>
  ...
> 
> the following gives me
> *** glibc detected *** double free or corruption (out): 0x0804d830 ***
> 
> raised PROGRAM_ERROR : unhandled signal
> 
>    procedure Lookup_Device is
>       function pcap_lookupdev(ebuff : Interfaces.C.Strings.Chars_Ptr) 
> return Interfaces.C.Strings.Chars_Ptr;
>       pragma Import (C, pcap_lookupdev, "pcap_lookupdev");
> 
>       Device : Interfaces.C.Strings.Chars_Ptr;
>       Errbuf_ptr  : Interfaces.C.Strings.Chars_Ptr;
>       Errbuf : Char_Array(1 .. 256);  -- the defined buffer size
>    begin

The problem is here:

>       Errbuf_Ptr := New_Char_Array(Errbuf);

New_Char_Array allocates a new char_array object, containing only 
the NUL-terminated string that is in Errbuf at this time. Since you 
have left Errbuf uninitialized, this may be a lot less than 256 
characters, so the errors are probably due to buffer overflow 
somewhere in the pcap library where it tries to put an error 
message into the char_array that Errrbuf_Ptr points to, but this 
char_array is too small.

If you want to continue with New_Char_Array, you should initialize 
Errbuf to contain a 256-character string:

    Errbuf : Char_Array (1 .. 256) := (
      others => Interfaces.C.To_C (' '));

or perhaps neater, but more complex, a NUL-terminated 255-character 
string:

    Errbuf : Char_Array (1 .. 256) := (
       1 .. 255 => Interfaces.C.To_C (' '),
       256      => Interfaces.C.nul);

Then New_Char_Array(Errbuf) will create a 256-character char_array 
that has room for the error message. (It works for me.)

If you use New_Char_Array you should also deallocate the new 
char_array by calling Interfaces.C.Strings.Free (Errbuf_Ptr) at a 
suitable point, when you no longer need this char_array.

I think it would be better to use the To_Chars_Ptr function, which 
makes a chars_ptr that points to Errbuf itself, without allocating 
another char_array, so there is no need to Free anything. This also 
needs a change in the declaration of Errbuf:

    Errbuf : aliased Char_Array := (1 .. 256 => Interfaces.C.nul);

The initial values (here nul) are irrelevant, as long as there are 
256 of them.

Then you replace the call of New_Char_Array with To_Chars_Ptr:

    Errbuf_Ptr := To_Chars_Ptr (Errbuf'Unchecked_Access, False);

followed by:

>       Device := pcap_lookupdev(Errbuf_ptr);

Also note that this can result in Device being a null pointer, 
which will cause an error in the following:

>       Ada.Text_IO.Put_Line(Value(Device));

so better check, like this:

    if Device = Null_Ptr then

       Put_Line ("Null device: " & Value (Errbuf_Ptr));

    else

       Put_Line ("Found device: " & Value (Device));

    end if;

HTH

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



^ permalink raw reply	[relevance 5%]

* Re: C chars_ptr STORAGE_ERROR in Imported function
  @ 2008-08-22  9:55  7%   ` Kim Rostgaard Christensen
  2008-08-22 11:43  5%     ` Niklas Holsti
  0 siblings, 1 reply; 200+ results
From: Kim Rostgaard Christensen @ 2008-08-22  9:55 UTC (permalink / raw)


Niklas Holsti wrote:
> Kim Rostgaard Christensen wrote:
>> Hello there
>>
>> I am in progress of binding the pcap c library to ada, it is a part of a
>> school project. And for that i need a funtion that modifies a 
>> parameter to a function like so:
>>
>> char    *pcap_lookupdev(char *);
>>
> ...
>>
>> Do I need to declare the buffer and then then pass its c pointer to 
>> the function?
> 
> That is certainly my interpretation of the "man" text:
> 
>    char *pcap_lookupdev(char *errbuf)
> 
>    pcap_lookupdev() returns a pointer to a network device
>    suitable for use with pcap_open_live() and pcap_lookupnet().
>    If there is an error, NULL is returned and errbuf is filled
>    in with an appropriate error message.
> 
> There is no hint that pcap_lookupdev() itself allocates the errbuf; it 
> just puts something in the caller-provided errbuf. And no doubt places a 
> NUL terminator after the message.
> 
> HTH
> 

the following gives me
*** glibc detected *** double free or corruption (out): 0x0804d830 ***

raised PROGRAM_ERROR : unhandled signal

    procedure Lookup_Device is
       function pcap_lookupdev(ebuff : Interfaces.C.Strings.Chars_Ptr) 
return Interfaces.C.Strings.Chars_Ptr;
       pragma Import (C, pcap_lookupdev, "pcap_lookupdev");

       Device : Interfaces.C.Strings.Chars_Ptr;
       Errbuf_ptr  : Interfaces.C.Strings.Chars_Ptr;
       Errbuf : Char_Array(1 .. 256);  -- the defined buffer size
    begin
       Errbuf_Ptr := New_Char_Array(Errbuf);
       Device := pcap_lookupdev(Errbuf_ptr);

       Ada.Text_IO.Put_Line(Value(Device));
    end Lookup_Device;



^ permalink raw reply	[relevance 7%]

* C chars_ptr STORAGE_ERROR in Imported function
@ 2008-08-22  8:36  6% Kim Rostgaard Christensen
    2008-08-22 18:48  6% ` anon
  0 siblings, 2 replies; 200+ results
From: Kim Rostgaard Christensen @ 2008-08-22  8:36 UTC (permalink / raw)


Hello there

I am in progress of binding the pcap c library to ada, it is a part of a
school project. And for that i need a funtion that modifies a parameter 
to a function like so:

char    *pcap_lookupdev(char *);

I have figured out this much:

  function pcap_lookupdev(errbuff : Interfaces.C.Strings.Chars_Ptr) 
return Interfaces.C.Strings.Chars_Ptr;
  pragma Import (C, pcap_lookupdev, "pcap_lookupdev");

This works in the sense that running it as root returns the device 
found, but when I run it as normal user I get

raised STORAGE_ERROR : stack overflow (or erroneous memory access)

Do I need to declare the buffer and then then pass its c pointer to the 
function?

It is declared like this in a c example:
char errbuf[PCAP_ERRBUF_SIZE];

Best
Kim Rostgaard Christensen



^ permalink raw reply	[relevance 6%]

* Re: Pointer
  2008-05-19  9:38  6% Pointer Sébastien
  2008-05-19  9:53  7% ` Pointer Dmitry A. Kazakov
@ 2008-05-19 16:17  0% ` Matthew Heaney
  1 sibling, 0 replies; 200+ results
From: Matthew Heaney @ 2008-05-19 16:17 UTC (permalink / raw)


On May 19, 5:38 am, Sébastien <seb.mor...@gmail.com> wrote:
>
> I'm getting from a C interfaces a char**data in a System.Address. I have
> the following hypothesis:
> - data is an array of n elements where n is known
> - There is no memory issue (meaning data[i] with i < n is allocated)
> - I do not have to free the memory (memory is managed by the C library)
>
> How can I retrieve all my values in the C arrays using a loop to create
> some Ada String (Interfaces.C.Strings.Value)?

procedure Op (argv_Address : System.Address; N : Natural) is
   type Argv_Type is array (Positive) of chars_ptr;
   pragma Convention (C, Argv_Type);

   Argv : Argv_Type;
   for Argv'Address use argv_Address;

begin
   for I in 1 .. N loop
      Put_Line (Value (Argv (I)));  -- or whatever
   end loop;
end Op;

Is that what you had in mind?



^ permalink raw reply	[relevance 0%]

* Re: Pointer
  2008-05-19 12:09  7%         ` Pointer Dmitry A. Kazakov
@ 2008-05-19 12:47  0%           ` Sébastien
  0 siblings, 0 replies; 200+ results
From: Sébastien @ 2008-05-19 12:47 UTC (permalink / raw)


> with Interfaces.C.Pointers;
> with Interfaces.C.Strings;  use Interfaces.C.Strings;
> with Interfaces.C; use Interfaces.C;
> 
> type Chars_Ptr_Array is array (size_t range <>) of aliased chars_ptr;
> pragma Convention (C, Chars_Ptr_Array);
> package Pointers_To_String is
>    new Interfaces.C.Pointers (size_t, chars_ptr, chars_ptr_array, null);
> use Pointers_To_String;
> ...   
> Data : Pointers_To_String.Pointer := MyCFunctionReturninCharStarStar;
> N: Natural := MYCFunctionTellingMeHowManyStrings;
> ...
> for Index in 1..N loop
>    declare
>       Element : String := Value (Data.all);
>    begin
>       ... -- Use the element
>    end;
>    Increment (Data); -- Move to the next one
> end loop;

Ok I didn't know Interfaces.C.Pointer, it's looks like exaclty what I 
need and it's a replacement for pointer arithmetic operations.



^ permalink raw reply	[relevance 0%]

* Re: Pointer
  2008-05-19 11:31  6%       ` Pointer Sébastien
  2008-05-19 12:09  6%         ` Pointer Ludovic Brenta
@ 2008-05-19 12:09  7%         ` Dmitry A. Kazakov
  2008-05-19 12:47  0%           ` Pointer Sébastien
  1 sibling, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2008-05-19 12:09 UTC (permalink / raw)


On Mon, 19 May 2008 11:31:57 +0000, S�bastien wrote:

>> procedure To_String (Pointer : in System.Address; Length : in Natural)
>> return String is
>>    Result : String (1 .. Length);
>>    for Result'Address use Pointer;
>>    pragma Import (Ada, Result); -- suppress default initialization
>> begin
>>    return Result;
>> end To_String;
>> 
>> But Dmitryi's solution is safer, of course. HTH
> 
> Ok, I was not clear enough. Converting char* to String is not an issue, 
> I'm using Interfaces.C.String with no problem. My problem is to convert 
> all the strings in the char** in string one by one.

Aha, it is const char *[] ...

> Something like this:
> CharPtrPtr: System.Address := MyCFunctionReturninCharStarStar;
> N: Natural := MYCFunctionTellingMeHowManyStrings;
> 
> for i in Natural range 0 .. N loop
>     -- Some ada code to convert CharPtrPtr[i] to String
> end loop;

with Interfaces.C.Pointers;
with Interfaces.C.Strings;  use Interfaces.C.Strings;
with Interfaces.C; use Interfaces.C;

type Chars_Ptr_Array is array (size_t range <>) of aliased chars_ptr;
pragma Convention (C, Chars_Ptr_Array);
package Pointers_To_String is
   new Interfaces.C.Pointers (size_t, chars_ptr, chars_ptr_array, null);
use Pointers_To_String;
...   
Data : Pointers_To_String.Pointer := MyCFunctionReturninCharStarStar;
N: Natural := MYCFunctionTellingMeHowManyStrings;
...
for Index in 1..N loop
   declare
      Element : String := Value (Data.all);
   begin
      ... -- Use the element
   end;
   Increment (Data); -- Move to the next one
end loop;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 7%]

* Re: Pointer
  2008-05-19 11:31  6%       ` Pointer Sébastien
@ 2008-05-19 12:09  6%         ` Ludovic Brenta
  2008-05-19 12:09  7%         ` Pointer Dmitry A. Kazakov
  1 sibling, 0 replies; 200+ results
From: Ludovic Brenta @ 2008-05-19 12:09 UTC (permalink / raw)


Sébastien wrote:
> char* get_nth(char** data, unsigned int n) {
>    return data[i];
> }
>
> Ada binding:
> function get_nth(data: System.Address; n: Int) return Char_Ptr;
> pragma Import(C, get_nth, "get_nth");
>
> Then:
> for i in Natural range 0 .. N loop
>     MyString := Interfaces.C.Strings.Value(get_nth(CharPtrPtr, i));
> end loop;
>
> I know it's working, but I have to code a C function in order to do
> that, is there a way to replace get_nth by an ada code function?
>
> Hope it's a better explanation ;-)

OK, then how about:

type Array_Of_C_Strings is array (Positive range <>) of
Interfaces.C.Strings.chars_ptr;
pragma Convention (C, Array_Of_C_Strings);

type Array_Of_Strings is array (Positive range <>) of access String;

function Get return Array_Of_C_Strings is
   function How_Many_Strings return Natural;
   pragma Import (C, How_Many_Strings,
"MYCFunctionTellingMeHowManyStrings");
   Length : constant Natural := How_Many_Strings;

   function Get_Array return Array_Of_C_Strings;
   pragma Import (C, Get_Array, "MyCFunctionReturninCharStarStar");

   Raw_Result : Array_Of_C_Strings (1 .. Length) := Get_Array;
   Result : Array_Of_Strings (1 .. Length);
begin
   for K in Result'Length loop
      Result (K) := new String'(Interfaces.C.Strings.Value (Raw_Result
(K)));
   end loop;
   return Result;
end Get;

This duplicates the strings and creates an array of access values;
each access value remembers the length of the string it points to.
There is probably another solution that avoids this duplication.

--
Ludovic Brenta.



^ permalink raw reply	[relevance 6%]

* Re: Pointer
  2008-05-19 10:34  0%     ` Pointer Ludovic Brenta
@ 2008-05-19 11:31  6%       ` Sébastien
  2008-05-19 12:09  6%         ` Pointer Ludovic Brenta
  2008-05-19 12:09  7%         ` Pointer Dmitry A. Kazakov
  0 siblings, 2 replies; 200+ results
From: Sébastien @ 2008-05-19 11:31 UTC (permalink / raw)


> procedure To_String (Pointer : in System.Address; Length : in Natural)
> return String is
>    Result : String (1 .. Length);
>    for Result'Address use Pointer;
>    pragma Import (Ada, Result); -- suppress default initialization
> begin
>    return Result;
> end To_String;
> 
> But Dmitryi's solution is safer, of course. HTH

Ok, I was not clear enough. Converting char* to String is not an issue, 
I'm using Interfaces.C.String with no problem. My problem is to convert 
all the strings in the char** in string one by one.

Something like this:
CharPtrPtr: System.Address := MyCFunctionReturninCharStarStar;
N: Natural := MYCFunctionTellingMeHowManyStrings;

for i in Natural range 0 .. N loop
    -- Some ada code to convert CharPtrPtr[i] to String
end loop;

Of course I can do somthing like that:

Compile this using
gcc -O2 -g3 -ansi -pedantic -W -Wall -c mybind.c -o mybind.o:

char* get_nth(char** data, unsigned int n) {
   return data[i];
}

Ada binding:
function get_nth(data: System.Address; n: Int) return Char_Ptr;
pragma Import(C, get_nth, "get_nth");

Then:
for i in Natural range 0 .. N loop
    MyString := Interfaces.C.Strings.Value(get_nth(CharPtrPtr, i));
end loop;

I know it's working, but I have to code a C function in order to do 
that, is there a way to replace get_nth by an ada code function?

Hope it's a better explanation ;-)



^ permalink raw reply	[relevance 6%]

* Re: Pointer
  2008-05-19 10:13  0%   ` Pointer Sébastien
  2008-05-19 10:32  0%     ` Pointer Dmitry A. Kazakov
@ 2008-05-19 10:34  0%     ` Ludovic Brenta
  2008-05-19 11:31  6%       ` Pointer Sébastien
  1 sibling, 1 reply; 200+ results
From: Ludovic Brenta @ 2008-05-19 10:34 UTC (permalink / raw)


Sébastien wrote:
> > Suggesting, n is returned from the C program:
> >
> > with Interfaces.C;  use Interfaces.C;
> > with Interfaces.C.Strings;  use Interfaces.C.Strings;
> >
> > function Get_It return String is
> >    procedure Internal (N : out size_t; Data : out chars_ptr);
> >    pragma Import (C, Internal, "<C-name>");
> >    Data : chars_ptr;
> >    N : size_t;
> > begin
> >    Internal (Data);
> >    return Value (N, Data);
> > end Get_It;
>
> Yes it's exaclty what I did ... and it's exaclty what I would like to
> avoid :-) Actually, I was looking for a pure Ada solution.
> I think there is a way using an unchecked type conversion, but how to be
> sure of the size of the System.Address?

procedure To_String (Pointer : in System.Address; Length : in Natural)
return String is
   Result : String (1 .. Length);
   for Result'Address use Pointer;
   pragma Import (Ada, Result); -- suppress default initialization
begin
   return Result;
end To_String;

But Dmitryi's solution is safer, of course. HTH

--
Ludovic Brenta.



^ permalink raw reply	[relevance 0%]

* Re: Pointer
  2008-05-19 10:13  0%   ` Pointer Sébastien
@ 2008-05-19 10:32  0%     ` Dmitry A. Kazakov
  2008-05-19 10:34  0%     ` Pointer Ludovic Brenta
  1 sibling, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2008-05-19 10:32 UTC (permalink / raw)


On Mon, 19 May 2008 10:13:48 +0000, S�bastien wrote:

>> Suggesting, n is returned from the C program:
>> 
>> with Interfaces.C;  use Interfaces.C;
>> with Interfaces.C.Strings;  use Interfaces.C.Strings;
>> 
>> function Get_It return String is
>>    procedure Internal (N : out size_t; Data : out chars_ptr);
>>    pragma Import (C, Internal, "<C-name>");
>>    Data : chars_ptr;
>>    N : size_t;
>> begin
>>    Internal (Data);
>>    return Value (N, Data);
>> end Get_It;
> 
> Yes it's exaclty what I did ... and it's exaclty what I would like to 
> avoid :-) Actually, I was looking for a pure Ada solution.

In what sense pure? Do you want to re-implement Interfaces.C.String?

> I think there is a way using an unchecked type conversion, but how to be 
> sure of the size of the System.Address?

(And how to sure about the size of Character vs. char?)

You could convert System.Address to a pointer of an Ada object using an
instance of System.Address_To_Access_Conversions.

(It seems that I don't fully understand your problem)

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 0%]

* Re: Pointer
  2008-05-19  9:53  7% ` Pointer Dmitry A. Kazakov
  2008-05-19  9:54  0%   ` Pointer Dmitry A. Kazakov
@ 2008-05-19 10:13  0%   ` Sébastien
  2008-05-19 10:32  0%     ` Pointer Dmitry A. Kazakov
  2008-05-19 10:34  0%     ` Pointer Ludovic Brenta
  1 sibling, 2 replies; 200+ results
From: Sébastien @ 2008-05-19 10:13 UTC (permalink / raw)


> Suggesting, n is returned from the C program:
> 
> with Interfaces.C;  use Interfaces.C;
> with Interfaces.C.Strings;  use Interfaces.C.Strings;
> 
> function Get_It return String is
>    procedure Internal (N : out size_t; Data : out chars_ptr);
>    pragma Import (C, Internal, "<C-name>");
>    Data : chars_ptr;
>    N : size_t;
> begin
>    Internal (Data);
>    return Value (N, Data);
> end Get_It;

Yes it's exaclty what I did ... and it's exaclty what I would like to 
avoid :-) Actually, I was looking for a pure Ada solution.
I think there is a way using an unchecked type conversion, but how to be 
sure of the size of the System.Address?




^ permalink raw reply	[relevance 0%]

* Re: Pointer
  2008-05-19  9:53  7% ` Pointer Dmitry A. Kazakov
@ 2008-05-19  9:54  0%   ` Dmitry A. Kazakov
  2008-05-19 10:13  0%   ` Pointer Sébastien
  1 sibling, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2008-05-19  9:54 UTC (permalink / raw)


On Mon, 19 May 2008 11:53:11 +0200, Dmitry A. Kazakov wrote:

> On Mon, 19 May 2008 09:38:08 +0000, S�bastien wrote:
> 
>> I'm getting from a C interfaces a char**data in a System.Address. I have 
>> the following hypothesis:
>> - data is an array of n elements where n is known
>> - There is no memory issue (meaning data[i] with i < n is allocated)
>> - I do not have to free the memory (memory is managed by the C library)
>> 
>> How can I retrieve all my values in the C arrays using a loop to create 
>> some Ada String (Interfaces.C.Strings.Value)?
> 
> Suggesting, n is returned from the C program:
> 
> with Interfaces.C;  use Interfaces.C;
> with Interfaces.C.Strings;  use Interfaces.C.Strings;
> 
> function Get_It return String is
>    procedure Internal (N : out size_t; Data : out chars_ptr);
>    pragma Import (C, Internal, "<C-name>");
>    Data : chars_ptr;
>    N : size_t;
> begin
>    Internal (Data);

Internal (N, Data);  -- Of course

>    return Value (N, Data);
> end Get_It;


-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 0%]

* Re: Pointer
  2008-05-19  9:38  6% Pointer Sébastien
@ 2008-05-19  9:53  7% ` Dmitry A. Kazakov
  2008-05-19  9:54  0%   ` Pointer Dmitry A. Kazakov
  2008-05-19 10:13  0%   ` Pointer Sébastien
  2008-05-19 16:17  0% ` Pointer Matthew Heaney
  1 sibling, 2 replies; 200+ results
From: Dmitry A. Kazakov @ 2008-05-19  9:53 UTC (permalink / raw)


On Mon, 19 May 2008 09:38:08 +0000, S�bastien wrote:

> I'm getting from a C interfaces a char**data in a System.Address. I have 
> the following hypothesis:
> - data is an array of n elements where n is known
> - There is no memory issue (meaning data[i] with i < n is allocated)
> - I do not have to free the memory (memory is managed by the C library)
> 
> How can I retrieve all my values in the C arrays using a loop to create 
> some Ada String (Interfaces.C.Strings.Value)?

Suggesting, n is returned from the C program:

with Interfaces.C;  use Interfaces.C;
with Interfaces.C.Strings;  use Interfaces.C.Strings;

function Get_It return String is
   procedure Internal (N : out size_t; Data : out chars_ptr);
   pragma Import (C, Internal, "<C-name>");
   Data : chars_ptr;
   N : size_t;
begin
   Internal (Data);
   return Value (N, Data);
end Get_It;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 7%]

* Pointer
@ 2008-05-19  9:38  6% Sébastien
  2008-05-19  9:53  7% ` Pointer Dmitry A. Kazakov
  2008-05-19 16:17  0% ` Pointer Matthew Heaney
  0 siblings, 2 replies; 200+ results
From: Sébastien @ 2008-05-19  9:38 UTC (permalink / raw)


Hi,

I'm getting from a C interfaces a char**data in a System.Address. I have 
the following hypothesis:
- data is an array of n elements where n is known
- There is no memory issue (meaning data[i] with i < n is allocated)
- I do not have to free the memory (memory is managed by the C library)

How can I retrieve all my values in the C arrays using a loop to create 
some Ada String (Interfaces.C.Strings.Value)?

thanks by advance,
Sebastien



^ permalink raw reply	[relevance 6%]

* Re: Questions on using prgma Import (C, foo)
  2008-02-26 13:50  4%     ` Stephen Leake
@ 2008-02-26 19:59  0%       ` pfpearson.net
  0 siblings, 0 replies; 200+ results
From: pfpearson.net @ 2008-02-26 19:59 UTC (permalink / raw)


On Feb 26, 7:50 am, Stephen Leake <stephen_le...@stephe-leake.org>
wrote:
> You should also consider providing a slightly thicker wrapper that
> does the conversion from Interfaces.C.Strings.chars_ptr to
> Standard.String; that will make this easier to use with plain Ada
> programs.

I plan on doing that, once I have the thin wrapper done.  A reason for
the thin wrapper is to retain speed - one of the benefits of lua.

> Lua has a website:http://www.lua.org/

Gee, I wish I'd said that :-)

> I'm not clear on how it manages dynamically allocated memory; that
> would be a concern for some embedded systems.

That's a good question, to which I may try to find an answer.  I don't
develop for embedded systems (I hope I didn't misuse the phrase
"embedded language" - I meant a language "embedded" within my
program), so I hadn't really thought about it much.

> I'm currently using OpenToken to build my own language for controlling
> my simulator. That language has no control structures or subroutines.
> I might consider switching to Lua to gain those things.

In general, I prefer to reuse languages -  *everyone* writes their
own, including where I work.  It's pretty poor (effective, but limited
and I suspect that it's slower than lua), which is why I want to
propose the use of lua.



^ permalink raw reply	[relevance 0%]

* Re: Questions on using prgma Import (C, foo)
  2008-02-25 19:48  0%   ` pfpearson.net
  2008-02-26 12:15  0%     ` Jeffrey Creem
@ 2008-02-26 13:50  4%     ` Stephen Leake
  2008-02-26 19:59  0%       ` pfpearson.net
  1 sibling, 1 reply; 200+ results
From: Stephen Leake @ 2008-02-26 13:50 UTC (permalink / raw)


pfpearson.net@gmail.com writes:

> On Feb 25, 1:28 pm, Pascal Obry <pas...@obry.net> wrote:
>> pfpearson....@gmail.com a �crit :
>>
>> > However, it only took me a minute to realize that this won't work.
>> > I see two options:
>> > 1. function lua_tolstring (...) return System.Adddress;
>> > 2. use the types declared in Interfaces.C.Strings.
>>
>> 2 is better I think:
>>
>>     function lua_tolstring
>>      (L     : lua_State_ptr;
>>       index : inteter;
>>       len   : size_t_ptr) return Interfaces.C.Strings.chars_ptr;
>>
>> Pascal.
>
> That's what I suspected.  Thanks.

You should also consider providing a slightly thicker wrapper that
does the conversion from Interfaces.C.Strings.chars_ptr to
Standard.String; that will make this easier to use with plain Ada
programs.

> Once I've gotten this done, is anyone interested in using this?  Lua
> really is a neat embedded langauge.  I hope to use it at work to
> handle reading in init data, and possibly to script some of the
> program's behavior.

Lua is used by monotone (http://monotone.ca), a distributed
configuration management system, that I'm starting to use. So I'm also
starting to use Lua.

It is a nice languaged, well designed for embedding in larger
projects.

Lua has a website: http://www.lua.org/

I'm not clear on how it manages dynamically allocated memory; that
would be a concern for some embedded systems.

I'm currently using OpenToken to build my own language for controlling
my simulator. That language has no control structures or subroutines.
I might consider switching to Lua to gain those things.

-- 
-- Stephe



^ permalink raw reply	[relevance 4%]

* Re: Questions on using prgma Import (C, foo)
  2008-02-25 19:48  0%   ` pfpearson.net
@ 2008-02-26 12:15  0%     ` Jeffrey Creem
  2008-02-26 13:50  4%     ` Stephen Leake
  1 sibling, 0 replies; 200+ results
From: Jeffrey Creem @ 2008-02-26 12:15 UTC (permalink / raw)


pfpearson.net@gmail.com wrote:
> On Feb 25, 1:28 pm, Pascal Obry <pas...@obry.net> wrote:
>> pfpearson....@gmail.com a �crit :
>>
>>> However, it only took me a minute to realize that this won't work.
>>> I see two options:
>>> 1. function lua_tolstring (...) return System.Adddress;
>>> 2. use the types declared in Interfaces.C.Strings.
>> 2 is better I think:
>>
>>     function lua_tolstring
>>      (L     : lua_State_ptr;
>>       index : inteter;
>>       len   : size_t_ptr) return Interfaces.C.Strings.chars_ptr;
>>
>> Pascal.
> 
> That's what I suspected.  Thanks.
> 
> Once I've gotten this done, is anyone interested in using this?  Lua
> really is a neat embedded langauge.  I hope to use it at work to
> handle reading in init data, and possibly to script some of the
> program's behavior.

It certainly is the sort of thing that can be generally useful even if 
no one has a specific need for it now. I'd suggest managing it on one of 
the big open source project websites so other can see it and use it 
should you ever abandon the project years from now.

My projects are all on sourceforge. There are those that (probably 
justifiably) would rather host on a other sites (like gna.org) which is 
also fine. It is nice however to pick someplace that will outlive  you 
and has an abandon project takeover capability.

Also consider your goals for licensing when you release the project but 
do pick a license.



^ permalink raw reply	[relevance 0%]

* Re: Questions on using prgma Import (C, foo)
  2008-02-25 19:28  5% ` Pascal Obry
@ 2008-02-25 19:48  0%   ` pfpearson.net
  2008-02-26 12:15  0%     ` Jeffrey Creem
  2008-02-26 13:50  4%     ` Stephen Leake
  0 siblings, 2 replies; 200+ results
From: pfpearson.net @ 2008-02-25 19:48 UTC (permalink / raw)


On Feb 25, 1:28 pm, Pascal Obry <pas...@obry.net> wrote:
> pfpearson....@gmail.com a écrit :
>
> > However, it only took me a minute to realize that this won't work.
> > I see two options:
> > 1. function lua_tolstring (...) return System.Adddress;
> > 2. use the types declared in Interfaces.C.Strings.
>
> 2 is better I think:
>
>     function lua_tolstring
>      (L     : lua_State_ptr;
>       index : inteter;
>       len   : size_t_ptr) return Interfaces.C.Strings.chars_ptr;
>
> Pascal.

That's what I suspected.  Thanks.

Once I've gotten this done, is anyone interested in using this?  Lua
really is a neat embedded langauge.  I hope to use it at work to
handle reading in init data, and possibly to script some of the
program's behavior.



^ permalink raw reply	[relevance 0%]

* Re: Questions on using prgma Import (C, foo)
  2008-02-25 19:22  5% Questions on using prgma Import (C, foo) pfpearson.net
@ 2008-02-25 19:28  5% ` Pascal Obry
  2008-02-25 19:48  0%   ` pfpearson.net
  0 siblings, 1 reply; 200+ results
From: Pascal Obry @ 2008-02-25 19:28 UTC (permalink / raw)
  To: pfpearson.net

pfpearson.net@gmail.com a �crit :
> However, it only took me a minute to realize that this won't work.
> I see two options:
> 1. function lua_tolstring (...) return System.Adddress;
> 2. use the types declared in Interfaces.C.Strings.

2 is better I think:

    function lua_tolstring
     (L     : lua_State_ptr;
      index : inteter;
      len   : size_t_ptr) return Interfaces.C.Strings.chars_ptr;

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



^ permalink raw reply	[relevance 5%]

* Questions on using prgma Import (C, foo)
@ 2008-02-25 19:22  5% pfpearson.net
  2008-02-25 19:28  5% ` Pascal Obry
  0 siblings, 1 reply; 200+ results
From: pfpearson.net @ 2008-02-25 19:22 UTC (permalink / raw)


I'm writing some Ada bindings for lua ( http://www.lua.org/ ), a very
small and fast interpreter with a clean C API.  While I've been
developing Ada for years, this is my first real foray into importing C
libraries (I've done the occasional import of memcpy() or such).

My question is how to handle C functions that return "char *".  The
Lua function is question is:
     const char *lua_tolstring (lua_State *L, int index, size_t *len);

At first I just wrote this as:
  function lua_tolstring (L: lua_State_ptr; index: inteter; len :
size_t_ptr) return Interfaces.C.Char_array;

However, it only took me a minute to realize that this won't work.
I see two options:
1. function lua_tolstring (...) return System.Adddress;
2. use the types declared in Interfaces.C.Strings.

Has anyone else been down this path?  If so, can you share your
experiences?

I've read the AARM, and done some Googling, and looked through the
sources in Gnat.  If you want me to RTFM, then please point me to the
manual, and I will gladly read it!

thanks!



^ permalink raw reply	[relevance 5%]

* Re: What is the best way to define the Imported C function
    2008-01-26 10:15  7% ` Martin Krischik
@ 2008-01-26 10:56  7% ` Dmitry A. Kazakov
  1 sibling, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2008-01-26 10:56 UTC (permalink / raw)


On Fri, 25 Jan 2008 21:05:02 -0800 (PST), qunying wrote:

> I am learning Ada and try to test the interface with C.
> 
> for this function, what is the best way to define the function in Ada?
> 
> int xcb_parse_display(const char *name, char **host, int *display, int
> *screen);
> 
> function parse_display (Name : String; Host: ??; Display :
> Integer_Ptr; Screen : Integer_Ptr) return Integer;
> pragma Import (C, parse_display, "xcb_parse_display");
> 
> Where Integer_Ptr is access Integer;

   Name : Interfaces.C.char_array

and use To_C in order to pass a String there. Ada's String is not C's
char[]

   Display : access Interfaces.C.int

Firstly Integer is not necessarily int, the built-in package Interfaces.C
provides integer types compatible with C. Secondly in out mode will do the
trick where int * is used as an in-out parameter rather than a pointer to
an array. Unfortunately you have a function, so in out is illegal.
Therefore access Interfaces.C.int instead.

> How to define the type for char **?  Sould I use "type char_ptr_ptr is
> access char_ptr;" where char_ptr is defined in Interfaces.C; or there
> is a better way to do it?

Like with int *, that depends on the semantics. If the idea is to return a
pointer to a string then just tell so:

   Host : access Interfaces.C.Strings.chars_ptr
   Screen : access Interfaces.C.int

Surely, you would like to make a wrapper around the mess to make it more
Ada-friendly:

   type Display_ID is private; -- An opaque handle to
   type Screen_ID is private;
      -- This either does the job or raises an exception
   procedure Parse_Display
          (  Name    : String;
             Host    : out Unbounded_String;
             Display : out Display_ID;
             Screen  : out Screen_ID
          );
...
private
   type Display_ID is new Interfaces.C.int;
   type Screen_ID is new Interfaces.C.int;

...
procedure Parse_Display
          (  Name    : String;
             Host    : out Unbounded_String;
             Display : out Display_ID;
             Screen  : out Screen_ID
          )  is
   function Internal
            (  Name    : Interfaces.C.char_array;
               Host    : access Interfaces.C.Strings.chars_ptr;
               Display : access Display_ID;
               Screen  : access Screen_ID
            )  return Interfaces.C.int;
   pragma Import (C, Internal, "xcb_parse_display");

   Display_Value : aliased Display_ID;
   Screen_Value  : aliased Screen_ID;
   Host_Value    : aliased  Interfaces.C.Strings.chars_ptr;
   Result        : Interfaces.C.int :=
      Internal
      (  Name    => To_C (Name),
         Host    => Host_Value'Access,
         Display => Display_Value'Access,
         Screen  => Screen_Value'Access
      );
begin
   if Result = 0 then
      Host := To_Unbounded_String (To_Ada (Host_Value));
      Display := Display_Value;
      Screen := Screen_Value;
   else
      raise <Something Appropriate>;
   end if;
end Parse_Display;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 7%]

* Re: What is the best way to define the Imported C function
  @ 2008-01-26 10:15  7% ` Martin Krischik
  2008-01-26 10:56  7% ` Dmitry A. Kazakov
  1 sibling, 0 replies; 200+ results
From: Martin Krischik @ 2008-01-26 10:15 UTC (permalink / raw)


qunying wrote:

> Hi,
> 
> I am learning Ada and try to test the interface with C.
> 
> for this function, what is the best way to define the function in Ada?
> 
> int xcb_parse_display(const char *name, char **host, int *display, int
> *screen);

function parse_display (
   Name : in Interfaces.C.Strings.char_array_access;
   Host   : access Interfaces.C.Strings.char_array_access;
   Display : access Interfaces.C.int;
   Screen : access Interfaces.C.int)
return Interfaces.C.int;

See:

http://www.adaic.com/standards/05rm/html/RM-B-3.html

Martin

-- 
mailto://krischik@users.sourceforge.net
Ada programming at: http://ada.krischik.com



^ permalink raw reply	[relevance 7%]

* Re: pragma Convention questions
  2007-11-11 16:39  4% pragma Convention questions Samuel Tardieu
  2007-11-11 19:14  0% ` Martin Krischik
@ 2007-11-15  5:06  0% ` Randy Brukardt
  1 sibling, 0 replies; 200+ results
From: Randy Brukardt @ 2007-11-15  5:06 UTC (permalink / raw)


"Samuel Tardieu" <sam@rfc1149.net> wrote in message
news:87sl3cd9cw.fsf@willow.rfc1149.net...
> I have several questions regarding pragma Convention in Ada95 for
> language lawyers.
>
> 1- pragma Convention on private types in language-define packages
>
> Is it allowed for a compiler implementor to use a pragma Convention
> on a private type in a language-defined package?

I would say that is not allowed, because it could cause portability problems
between implementations. But I don't have any RM reference for that opinion,
so if you really care you'll need to ask on Ada-Comment. Also:

> For example, would it be allowed to use
>
>   pragma Convention (C, chars_ptr);
>
> in the private part of Interfaces.C.Strings? (the real motive to this
> question is to get rid of a warning in GNAT about conversion between
> pointers of different conventions -- the type is already compatible
> with C as per RM B3.1(1))

I think in this case, you could never tell the difference, so it would be OK
to do. (One wonders why the Standard didn't include that in the first
place.)

> 2- pragma Convention, renaming and Intrinsic
>
> Is the following code legal?
>
> package U is
>    type Foo is (Foo1, Foo2);
>    function F return Foo renames Foo1;
>    pragma Convention (Ada, F);
>    type Foo_Access is access function return Foo;
>    X : Foo_Access := F'Access;
> end U;
>
> GNAT rejects X initialization with 'prefix of "Access" attribute
> cannot be intrinsic'. Which means that the pragma Convention failed
> silently. Is it allowed to have it fail without a compilation error?
> Or is the 'Access legal?

I think that it should either work or the pragma Convention should be
rejected. To allow the change of the convention to one that is legal and
still reject the 'Access is bogus. (OTOH, this doesn't seem like a very
important bug, and I would not be surprised if it took a long time to get
fixed.)

                                   Randy.





^ permalink raw reply	[relevance 0%]

* Re: pragma Convention questions
  2007-11-11 20:57  3%   ` Samuel Tardieu
@ 2007-11-12  8:14  0%     ` Martin Krischik
  0 siblings, 0 replies; 200+ results
From: Martin Krischik @ 2007-11-12  8:14 UTC (permalink / raw)


Samuel Tardieu schrieb:
>>>>>> "Martin" == Martin Krischik <krischik@users.sourceforge.net> writes:
> 
> Martin> Yes. However the type must not be used beforehand - which is
> Martin> unlikely. Real language lawyers can tell you the term after
> Martin> which a type can not have any further modifications.
> 
> Thank you, I know the freezing rules and they would not be
> violated. My question was related to the legality of doing that when
> I could not find the RM section which allows you to change the default
> convention (Ada) of language-defined types (Interfaces.C.Strings.chars_ptr).

I think the RM always stops at "private" leaving the implementer to do
whatever they want in the private section. I have seen private sections
full of pragma Import.

> Martin> F does not actually exist and therefore has no address to
> Martin> access. And for "Convention Ada" that's ok. What you really
> Martin> meant to do is:
> 
> Martin> pragma Export (Ada, F);
> 
> I don't think so, pragma Convention should be enough. Note that
> renaming an existing function instead of an enumeration literal
> doesn't exhibit the same behaviour.

I don't think so. Unless you export a function/procedure I would think
the function/procedure is fair game to be optimized away by a smart linker.

> Martin> But somehow I think that will fail because F does exists
> Martin> physically.
> 
> It doesn't exist physically because it inherits the convention of the
> renamed entity (the enumeration literal, which has an Intrinsic
> convention). That's precisely why I don't understand why GNAT lets me
> specify its convention if it isn't able to honour it.

Question is:

> Note that the fact that an enumeration literal doesn't exist
> physically as a function doesn't prevent you from using it as a
> generic actual subprogram:
> 
> package W is
>    generic
>       with function F return Boolean;
>    package Gen is end Gen;
>    package Inst is new Gen (False);
> end W;

But here F can be inline expanded - so intrinsic is ok.

> (however, legality rules prevent you from ever taking a 'Access from
> inside the generic as formal subprograms are not subtype conformant
> with anything else, so my question would be void in this case)
> 
> The more I think about it the more I think GNAT should refuse the
> pragma Convention, just as it refuses it if you try to apply it
> directly to an enumeration literal. That's why I'd like some advice
> here. I'll ask ada-comment, I hadn't thought about it, thanks.

I think you are right and it probably is a compiler bug.

Martin

-- 
mailto://krischik@users.sourceforge.net
Ada programming at: http://ada.krischik.com



^ permalink raw reply	[relevance 0%]

* Re: pragma Convention questions
  2007-11-11 19:14  0% ` Martin Krischik
@ 2007-11-11 20:57  3%   ` Samuel Tardieu
  2007-11-12  8:14  0%     ` Martin Krischik
  0 siblings, 1 reply; 200+ results
From: Samuel Tardieu @ 2007-11-11 20:57 UTC (permalink / raw)


>>>>> "Martin" == Martin Krischik <krischik@users.sourceforge.net> writes:

Martin> Yes. However the type must not be used beforehand - which is
Martin> unlikely. Real language lawyers can tell you the term after
Martin> which a type can not have any further modifications.

Thank you, I know the freezing rules and they would not be
violated. My question was related to the legality of doing that when
I could not find the RM section which allows you to change the default
convention (Ada) of language-defined types (Interfaces.C.Strings.chars_ptr).

Martin> F does not actually exist and therefore has no address to
Martin> access. And for "Convention Ada" that's ok. What you really
Martin> meant to do is:

Martin> pragma Export (Ada, F);

I don't think so, pragma Convention should be enough. Note that
renaming an existing function instead of an enumeration literal
doesn't exhibit the same behaviour.

Martin> But somehow I think that will fail because F does exists
Martin> physically.

It doesn't exist physically because it inherits the convention of the
renamed entity (the enumeration literal, which has an Intrinsic
convention). That's precisely why I don't understand why GNAT lets me
specify its convention if it isn't able to honor it.

Note that the fact that an enumeration literal doesn't exist
physically as a function doesn't prevent you from using it as a
generic actual subprogram:

package W is
   generic
      with function F return Boolean;
   package Gen is end Gen;
   package Inst is new Gen (False);
end W;

(however, legality rules prevent you from ever taking a 'Access from
inside the generic as formal subprograms are not subtype conformant
with anything else, so my question would be void in this case)

The more I think about it the more I think GNAT should refuse the
pragma Convention, just as it refuses it if you try to apply it
directly to an enumeration literal. That's why I'd like some advice
here. I'll ask ada-comment, I hadn't thought about it, thanks.

Martin> I take it you know C

Yup, but there is no need to resort to an inferior language :)

  Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/



^ permalink raw reply	[relevance 3%]

* Re: pragma Convention questions
  2007-11-11 16:39  4% pragma Convention questions Samuel Tardieu
@ 2007-11-11 19:14  0% ` Martin Krischik
  2007-11-11 20:57  3%   ` Samuel Tardieu
  2007-11-15  5:06  0% ` Randy Brukardt
  1 sibling, 1 reply; 200+ results
From: Martin Krischik @ 2007-11-11 19:14 UTC (permalink / raw)


Samuel Tardieu wrote:

> I have several questions regarding pragma Convention in Ada95 for
> language lawyers.

The language lawyers are on mailto: ada-comment@ada-auth.org ;-)
 
> 1- pragma Convention on private types in language-define packages
> 
> Is it allowed for a compiler implementor to use a pragma Convention
> on a private type in a language-defined package?
> 
> For example, would it be allowed to use
> 
>   pragma Convention (C, chars_ptr);

Yes. However the type must not be used beforehand - which is unlikely. Real
language lawyers can tell you the term after which a type can not have any
further modifications.
 
> in the private part of Interfaces.C.Strings? (the real motive to this
> question is to get rid of a warning in GNAT about conversion between
> pointers of different conventions -- the type is already compatible
> with C as per RM B3.1(1))
> 
> 2- pragma Convention, renaming and Intrinsic
> 
> Is the following code legal?
> 
> package U is
>    type Foo is (Foo1, Foo2);
>    function F return Foo renames Foo1;
>    pragma Convention (Ada, F);
>    type Foo_Access is access function return Foo;
>    X : Foo_Access := F'Access;
> end U;
> 
> GNAT rejects X initialization with 'prefix of "Access" attribute
> cannot be intrinsic'. Which means that the pragma Convention failed
> silently. Is it allowed to have it fail without a compilation error?
> Or is the 'Access legal?

This is a different problem. F does not actually exist and therefore has no
address to access. And for "Convention Ada" that's ok. What you really
meant to do is:

pragma Export (Ada, F);

But somehow I think that will fail because F does exists physically. Same
way you can do: 

enum Foo {Foo1, Foo2};
#define F Foo1
Foo *X = &F;

in C. (I take it you know C).

Martin

-- 
mailto://krischik@users.sourceforge.net
Ada programming at: http://ada.krischik.com



^ permalink raw reply	[relevance 0%]

* pragma Convention questions
@ 2007-11-11 16:39  4% Samuel Tardieu
  2007-11-11 19:14  0% ` Martin Krischik
  2007-11-15  5:06  0% ` Randy Brukardt
  0 siblings, 2 replies; 200+ results
From: Samuel Tardieu @ 2007-11-11 16:39 UTC (permalink / raw)


I have several questions regarding pragma Convention in Ada95 for
language lawyers.

1- pragma Convention on private types in language-define packages

Is it allowed for a compiler implementor to use a pragma Convention
on a private type in a language-defined package?

For example, would it be allowed to use

  pragma Convention (C, chars_ptr);

in the private part of Interfaces.C.Strings? (the real motive to this
question is to get rid of a warning in GNAT about conversion between
pointers of different conventions -- the type is already compatible
with C as per RM B3.1(1))

2- pragma Convention, renaming and Intrinsic

Is the following code legal?

package U is
   type Foo is (Foo1, Foo2);
   function F return Foo renames Foo1;
   pragma Convention (Ada, F);
   type Foo_Access is access function return Foo;
   X : Foo_Access := F'Access;
end U;

GNAT rejects X initialization with 'prefix of "Access" attribute
cannot be intrinsic'. Which means that the pragma Convention failed
silently. Is it allowed to have it fail without a compilation error?
Or is the 'Access legal?

  Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/



^ permalink raw reply	[relevance 4%]

* Re: Byte streams
  @ 2007-08-03  5:34  6% ` Jeffrey R. Carter
  0 siblings, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2007-08-03  5:34 UTC (permalink / raw)


shaunpatterson@gmail.com wrote:
> 
> I've written a socket functions to send and receive data in C and then
> created a spec in Ada so I could use those same functions:
> 
> -- C functions --
> 
> unsigned char *readBytes (const unsigned int numBytes);
> void sendBytes (unsigned char *data, const unsigned int numBytes);
> 
> 
> --- Ada side
> type Byte is mod 256;
> for Byte'Size use 8;
> 
> type ByteStream is array (Integer range <>) of Byte;
> 
> 
> function readBytes (numBytes : Integer) return System.Address;
> pragma import (C, readBytes, "readBytes");

Integer? What would Readbytes (-7) mean?

> procedure sendBytes (data : ByteStream; numBytes : Integer);
> pragma import (C, sendBytes, "sendBytes");

For a direct translation, you should use the types in Interfaces.C and 
Interfaces.C.Strings (ARM B.3[.1]):

function Read_Bytes (Num_Bytes : in Interfaces.C.Unsigned)
return Interfaces.C.Strings.Chars_Ptr;

procedure Send_Bytes (Data      : in Interfaces.C.Char_Array;
                       Num_Bytes : in Interfaces.C.Unsigned);

More in the spirit rather than the letter of what the C is trying to 
say, you probably want to use System.Storage_Elements.Storage_Array:

procedure Send_Bytes
    (Data      : in System.Storage_Elements.Storage_Array;
     Num_Bytes : in Interfaces.C.Unsigned);

You send data by creating a subtype of 
System.Storage_Elements.Storage_Array with a length equal to the value 
you'll pass to Num_Bytes, and instantiating Ada.Unchecked_Conversion 
with this subtype as the target.

>                 type IntegerPtr is access all Integer;
>                 function to_IntegerPtr is new Unchecked_Conversion
>                       (source => System.Address, target =>
> IntegerPtr);
> 
> --- this works...and I can do all the conversions I need using an
> unchecked_conversion

This is highly compiler dependent. There is no guarantee that a 
System.Address and a C pointer are the same size, much less the same 
representation. There is no guarantee that a System.Address and an 
access value are the same size, much less the same representation. There 
are compilers where these things aren't and this won't work.

For situations where you must convert between System.Address and access 
values, there's System.Address_To_Access_Conversions, but this isn't one 
of those cases.

Reading is a little more complicated:

with System;

type Value is ...

type Value_Ptr is access all Value;
pragma Convention (C, Value_Ptr);

The pragma Convention is important; it tells the compiler to use the 
same representation as C. That may be different from Ada's default 
representation.

function Get (Num_Bytes : in Interfaces.C.Unsigned :=
                  Value'Size / System.Storage_Unit)
return Value_Ptr;

This is a way to do it at the low level (streams are another, and 
perhaps better, way). But Ada is usually about hiding the low level. You 
shouldn't want your application declaring access types and imported 
functions and doing unchecked conversions all over the place.

generic -- Socket_IF
    type Value (<>) is private;
package Socket_IF is
    procedure Send (Data : in Value);

    function Read return Value;
end Socket_IF;

with Ada.Unchecked_Conversion;
with Interfaces.C;
with System.Storage_Elements;

package Body Socket_IF is
    subtype Unsigned is Interfaces.C.Unsigned;
    use type Unsigned;

    Num_Bytes : constant Unsigned := Value'Size / System.Storage_Unit;

    procedure Send (Data : in Value) is
       subtype List is
          System.Storage_Elements.Storage_Array (1 .. Num_Bytes);

       function To_List is new Ada.Unchecked_Conversion
          (Source => Value, Target => List);

       procedure C_Send (Data : in List; Size : in Unsigned);
       pragma Import (C, C_Send, ...);
    begin -- Send
       C_Send (Data => To_List (Data), Size => Num_Bytes);
    end Send;

    function Read return Value is
       type Value_Ptr is access all Value;
       pragma Convention (C, Value_Ptr);

       function C_Read (Size : in Unsigned) return Value_Ptr;
       pragma Import (C, C_Read, ...);
    begin -- Read
       return C_Read (Num_Bytes).all;
    end Read;
end Socket_IF;

I haven't tested this, but it might even work.

Now your application only has to instantiate Socket_IF for each type of 
interest, and call the resulting Send and Read operations. Much 
replication of code is eliminated, and you only have to get this right once.

Something similar for the streams approach is left as an exercise for 
the reader.

-- 
Jeff Carter
"We call your door-opening request a silly thing."
Monty Python & the Holy Grail
17



^ permalink raw reply	[relevance 6%]

* Re: Translating a VB dll header to Ada
  2007-04-14 15:30  7%                 ` Dmitry A. Kazakov
@ 2007-04-14 21:37  0%                   ` vienapl
  0 siblings, 0 replies; 200+ results
From: vienapl @ 2007-04-14 21:37 UTC (permalink / raw)


That is the correct answer, it works!

Thank you a lot Philippe and Dmitry.

However, now I'm having trouble with the

  procedure CKHSendString (helper : System.Address; data : in
Interfaces.C.Char_Array);
  pragma Import (C, CKHSendString, External_Name => "CKHSendString");

function. It doesn't raise an exception, but it does not seem to do
anything at all. It works fine when used from the VB6 or C++ samples.

Thank you so much, again.

On Apr 14, 5:30 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On 14 Apr 2007 05:16:33 -0700, vien...@hotmail.com wrote:
>
> > Yes, it does work with only those two functions.
>
> > I don't know which parameter could be wrong on the CTHSetText
> > function. If I change a Char_Array for a WChar_Array I get a raised
> > PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION instead, but the debugger
> > prompts the same message.
>
> OK, C++ code you have referred to, looks quite ..., so let me suggest a bit
> offending thing. What if they copy pointers to strings?
>
> So what happens if you allocate the string passed to CTHSetText statically:
>
>    Object_Text : Interfaces.C.Char_Array :=
>        Interfaces.C.To_C ("Object");
> begin
>    ...
>    CTHSetText (TextHelperID, Object_Text);
>        -- CTHSetText remembers a pointer to Object_Text, which has to
>        -- exist as long as the library may dereference it
>    ...
>
> Another suggestion. If CTHSetText actually takes a pointer to a dynamically
> allocated string which will be freed later somewhere inside the library.
> Then CTHSetText should be declared like this:
>
>    procedure CTHSetText
>      (Helper : System.Address; Name_Ptr : Interfaces.C.Strings.chars_ptr);
>    pragma Import (C, CTHSetText, ...);
>
> and used as:
>
>    CTHSetText (TextHelperID, Interfaces.C.Strings.New_String ("Object"));
>        -- CTHSetText takes care of the memory allocated
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de





^ permalink raw reply	[relevance 0%]

* Re: Translating a VB dll header to Ada
  @ 2007-04-14 15:30  7%                 ` Dmitry A. Kazakov
  2007-04-14 21:37  0%                   ` vienapl
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2007-04-14 15:30 UTC (permalink / raw)


On 14 Apr 2007 05:16:33 -0700, vienapl@hotmail.com wrote:

> Yes, it does work with only those two functions.
> 
> I don't know which parameter could be wrong on the CTHSetText
> function. If I change a Char_Array for a WChar_Array I get a raised
> PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION instead, but the debugger
> prompts the same message.

OK, C++ code you have referred to, looks quite ..., so let me suggest a bit
offending thing. What if they copy pointers to strings?

So what happens if you allocate the string passed to CTHSetText statically:

   Object_Text : Interfaces.C.Char_Array :=
       Interfaces.C.To_C ("Object");
begin
   ...
   CTHSetText (TextHelperID, Object_Text);
       -- CTHSetText remembers a pointer to Object_Text, which has to
       -- exist as long as the library may dereference it
   ...

Another suggestion. If CTHSetText actually takes a pointer to a dynamically
allocated string which will be freed later somewhere inside the library.
Then CTHSetText should be declared like this:

   procedure CTHSetText
     (Helper : System.Address; Name_Ptr : Interfaces.C.Strings.chars_ptr);
   pragma Import (C, CTHSetText, ...);

and used as:

   CTHSetText (TextHelperID, Interfaces.C.Strings.New_String ("Object"));
       -- CTHSetText takes care of the memory allocated

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 7%]

* Re: Interfacing with C - pointer problem
  2007-01-31 18:10  7%   ` Adam Beneschan
@ 2007-01-31 23:53  0%     ` Jeffrey R. Carter
  0 siblings, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2007-01-31 23:53 UTC (permalink / raw)


Adam Beneschan wrote:
>>    type LPSTR is access Interfaces.C.Char;
>>    procedure C_Func (x : LPSTR);  -- expects an address (C-pointer, 32-bit)
>> and then
>>    data : Interfaces.C.char_array := Interfaces.C.To_C("ABC");
>> and
>>    C_Func (data(data'first)'unchecked_access);
> 
> Or perhaps better:
> 
>    procedure C_Func (x : Interfaces.C.Strings.chars_ptr);
> 
>    data : aliased Interfaces.C.char_array := Interfaces.C.To_C
> ("ABC");
> 
>    C_Func (Interfaces.C.Strings.To_Chars_Ptr (data'unchecked_access));
> 
> May as well use the stuff Ada provides for this exact purpose.

Right. Therefore, even better:

procedure C_Func (X : in Interfaces.C.Char_Array);
pragma Import (C, C_Func, ...);

Data : Interfaces.C.Char_Array := Interfaces.C.To_C ("ABC);

C_Func (X => Data);

The language passes this a a pointer to Data (Data'First). See ARM B.3 
(70): "An Ada parameter of an array type with component type T, of any 
mode, is passed as a t* argument to a C function, where t is the C type 
corresponding to the Ada type T."

-- 
Jeff Carter
"Alms for an ex-leper!"
Monty Python's Life of Brian
75



^ permalink raw reply	[relevance 0%]

* Re: Interfacing with C - pointer problem
  @ 2007-01-31 18:10  7%   ` Adam Beneschan
  2007-01-31 23:53  0%     ` Jeffrey R. Carter
  0 siblings, 1 reply; 200+ results
From: Adam Beneschan @ 2007-01-31 18:10 UTC (permalink / raw)


On Jan 30, 1:10 pm, tmo...@acm.org wrote:
> >   type LPSTR is access all String;
>
> > This does not work correct. What I found is, that data'Address is 32
> > bit and LPSTR is 64 bit.
>
>    Because LPSTR points to a dynamic size string and thus needs to
> carry along bounds information.  A C LPSTR does not point to a dynamic
> string, but instead points to a single character - the first in the
> string.  So the match is
>    type LPSTR is access Interfaces.C.Char;
>    procedure C_Func (x : LPSTR);  -- expects an address (C-pointer, 32-bit)
> and then
>    data : Interfaces.C.char_array := Interfaces.C.To_C("ABC");
> and
>    C_Func (data(data'first)'unchecked_access);

Or perhaps better:

   procedure C_Func (x : Interfaces.C.Strings.chars_ptr);

   data : aliased Interfaces.C.char_array := Interfaces.C.To_C
("ABC");

   C_Func (Interfaces.C.Strings.To_Chars_Ptr (data'unchecked_access));

May as well use the stuff Ada provides for this exact purpose.

                          -- Adam




^ permalink raw reply	[relevance 7%]

* Re: Interfacing with C - pointer problem
  @ 2007-01-30 15:53  5% ` Frank J. Lhota
    1 sibling, 0 replies; 200+ results
From: Frank J. Lhota @ 2007-01-30 15:53 UTC (permalink / raw)


Try using the Interfaces.C.Strings facilities instead. 





^ permalink raw reply	[relevance 5%]

* GPS example fails to compile
@ 2006-06-21 20:43  4% Xcriber51
  0 siblings, 0 replies; 200+ results
From: Xcriber51 @ 2006-06-21 20:43 UTC (permalink / raw)


Hi

After finally deciding to dive into the world of a language that requires
you to write...

    function Get_It (n: Integer) return Integer;

..what you can say in C as...

    int get_it (int n);
    
..I have downloaded the much-touted GPS IDE. 

Have I pissed you off already? Ok, that was just to get your attention,
forget that.

Seriously, after installing the IDE, I went ahead with the first tutorial:
SDC (the simple calculator), under "C:\GPS\doc\gps\examples\demo" (with the
default Windows installation), defined by the project file "sdc.gpr".

When I reached the full compilation stage of the Tutorial, I got a nasty
failure: gnatmake stops at "matrix_binding.adb", telling me that a series
of binding functions have "undefined reference to" 'name-of-function'.

The functions are in a C file ("matrix_utils.c" and/or "matrix.h")
included in the project. 

But my question is this: As I was trying to figure out how Ada manages
binding with external language modules (in our case with C code), I saw
that it uses the following syntax:

    function Alloc (Rows, Columns : Integer) return Matrix_Type is
        function C_Alloc (Rows, Columns : short) return Matrix_Type;
        pragma Import (C, C_Alloc, "matrixAlloc");
    begin
        return C_Alloc (short (Rows), short (Columns));
    end Alloc;

Now as I gather from another example in this forum, this "Import" function
works like so:

    -- Based on our example
    pragma Import (
        Convention      => C,
        Entity          => C_Alloc,
        External_Name   => "matrixAlloc"
        );

That's fine, but how does the compiler know where the heck "matrixAlloc"
is? I can't see the actual C file where the "matrixAlloc" and similar
functions are located included or explicitly referred to in the
"matrix_binding.ads" file, either. 

I checked:

- the .GPR file - the project directories are listed there, but not the
actual external module names;

- the GPS help system (which has topic headings like
"Interfaces.C.Strings", although they don't lead to any help files - that
link refers to an .ADS file, for instance);

- "Ada Distilled", the Wikibook "Ada Programming", the site "AdaPower",
etc.

I just couldn't find something that actually explains this to me.

Obviously - by Eric Raymondian criteria -, I'm dumb.

Any patient soul out there to explain how the f--- Ada does binding with
an external language module? (Not the "pragma import" construct, dammit,
but how the whole thing comes together.)

Thanks, patient soul!


-- Ken

P.S. Oh, and by the way: Why doesn't the example compile? Is it because I
installed GPS on an XP system when it was a full moon?






^ permalink raw reply	[relevance 4%]

* Re: Is there some way of calling a system command?
  2006-06-11 13:19  7% ` jimmaureenrogers
@ 2006-06-15 14:03  0%   ` Michel Simeon
  2013-11-26 15:35  0%   ` tolkamp
  1 sibling, 0 replies; 200+ results
From: Michel Simeon @ 2006-06-15 14:03 UTC (permalink / raw)


I am learning Ada and does not know C.
I tried your approach to call an othe program from Ada and it worked, except 
for one problem: the calling program will wait for the return parameter (Rc 
in your exemple) and thus freeze till the other one is closed.
Could i do something similar but withour the retrun parameter ?

-- 
Michel Simeon

<jimmaureenrogers@worldnet.att.net> wrote in message 
news:1150031952.347657.244910@i40g2000cwc.googlegroups.com...
> Aldebaran wrote:
>> I am a newbie Ada-programmer and need help with this topic.
>> In C one can launch a system command, for instance through
>>  the following function.
>>
>>  system("ls ");
>>
>> or in JAVA
>>
>>  exec("ls");
>>
>> Is there some similar  way of calling a system command in ADA?
>
> The easiest way is to simply call the C system command.
> The example below was run on my Windows XP system.
>
> with Interfaces.C.Strings;
> use Interfaces.C.Strings;
>
> procedure System_Example is
>   function System_Call(Command : Chars_Ptr) return Interfaces.C.Int;
>   pragma Import(Convention => C, Entity => System_Call,
>      External_Name => "system");
>   Rc : Interfaces.C.Int;
>
> begin
>   Rc := System_Call(New_String("dir"));
>
> end System_Example;
>
> The important part of the example is the creation of a function
> specification I have named System_Call. That function specification
> take a parameter of Chars_Ptr, which corresponds to a C char *.
> The function specification is used as the Ada interface to the C
> system call. The compiler is notified of that association through
> the pragma Import. That pragma causes the compiler to link the C
> system command and call it whenever System_Call is called in the
> Ada code.
>
> Jim Rogers
> 





^ permalink raw reply	[relevance 0%]

* Re: Is there some way of calling a system command?
  @ 2006-06-11 13:19  7% ` jimmaureenrogers
  2006-06-15 14:03  0%   ` Michel Simeon
  2013-11-26 15:35  0%   ` tolkamp
  0 siblings, 2 replies; 200+ results
From: jimmaureenrogers @ 2006-06-11 13:19 UTC (permalink / raw)


Aldebaran wrote:
> I am a newbie Ada-programmer and need help with this topic.
> In C one can launch a system command, for instance through
>  the following function.
>
>  system("ls ");
>
> or in JAVA
>
>  exec("ls");
>
> Is there some similar  way of calling a system command in ADA?

The easiest way is to simply call the C system command.
The example below was run on my Windows XP system.

with Interfaces.C.Strings;
use Interfaces.C.Strings;

procedure System_Example is
   function System_Call(Command : Chars_Ptr) return Interfaces.C.Int;
   pragma Import(Convention => C, Entity => System_Call,
      External_Name => "system");
   Rc : Interfaces.C.Int;

begin
   Rc := System_Call(New_String("dir"));

end System_Example;

The important part of the example is the creation of a function
specification I have named System_Call. That function specification
take a parameter of Chars_Ptr, which corresponds to a C char *.
The function specification is used as the Ada interface to the C
system call. The compiler is notified of that association through
the pragma Import. That pragma causes the compiler to link the C
system command and call it whenever System_Call is called in the
Ada code.

Jim Rogers




^ permalink raw reply	[relevance 7%]

* Problem with a C string to Ada conversion
@ 2006-06-08 21:45  8% Gautier
  0 siblings, 0 replies; 200+ results
From: Gautier @ 2006-06-08 21:45 UTC (permalink / raw)


Hi.
I'm trying to convert a C string to an Ada one and I don't see what's 
wrong with my code (also tried the variant commented out)...

with GL;
with Interfaces.C.Strings;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Unchecked_Conversion;

procedure Get_GL_Info is

   use GL;

   function GetString (name: StringEnm) return String is
     function Cvt is new 
Ada.Unchecked_Conversion(ubytePtr,Interfaces.C.Strings.chars_ptr);
     ps: constant ubytePtr:= GL.GetString(name);
     --ca: Interfaces.C.char_array:= Interfaces.C.Strings.Value(Cvt(ps));
   begin
     return Interfaces.C.Strings.Value(Cvt(ps));
     --return Interfaces.C.To_Ada(ca);
   end GetString;

begin
   for i in GL.StringEnm loop
     Put_Line(GL.StringEnm'Image(i) & ": [" & GetString(i) & ']');
   end loop;
end Get_GL_Info;

Here is what happens with this code:
The .exe built by GNAT 3.15p / Windows enters seemingly a memory 
munching race ending by a crash;
the one built by ObjectAda 7.2.2 says immediately:

Program terminated by an exception propagated out of the main subprogram.
Exception raised : INTERFACES.C.STRINGS.DEREFERENCE_ERROR
Executable name: GET_GL_INFO.EXE

Line      Subprogram name                 File
--------  ------------------------------  ------------
      181  interfaces.c.strings.strlen     interfaces.c.strings.bdy
      253  interfaces.c.strings.value      interfaces.c.strings.bdy
      297  interfaces.c.strings.value__3   interfaces.c.strings.bdy
       15  get_gl_info.getstring           get_gl_info.adb
       21  get_gl_info                     get_gl_info.adb
      320  _rtsadamain                     init.c

End of propagation.
Program aborted.

Any clue ? TIA! Gautier
_______________________________________________________________
Ada programming -- http://www.mysunrise.ch/users/gdm/gsoft.htm

NB: For a direct answer, e-mail address on the Web site!



^ permalink raw reply	[relevance 8%]

* Re: Calling C++ from Ada
  @ 2006-05-14 18:38  6%         ` Jeffrey R. Carter
  0 siblings, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2006-05-14 18:38 UTC (permalink / raw)


Yves Bailly wrote:
> 
> Is this approach too nasty ? Is it more or less portable ?

Your assumption that System.Address is equivalent to a C pointer is not 
portable among compilers. A better approach might be to have your 
imported C creation subprogram take an Interfaces.C.Strings.Chars_Ptr, 
and pass an 'Unchecked_Access to Interfaces.C.Strings.To_Chars_Ptr 
instead of 'Address.

-- 
Jeff Carter
"Perfidious English mouse-dropping hoarders."
Monty Python & the Holy Grail
10



^ permalink raw reply	[relevance 6%]

* Ada to Interfacing C# (Urgent)
@ 2006-03-24 18:30  6% Hakan
  0 siblings, 0 replies; 200+ results
From: Hakan @ 2006-03-24 18:30 UTC (permalink / raw)


I have been using a library written in Ada 95 for a while. (source code
available in Ada 95 and is written by someone else)
I have built an ADA DLL by using GNAT compiler for  Windows using this
library and
written some wrapper code in .Net 2003 with C#  which calls services
from the ADA DLL.
My problem is I get and "Object Reference Not set to an istance.."
error (or Access Violation error) in the Visual Studio 2003 Environment
when calling the
"Create_Exception_Ptr(ref ExcpWrp)" service given below:

The C# Code where the problem is:
[DllImport(("Mydll.dll"), CallingConvention=CallingConvention.Cdecl)]
internal static extern void Create_Exception_Ptr(ref IntPtr ExcpWrp);
public IntPtr CreatePtr()
{
   IntPtr ExcpWrp = IntPtr.Zero;
   try
{
    Create_Exception_Ptr(ref ExcpWrp);
}
catch (System.Exception ex)
{
string msg = ex.Message;
}
return ExcpWrp;
}
The corresponding Ada code is:

---spec file--
with Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;
.........
package C renames Interfaces.C;
type Exception_Ptr is access all chars_ptr;
pragma Controlled(Exception_Ptr);
procedure Create_Exception_Ptr(ExceptionPtr : in out Exception_Ptr);
pragma Export (C, Create_Exception_Ptr,"Create_Exception_Ptr");

-- body file--
....
procedure Create_Exception_Ptr(ExceptionPtr : in out Exception_Ptr) is
begin
  ExceptionPtr := new Chars_Ptr;
  ExceptionPtr.all:=Null_Ptr;
  ExceptionPtr.all:=New_Char_Array(C.To_C("NULL"));
end Create_Exception_Ptr;

 Actually, the problem arised when I start using the new version of my
Ada software Library (There was no problem with the old version. The
same code in C# and Ada works fine) The new Ada software library is big
in size and has a lot of Storage Pool allocation. Not  much dynamic
memory allocation. I tried to debug the Ada DLL, but I realized the
debugger does not go inside the function at runtime and an error
message ....SEGMENTATION FAULT....secondary_stack......is given.

Does anyone has an idea to overcome this problem? Please help for this,
 I have a time constraint. (I have used both Gnat 3.15p and Gnat
5.03a1, but found no solution)
 
Thanks a lot.
 
Best regards, Hakan.




^ permalink raw reply	[relevance 6%]

* Re: Ada95 skills test - Beta version(FREE)
  2006-02-22  3:23  4% ` jimmaureenrogers
@ 2006-02-23  2:40  0%   ` Stephen Leake
  0 siblings, 0 replies; 200+ results
From: Stephen Leake @ 2006-02-23  2:40 UTC (permalink / raw)


"jimmaureenrogers@worldnet.att.net" <jimmaureenrogers@worldnet.att.net> writes:

> <snip comments>
>
> One question dealt with interfacing a C function to Ada.
> It requires knowledge of C and Ada, which is not appropriate
> for an Ada test. 

This I disagree with. Many libraries are only available in C,
as are most operating systems. Ada is very good at interfacing with C,
so it is appropriate that the topic be covered in some way.

> Furthermore, none of the multiple choice answers is correct. The C
> function requires an array of char. Most likely that is a C string,
> which is null terminated, while corresponding Ada strings are not.
> The example makes no use of Interfaces.C.Strings.

Hmm. You must have taken a different test than I did; the C interface
question I saw was about link names. it was also slightly wrong.

> I suggest that you hire an experienced Ada programmer to
> develop the test. 

They tried to do that here last year. I offered to help; I don't know
who ended up writing the test.

> The person who developed the test does not understand Ada well
> enough. The test should not be some clone of a C++ or Java test.

It didn't strike me as a clone. But I should take their C++ and Java
tests first; that would provide some insight.

I hope you provided your input on the test forms.

-- 
-- Stephe



^ permalink raw reply	[relevance 0%]

* Re: Ada95 skills test - Beta version(FREE)
  @ 2006-02-22  3:23  4% ` jimmaureenrogers
  2006-02-23  2:40  0%   ` Stephen Leake
  0 siblings, 1 reply; 200+ results
From: jimmaureenrogers @ 2006-02-22  3:23 UTC (permalink / raw)



SaraL wrote:
> We appreciate your effort to help us make our Ada95 certification test
> the best it can possibly be!

This test looks like an Ada translation of a test for some other
language.

Many of the questions reveal a distinctly non-Ada approach to
programming.

For instance, the question about how to make a global variable.
Globals provide an amazing opportunity for coupling and side effects,
both of which are contrary to the spirit of Ada.

The indentation style of the code examples is difficult to read.
The variable names for the examples are normally single character.

Terminology used in the test is odd.

There is a heavy emphasis on examples with discriminant types.

The headings for questions are not well matched with the content
of the questions. This is unnecessarily misleading.

Many negative questions, such as "which answer is not true" are
asked. Negative logic is always less direct than positive logic.

The questions cover very little of the Ada language, while
concentrating
on areas including discriminants and nesting.

The questions about visibility do not adequately cover the Ada concepts
of scope and visibility. They also demonstrate coding styles that would
fail any decent code review.

The questions about pass by value or pass by reference are only
truly appropriate for compiler developers. Ada programmers do not
spend time fretting over the passing mechanism of procedure
parameters.

While there was one question dealing with protected types and tasks
it dealt only with priority issues. Protected types deserve a much more
in-depth treatment, including entries, procedures, functions, and
re-queuing.

There was no question about the select command, Ada rendezvous, or
asynchronous transfer of control.

There were no questions about the use of floating point numbers.
One question implied that fixed point numbers are superiour to
floating point numbers. That is clearly false. Each has its own proper
use.

There were no questions concerning subtypes.

One example of types was clearly syntactically wrong, which
invalidated the entire question. It has language similar to the
following:

type T is private;

type B is T;

Ada syntax requires the declaration of B to be either:

subtype B is T;

or

type B is new T;

One question dealt with interfacing a C function to Ada.
It requires knowledge of C and Ada, which is not appropriate
for an Ada test. Furthermore, none of the multiple choice
answers is correct. The C function requires an array of char.
Most likely that is a C string, which is null terminated, while
corresponding Ada strings are not. The example makes no
use of Interfaces.C.Strings.

I suggest that you hire an experienced Ada programmer to
develop the test. The person who developed the test does not
understand Ada well enough. The test should not be some
clone of a C++ or Java test.

Jim Rogers




^ permalink raw reply	[relevance 4%]

* Re: binding to C: popen
  2006-02-21 15:52  5%     ` Georg Bauhaus
@ 2006-02-21 16:16  0%       ` Poul-Erik Andreasen
  0 siblings, 0 replies; 200+ results
From: Poul-Erik Andreasen @ 2006-02-21 16:16 UTC (permalink / raw)


Georg Bauhaus wrote:
> Poul-Erik Andreasen wrote:
> 
> 
>>Yes but a C pointer is in Ada represented as system.address and i can
>>not test that for O the the systems.address_image gives 0804C060 and if
>>that is a stadart c value for a null-pointer things are fine, but that
>>seems to be a hack.
> 
> 
> System.Null_Address, or Interfaces.C.Strings.Null_Ptr perhaps?
> 
> You could consider writing a predicate like
> 
>   fucntion is_null(p: System.Address) return Boolean;
> 
> in order to have the comparison in one place only.
> 
> HTH,
>  Georg 
In the meantime i have found out that i will not help much. The 
null-pointer return will only occur if there is a internal error, and 
since  sh normaly will succed even if the command fails it somthing that
rarely occurs. I can not even find out a way to test it.

Poul-Erik



^ permalink raw reply	[relevance 0%]

* Re: binding to C: popen
    2006-02-21 15:52  5%     ` Georg Bauhaus
@ 2006-02-21 16:12  6%     ` Alex R. Mosteo
  1 sibling, 0 replies; 200+ results
From: Alex R. Mosteo @ 2006-02-21 16:12 UTC (permalink / raw)


Poul-Erik Andreasen wrote:
> jimmaureenrogers@worldnet.att.net wrote:
> 
>> Poul-Erik Andreasen wrote:
>>
>>> This ictually going as it is suppose to, but i would like set in an
>>> exception if the piping dosn't have succes. Acording to the C manual
>>> popen returns null if it fails. But how do i test on that in the 
>>> FILEs type?
>>
>>
>>
>> The popen man page describes the command as:
>> FILE *popen(const char *command, const char *mode);
>>
>> Note that popen returns a file pointer. Upon failure it returns a null
>> pointer.
>>
>> It seems that you might be able to test if the return value is null.
>>
>> Jim Rogers
>>
> 
> Yes but a C pointer is in Ada represented as system.address (...)

Not necessarily. Have a look at Interfaces.C, Interfaces.C.Pointers and 
Interfaces.C.Strings.

Also with Gnat an access type with pragma Convention (C, ...) can do the 
trick. You can easily check for null pointers that way.



^ permalink raw reply	[relevance 6%]

* Re: binding to C: popen
  @ 2006-02-21 15:52  5%     ` Georg Bauhaus
  2006-02-21 16:16  0%       ` Poul-Erik Andreasen
  2006-02-21 16:12  6%     ` Alex R. Mosteo
  1 sibling, 1 reply; 200+ results
From: Georg Bauhaus @ 2006-02-21 15:52 UTC (permalink / raw)


Poul-Erik Andreasen wrote:

> Yes but a C pointer is in Ada represented as system.address and i can
> not test that for O the the systems.address_image gives 0804C060 and if
> that is a stadart c value for a null-pointer things are fine, but that
> seems to be a hack.

System.Null_Address, or Interfaces.C.Strings.Null_Ptr perhaps?

You could consider writing a predicate like

  fucntion is_null(p: System.Address) return Boolean;

in order to have the comparison in one place only.

HTH,
 Georg 



^ permalink raw reply	[relevance 5%]

* Adding support for multiple tasks in wxAda
@ 2005-10-25 14:02  4% Lucretia
  0 siblings, 0 replies; 200+ results
From: Lucretia @ 2005-10-25 14:02 UTC (permalink / raw)


Hi,

Here's that question I promised I'd bring in ;-D

Here's the basic structure of wxAda types which can handle events.

<wx.Base.Event_Handler>
package wx.Base.Event_Handler is

  -- This is the actual type (wxEvtHandler) we are creating here.
  type Event_Handler_Type is new wx.Base.Object.Object_Type with
private;

  ...
  procedure Add_Pending_Event(
    Self  : in out Event_Handler_Type;
    Event : in wxEvent.Event_Type);

  -- The Connect procedure need to be a generic, so that the Callback
can be passed properly. It can be a number of different types.
  generic
    type Connect_Callback_Type is private;
  procedure Connect(
    Self      : in Event_Handler_Type'Class;
    Id,
    LastId    : in wx.Base.Id.Id_Type;
    EventType : in wxEvent.Event_Id_Type;
    Callback  : in Connect_Callback_Type);
  ...
  function Process_Event(
    Self  : in Event_Handler_Type;
    Event : in wxEvent.Event_Type) return Boolean;
  ...

end wx.Base.Event_Handler;
</wx.Base.Event_Handler>

<wx.Core.Window>
package wx.Core.Window is

  -- This is the actual type (wxWindow) we are creating here.
  type Window_Type is new wx.Base.Event_Handler.Event_Handler_Type with
private;

  ...

end wx.Core.Window;
</wx.Core.Window>

<wx.Core.Control>
package wx.Core.Control is

  -- This is the actual type (wxControl) we are creating here.
  type Control_Type is new wx.Core.Window.Window_Type with private;

  ...

end wx.Core.Control;
</wx.Core.Control>

This basically means that all windows and controls can handle their own
events.

The Connect generic procedure in wx.Base.Event_Handler is used to
connect event id's to callbacks, it's this generic that glues the C/C++
code to the Ada code, via the C wxEvtHandler_Connect function. Within
this function I use a C++ static function as the basic event handler
callback and package up the data passed to Connect from wxAda as the
callback data. Then within this callback, I then unpack the data from
wxAda and call the event handler within Ada (exported as a C function).

<wxbase_evthandler.cc>
void wxAdaCallbackObject::EventHandler(wxEvent &Event)
    {
    wxAdaCallbackObject *CallbackObject =
        wx_static_cast(wxAdaCallbackObject *,
Event.m_callbackUserData);

    Ada_Event_Handler(
        CallbackObject->_ParentEventHandler,
        CallbackObject->_Callback,
        &Event,
        Event.GetClassInfo()->GetClassName());
    }


void wxEvtHandler_Connect(
    wxAdaEvtHandler *Self,
    int              Id,
    int              LastId,
    int              EventType,
    void            *ParentEventHandler,
    void            *Callback)
    {
    wxObjectEventFunction EventCallback =
        wx_static_cast(wxObjectEventFunction,
&wxAdaCallbackObject::EventHandler);

    Self->Connect(
        Id,
        LastId,
        EventType,
        EventCallback,
        new wxAdaCallbackObject(ParentEventHandler, Callback));
    }
</wxbase_evthandler.cc>

>From this function I then determine whether it is a wxAda derived type
(inside Create_Ada_Event). If so, there exists a wxAda type which I can
just get hold of otherwise I "new" a proxy type. This returned event
type is then passed as a parameter to the actual Ada callback function
which was originally passed to the Connect generic above.

This proxy type has to be allocated dynamically, because at this point
we only know an event has been triggered, but not which type of event.
Inside the event handler (at the Ada level) the programmer will provide
a callback with the correct event type as a parameter, so we implicitly
convert the event type to the correct type to get the extra primitives
and/or data that that event type implements.

<wx.Base.Event_Handler>
package body wx.Base.Event_Handler is

  ...

  procedure Ada_Event_Handler(
    Parent     : Event_Handler_Class;
    Callback   : in Event_Function;
    Event      : in System.Address;
    Class_Name : in Interfaces.C.Strings.chars_ptr) is

    CXX_Class_Name : String              :=
Interfaces.C.To_Ada(Interfaces.C.Strings.Value(Class_Name));
    Ada_Event      : wxEvent.Event_Class := null;

    type Event_Access is access all wxEvent.Event_Type;

    procedure Free is new Ada.Unchecked_Deallocation(
      Object => wxEvent.Event_Type,
      Name   => Event_Access);

    function To_Access is new Ada.Unchecked_Conversion(
      Source => wxEvent.Event_Class,
      Target => Event_Access);

    Ada_Event_Acccess : Event_Access := null;

  begin

    Text_IO.Put_Line("Ada_Event_Handler: " & CXX_Class_Name);

    Ada_Event := Create_Ada_Event(Event, CXX_Class_Name);

    Callback(Parent, wxEvent.Event_Type(Ada_Event.all));

    if CXX_Class_Name /= "wxAdaEvent" then

      -- The next line would work, if it didn't get called again on
exit of the app!
      --Finalize(Ada_Event.all);

      Ada_Event_Acccess := To_Access(Ada_Event);

      Free(Ada_Event_Acccess);

    end if;

    return;

  end Ada_Event_Handler;

  ...

end wx.Base.Event_Handler;
</wx.Base.Event_Handler>

In wxWidgets a programmer would normally create a window (usually a
wxPanel) and then layout the controls on this panel, all the event
handlers (the callbacks) for the controls would be connected to the
wxPanel rather than the individual controls. It would be possible to
set up an event handler for each control, but that's really a special
case.

So given a contrived example, some Panel_Type has some controls
displayed upon it. There are a load of event handlers connected to the
Panel_Type. We also have one task per control, which does some trivial
update by sending events to the Panel_Type. Now we need to make the
event handling protected in some way, but seeing as Ada_Event_Handler
is essentially called from C this could be a problem. If I were to
create a protected type for handling events, can this safely be called
from C or from within a C function (Ada_Event_Handler)?

Thanks,
Luke.




^ permalink raw reply	[relevance 4%]

Results 1-200 of ~400   | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2005-10-25 14:02  4% Adding support for multiple tasks in wxAda Lucretia
2006-02-21 14:37     binding to C: popen Poul-Erik Andreasen
2006-02-21 15:25     ` jimmaureenrogers
2006-02-21 15:45       ` Poul-Erik Andreasen
2006-02-21 15:52  5%     ` Georg Bauhaus
2006-02-21 16:16  0%       ` Poul-Erik Andreasen
2006-02-21 16:12  6%     ` Alex R. Mosteo
2006-02-21 15:44     Ada95 skills test - Beta version(FREE) SaraL
2006-02-22  3:23  4% ` jimmaureenrogers
2006-02-23  2:40  0%   ` Stephen Leake
2006-03-24 18:30  6% Ada to Interfacing C# (Urgent) Hakan
2006-05-13 14:48     Calling C++ from Ada Yves Bailly
2006-05-13 17:02     ` Jeffrey Creem
2006-05-13 19:08       ` Yves Bailly
2006-05-13 19:55         ` Jeffrey Creem
2006-05-14  8:59           ` Yves Bailly
2006-05-14 18:38  6%         ` Jeffrey R. Carter
2006-06-08 21:45  8% Problem with a C string to Ada conversion Gautier
2006-06-11  8:46     Is there some way of calling a system command? Aldebaran
2006-06-11 13:19  7% ` jimmaureenrogers
2006-06-15 14:03  0%   ` Michel Simeon
2013-11-26 15:35  0%   ` tolkamp
2013-11-26 16:10  0%     ` adambeneschan
2013-11-26 18:54  0%       ` tolkamp
2013-11-26 18:24  0%     ` Per Sandberg
2006-06-21 20:43  4% GPS example fails to compile Xcriber51
2007-01-30 14:23     Interfacing with C - pointer problem Gerd
2007-01-30 15:53  5% ` Frank J. Lhota
2007-01-30 21:10     ` tmoran
2007-01-31 18:10  7%   ` Adam Beneschan
2007-01-31 23:53  0%     ` Jeffrey R. Carter
2007-04-11 19:48     Translating a VB dll header to Ada vienapl
2007-04-12  8:06     ` Dmitry A. Kazakov
2007-04-12 14:17       ` vienapl
2007-04-12 17:16         ` Dmitry A. Kazakov
2007-04-13 15:25           ` vienapl
2007-04-13 16:55             ` Dmitry A. Kazakov
2007-04-14  1:05               ` vienapl
2007-04-14  7:17                 ` Dmitry A. Kazakov
2007-04-14 12:16                   ` vienapl
2007-04-14 15:30  7%                 ` Dmitry A. Kazakov
2007-04-14 21:37  0%                   ` vienapl
2007-08-02 19:21     Byte streams shaunpatterson
2007-08-03  5:34  6% ` Jeffrey R. Carter
2007-11-11 16:39  4% pragma Convention questions Samuel Tardieu
2007-11-11 19:14  0% ` Martin Krischik
2007-11-11 20:57  3%   ` Samuel Tardieu
2007-11-12  8:14  0%     ` Martin Krischik
2007-11-15  5:06  0% ` Randy Brukardt
2008-01-26  5:05     What is the best way to define the Imported C function qunying
2008-01-26 10:15  7% ` Martin Krischik
2008-01-26 10:56  7% ` Dmitry A. Kazakov
2008-02-25 19:22  5% Questions on using prgma Import (C, foo) pfpearson.net
2008-02-25 19:28  5% ` Pascal Obry
2008-02-25 19:48  0%   ` pfpearson.net
2008-02-26 12:15  0%     ` Jeffrey Creem
2008-02-26 13:50  4%     ` Stephen Leake
2008-02-26 19:59  0%       ` pfpearson.net
2008-05-19  9:38  6% Pointer Sébastien
2008-05-19  9:53  7% ` Pointer Dmitry A. Kazakov
2008-05-19  9:54  0%   ` Pointer Dmitry A. Kazakov
2008-05-19 10:13  0%   ` Pointer Sébastien
2008-05-19 10:32  0%     ` Pointer Dmitry A. Kazakov
2008-05-19 10:34  0%     ` Pointer Ludovic Brenta
2008-05-19 11:31  6%       ` Pointer Sébastien
2008-05-19 12:09  6%         ` Pointer Ludovic Brenta
2008-05-19 12:09  7%         ` Pointer Dmitry A. Kazakov
2008-05-19 12:47  0%           ` Pointer Sébastien
2008-05-19 16:17  0% ` Pointer Matthew Heaney
2008-08-22  8:36  6% C chars_ptr STORAGE_ERROR in Imported function Kim Rostgaard Christensen
2008-08-22  9:03     ` Niklas Holsti
2008-08-22  9:55  7%   ` Kim Rostgaard Christensen
2008-08-22 11:43  5%     ` Niklas Holsti
2008-08-22 18:48  6% ` anon
2008-08-23 10:11  7%   ` Niklas Holsti
2008-09-12 12:05     Command Line on windows RasikaSrinivasan
2008-09-12 15:18     ` Jeffrey R. Carter
2008-09-12 15:27  5%   ` Adam Beneschan
2008-11-03 16:27  6% Directory Operations andrei.krivoshei
2008-11-03 17:33  0% ` Dmitry A. Kazakov
2008-11-04 12:57  0%   ` AndreiK
2008-11-04 14:44  7%     ` Dmitry A. Kazakov
2009-02-14  6:58  6% Converting pointers to non nul-terminated C "strings" to Ada string xorquewasp
2009-02-14  9:26  6% ` Dmitry A. Kazakov
2009-02-14 10:38  0%   ` xorquewasp
2009-02-14 11:16  0%     ` Dmitry A. Kazakov
2009-02-14  9:28  6% ` sjw
2009-02-14  9:33  0% ` likai3g
2009-08-01 17:53     Interpretation of extensions different from Unix/Linux? vlc
2009-08-04 11:31     ` vlc
2009-08-04 11:44       ` Jacob Sparre Andersen
2009-08-04 12:25         ` vlc
2009-08-04 19:18           ` Jeffrey R. Carter
2009-08-04 19:52             ` Dmitry A. Kazakov
2009-08-04 20:45               ` Jeffrey R. Carter
2009-08-04 21:22                 ` Dmitry A. Kazakov
2009-08-04 22:04                   ` Jeffrey R. Carter
2009-08-05  8:33                     ` Dmitry A. Kazakov
2009-08-14  4:56                       ` Randy Brukardt
2009-08-14  8:01                         ` Dmitry A. Kazakov
2009-08-14 23:54                           ` Randy Brukardt
2009-08-15  8:10                             ` Dmitry A. Kazakov
2009-08-17 22:28                               ` Randy Brukardt
2009-08-18  7:48                                 ` Dmitry A. Kazakov
2009-08-18 20:37                                   ` Randy Brukardt
2009-08-19  8:04                                     ` Dmitry A. Kazakov
2009-08-19 22:40                                       ` Randy Brukardt
2009-08-20 19:40                                         ` Dmitry A. Kazakov
2009-08-21  0:08                                           ` Randy Brukardt
2009-08-21 10:11  5%                                         ` Enumeration of network shared under Windows (was: Interpretation of extensions different from Unix/Linux?) Dmitry A. Kazakov
2009-09-11  7:57     Trouble writing Ada callback from C Jerry
2009-09-11  8:24  6% ` Ludovic Brenta
2009-09-12  5:28  5%   ` Jerry
2009-09-12  8:44  6%     ` Georg Bauhaus
2010-03-08 11:40  5% This MIDI stuff, would someone be interested in reviewing my code? John McCabe
2010-03-08 17:24  5% ` Jeffrey R. Carter
2010-03-09 10:21  0%   ` John McCabe
2010-03-13  8:12  0% ` Christophe Chaumet
2010-04-21 16:43     How to access this package written in C? resander
2010-04-22 21:12     ` Keith Thompson
2010-04-23 12:58       ` resander
2010-04-26 18:16         ` Robert A Duff
2010-04-26 19:57           ` Keith Thompson
2010-04-27  0:20  4%         ` Robert A Duff
2010-07-11  4:22  6% Example GNAT Ada program for openGl anon
2010-10-21  9:13     The "black magic" of ioctl Francesco Piraneo Giuliano
2010-10-21 10:20     ` Ludovic Brenta
2010-10-21 11:31       ` Francesco Piraneo Giuliano
2010-10-22 20:16  6%     ` michael bode
2010-12-24 16:36     Access Type kug1977
2010-12-24 17:30     ` Robert A Duff
2010-12-24 20:59       ` kug1977
2010-12-27  1:50  7%     ` Ludovic Brenta
2010-12-27 12:29           ` Simon Wright
2010-12-27 17:53             ` Ludovic Brenta
2010-12-27 18:15  5%           ` Simon Wright
2010-12-27 20:03  0%             ` Pascal Obry
2011-01-20 20:21  5% problems with interfacing c Stoik
2011-01-20 20:56  0% ` Dmitry A. Kazakov
2011-01-20 21:31  0%   ` Yannick Duchêne (Hibou57)
2011-01-28  0:39  0%   ` Stoik
2011-04-11 10:26     GNAT.Serial_Communications tonyg
2011-04-15 13:58     ` GNAT.Serial_Communications tonyg
2011-04-15 16:32       ` GNAT.Serial_Communications tonyg
2011-04-15 17:12         ` GNAT.Serial_Communications Simon Clubley
2011-04-15 17:32           ` GNAT.Serial_Communications tonyg
2011-04-15 18:49             ` GNAT.Serial_Communications Simon Clubley
2011-04-16  0:07               ` GNAT.Serial_Communications tonyg
2011-04-16  8:29                 ` GNAT.Serial_Communications Simon Clubley
2011-04-16 10:19                   ` GNAT.Serial_Communications tonyg
2011-04-16 10:33                     ` GNAT.Serial_Communications tonyg
2011-04-16 11:15                       ` GNAT.Serial_Communications Brian Drummond
2011-04-16 12:03                         ` GNAT.Serial_Communications tonyg
2011-04-16 15:12                           ` GNAT.Serial_Communications Simon Clubley
2011-04-18 20:43                             ` GNAT.Serial_Communications tonyg
2011-04-19 11:46                               ` GNAT.Serial_Communications tonyg
2011-04-19 12:09                                 ` GNAT.Serial_Communications Ludovic Brenta
2011-04-19 19:57  7%                               ` GNAT.Serial_Communications Alex Mentis
2011-04-20 11:37  0%                                 ` GNAT.Serial_Communications tonyg
2011-08-09 14:31  6% ADA and Open GL ldries46
2011-11-09  1:19     Read Windows login username in Ada 95 Rego, P.
2011-11-09 20:47  7% ` Rego, P.
2011-11-09 21:52  0%   ` Jeffrey Carter
2011-11-10  1:21  0%     ` Rego, P.
2011-11-18 19:40     Calling Ada Procedure from C - how to handle a char ptr/array awdorrin
2011-11-18 19:56     ` Jeffrey Carter
2011-11-18 20:19       ` awdorrin
2011-11-18 20:41         ` awdorrin
2011-11-18 21:38  5%       ` Adam Beneschan
2011-11-19  2:16     ` Adam Beneschan
2011-11-21 16:33  4%   ` awdorrin
2011-11-22 13:20  6%     ` awdorrin
2011-11-22 13:28  0%       ` Simon Wright
2011-11-28 15:55  5% Interfaces.C.String.Update awdorrin
2011-11-28 16:09  0% ` Interfaces.C.String.Update Adam Beneschan
2011-11-28 16:22  0% ` Interfaces.C.String.Update Ludovic Brenta
2011-11-28 16:35       ` Interfaces.C.String.Update awdorrin
2011-11-28 17:37  5%     ` Interfaces.C.String.Update Ludovic Brenta
2012-02-16 20:38  7% Windows LDAP group-user checking in Ada 95 Rego, P.
2012-02-16 20:55  7% ` Dmitry A. Kazakov
2012-07-20 20:05     Ada "library only" compiler ? Patrick
2012-07-20 21:11     ` Niklas Holsti
2012-07-20 23:30       ` Patrick
2012-07-21 16:47         ` Niklas Holsti
2012-07-21 17:47           ` Patrick
2012-07-21 22:53             ` Brian Drummond
2012-07-22  3:25               ` Patrick
2012-07-22 17:54  7%             ` Brian Drummond
2013-08-05 12:41     library/binding for sftp? Stephen Leake
2013-08-06  6:24     ` Stephen Leake
2013-08-06  6:54       ` Dmitry A. Kazakov
2013-08-07 10:06         ` Stephen Leake
2013-08-07 13:04           ` Dmitry A. Kazakov
2013-08-07 17:15             ` Simon Clubley
2013-08-07 19:57               ` Dmitry A. Kazakov
2013-08-07 20:09                 ` Alan Jump
2013-08-07 20:26                   ` Dmitry A. Kazakov
2013-08-07 20:32                     ` Alan Jump
2013-08-08  9:14                       ` Björn Persson
2013-08-08  9:49                         ` Dmitry A. Kazakov
2013-08-08 11:37                           ` Björn Persson
2013-08-08 19:18                             ` Randy Brukardt
2013-08-09  8:49                               ` Björn Persson
2013-08-09 20:12                                 ` Randy Brukardt
2013-08-19 17:26                                   ` Stefan.Lucks
2013-08-19 23:15                                     ` Randy Brukardt
2013-08-20  8:14                                       ` Stefan.Lucks
2013-08-20 20:59                                         ` Randy Brukardt
2013-08-21  7:27                                           ` Stefan.Lucks
2013-08-21 16:46                                             ` Alan Jump
2013-08-22  5:53  7%                                           ` Per Sandberg
2014-03-31 23:21  7% gprbuild and Linker_Options bug? Qun-Ying
2014-05-19 22:26     How to import C pointers to structures? Victor Porton
2014-05-19 22:33     ` Shark8
2014-05-19 22:44  5%   ` Adam Beneschan
2014-05-20  0:10  0%     ` Shark8
2014-05-20  0:22  0%       ` Adam Beneschan
2014-07-06 15:19     Ada's ranking of popularity at IEEE Spectrum Dan'l Miller
2014-07-06 19:41     ` sbelmont700
2014-07-08 17:25       ` Shark8
2014-07-08 23:03         ` sbelmont700
2014-07-09  2:30  4%       ` Shark8
2014-07-21 23:44     How to convert a C "char *" value to Ada string? Victor Porton
2014-07-22  0:19  5% ` Victor Porton
2014-07-22  0:28  7% ` Randy Brukardt
2014-07-26 14:13  5% Troubles with C strings Victor Porton
2014-07-26 15:15  0% ` Shark8
2014-07-26 15:52  0%   ` Victor Porton
2014-07-26 19:06  0%   ` Peter Chapin
2014-07-26 19:09  0%     ` Victor Porton
2014-08-01 22:16  0%       ` Victor Porton
2014-07-26 16:01  6% Allocating a C string without heap Victor Porton
2014-07-26 16:20  0% ` Dmitry A. Kazakov
2014-07-26 16:30  0%   ` Victor Porton
2014-07-26 18:38  0%     ` Dmitry A. Kazakov
2014-08-04 11:28  6% AUnit question Victor Porton
2014-08-09 19:25     Ada.Containers.Indefinite_Holders in GNAT and Ada2012 Victor Porton
2014-08-09 19:43     ` Victor Porton
2014-08-10 13:06  5%   ` Victor Porton
2014-08-10 15:32  0%     ` Simon Wright
2014-10-17 23:22  5% Interface with C codes Anh Vo
2014-10-17 23:30  6% ` Anh Vo
2014-10-18 18:33  0%   ` Stephen Leake
2014-10-19  4:33  6%     ` Anh Vo
2014-10-19  9:24  0%       ` Simon Clubley
2014-10-19 11:46  0%       ` Brian Drummond
2014-10-17 23:49  0% ` Adam Beneschan
2014-10-18  0:04  0%   ` Anh Vo
2014-10-18  1:04  6%     ` Anh Vo
2014-10-18  2:20  6% ` Jeffrey Carter
2014-10-18 17:00  0%   ` Anh Vo
2014-10-18  6:27  0% ` Per Sandberg
2015-02-02  5:50  4% Did I find mamory leak in Generic Image Decoder (GID) ? reinkor
2015-02-24  9:07     silly ravenscar question jan.de.kruyf
2015-02-24 11:02     ` Jacob Sparre Andersen
2015-02-24 11:23       ` jan.de.kruyf
2015-02-24 15:30         ` Brad Moore
2015-02-24 16:52  4%       ` Simon Wright
2015-04-06 17:27  5% ANN: STM32F4 GNAT Run Time Systems 20150406 Simon Wright
2015-07-23  2:20  5% Returning a string from C NiGHTS
2015-07-23  4:48  0% ` Jeffrey R. Carter
2015-07-23  7:17  6% ` Dmitry A. Kazakov
2015-09-16 12:55  7% Can I get rid of C libraries dependencies? Leff Ivanov
2016-02-07 22:45  5% ANN: Cortex GNAT RTS 20160207 Simon Wright
2016-03-14 17:42  5% ANN: Cortex GNAT RTS 20160314 Simon Wright
2016-05-02 16:45  5% A suggestion about interfacing with C mockturtle
2016-05-02 19:07  0% ` Jeffrey R. Carter
2016-05-02 19:40  0% ` Per Sandberg
2016-05-22 14:20  4% ANN: Cortex GNAT RTS 20160522 Simon Wright
2016-06-19  6:08  6% How to use/obtain output from system commands (in an Ada program) ? reinkor
2016-06-19  7:23  0% ` Dmitry A. Kazakov
2016-06-20  8:34  0%   ` reinkor
2017-07-07 21:03     Convert chars_ptr to Ada String Victor Porton
2017-07-07 22:23  5% ` Anh Vo
2017-07-07 22:48  6%   ` Victor Porton
2017-07-07 23:14  6%     ` Anh Vo
2017-07-09  6:49  0%       ` Victor Porton
2017-07-10  4:58  5%         ` Anh Vo
2017-07-10  9:31  0%           ` Victor Porton
2017-07-10  9:48                 ` Dmitry A. Kazakov
2017-07-10 12:41  6%               ` Mark Lorenzen
2017-07-10 14:24  0%                 ` Dmitry A. Kazakov
2017-08-04 22:17     Convert an access to constant to access to variable Victor Porton
2017-08-05 17:27     ` Stephen Leake
2017-08-05 17:41       ` Victor Porton
2017-08-07 23:16  6%     ` Randy Brukardt
2017-08-05 13:41  6% Need a way to convert a constant to a variable Victor Porton
2017-08-05 14:48  0% ` Dmitry A. Kazakov
2017-08-05 15:11  0%   ` Victor Porton
2017-08-05 15:41  7% ` Jeffrey R. Carter
2017-08-05 16:25  0%   ` Victor Porton
2017-08-05 17:59  0% ` Per Sandberg
2017-09-21 18:14     Ada.Strings.Unbounded vs Ada.Containers.Indefinite_Holders Victor Porton
2017-09-21 21:30     ` AdaMagica
2017-09-22 12:16       ` Victor Porton
2017-09-22 19:25         ` Simon Wright
2017-09-22 22:15           ` Victor Porton
2017-09-23  8:09             ` Dmitry A. Kazakov
2017-09-23  9:16  5%           ` Jeffrey R. Carter
2017-10-11 21:52     Convert between C "void*" pointer and an access Victor Porton
2017-10-11 22:58  6% ` Victor Porton
2017-10-11 23:12  6%   ` Victor Porton
2017-10-12  1:01  3%     ` Victor Porton
2018-02-23  8:54  7% non-local pointer cannot point to local object artium
2018-02-23  9:22  0% ` J-P. Rosen
2018-05-25 22:22  6% Interfaces.C.Strings chars_ptr memory management strategy NiGHTS
2018-05-26  2:52  8% ` Shark8
2018-05-26 12:44  8%   ` NiGHTS
2018-05-26 13:56  8%     ` Shark8
2018-05-30 13:10  7% ` Alejandro R. Mosteo
2018-05-30 19:56  6%   ` Randy Brukardt
2018-05-31 10:34  8%     ` Alejandro R. Mosteo
2018-05-31 22:25  7%       ` Randy Brukardt
2018-06-05 12:42  8%         ` Alejandro R. Mosteo
2018-06-03 18:31 14% ` ytomino
2018-06-03 19:33  8%   ` Dmitry A. Kazakov
2018-06-03 20:03 12%     ` ytomino
2018-06-04  7:06  8%       ` Dmitry A. Kazakov
2018-06-04  7:47  8%         ` ytomino
2018-06-03 20:37  8%     ` ytomino
2018-05-26 21:43     Strings with discriminated records NiGHTS
2018-05-27 17:11  7% ` NiGHTS
2018-05-27 18:07  0%   ` Simon Wright
2018-05-27 23:08  0%     ` NiGHTS
2018-05-28  1:44  0%       ` Jere
2018-05-28  3:05  0%         ` NiGHTS
2018-05-27 18:25  0%   ` Dmitry A. Kazakov
2018-05-27 22:44  0%     ` NiGHTS
2018-05-28  7:29  6%       ` Dmitry A. Kazakov
2018-05-28  7:42  4%       ` Simon Wright
2019-03-01 13:48     How to bind this properly, C ** which is an array Lucretia
2019-03-01 19:57     ` Per Sandberg
2019-03-01 20:25       ` Lucretia
2019-03-01 22:02  7%     ` Per Sandberg
2019-03-25  5:46  5% differences between Ada and C in gnat forcing me to use C instead of Ada matthewbrentmccarty
2019-03-25  5:58  0% ` Jere
2019-03-25 14:09  4% ` matthewbrentmccarty
2019-03-25 16:42     ` matthewbrentmccarty
2019-03-25 18:18       ` Dmitry A. Kazakov
2019-04-04  0:51  5%     ` matthewbrentmccarty
2020-04-29  8:46     Getting the 3 letter time zone abbreviation Bob Goddard
2020-04-29  9:09     ` Dmitry A. Kazakov
2020-04-29 19:20       ` Bob Goddard
2020-04-29 19:53         ` Dmitry A. Kazakov
2020-04-30 18:59           ` Bob Goddard
2020-04-30 21:11             ` Dmitry A. Kazakov
2020-05-02 12:46  7%           ` Bob Goddard
2022-02-02 17:21  5% Plugin with controlled variable for initialization hreba
2022-02-02 18:05  0% ` Dmitry A. Kazakov
2023-08-04 20:09     ALR unable to get many packages Kenneth Wolcott
2023-08-05  7:28     ` Simon Wright
2023-08-05 21:02       ` Kenneth Wolcott
2023-08-05 22:12         ` Simon Wright
2023-08-05 22:41           ` Kenneth Wolcott
2023-08-06 11:30             ` Simon Wright
2023-08-06 23:20               ` Kenneth Wolcott
2023-08-06 23:29  3%             ` Kenneth Wolcott

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox