comp.lang.ada
 help / color / mirror / Atom feed
From: "David C. Hoos, Sr." <david.c.hoos.sr@ada95.com>
Subject: how to read C extern variables from Ada?
Date: 1999/02/28
Date: 1999-02-28T00:00:00+00:00	[thread overview]
Message-ID: <5lkp7H5Y#GA.155@pet.hiwaay.net> (raw)
In-Reply-To: 7bbd3c$gf7@drn.newsguy.com


how to read C extern variables from Ada? wrote in message
<7bbd3c$gf7@drn.newsguy.com>...
>Hello,
>
>It is easy to interface to C from Ada. But one problem that I could not
>see mentioned in annex B, is how to get access to 'extern' variables.
>
>For example, I can call getopt() from Ada. But the problem is that getopt()
>sets values into an extern variables that are defined is C header files,
>and so can be read from C client programs after the call to getopt()
>returns.
>
>--------------------
>SYNOPSIS
>    #include <unistd.h>
>
>    int getopt(int argc, char * const argv[], const char *optstring);
>    extern char *optarg;
>    extern int optind, opterr, optopt;
>-----------------------
>
>So, in the above, after I call getopt(), I need a way to 'read' optarg.
There
>is no C API to read optarg. So, How to do this in Ada??
>
The simple answer is that one uses pragma import, e.g.:

Option_Argument : Interfaces.C.Char_Array;
pragma Import (C. Option_Argument, "optarg");

But, the details get a little messy.  Here's a possible implementation:

--- begin source code ---
with Ada.Command_Line;
with Ada.Text_Io;
with Interfaces.C.Pointers;
with System;
procedure Command_Line_Options is
   package C_String_Pointers is new Interfaces.C.Pointers
     (Index => Interfaces.C.Size_T,
      Element => Interfaces.C.Char,
      Element_Array => Interfaces.C.Char_Array,
      Default_Terminator => Interfaces.C.Nul);

   type C_String_Vector is array (Interfaces.C.Size_T range <>) of
     aliased C_String_Pointers.Pointer;

   package C_String_Vector_Pointers is new Interfaces.C.Pointers
     (Index => Interfaces.C.Size_T,
      Element => C_String_Pointers.Pointer,
      Element_Array => C_String_Vector,
      Default_Terminator => Null);

   subtype String_Pointer is C_String_Pointers.Pointer;

   subtype C_String_Vector_Pointer is C_String_Vector_Pointers.Pointer;

   use type Interfaces.C.Char_Array;
   use type Interfaces.C.Int;
   use type C_String_Pointers.Pointer;

   function Next_Option_Character_Pos
     (Argument_Count  : in Interfaces.C.Int;
      Argument_Vector_Pointer : in C_String_Vector_Pointer;
      Option_String   : in Interfaces.C.Char_Array)
      return Interfaces.C.Int;
   pragma Import (C, Next_Option_Character_Pos, "getopt");

   Argument_Vector_Pointer : C_String_Vector_Pointer;
   pragma Import (C, Argument_Vector_Pointer, "gnat_argv");

   Argument_Vector : constant C_String_Vector :=
     C_String_Vector_Pointers.Value (Ref => Argument_Vector_Pointer);

   Argument_Count : constant Interfaces.C.Int := Argument_Vector'Length - 1;
   Option_Argument_Pointer : C_String_Pointers.Pointer;
   pragma Import (C, Option_Argument_Pointer, "optarg");

   Option_Character_Pos : Interfaces.C.Int := 0;
   Option_Character : Character;

   Option_Index  :  Interfaces.C.Int;
   pragma Import (C, Option_Index, "optind");

   Option_Error  :  Interfaces.C.Int;
   pragma Import (C, Option_Error, "opterr");

   Option_Option :  Interfaces.C.Int;
   pragma Import (C, Option_Option, "optopt");

begin

   Ada.Text_Io.Put_Line
     ("Argument count =>" & Interfaces.C.Int'Image (Argument_Count));

   for A in Argument_Vector'First ..
     Interfaces.C.Size_T'Pred (Argument_Vector'Last) loop
      Ada.Text_Io.Put_Line
        ("Argument (" & Interfaces.C.Size_T'Image (A) & ") is """ &
         Interfaces.C.To_Ada
         (C_String_Pointers.Value (Argument_Vector (A))) &
         """");
   end loop;

     Option_Error := 1;

     loop
        Option_Character_Pos := Next_Option_Character_Pos
          (Argument_Count =>  Argument_Count,
           Argument_Vector_Pointer => Argument_Vector_Pointer,
           Option_String => "a:bc" & Interfaces.C.nul);

        exit when Option_Character_Pos < 0 or else Option_Character_Pos >
255;

        Option_Character := Character'Val (Option_Character_Pos);

        Ada.Text_Io.Put_Line
          ("Option_Index =" &
           Interfaces.C.Int'Image (Option_Index));

        Ada.Text_Io.Put_Line
          ("Option_Option =" &
           Interfaces.C.Int'Image (Option_Option));

        Ada.Text_Io.Put_Line
          ("Option_Character =" & Option_Character);

        for A in Argument_Vector'First ..
          Interfaces.C.Size_T'Pred (Argument_Vector'Last) loop
           Ada.Text_Io.Put_Line
             ("Argument (" & Interfaces.C.Size_T'Image (A) & ") is """ &
              Interfaces.C.To_Ada
              (C_String_Pointers.Value (Argument_Vector (A))) &
              """");
        end loop;

          if Option_Argument_Pointer /= null then
             Ada.Text_Io.Put_Line
               ("Option argument = """ &
                Interfaces.C.To_Ada
                (C_String_Pointers.Value (Option_Argument_Pointer)));
          end if;

     end loop;

end Command_Line_Options;

--- end source code ---








  reply	other threads:[~1999-02-28  0:00 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-02-28  0:00 nabbasi@pacbell.net how to read C extern variables from Ada?
1999-02-28  0:00 ` David C. Hoos, Sr. [this message]
1999-02-28  0:00 ` nabbasi@pacbell.net Matthew Heaney
1999-03-02  0:00 ` nabbasi@pacbell.net Stephen Leake
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox