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: When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced?
  2023-07-29 23:53  7%           ` Kenneth Wolcott
@ 2023-07-30  4:43  6%             ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2023-07-30  4:43 UTC (permalink / raw)


'Image doesn't support any formatting, so no "Aft" or "Exp". The slicing 
isn't the problem. :-)

You can use Text_IO to write to a string if you need formatting. 'Image is 
for quick & dirty debugging, not fancy output. (Of course, if you're lucky 
and it does what you need, then feel free to use it.)

                                 Randy.

"Kenneth Wolcott" <kennethwolcott@gmail.com> wrote in message 
news:2a5702b3-dbbc-4255-a4d4-e801f227fed3n@googlegroups.com...
On Saturday, July 29, 2023 at 4:49:08?PM UTC-7, Kenneth Wolcott wrote:
> On Saturday, July 29, 2023 at 4:07:17?AM UTC-7, AdaMagica wrote:
> > > Powers_of_2 := Powers_of_2 * To_Big_Integer (2);
> > With the aspect Integer_Literal, also Powers_of_2 * 2 must work. The 
> > attributes Integer_Literal, Real_Literal, Put_Image make the new big 
> > numbers nearly work like numeric types (they are not). A difference: The 
> > range syntax for instance in loops A .. B is illegal.
> I understand that the range syntax in loops implies that the loop variable 
> is acting like an enumerated type which is not true for Big_Integers.
>
> What confused me is that I thought I had to convert the numeric literal 
> (I'll have to go back and look at the package spec again to get this 
> firmly understood.
>
> I have an another question about string slicing: I've tried (obviously 
> incorrectly) to use a variable is one of the slice integers. Can this be 
> done?
>
> Thanks,
> Ken

Apparently not :-(

gnatmake main.adb
gcc -c main.adb
main.adb:28:67: error: named parameters not permitted for attributes
     9 with Ada.Text_IO; use Ada.Text_IO;
    10 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
    11 with Ada.Float_Text_IO; use Ada.Float_Text_IO;
    12 with Ada.Numerics.Elementary_Functions; use 
Ada.Numerics.Elementary_Functions;
    13 with Ada.Command_Line; use Ada.Command_Line;
    14
    15 procedure Main is
    16   Substr : String := Argument (1);
    17   Nth : Positive := Integer'Value (Argument (2));
    18   I, J : Natural;
    19   Temp : Float;
    20 begin
    21   I := 0;
    22   J := 0;
    23   loop
    24     I := I + 1;
    25     exit when I >= 10;
    26     Temp := 10.0 ** (log (2.0, 10.0) * Float (I));
    27     if I >= 4  then
    28       if (Float'Image (10.0 ** (log (2.0, 10.0) * Float (I)), Aft => 
0, Exp => 0) (1 .. Substr'Length) = Substr then
    29         J := J + 1;
    30         if J = Nth then
    31           Put (I, 0);
    32           New_Line;
    33           exit;
    34         end if;
    35       end if;
    36     end if;
    37   end loop;
    38 end Main;

Thanks,
Ken 


^ permalink raw reply	[relevance 6%]

* Re: When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced?
  @ 2023-07-29 23:53  7%           ` Kenneth Wolcott
  2023-07-30  4:43  6%             ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: Kenneth Wolcott @ 2023-07-29 23:53 UTC (permalink / raw)


On Saturday, July 29, 2023 at 4:49:08 PM UTC-7, Kenneth Wolcott wrote:
> On Saturday, July 29, 2023 at 4:07:17 AM UTC-7, AdaMagica wrote: 
> > > Powers_of_2 := Powers_of_2 * To_Big_Integer (2); 
> > With the aspect Integer_Literal, also Powers_of_2 * 2 must work. The attributes Integer_Literal, Real_Literal, Put_Image make the new big numbers nearly work like numeric types (they are not). A difference: The range syntax for instance in loops A .. B is illegal.
> I understand that the range syntax in loops implies that the loop variable is acting like an enumerated type which is not true for Big_Integers. 
> 
> What confused me is that I thought I had to convert the numeric literal (I'll have to go back and look at the package spec again to get this firmly understood. 
> 
> I have an another question about string slicing: I've tried (obviously incorrectly) to use a variable is one of the slice integers. Can this be done? 
> 
> Thanks, 
> Ken

Apparently not :-(

gnatmake main.adb
gcc -c main.adb
main.adb:28:67: error: named parameters not permitted for attributes
     9	with Ada.Text_IO; use Ada.Text_IO;
    10	with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
    11	with Ada.Float_Text_IO; use Ada.Float_Text_IO;
    12	with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;
    13	with Ada.Command_Line; use Ada.Command_Line;
    14
    15	procedure Main is
    16	  Substr : String := Argument (1);
    17	  Nth : Positive := Integer'Value (Argument (2));
    18	  I, J : Natural;
    19	  Temp : Float;
    20	begin
    21	  I := 0;
    22	  J := 0;
    23	  loop
    24	    I := I + 1;
    25	    exit when I >= 10;
    26	    Temp := 10.0 ** (log (2.0, 10.0) * Float (I));
    27	    if I >= 4  then
    28	      if (Float'Image (10.0 ** (log (2.0, 10.0) * Float (I)), Aft => 0, Exp => 0) (1 .. Substr'Length) = Substr then
    29	        J := J + 1;
    30	        if J = Nth then
    31	          Put (I, 0);
    32	          New_Line;
    33	          exit;
    34	        end if;
    35	      end if;
    36	    end if;
    37	  end loop;
    38	end Main;

Thanks,
Ken

^ permalink raw reply	[relevance 7%]

* Re: When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced?
  @ 2023-07-27 22:47  6%   ` Kenneth Wolcott
    0 siblings, 1 reply; 200+ results
From: Kenneth Wolcott @ 2023-07-27 22:47 UTC (permalink / raw)


On Thursday, July 27, 2023 at 1:53:38 AM UTC-7, Jeffrey R.Carter wrote:
> On 2023-07-27 07:26, Kenneth Wolcott wrote: 
> > 
> > When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced? 
> > 
> > I'd like to slice out the first two digits from the output of the To_String function of Ada.Big_Numbers.Big_Integers. 
> > 
> > When trying to do the usual string slicing on the output I get a silent failure, it is just as if I typed the null statement.
> It would be helpful if you could show what you're doing and what results you 
> get. This 
> 
> with Ada.Numerics.Discrete_Random; 
> with Ada.Text_IO; 
> 
> procedure Func_Slice is 
> subtype Digit is Character range '0' .. '9'; 
> 
> package Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Digit); 
> 
> Gen : Random.Generator; 
> 
> function Image (N : in Natural) return String is 
> (if N = 0 then "" else Random.Random (Gen) & Image (N - 1) ); 
> -- Returns a string of N random Digits 
> begin -- Func_Slice 
> Random.Reset (Gen => Gen); 
> Ada.Text_IO.Put_Line (Item => Image (10) (1 .. 2) ); 
> end Func_Slice; 
> 
> works as expected 
> 
> $ gnatmake -m -j0 -gnat12 -gnatan -gnato2 -O2 -fstack-check func_slice.adb 
> x86_64-linux-gnu-gcc-12 -c -gnat12 -gnatan -gnato2 -O2 -fstack-check func_slice.adb 
> x86_64-linux-gnu-gnatbind-12 -x func_slice.ali 
> x86_64-linux-gnu-gnatlink-12 func_slice.ali -O2 -fstack-check 
> $ ./func_slice 
> 10 
> $ ./func_slice 
> 51 

Hi Jeff;

  After going back and exhaustively reviewing the AdaCore Learning Introduction sections on Strings and Arrays, I determined that I was not slicing with the correct syntax for what I wanted to obtain, it seems that I was slicing built-in whitespace, not the digits I was looking for.  So I am now extracting the two-digit slice using (2 .. 3) rather than (1 .. 2) and I am now obtaining the desired output.  What I was trying to do was to obtain the slice from the string on the fly, not first saving the string to a variable.

This is what I have now (which works great):
---------------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Numerics.Big_Numbers.Big_Integers; use Ada.Numerics.Big_Numbers.Big_Integers;

procedure Powers_Of_2_With_Leading_Digits_Of_12 is
  Max : Positive := Integer'Value (Argument (1));
  Powers_of_2 : Big_Positive := 1;
begin
  for I in 1 .. Max loop
    Powers_of_2 := Powers_of_2 * To_Big_Integer (2);
    if I >= 4 then
      declare
        Powers_of_2_in_String_Format : String := To_String (Powers_of_2);
        First_Pair_of_String_Digits : String := Powers_of_2_in_String_Format (2 .. 3);
      begin
        if First_Pair_of_String_Digits = "12" then
          Put ("2^");
          Put (I, 0);
          Put_Line (To_String (Powers_of_2));
        end if;
      end; -- declare
    end if;
  end loop;
end Powers_Of_2_With_Leading_Digits_Of_12;
---------------------------------------------------------------------------

Now I can generalize this to more closely match the task requirements.

I think I tried to incorrectly create the slice from the To_String output directly without creating the variable in which to store the slice, which then requires the declare block.

Thanks,
Ken

^ permalink raw reply	[relevance 6%]

* Re: Build order with gprbuild
  @ 2023-03-01 20:08  5%   ` Gautier write-only address
  0 siblings, 0 replies; 200+ results
From: Gautier write-only address @ 2023-03-01 20:08 UTC (permalink / raw)


Between normal Ada projects, everything works as you describe (and as expected).
However, in the special case where project B, instead of transforming Ada files into .o files, transforms other kind of files into Ada files that are with-ed by units of project A, things get off the road: project A doesn't see out-of-date Ada files produced by project B.

Here is a full example. Files are reproduced below (they are meant to land into the same directory).
Then you do the following commands:

gprbuild -P fuzzy_gen.gpr
gprbuild -P code_generation.gpr
gnatstudio -P main.gpr

First build launched from GNAT Studio does the following on my machine:

    Compile
    [Ada]          main.adb
    [Fuzzy]        x789.cfg
    Ada file "fuzzy_x789.adb" is up to date
    [Fuzzy]        x456.cfg
    Ada file "fuzzy_x456.adb" is up to date
    [Fuzzy]        x123.cfg
    Ada file "fuzzy_x123.adb" is up to date
    [Ada]          fuzzy_x123.adb
    [Ada]          fuzzy_x456.adb
    [Ada]          fuzzy_x789.adb
    Bind
    [gprbind]      main.bexch
    [Ada]          main.ali
    Link
    [link]         main.adb

Second build has an expected output as well:

    Compile
       [Fuzzy]        x789.cfg
    Ada file "fuzzy_x789.adb" is up to date
       [Fuzzy]        x456.cfg
    Ada file "fuzzy_x456.adb" is up to date
       [Fuzzy]        x123.cfg
    Ada file "fuzzy_x123.adb" is up to date
    gprbuild: "main.exe" up to date

Now, say you modify x123.cfg and save it.
    Compile
       [Fuzzy]        x789.cfg
    Ada file "fuzzy_x789.adb" is up to date
       [Fuzzy]        x456.cfg
    Ada file "fuzzy_x456.adb" is up to date
       [Fuzzy]        x123.cfg
    Converting "x123.cfg" into "fuzzy_x123.adb"...
    gprbuild: "main.exe" up to date

That's *not* what I would like: gprbuild did not detect the out-of-date file "fuzzy_x123.adb" in time.
A second call to gprbuild compiles the changed "fuzzy_x123.adb" and all is well, but it is one step too late.

The files
=========

1) The code generator
=====================

fuzzy_gen.gpr:
-------------

project Fuzzy_Gen is
  for Object_Dir use "obj";
  for Exec_Dir use "gen";
  for Create_Missing_Dirs use "True";
  for Main use ("fuzzy_gen.adb");
end Fuzzy_Gen;

fuzzy_gen.adb:
-------------

with Ada.Calendar,
     Ada.Command_Line,
     Ada.Directories,
     Ada.Text_IO;

procedure Fuzzy_Gen is
  use Ada.Command_Line, Ada.Directories, Ada.Text_IO;

  procedure Convert (arg : String) is
    cfg : constant String := Simple_Name (arg);
    cfg_file_name : constant String := "../" & cfg;
    ada_unit_name : constant String :=
      "fuzzy_" & cfg (cfg'First .. cfg'Last - 4);
    ada_file_name : constant String := ada_unit_name & ".adb";
    cfg_in, ada_out : File_Type;
    use type Ada.Calendar.Time;
  begin
    if Exists (ada_file_name) and then
       Modification_Time (ada_file_name) >=
       Modification_Time (cfg_file_name)
    then
      Put_Line ("Ada file """ & ada_file_name & """ is up to date");
      return;
    end if;
    Put_Line
      ("Converting """ & cfg & """ into """ & ada_file_name & """...");
    Open (cfg_in, In_File, cfg_file_name);
    Create (ada_out, Out_File, ada_file_name);
    Put_Line
      (ada_out, "function " & ada_unit_name & " return String is");
    Put_Line (ada_out, "begin");
    Put_Line (ada_out, "  return """ & Get_Line (cfg_in) & """;");
    Put_Line (ada_out, "end;");
    Close (cfg_in);
    Close (ada_out);
  end Convert;


begin
  if Argument_Count = 0 then
    Put_Line (Current_Error, "config file name missing");
  else
    Convert (Argument (1));
  end if;
end Fuzzy_Gen;

2) The project that generates Ada files ("project B")
=====================================================

code_generation.gpr:
-------------------
project Code_Generation is

   for Languages use ("Fuzzy");
   for Source_Dirs use (".");
   for Object_Dir use "gen";
   for Objects_Linked  ("Fuzzy") use "False";

   package Naming is
      for Body_Suffix ("Fuzzy") use ".cfg";
   end Naming;

   package Compiler is
      for Driver ("Fuzzy") use "fuzzy_gen";
   end Compiler;

end Code_Generation;

x123.cfg:
--------
123

x456.cfg:
--------
456

x789.cfg:
--------
789

3) The main project (project A)
===============================

main.gpr:
--------
with "code_generation.gpr";

project Main is
  for Source_Dirs use (".", "gen");
  for Object_Dir use "obj";
  for Create_Missing_Dirs use "True";
  for Main use ("main.adb");
end Main;

main.adb:
--------
with Ada.Text_IO;
with Fuzzy_X123,
     Fuzzy_X456,
     Fuzzy_X789;

procedure Main is
begin
  Ada.Text_IO.Put
    ("Messages from elsewhere:" &
     " """ & Fuzzy_X123 & '"' &
     " """ & Fuzzy_X456 & '"' &
     " """ & Fuzzy_X789 & '"');
end;

^ permalink raw reply	[relevance 5%]

* Re: CONSTRAINT ERROR: erroneous memory access
  2020-06-06 23:40  4% CONSTRAINT ERROR: erroneous memory access jcupak
@ 2020-06-07 15:53  0% ` Anh Vo
  0 siblings, 0 replies; 200+ results
From: Anh Vo @ 2020-06-07 15:53 UTC (permalink / raw)


On Saturday, June 6, 2020 at 4:40:04 PM UTC-7, jcu...@gmail.com wrote:
> It has been a few years since I have written Ada; I used and taught Ada 95 back when I was working for a defense contractor. But, now that I'm retired, I wanted to get up to speed with Ada 2012, so I decided to implement a main program to see how the Shortest_Paths generic package works (taken from A.18.31, pages 574-576). But, when I read in the data and call the Shortest_Path function, it returns with CONSTRAINT ERROR: erroneous memory access. I've tried multiple times, but can't seem to figure out what I'm doing (or NOT doing) wrong. 
> 
> Here's the main program:
> 
> with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
> with Ada.Float_Text_IO;   use Ada.Float_Text_IO;
> with Ada.Text_IO;         use Ada.Text_IO;
> with Shortest_Paths;
> with Ada.Command_Line;    use Ada.Command_Line;
> with DirectedEdge;        use DirectedEdge;
> with Ada.Containers;      use Ada.Containers;
> with Ada.Exceptions;
> 
> procedure Main_Test is
> 
>    Input_File : Ada.Text_IO.File_Type;
> 
>    Vertices   : Integer; -- Number of nodes
>    Edges      : Integer; -- Number of paths
> 
>    Tail       : Integer; -- Node From
>    Head       : Integer; -- Node To
>    Weight     : Float;   -- Path Weight/Distance/Cost
> 
>    -- Instantiate Shortest Paths package with 0..Integer'Last subtype
>    package SP is new Shortest_Paths(Node => Natural);
>    
>    -- Use Edge'Read to read the Edge components into Item
>    
>    -- Display directed edge components
>    procedure Display(Edge : in SP.Edge) is
>    begin
>       Put(Edge.From, Width=>1); Put("->");
>       Put(Edge.To,   Width=>1); Put(" ");
>       Put(Float(Edge.Length), Fore => 0, Aft => 2, Exp => 0); Put(" ");
>    end Display;
> 
>    -- Display directed edge components at cursor
>    -- Replace List'Write with Display
>    procedure Display(Cursor: in SP.Adjacency_Lists.Cursor)
>    is
>       Edge : SP.Edge := SP.Adjacency_Lists.Element(Cursor);
>    begin
>       Display(Edge); -- Let other procedure do all the work
>    end Display;
> 
> begin
> 
> -- Open input file using arg 1
>    Open (File => Input_File,
>          Mode => In_File,
>          Name => Argument(1)); -- ../tinyEWD.txt
> 
>    Set_Input(Input_File);        -- Redirect input
>    New_Line;
>    Put("Processing '"); Put(Argument(1)); Put_Line("'");
> 
>    -- Read number of nodes (vertices)
>    Get(Vertices); New_Line;
>    Put("Vertices: ");Put(Vertices, width=>2);New_Line;
> 
>    -- Read number of paths (edges)
>    Get(Edges);
>    Put("Edges:    ");Put(Edges, Width=>2);New_Line(2);
> 
>    declare
>    
>       -- Constrain Vertex to zero-based subrange
>       subtype Vertex is Natural range 0..Vertices-1;
>       
>       -- Adj is DLL of Adjacency Lists for each Vertex
>       Adj    : array (Vertex) of SP.Adjacency_Lists.List;
>       
>       -- Edge is a record of Tail, Head, and Weight components
>       Edge   : SP.Edge;
>    
>    begin
>    
>       Put_Line("Creating Adjacency Lists"); New_Line;
>    
>       -- For each node, create empty list of adjacent nodes
>       Create_Empty_Adjacency_Lists: for Node in Vertex loop
>       
>          -- Initialize each adjacency list to empty
>          Adj(Node) := SP.Adjacency_Lists.Empty_List;
>       
>       end loop Create_Empty_Adjacency_Lists;
>    
>       -- Display and append new edge to adjacency list for node
>       -- Constrain Edge index to natural subrange
>       Append_New_Edge: for E in 0..Edges-1 loop
>       
>          Put("Edge:     ");Put(E, Width=>2);Put(" ");
>       
>          -- Get edge components from data file
>          Get(Tail);   -- Tail
>          Get(Head);   -- Head
>          Get(Weight); -- Distance/Weight
>       
>          -- Set edge components
>          Edge.From   := Tail;
>          Edge.To     := Head;
>          Edge.Length := SP.Distance(Weight);
>       
>          -- Display Edge
>          Display(Edge);
>          Put(" Appended to edge ");Put(Tail,1);
>          New_Line;
>       
>          -- Append new edge to From adjacency list
>          -- Indicating path to another node
>          Adj(Edge.From).Append(Edge);
>       
>       end loop Append_New_Edge;
>       New_Line;
>    
>       Close(Input_File);
>       Set_Input(Standard_Input); -- Reset input source
>    
>       Put_Line("Node Adjacency Lists");
>    
>       -- Display contents of each adjacency list
>       Display_Adjacency_Lists: for Node in Vertex loop
>       
>          Put("Adj[");Put(Node, Width=>1);Put("] ");
>       
>          declare
>             Edges  : Ada.Containers.Count_Type;
>          begin
>          
>             -- How many edges are in this node?
>             Edges := SP.Adjacency_Lists.Length(Adj(Node));
>             Put(Integer(Edges), Width => 1);
>             if (Edges > 1) then
>                Put(" Edges: ");
>             else
>                Put(" Edge:  ");
>             end if;
>          
>             -- Iterate over all nodes in this adjacency list
>             -- and Display each edge for each node
>             SP.Adjacency_Lists.Iterate(Adj(Node), Process => Display'Access);
>          
>          end;
>          New_Line;
>       
>       end loop Display_Adjacency_Lists;
>       New_Line;
>    
>       -- Create Edge-Weighted Graph of Node and Adjacency List
>       declare
>          EWG    : SP.Graphs.Vector; -- Edge Weighted Graphs
>          Path   : SP.Paths.List;    -- Shortest Path
>       begin
>       
>          Put_Line("Creating Edge-Weighted Graphs.");
>          EWG := SP.Graphs.Empty_Vector;
>          Put_Line("EWG Empty_Vector created.");
>          
>          Put("Initializing Shortest Path to empty list...");
>          Path := SP.Paths.Empty_List;
>          Put_Line("done.");
>          
>          for Vertex in 0..Vertices-1 loop
>             Put("Vertex: ");Put(Vertex, Width => 1);
>             EWG.Append(Adj(Vertex));
>             Put_Line(" appended to EWG.");
>          end loop;
>          New_Line;
>          
>          Put("EWG.Length = "); Put(Integer(EWG.Length), Width => 1);New_Line;
>       
>          Put_Line("Finding shortest path from node 0 to node 6");
>          declare
>             use Ada.Exceptions;
>          begin
>             -- Compute Shortest Path
>             Path := SP.Shortest_Path
>                (EWG, Source => 0, Target => 6);
>             exception
>                when Error: others =>
>                   New_Line;
>                   Put_Line(Exception_Name(Error));
>                   Put_Line(Exception_Message(Error));
>                   New_Line;
>                   Return;
>          end;
>       
>          Put("The Shortest Path from Node 0 to Node 6 ");
>          Put("contains "); Put(Integer(Path.Length)); Put(" entries.");
>          -- Display path
>       end;
>    
>    
>    end;
> 
> end Main_Test;
> 
> And here's the test data (taken from Algorithms, by Sedwick):
> 
> 8
> 15
> 4 5 0.35
> 5 4 0.35
> 4 7 0.37
> 5 7 0.28
> 7 5 0.28
> 5 1 0.32
> 0 4 0.38
> 0 2 0.26
> 7 3 0.39
> 1 3 0.29
> 2 7 0.34
> 6 2 0.40
> 3 6 0.52
> 6 0 0.58
> 6 4 0.93

It is hard to comment without Ada units Shortest_Path and DirectedEdge posted. In other word, your code does not compile.

Anh Vo 

^ permalink raw reply	[relevance 0%]

* CONSTRAINT ERROR: erroneous memory access
@ 2020-06-06 23:40  4% jcupak
  2020-06-07 15:53  0% ` Anh Vo
  0 siblings, 1 reply; 200+ results
From: jcupak @ 2020-06-06 23:40 UTC (permalink / raw)


It has been a few years since I have written Ada; I used and taught Ada 95 back when I was working for a defense contractor. But, now that I'm retired, I wanted to get up to speed with Ada 2012, so I decided to implement a main program to see how the Shortest_Paths generic package works (taken from A.18.31, pages 574-576). But, when I read in the data and call the Shortest_Path function, it returns with CONSTRAINT ERROR: erroneous memory access. I've tried multiple times, but can't seem to figure out what I'm doing (or NOT doing) wrong. 

Here's the main program:

with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Float_Text_IO;   use Ada.Float_Text_IO;
with Ada.Text_IO;         use Ada.Text_IO;
with Shortest_Paths;
with Ada.Command_Line;    use Ada.Command_Line;
with DirectedEdge;        use DirectedEdge;
with Ada.Containers;      use Ada.Containers;
with Ada.Exceptions;

procedure Main_Test is

   Input_File : Ada.Text_IO.File_Type;

   Vertices   : Integer; -- Number of nodes
   Edges      : Integer; -- Number of paths

   Tail       : Integer; -- Node From
   Head       : Integer; -- Node To
   Weight     : Float;   -- Path Weight/Distance/Cost

   -- Instantiate Shortest Paths package with 0..Integer'Last subtype
   package SP is new Shortest_Paths(Node => Natural);
   
   -- Use Edge'Read to read the Edge components into Item
   
   -- Display directed edge components
   procedure Display(Edge : in SP.Edge) is
   begin
      Put(Edge.From, Width=>1); Put("->");
      Put(Edge.To,   Width=>1); Put(" ");
      Put(Float(Edge.Length), Fore => 0, Aft => 2, Exp => 0); Put(" ");
   end Display;

   -- Display directed edge components at cursor
   -- Replace List'Write with Display
   procedure Display(Cursor: in SP.Adjacency_Lists.Cursor)
   is
      Edge : SP.Edge := SP.Adjacency_Lists.Element(Cursor);
   begin
      Display(Edge); -- Let other procedure do all the work
   end Display;

begin

-- Open input file using arg 1
   Open (File => Input_File,
         Mode => In_File,
         Name => Argument(1)); -- ../tinyEWD.txt

   Set_Input(Input_File);        -- Redirect input
   New_Line;
   Put("Processing '"); Put(Argument(1)); Put_Line("'");

   -- Read number of nodes (vertices)
   Get(Vertices); New_Line;
   Put("Vertices: ");Put(Vertices, width=>2);New_Line;

   -- Read number of paths (edges)
   Get(Edges);
   Put("Edges:    ");Put(Edges, Width=>2);New_Line(2);

   declare
   
      -- Constrain Vertex to zero-based subrange
      subtype Vertex is Natural range 0..Vertices-1;
      
      -- Adj is DLL of Adjacency Lists for each Vertex
      Adj    : array (Vertex) of SP.Adjacency_Lists.List;
      
      -- Edge is a record of Tail, Head, and Weight components
      Edge   : SP.Edge;
   
   begin
   
      Put_Line("Creating Adjacency Lists"); New_Line;
   
      -- For each node, create empty list of adjacent nodes
      Create_Empty_Adjacency_Lists: for Node in Vertex loop
      
         -- Initialize each adjacency list to empty
         Adj(Node) := SP.Adjacency_Lists.Empty_List;
      
      end loop Create_Empty_Adjacency_Lists;
   
      -- Display and append new edge to adjacency list for node
      -- Constrain Edge index to natural subrange
      Append_New_Edge: for E in 0..Edges-1 loop
      
         Put("Edge:     ");Put(E, Width=>2);Put(" ");
      
         -- Get edge components from data file
         Get(Tail);   -- Tail
         Get(Head);   -- Head
         Get(Weight); -- Distance/Weight
      
         -- Set edge components
         Edge.From   := Tail;
         Edge.To     := Head;
         Edge.Length := SP.Distance(Weight);
      
         -- Display Edge
         Display(Edge);
         Put(" Appended to edge ");Put(Tail,1);
         New_Line;
      
         -- Append new edge to From adjacency list
         -- Indicating path to another node
         Adj(Edge.From).Append(Edge);
      
      end loop Append_New_Edge;
      New_Line;
   
      Close(Input_File);
      Set_Input(Standard_Input); -- Reset input source
   
      Put_Line("Node Adjacency Lists");
   
      -- Display contents of each adjacency list
      Display_Adjacency_Lists: for Node in Vertex loop
      
         Put("Adj[");Put(Node, Width=>1);Put("] ");
      
         declare
            Edges  : Ada.Containers.Count_Type;
         begin
         
            -- How many edges are in this node?
            Edges := SP.Adjacency_Lists.Length(Adj(Node));
            Put(Integer(Edges), Width => 1);
            if (Edges > 1) then
               Put(" Edges: ");
            else
               Put(" Edge:  ");
            end if;
         
            -- Iterate over all nodes in this adjacency list
            -- and Display each edge for each node
            SP.Adjacency_Lists.Iterate(Adj(Node), Process => Display'Access);
         
         end;
         New_Line;
      
      end loop Display_Adjacency_Lists;
      New_Line;
   
      -- Create Edge-Weighted Graph of Node and Adjacency List
      declare
         EWG    : SP.Graphs.Vector; -- Edge Weighted Graphs
         Path   : SP.Paths.List;    -- Shortest Path
      begin
      
         Put_Line("Creating Edge-Weighted Graphs.");
         EWG := SP.Graphs.Empty_Vector;
         Put_Line("EWG Empty_Vector created.");
         
         Put("Initializing Shortest Path to empty list...");
         Path := SP.Paths.Empty_List;
         Put_Line("done.");
         
         for Vertex in 0..Vertices-1 loop
            Put("Vertex: ");Put(Vertex, Width => 1);
            EWG.Append(Adj(Vertex));
            Put_Line(" appended to EWG.");
         end loop;
         New_Line;
         
         Put("EWG.Length = "); Put(Integer(EWG.Length), Width => 1);New_Line;
      
         Put_Line("Finding shortest path from node 0 to node 6");
         declare
            use Ada.Exceptions;
         begin
            -- Compute Shortest Path
            Path := SP.Shortest_Path
               (EWG, Source => 0, Target => 6);
            exception
               when Error: others =>
                  New_Line;
                  Put_Line(Exception_Name(Error));
                  Put_Line(Exception_Message(Error));
                  New_Line;
                  Return;
         end;
      
         Put("The Shortest Path from Node 0 to Node 6 ");
         Put("contains "); Put(Integer(Path.Length)); Put(" entries.");
         -- Display path
      end;
   
   
   end;

end Main_Test;

And here's the test data (taken from Algorithms, by Sedwick):

8
15
4 5 0.35
5 4 0.35
4 7 0.37
5 7 0.28
7 5 0.28
5 1 0.32
0 4 0.38
0 2 0.26
7 3 0.39
1 3 0.29
2 7 0.34
6 2 0.40
3 6 0.52
6 0 0.58
6 4 0.93

^ permalink raw reply	[relevance 4%]

* Re: Getting the 3 letter time zone abbreviation
  @ 2020-04-30 21:11  6%         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2020-04-30 21:11 UTC (permalink / raw)


On 2020-04-30 20:59, Bob Goddard wrote:
> On Wednesday, 29 April 2020 20:53:11 UTC+1, Dmitry A. Kazakov  wrote:
>> On 2020-04-29 21:20, Bob Goddard wrote:
>>
>>> Seems easier just to import strftime and call it requesting just "%Z". This is on Linux, but MS suggests it should also work on Windows.
>>
>> An interesting idea. Did you try it under Windows? (There is a
>> suspicious remark that it depends on the setlocale)
> 
> 'Fraid not, I'm a Linux user. I just noticed that Windows does have it.

OK, I tested it. As expected it does not work. For example this one:
---------------------------
with Ada.Command_Line;           use Ada.Command_Line;
with Interfaces.C;               use Interfaces.C;
with Ada.Exceptions;             use Ada.Exceptions;
with Ada.Text_IO;                use Ada.Text_IO;

with System;

procedure Strftime_Test is

    type tm is record
       tm_sec   : int;
       tm_min   : int;
       tm_hour  : int;
       tm_mday  : int;
       tm_mon   : int;
       tm_year  : int;
       tm_wday  : int;
       tm_yday  : int;
       tm_isdst : int;
    end record;
    pragma Convention (C, tm);
    type tm_Ptr is access all tm;
    pragma Convention (C, tm_Ptr);

    type time_t is new Interfaces.Unsigned_64;

    function localtime (timep : access time_t) return tm_Ptr;
    pragma Import (C, localtime);

    function time (destTime : System.Address := System.Null_Address)
       return time_t;
    pragma Import (C, time, "_time64");

    function strftime
             (  strDest : char_array;
                maxsize : size_t;
                format  : char_array;
                timeptr : access tm
             )  return size_t;
    pragma Import (C, strftime);

    Result    : size_t;
    Buffer    : char_array (1..200);
    Now       : aliased time_t := 0;
    Local_Ptr : tm_Ptr;
begin
    Now := time;
    Put_Line ("Time=" & time_t'Image (Now));
    Local_Ptr := localtime (Now'Access);
    if Local_Ptr /= null then
       declare
          Local : tm renames localtime (Now'Access).all;
       begin
          Put_Line
          (  int'Image (Local.tm_year)
          &  " -"
          &  int'Image (Local.tm_mon)
          &  " -"
          &  int'Image (Local.tm_mday)
          &  " "
          &  int'Image (Local.tm_hour)
          &  " :"
          &  int'Image (Local.tm_min)
          &  " :"
          &  int'Image (Local.tm_sec)
          );
          Result := strftime
                    (  Buffer,
                       Buffer'Length,
                       To_C ("%#Z"),
                       Local'Access
                    );
          Put_Line ("Result=" & To_Ada (Buffer (1..Result), False));
       end;
    end if;
    Set_Exit_Status (0);
exception
    when Error : Status_Error | Data_Error =>
       Put_Line (Exception_Message (Error));
       Set_Exit_Status (1);
    when Error : others =>
       Put_Line ("Fault: " & Exception_Information (Error));
       Set_Exit_Status (2);
end Strftime_Test;
----------------------------------

Gives the output on my Windows machine:

    Result=W. Europe Daylight Time

instead of

    CEST

Windows POSIX layer relies on Windows API. If the API does something 
wrong, so would whatever POSIX function.

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

^ permalink raw reply	[relevance 6%]

* Re: hello world ada-ncurses new_window
  @ 2019-11-08  6:50  6% ` J-P. Rosen
  0 siblings, 0 replies; 200+ results
From: J-P. Rosen @ 2019-11-08  6:50 UTC (permalink / raw)


Le 07/11/2019 à 23:05, Alain De Vos a écrit :
>          GNAT.OS_Lib.OS_Exit (1);
Package Ada.Command_Line has a procedure Set_Exit_Status. It's always
better to use standard subprograms, Ada is for portability after all!

-- 
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 6%]

* Read-write mutex sometimes fails on deadlock
@ 2017-10-28 20:02  1% pascal.malaise
  0 siblings, 0 replies; 200+ results
From: pascal.malaise @ 2017-10-28 20:02 UTC (permalink / raw)


Hi,

[long post because it includes the full sources and output, sorry]

I have a package that implements several kinds of mutexes, including a
read-write mutex. Here is the full source (spec and body) with only the
read-write part.

mutexes.ads
-----------

private with Ada.Task_Identification;
-- Mutex (single and Read_Write) management
package Mutexes is

  -- Kind of mutex
  -- Read_Write allows several readers but one writer at a time.
  --  This implementation is fair but somewhat CPU-consuming because
  --  the arrival of a reader while writer(s) are waiting triggers a
  --  re-evaluation to let it pass if it has a higher (task) priority.
  -- Kind of requested access for a Read_Write mutex
  type Access_Kind is (Read, Write);

  -- Mutex object, free at creation
  type Mutex is tagged limited private;

  -- Get access to a mutex.
  -- With RW mutex (Read_Write), simultaneous read are possible,
  --  but there is only one writer at a time and no reader at that time.
  -- If delay is negative, wait until mutex is got,
  -- If delay is null, try and give up if not free,
  -- If delay is positive, try during the specified delay.
  -- Raises Already_Got if the current task if it has already got the RW mutex
  --  for write.
  -- Note that there is no check of "Read then Write" deadlock.
  Already_Got : exception;
  function Get (A_Mutex      : in out Mutex;
                Waiting_Time : in Duration;
                Kind         : in Access_Kind := Read) return Boolean;
  -- Get access to a mutex : infinite wait.
  procedure Get (A_Mutex      : in out Mutex;
                 Kind         : in Access_Kind := Read);
  function Get (A_Mutex : in out Mutex) return Boolean;


  -- Release access to a mutex.
  -- Raises Not_Owner if current task doesn't own the the RW mutex for write
  --  (no check when releasing RW mutex aquired for read).
  Not_Owner : exception;
  procedure Release (A_Mutex : in out Mutex);

  -- Is current task the "owner" (access got) of a simple mutex
  -- Is it the writer in case of a RW mutex
  function Is_Owner (A_Mutex : in Mutex) return Boolean;

private

  -- Read/write mutex
  -- We want to queue all requests (read and write) within the same queue
  --  to ensure fairness (avoid starvation).
  -- But the condition for read is "no writer" (not Writer)
  --  and for write it is "no writer and no reader"
  --  (not Writer and then Readers = 0)
  -- So the guard of the common queue is "no writer", but a writer may pass it
  --  while there are reader. In this case, we would like to requeue it in the
  --  same queue and in the beginning of it; note that "requeue" requeues at
  --  the end :-(. The artifact is to requeue the task, and all other
  --  tasks queueing after it as well, in an alternate queue (Swapping).
  -- Benefit: a new reader may enter while writer(s) are queueing, if its
  --  priority is better. Fairness ++.
  -- Drawback: each new reader while writer(s) are queueing triggers an open
  --  then a swap of the queues. Perfo --.

  -- So there are two queues
  type Queue_Range is mod 2;

  -- The read/write access lock and queues. No time.
  protected type Rw_Mutex_Protect is

    -- Gets the lock. Blocking.
    entry Mutex_Get (Kind : in Access_Kind);

    -- Releases the lock
    procedure Mutex_Release;

    -- Is current task write owner of the lock
    function Mutex_Owns return Boolean;
  private
    -- Number of readers
    Readers : Natural := 0;
    -- Writer identification
    Owner : Ada.Task_Identification.Task_Id;
    -- Numer of times it has got the write lock
    Writer : Natural := 0;

    -- Two queues, one is active at a time
    entry Queues (Queue_Range) (Kind : in Access_Kind);
    Current_Queue : Queue_Range := Queue_Range'First;
    -- The status of the queue:
    -- Swapping or not
    Swapping : Boolean := False;
    -- If not swapping, is the mutex open or not
    -- if swapping, will it be open or not
    Open : Boolean := True;

  end Rw_Mutex_Protect;

  -- The general purpose mutex
  type Mutex is tagged limited record
    Rw_Mutex : Rw_Mutex_Protect;
  end record;
end Mutexes;


mutexes.adb
-----------

with Ada.Text_Io;
package body Mutexes is

  use type Ada.Task_Identification.Task_Id;
  function Image (Id : in Ada.Task_Identification.Task_Id) return String
           renames Ada.Task_Identification.Image;

  Debug_Set : Boolean := False;
  Debug_On : Boolean := False;
  procedure Trace (Id : in Ada.Task_Identification.Task_Id;
                   Msg : in String) is
  begin
    if not Debug_Set then
      -- Initial setup
      Debug_Set := True;
      Debug_On := True;
    end if;
    if Debug_On then
      Ada.Text_Io.Put_Line (Msg & " " & Image (Id));
    end if;
  end Trace;

  -- The protected object which implements the read/write mutex
  protected body Rw_Mutex_Protect is

    -- Gets the lock. Blocking.
    -- Do not let a new request be inserted in the middle of a queue while
    -- we are swapping queues.
    entry Mutex_Get (Kind : in Access_Kind) when not Swapping is
    begin
      -- Are we already the writer
      if Writer /= 0 and then Mutex_Get'Caller = Owner then
        raise Already_Got;
      end if;

      -- Queue the request in the active queue
      Trace (Mutex_Get'Caller, "Read_Write get queueing");
      requeue Queues(Current_Queue) with abort;
    end Mutex_Get;

    -- Releases the lock. No Check of kind but the lock must have been
    -- got.
    procedure Mutex_Release is
    begin
      if Readers > 0 then
        -- There are readers, one of them is releasing the lock
        Readers := Readers - 1;
        if Readers = 0 then
          -- The last reader leaves, so the lock becomes available
          --  for writers
          Trace (Ada.Task_Identification.Current_Task, "Last reader releases");
          Open := True;
        else
          Trace (Ada.Task_Identification.Current_Task, "Reader releases");
        end if;
      elsif Writer /= 0
      and then Ada.Task_Identification.Current_Task = Owner then
        -- The writer is releasing the lock
        if Writer /= 1 then
          Writer := Writer - 1;
          return;
        end if;
        -- Really releasing
        Trace (Ada.Task_Identification.Current_Task, "Writer releases");
        Writer := 0;
        Open := True;
      else
        -- Called while no lock was got or not called by the writer
        raise Not_Owner;
      end if;
    end Mutex_Release;

    function Mutex_Owns return Boolean is
      (Writer /= 0 and then Ada.Task_Identification.Current_Task = Owner);

    -- Two queues, one active at a time
    -- Passes when swapping queues or else when open
    entry Queues (for Queue in Queue_Range) (Kind : in Access_Kind)
          when Queue = Current_Queue
          and then (Swapping or else Open) is
    begin
      if Swapping then
        -- Swapping queueing tasks from one queue to the other
        Trace (Queues'Caller, "Swapping");
        if Queues(Queue)'Count = 0 then
          -- This is the last task: end of swapping
          -- Open remains unchanged (maybe open by a release)
          Swapping := False;
          Current_Queue := Current_Queue + 1;
          Trace (Queues'Caller, "End swapping");
        end if;
        -- Requeue the task on the other queue
        requeue Queues(Queue + 1) with abort;
      else
        -- The queue is open: The lock is either free or allocated to reader(s)
        if Kind = Read then
          Trace (Queues'Caller, "Another reader");
          -- Read lock
          Readers := Readers + 1;
        else
          -- Write lock:
          -- If we are here, it means that the gate is open so no writer
          --  has already got the lock
          -- Either we get the lock (queue is closed until we release)
          -- or we queue (no currently queueing read can pass)
          -- so in both case, the queue is closed
          -- Note that a new request may re-open the queue and enter
          --  before us if it as a better prio
          Open := False;
          if Readers = 0 then
            -- No reader => we get the write lock
            Writer := 1;
            Owner := Queues'Caller;
            Trace (Queues'Caller, "Writer has got lock");
          else
            -- We have to wait until last reader releases the lock
            -- If we are alone, requeue ourself. Otherwise
            --  requeue in the alternate queue this task, then all the other
            --  queueing tasks, so we remain first (if same prios)
            Swapping := Queues(Queue)'Count > 0;
            if Swapping then
              Trace (Queues'Caller, "Start swapping");
              requeue Queues(Queue + 1) with abort;
            else
              Trace (Queues'Caller, "Writer waits for current reader");
              requeue Queues(Queue) with abort;
            end if;
          end if;
        end if;
      end if;
    end Queues;

  end Rw_Mutex_Protect;

  function Get (A_Mutex      : in out Mutex;
                Waiting_Time : in Duration;
                Kind         : in Access_Kind := Read) return Boolean is
    Result : Boolean;
  begin
    if Waiting_Time < 0.0 then
      -- Negative delay : unconditional waiting
      A_Mutex.Rw_Mutex.Mutex_Get (Kind);
      Result := True;
    else
      select
        A_Mutex.Rw_Mutex.Mutex_Get (Kind);
        Result := True;
      or
        delay Waiting_Time;
        Result := False;
      end select;
    end if;
    return Result;
  end Get;

  function Get (A_Mutex : in out Mutex) return Boolean is
    (Get (A_Mutex, -1.0, Read));

  -- Get a mutex : infinite wait
  procedure Get (A_Mutex      : in out Mutex;
                 Kind         : in Access_Kind := Read) is
    Dummy : Boolean;
  begin
    Dummy := Get (A_Mutex, -1.0, Kind);
  end Get;

  -- Release a mutex
  procedure Release (A_Mutex : in out Mutex) is
  begin
    -- Request releasing
    A_Mutex.Rw_Mutex.Mutex_Release;
  end Release;

  -- Does current task own the mutex (for write)
  function Is_Owner (A_Mutex : Mutex) return Boolean is
  begin
    return A_Mutex.Rw_Mutex.Mutex_Owns;
  end Is_Owner;

end Mutexes;



Finally, I have a test program of the read-write mutex, which creates 10 tasks,
each of them taking the mutex, for read or write, during some time. The tasks
randomly terminate, and when all of them are done then the test is OK.


t_read_write.adb
----------------
with Ada.Text_Io, Ada.Command_Line, Ada.Calendar, Ada.Task_Identification,
     Ada.Numerics.Float_Random;
with Gnat.Calendar;
with Mutexes;
-- Test Read-Write mutex
procedure T_Read_Write is
  pragma Priority(10);

  -- True if gnat, otherwise remove usage of Gnat.Calendar
  Has_Gnat : constant Boolean := True;

  -- The number of tasks
  subtype Range_Actor is Natural range 0 .. 10;
  Main_Index : constant Range_Actor := 0;
  subtype Range_Task is Positive range 1 .. Range_Actor'Last;

  -- Date of last output of a task
  Last_Time : Ada.Calendar.Time;
  use type Ada.Calendar.Time;
  -- Delay of inactivity
  Inactivity : constant Duration := 5.0;

  -- Random generator
  Gen : Ada.Numerics.Float_Random.Generator;
  function Random (Mini : in Integer := 0;
                   Maxi : in Integer := 1) return Integer is
    F : Float;
    Res : Integer;
  begin
    F := Float(Mini) + Ada.Numerics.Float_Random.Random(Gen)
                       * Float(Maxi - Mini);
    Res := Integer (F);
    while Res > Maxi and then Res > Mini loop
      Res := Res - 1;
    end loop;
    return Res;
  end Random;

  -- Image of a date 
  function Image (Date : Ada.Calendar.Time) return String is
    Year   : Ada.Calendar.Year_Number;
    Month  : Ada.Calendar.Month_Number;
    Day    : Ada.Calendar.Day_Number;

    Hour       : Gnat.Calendar.Hour_Number;
    Minute     : Gnat.Calendar.Minute_Number;
    Second     : Gnat.Calendar.Second_Number;
    Sub_Second : Gnat.Calendar.Second_Duration;
    function Img (D : Gnat.Calendar.Second_Duration) return String is
      S : constant String := D'Img;
    begin
      return S(3 .. S'Last);
    end Img;
    Dur    : Ada.Calendar.Day_Duration;
    function Img (N : Integer) return String is
      S : constant String := N'Img;
    begin
      if S'Last = 2 then
        -- " d", 1 digit => "0" & d
        return "0" & S(2);
      else
        -- " dd", d
        return S(2 .. S'Last);
      end if;
    end Img;
    
  begin
    if Has_Gnat then
      Gnat.Calendar.Split (Date, Year, Month, Day, Hour, Minute, Second,
                           Sub_Second);
      return Img (Year) & "-" & Img (Month) & "-" & Img (Day) & "T"
           & Img (Hour) & ":" & Img (Minute) & ":" & Img (Second)
           & Img (Sub_Second);

    else
      Ada.Calendar.Split (Date, Year, Month, Day, Dur);
      return Img (Year) & "/" & Img (Month) & "/" & Img (Day) & Dur'Img;
    end if;
  end Image;

  -- Put a task activity
  procedure Put_Line (Index : in Range_Actor; Msg : in String) is
  begin
    Last_Time := Ada.Calendar.Clock;
    declare
      Date : constant String := Image (Last_Time);
      Str : constant String
          := (if Index in Range_Task then Index'Img else "Main")
           & " " & Msg;
    begin
      Ada.Text_Io.Put_Line (Date & " " & Str);
    end;
  end Put_Line;
  Lock : access Mutexes.Mutex;

  -- The client tasks
  task type T is
   pragma Priority(10);
    entry Num (I : in Range_Task);
    entry Done;
  end T;

  function Image (D : Duration) return String is
    Str : constant String := D'Img;
  begin
    return Str (1 .. 4);
  end Image;

  task body T is
    Index : Range_Task;
    Dur : Duration;
    Kind : Mutexes.Access_Kind;
    subtype Str5 is String (1 .. 5);
    Kind_Strs : constant array (Mutexes.Access_Kind) of Str5 := (
      Mutexes.Read  => " Read",
      Mutexes.Write => "Write");
    Res : Boolean;
  begin
    -- Get name
    accept Num (I : in Range_Task) do
      Index := I;
    end Num;
    Put_Line (Index ,
      "Task started, id "
    & Ada.Task_Identification.Image (Ada.Task_Identification.Current_Task));
    -- Work until termination requested in Critical
    loop
      delay 0.01;
      -- Wait from -0.1 to 0.5
      Dur := Duration (Random (-1, 5)) / 10.0;
      -- 10% chances to write
      if Random (0, 9) = 0 then
        Kind := Mutexes.Write;
      else
        Kind := Mutexes.Read;
      end if;
      -- Get lock
      Put_Line (Index, "get " & Kind_Strs(Kind) & " " & Image(Dur));
      Res := Lock.Get (Dur, Kind);
      -- Trace result
      if Res then
        Put_Line (Index, "OK");
      else
        Put_Line (Index, "NOK");
      end if;

      if Res then
        -- Got it: Work (wait) from 0.1 to 0.5
        Put_Line (Index, "waiting");
        delay Duration (Random (1, 5)) / 10.0;
        Put_Line (Index, "waited");

        -- Release lock
        Put_Line (Index, "release");
        Lock.Release;
      end if;

      -- 10% chances to terminate
      exit when Random (0, 9) = 0;
    end loop;
    Put_Line (Index, "terminate");
    -- Ready to end
    accept Done;
  end T;

  Tasks : array (Range_Task) of T;
  Runs  : array (Range_Task) of Boolean;
  Nb_Run : Natural;

-- The main: activate and monitor the tasks
begin
  Lock := new Mutexes.Mutex;

  -- Randomize
  Ada.Numerics.Float_Random.Reset (Gen, 
    Integer (Ada.Calendar.Seconds (Ada.Calendar.Clock)));

  -- Give to each actor it's name
  Put_Line (Main_Index, "Starting");
  Nb_Run := 0;
  for I in Range_Task loop
    Tasks(I).Num (I);
    Runs(I) := True;
    Nb_Run := Nb_Run + 1;
  end loop;

  -- Wait until termination of all tasks
  Main: while Nb_Run /= 0 loop

    -- Try to terminate tasks: wait 1s altogether
    for I in Range_Task loop
      if Runs(I) then
        select
          Tasks(I).Done;
          Runs(I) := False;
          Nb_Run := Nb_Run - 1;
        or
          delay 1.0 / Duration(Nb_Run);
        end select;
      end if;
    end loop;

    -- Monitor activity
    if Ada.Calendar.Clock - Last_Time > Inactivity then
      -- Deadlock detected => abort tasks
      Put_Line (Main_Index, "Deadlock detected, aborting");
      Ada.Command_Line.Set_Exit_Status (1);
      for I in Range_Task loop
        if Runs(I) then
          abort Tasks(I);
          -- This will exit Main
          Nb_Run := Nb_Run - 1;
        end if;
      end loop;
    end if;
  end loop Main;

  Put_Line (Main_Index, "Done");

end T_Read_Write;


Most of the time it works, but from time to time (every 100 to 1000 iterations)
the test fails: the main detects a deadlock because of no output activity during
more than 5 secs, and exits on error.
You can test on Unix with the following scripts (launch "./Loop"):

trw
---
#!/bin/bash
./t_read_write >out 2>err

Loop
----
#!/bin/bash

# Loop until failure
res=0
let n=0+1
while [ $res -eq 0 ] ; do
  echo `date +"%Y-%m-%dT%H:%M:%S"`" Iteration "$n":"
  ./trw
  if [ $? -ne 0 ] ; then
    echo "Failed!"
    exit 1
  fi
  let n=$n+1
done



When everything is OK all the tasks terminate one after the other, but in case
of failure, here is the output:

2017-10-28T21:15:21.139556000 Main Starting
2017-10-28T21:15:21.139602000  1 Task started, id tasks(1)_0000000000E63F10
2017-10-28T21:15:21.139618000  2 Task started, id tasks(2)_0000000000E68040
2017-10-28T21:15:21.139644000  3 Task started, id tasks(3)_0000000000E6B650
2017-10-28T21:15:21.139662000  4 Task started, id tasks(4)_0000000000E6EC60
2017-10-28T21:15:21.139679000  5 Task started, id tasks(5)_0000000000E72270
2017-10-28T21:15:21.139695000  6 Task started, id tasks(6)_0000000000E75880
2017-10-28T21:15:21.139709000  7 Task started, id tasks(7)_0000000000E78E90
2017-10-28T21:15:21.139732000  8 Task started, id tasks(8)_0000000000E7C4A0
2017-10-28T21:15:21.139752000  9 Task started, id tasks(9)_0000000000E7FAB0
2017-10-28T21:15:21.139759000  10 Task started, id tasks(10)_0000000000E830C0
2017-10-28T21:15:21.149687000  1 get  Read  0.0
2017-10-28T21:15:21.149690000  3 get Write  0.1
2017-10-28T21:15:21.149700000  2 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
2017-10-28T21:15:21.149744000  5 get  Read  0.0
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:21.149782000  4 get Write  0.5
Read_Write get queueing tasks(3)_0000000000E6B650
Writer waits for current reader tasks(3)_0000000000E6B650
2017-10-28T21:15:21.149804000  8 get  Read  0.1
2017-10-28T21:15:21.149786000  1 OK
2017-10-28T21:15:21.149769000  6 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.149825000  9 get  Read  0.5
2017-10-28T21:15:21.149829000  2 NOK
Read_Write get queueing tasks(9)_0000000000E7FAB0
2017-10-28T21:15:21.149855000  10 get  Read  0.0
2017-10-28T21:15:21.149875000  7 get  Read  0.2
2017-10-28T21:15:21.149816000  1 waiting
Read_Write get queueing tasks(4)_0000000000E6EC60
Read_Write get queueing tasks(8)_0000000000E7C4A0
Read_Write get queueing tasks(6)_0000000000E75880
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.149917000  6 NOK
2017-10-28T21:15:21.149926000  5 NOK
Read_Write get queueing tasks(10)_0000000000E830C0
Read_Write get queueing tasks(7)_0000000000E78E90
2017-10-28T21:15:21.149940000  10 NOK
2017-10-28T21:15:21.159909000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.159990000  5 get  Read  0.3
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.160006000  10 get  Read  0.5
2017-10-28T21:15:21.159993000  6 get  Read  0.0
Read_Write get queueing tasks(6)_0000000000E75880
2017-10-28T21:15:21.160032000  6 NOK
Read_Write get queueing tasks(10)_0000000000E830C0
2017-10-28T21:15:21.170103000  6 get  Read  0.4
Read_Write get queueing tasks(6)_0000000000E75880
2017-10-28T21:15:21.249871000  3 NOK
2017-10-28T21:15:21.249967000  8 NOK
2017-10-28T21:15:21.259960000  2 NOK
2017-10-28T21:15:21.259964000  3 get  Read  0.1
Read_Write get queueing tasks(3)_0000000000E6B650
2017-10-28T21:15:21.260036000  8 get  Read -0.1
Read_Write get queueing tasks(8)_0000000000E7C4A0
2017-10-28T21:15:21.270048000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.270066000  2 NOK
2017-10-28T21:15:21.280139000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.349953000  1 waited
2017-10-28T21:15:21.349976000  1 release
Last reader releases tasks(1)_0000000000E63F10
Another reader tasks(9)_0000000000E7FAB0
Start swapping tasks(4)_0000000000E6EC60
Swapping tasks(7)_0000000000E78E90
2017-10-28T21:15:21.350007000  9 OK
2017-10-28T21:15:21.350051000  9 waiting
Swapping tasks(5)_0000000000E72270
2017-10-28T21:15:21.360060000  1 get  Read  0.0
Swapping tasks(10)_0000000000E830C0
Swapping tasks(6)_0000000000E75880
Swapping tasks(8)_0000000000E7C4A0
Swapping tasks(2)_0000000000E68040
End swapping tasks(2)_0000000000E68040
Read_Write get queueing tasks(1)_0000000000E63F10
2017-10-28T21:15:21.360109000  3 NOK
2017-10-28T21:15:21.360121000  1 NOK
2017-10-28T21:15:21.370195000  3 get  Read  0.3
Read_Write get queueing tasks(3)_0000000000E6B650
2017-10-28T21:15:21.370204000  1 get Write  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
2017-10-28T21:15:21.370242000  1 NOK
2017-10-28T21:15:21.380223000  2 NOK
2017-10-28T21:15:21.380324000  1 get  Read -0.1
Read_Write get queueing tasks(1)_0000000000E63F10
2017-10-28T21:15:21.390298000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.460071000  5 NOK
2017-10-28T21:15:21.470153000  5 get  Read  0.0
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.470170000  5 NOK
2017-10-28T21:15:21.480242000  5 get  Read  0.1
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.570194000  6 NOK
2017-10-28T21:15:21.580275000  6 get  Read  0.0
Read_Write get queueing tasks(6)_0000000000E75880
2017-10-28T21:15:21.580293000  6 NOK
2017-10-28T21:15:21.580321000  5 NOK
2017-10-28T21:15:21.590365000  2 NOK
2017-10-28T21:15:21.590374000  6 get  Read  0.4
Read_Write get queueing tasks(6)_0000000000E75880
2017-10-28T21:15:21.590401000  5 get  Read  0.2
Read_Write get queueing tasks(5)_0000000000E72270
2017-10-28T21:15:21.600438000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:21.649962000  4 NOK
2017-10-28T21:15:21.660056000  4 get  Read  0.2
Read_Write get queueing tasks(4)_0000000000E6EC60
2017-10-28T21:15:21.660107000  10 NOK
2017-10-28T21:15:21.670184000  10 get  Read  0.0
Read_Write get queueing tasks(10)_0000000000E830C0
2017-10-28T21:15:21.670203000  10 NOK
2017-10-28T21:15:21.670286000  3 NOK
2017-10-28T21:15:21.680277000  10 get  Read -0.1
Read_Write get queueing tasks(10)_0000000000E830C0
2017-10-28T21:15:21.680365000  3 get  Read  0.3
Read_Write get queueing tasks(3)_0000000000E6B650
2017-10-28T21:15:21.750125000  9 waited
2017-10-28T21:15:21.750140000  9 release
Last reader releases tasks(9)_0000000000E7FAB0
Another reader tasks(8)_0000000000E7C4A0
Another reader tasks(1)_0000000000E63F10
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:21.750191000  1 OK
2017-10-28T21:15:21.750202000  6 OK
Another reader tasks(5)_0000000000E72270
2017-10-28T21:15:21.750215000  6 waiting
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:21.750166000  8 OK
2017-10-28T21:15:21.750251000  5 OK
Another reader tasks(4)_0000000000E6EC60
2017-10-28T21:15:21.750264000  5 waiting
2017-10-28T21:15:21.750275000  4 OK
2017-10-28T21:15:21.750286000  2 OK
2017-10-28T21:15:21.750298000  2 waiting
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:21.750287000  4 waiting
2017-10-28T21:15:21.750254000  8 waiting
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:21.750353000  9 terminate
2017-10-28T21:15:21.750356000  3 OK
2017-10-28T21:15:21.750205000  1 waiting
2017-10-28T21:15:21.750381000  3 waiting
2017-10-28T21:15:21.750338000  10 OK
2017-10-28T21:15:21.750420000  10 waiting
2017-10-28T21:15:21.950478000  3 waited
2017-10-28T21:15:21.950503000  3 release
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:21.960583000  3 get  Read  0.0
Read_Write get queueing tasks(3)_0000000000E6B650
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:21.960607000  3 OK
2017-10-28T21:15:21.960615000  3 waiting
2017-10-28T21:15:22.150289000  6 waited
2017-10-28T21:15:22.150308000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:22.150351000  5 waited
2017-10-28T21:15:22.150361000  5 release
Reader releases tasks(5)_0000000000E72270
2017-10-28T21:15:22.150377000  2 waited
2017-10-28T21:15:22.150386000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:22.150411000  4 waited
2017-10-28T21:15:22.150425000  4 release
Reader releases tasks(4)_0000000000E6EC60
2017-10-28T21:15:22.150444000  8 waited
2017-10-28T21:15:22.150453000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:22.150488000  10 waited
2017-10-28T21:15:22.150498000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:22.160386000  5 get  Read  0.3
2017-10-28T21:15:22.160388000  6 get  Read  0.3
Read_Write get queueing tasks(5)_0000000000E72270
Another reader tasks(5)_0000000000E72270
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:22.160455000  2 get  Read  0.1
2017-10-28T21:15:22.160498000  4 get  Read  0.2
2017-10-28T21:15:22.160457000  6 OK
2017-10-28T21:15:22.160517000  6 waiting
Read_Write get queueing tasks(2)_0000000000E68040
2017-10-28T21:15:22.160433000  5 OK
2017-10-28T21:15:22.160542000  8 get  Read  0.0
2017-10-28T21:15:22.160547000  5 waiting
Another reader tasks(2)_0000000000E68040
Read_Write get queueing tasks(4)_0000000000E6EC60
Another reader tasks(4)_0000000000E6EC60
2017-10-28T21:15:22.160580000  2 OK
2017-10-28T21:15:22.160611000  4 OK
Read_Write get queueing tasks(8)_0000000000E7C4A0
2017-10-28T21:15:22.160578000  10 get  Read  0.4
2017-10-28T21:15:22.160624000  4 waiting
Another reader tasks(8)_0000000000E7C4A0
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:22.160615000  2 waiting
2017-10-28T21:15:22.160655000  8 OK
2017-10-28T21:15:22.160674000  10 OK
2017-10-28T21:15:22.160692000  8 waiting
2017-10-28T21:15:22.160702000  10 waiting
2017-10-28T21:15:22.250462000  1 waited
2017-10-28T21:15:22.250475000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:22.260551000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:22.260571000  1 OK
2017-10-28T21:15:22.260579000  1 waiting
2017-10-28T21:15:22.260775000  10 waited
2017-10-28T21:15:22.260785000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:22.270860000  10 get  Read -0.1
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:22.270879000  10 OK
2017-10-28T21:15:22.270887000  10 waiting
2017-10-28T21:15:22.360594000  6 waited
2017-10-28T21:15:22.360619000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:22.360646000  1 waited
2017-10-28T21:15:22.360658000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:22.360684000  4 waited
2017-10-28T21:15:22.360686000  3 waited
2017-10-28T21:15:22.360696000  4 release
Reader releases tasks(4)_0000000000E6EC60
2017-10-28T21:15:22.360706000  3 release
2017-10-28T21:15:22.360723000  4 terminate
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:22.360743000  2 waited
2017-10-28T21:15:22.360767000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:22.370699000  6 get  Read -0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:22.370720000  6 OK
2017-10-28T21:15:22.370728000  6 waiting
2017-10-28T21:15:22.370735000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:22.370754000  1 OK
2017-10-28T21:15:22.370762000  1 waiting
2017-10-28T21:15:22.370817000  3 get  Read  0.0
Read_Write get queueing tasks(3)_0000000000E6B650
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:22.370835000  3 OK
2017-10-28T21:15:22.370838000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:22.370843000  3 waiting
2017-10-28T21:15:22.370866000  2 OK
2017-10-28T21:15:22.370882000  2 waiting
2017-10-28T21:15:22.460633000  5 waited
2017-10-28T21:15:22.460653000  5 release
Reader releases tasks(5)_0000000000E72270
2017-10-28T21:15:22.460667000  5 terminate
2017-10-28T21:15:22.560780000  8 waited
2017-10-28T21:15:22.560798000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:22.570880000  8 get  Read  0.3
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:22.570902000  8 OK
2017-10-28T21:15:22.570911000  8 waiting
2017-10-28T21:15:22.570949000  2 waited
2017-10-28T21:15:22.570959000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:22.581035000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:22.581054000  2 OK
2017-10-28T21:15:22.581062000  2 waiting
2017-10-28T21:15:22.670800000  6 waited
2017-10-28T21:15:22.670856000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:22.680902000  6 get  Read  0.2
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:22.680930000  6 OK
2017-10-28T21:15:22.680938000  6 waiting
2017-10-28T21:15:22.770837000  1 waited
2017-10-28T21:15:22.770857000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:22.770938000  3 waited
2017-10-28T21:15:22.770939000  10 waited
2017-10-28T21:15:22.770951000  3 release
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:22.770965000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:22.780936000  1 get  Read  0.1
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:22.780975000  1 OK
2017-10-28T21:15:22.780983000  1 waiting
2017-10-28T21:15:22.781041000  3 get  Read  0.2
Read_Write get queueing tasks(3)_0000000000E6B650
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:22.781059000  10 get  Read  0.0
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:22.781059000  3 OK
2017-10-28T21:15:22.781092000  10 OK
2017-10-28T21:15:22.781102000  3 waiting
2017-10-28T21:15:22.781112000  10 waiting
2017-10-28T21:15:22.881010000  6 waited
2017-10-28T21:15:22.881023000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:22.891099000  6 get  Read  0.4
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:22.891118000  6 OK
2017-10-28T21:15:22.891126000  6 waiting
2017-10-28T21:15:22.981185000  3 waited
2017-10-28T21:15:22.981200000  3 release
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:22.991277000  3 get  Read  0.3
Read_Write get queueing tasks(3)_0000000000E6B650
Another reader tasks(3)_0000000000E6B650
2017-10-28T21:15:22.991297000  3 OK
2017-10-28T21:15:22.991305000  3 waiting
2017-10-28T21:15:23.070985000  8 waited
2017-10-28T21:15:23.071001000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.081054000  1 waited
2017-10-28T21:15:23.081066000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:23.081078000  8 get  Read  0.4
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.081098000  8 OK
2017-10-28T21:15:23.081106000  8 waiting
2017-10-28T21:15:23.081130000  2 waited
2017-10-28T21:15:23.081139000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:23.091142000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:23.091162000  1 OK
2017-10-28T21:15:23.091170000  1 waiting
2017-10-28T21:15:23.091220000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:23.091242000  2 OK
2017-10-28T21:15:23.091250000  2 waiting
2017-10-28T21:15:23.091369000  3 waited
2017-10-28T21:15:23.091379000  3 release
Reader releases tasks(3)_0000000000E6B650
2017-10-28T21:15:23.091391000  3 terminate
2017-10-28T21:15:23.181190000  10 waited
2017-10-28T21:15:23.181206000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:23.191284000  10 get  Read  0.4
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:23.191304000  10 OK
2017-10-28T21:15:23.191312000  10 waiting
2017-10-28T21:15:23.291193000  6 waited
2017-10-28T21:15:23.291207000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:23.291316000  2 waited
2017-10-28T21:15:23.291329000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:23.301282000  6 get  Read  0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:23.301302000  6 OK
2017-10-28T21:15:23.301310000  6 waiting
2017-10-28T21:15:23.301406000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:23.301442000  2 OK
2017-10-28T21:15:23.301450000  2 waiting
2017-10-28T21:15:23.381183000  8 waited
2017-10-28T21:15:23.381228000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.391314000  8 get  Read  0.2
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.391339000  8 OK
2017-10-28T21:15:23.391347000  8 waiting
2017-10-28T21:15:23.501526000  2 waited
2017-10-28T21:15:23.501556000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:23.511639000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:23.511663000  2 OK
2017-10-28T21:15:23.511671000  2 waiting
2017-10-28T21:15:23.591239000  1 waited
2017-10-28T21:15:23.591261000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:23.591417000  8 waited
2017-10-28T21:15:23.591432000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.601334000  1 get  Read  0.2
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:23.601356000  1 OK
2017-10-28T21:15:23.601365000  1 waiting
2017-10-28T21:15:23.601513000  8 get  Read  0.5
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:23.601535000  8 OK
2017-10-28T21:15:23.601544000  8 waiting
2017-10-28T21:15:23.691386000  10 waited
2017-10-28T21:15:23.691426000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:23.701508000  10 get  Read -0.1
Read_Write get queueing tasks(10)_0000000000E830C0
Another reader tasks(10)_0000000000E830C0
2017-10-28T21:15:23.701530000  10 OK
2017-10-28T21:15:23.701538000  10 waiting
2017-10-28T21:15:23.801385000  6 waited
2017-10-28T21:15:23.801402000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:23.811480000  6 get  Read  0.3
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:23.811501000  6 OK
2017-10-28T21:15:23.811509000  6 waiting
2017-10-28T21:15:23.901439000  1 waited
2017-10-28T21:15:23.901452000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:23.901611000  10 waited
2017-10-28T21:15:23.901623000  10 release
Reader releases tasks(10)_0000000000E830C0
2017-10-28T21:15:23.901637000  10 terminate
2017-10-28T21:15:23.911529000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:23.911553000  1 OK
2017-10-28T21:15:23.911561000  1 waiting
2017-10-28T21:15:23.911744000  2 waited
2017-10-28T21:15:23.911758000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:23.921835000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:23.921856000  2 OK
2017-10-28T21:15:23.921864000  2 waiting
2017-10-28T21:15:24.101621000  8 waited
2017-10-28T21:15:24.101640000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.111575000  6 waited
2017-10-28T21:15:24.111589000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:24.111717000  8 get  Read  0.3
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.111737000  8 OK
2017-10-28T21:15:24.111745000  8 waiting
2017-10-28T21:15:24.121665000  6 get  Read  0.2
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:24.121684000  6 OK
2017-10-28T21:15:24.121692000  6 waiting
2017-10-28T21:15:24.211634000  1 waited
2017-10-28T21:15:24.211658000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:24.221736000  6 waited
2017-10-28T21:15:24.221737000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:24.221767000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:24.221793000  1 OK
2017-10-28T21:15:24.221834000  1 waiting
2017-10-28T21:15:24.221931000  2 waited
2017-10-28T21:15:24.221941000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:24.231875000  6 get  Read  0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:24.231895000  6 OK
2017-10-28T21:15:24.231903000  6 waiting
2017-10-28T21:15:24.232011000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:24.232030000  2 OK
2017-10-28T21:15:24.232037000  2 waiting
2017-10-28T21:15:24.411815000  8 waited
2017-10-28T21:15:24.411839000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.421919000  8 get  Read -0.1
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.421940000  8 OK
2017-10-28T21:15:24.421948000  8 waiting
2017-10-28T21:15:24.431974000  6 waited
2017-10-28T21:15:24.431986000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:24.442064000  6 get  Read  0.3
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:24.442087000  6 OK
2017-10-28T21:15:24.442094000  6 waiting
2017-10-28T21:15:24.521907000  1 waited
2017-10-28T21:15:24.521922000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:24.531998000  1 get  Read  0.2
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:24.532018000  1 OK
2017-10-28T21:15:24.532026000  1 waiting
2017-10-28T21:15:24.532108000  2 waited
2017-10-28T21:15:24.532119000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:24.542201000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:24.542224000  2 OK
2017-10-28T21:15:24.542232000  2 waiting
2017-10-28T21:15:24.622024000  8 waited
2017-10-28T21:15:24.622040000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.632119000  8 get  Read  0.2
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.632139000  8 OK
2017-10-28T21:15:24.632147000  8 waiting
2017-10-28T21:15:24.832096000  1 waited
2017-10-28T21:15:24.832133000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:24.842170000  6 waited
2017-10-28T21:15:24.842188000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:24.842214000  1 get  Read -0.1
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:24.842235000  1 OK
2017-10-28T21:15:24.842243000  1 waiting
2017-10-28T21:15:24.852266000  6 get  Read  0.0
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:24.852287000  6 OK
2017-10-28T21:15:24.852295000  6 waiting
2017-10-28T21:15:24.932222000  8 waited
2017-10-28T21:15:24.932238000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.942304000  8 get  Read  0.5
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:24.942309000  2 waited
2017-10-28T21:15:24.942346000  8 OK
2017-10-28T21:15:24.942357000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:24.942367000  8 waiting
2017-10-28T21:15:24.952453000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:24.952480000  2 OK
2017-10-28T21:15:24.952488000  2 waiting
2017-10-28T21:15:25.052369000  6 waited
2017-10-28T21:15:25.052384000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:25.062461000  6 get  Read  0.4
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:25.062481000  6 OK
2017-10-28T21:15:25.062489000  6 waiting
2017-10-28T21:15:25.162556000  6 waited
2017-10-28T21:15:25.162575000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:25.172668000  6 get  Read -0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:25.172689000  6 OK
2017-10-28T21:15:25.172697000  6 waiting
2017-10-28T21:15:25.242313000  1 waited
2017-10-28T21:15:25.242329000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:25.252407000  1 get  Read  0.0
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:25.252428000  1 OK
2017-10-28T21:15:25.252436000  1 waiting
2017-10-28T21:15:25.342454000  8 waited
2017-10-28T21:15:25.342491000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.352573000  8 get  Read  0.4
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.352594000  8 OK
2017-10-28T21:15:25.352602000  8 waiting
2017-10-28T21:15:25.452564000  2 waited
2017-10-28T21:15:25.452584000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:25.452672000  8 waited
2017-10-28T21:15:25.452686000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.462663000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:25.462683000  2 OK
2017-10-28T21:15:25.462691000  2 waiting
2017-10-28T21:15:25.462762000  8 get  Read  0.2
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.462781000  8 OK
2017-10-28T21:15:25.462789000  8 waiting
2017-10-28T21:15:25.572774000  6 waited
2017-10-28T21:15:25.572789000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:25.582868000  6 get  Read  0.1
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:25.582889000  6 OK
2017-10-28T21:15:25.582897000  6 waiting
2017-10-28T21:15:25.662860000  8 waited
2017-10-28T21:15:25.662894000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.672970000  8 get  Read  0.5
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:25.672993000  8 OK
2017-10-28T21:15:25.673001000  8 waiting
2017-10-28T21:15:25.752510000  1 waited
2017-10-28T21:15:25.752531000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:25.762609000  1 get  Read  0.3
Read_Write get queueing tasks(1)_0000000000E63F10
Another reader tasks(1)_0000000000E63F10
2017-10-28T21:15:25.762630000  1 OK
2017-10-28T21:15:25.762638000  1 waiting
2017-10-28T21:15:25.862708000  1 waited
2017-10-28T21:15:25.862720000  1 release
Reader releases tasks(1)_0000000000E63F10
2017-10-28T21:15:25.862732000  1 terminate
2017-10-28T21:15:25.862767000  2 waited
2017-10-28T21:15:25.862783000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:25.872861000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:25.872882000  2 OK
2017-10-28T21:15:25.872890000  2 waiting
2017-10-28T21:15:26.073070000  8 waited
2017-10-28T21:15:26.073087000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:26.082972000  6 waited
2017-10-28T21:15:26.082988000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:26.083163000  8 get  Read  0.2
Read_Write get queueing tasks(8)_0000000000E7C4A0
Another reader tasks(8)_0000000000E7C4A0
2017-10-28T21:15:26.083181000  8 OK
2017-10-28T21:15:26.083189000  8 waiting
2017-10-28T21:15:26.093071000  6 get  Read  0.3
Read_Write get queueing tasks(6)_0000000000E75880
Another reader tasks(6)_0000000000E75880
2017-10-28T21:15:26.093095000  6 OK
2017-10-28T21:15:26.093103000  6 waiting
2017-10-28T21:15:26.172971000  2 waited
2017-10-28T21:15:26.172987000  2 release
Reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:26.183059000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:26.183080000  2 OK
2017-10-28T21:15:26.183106000  2 waiting
2017-10-28T21:15:26.383260000  8 waited
2017-10-28T21:15:26.383286000  8 release
Reader releases tasks(8)_0000000000E7C4A0
2017-10-28T21:15:26.383301000  8 terminate
2017-10-28T21:15:26.393182000  6 waited
2017-10-28T21:15:26.393198000  6 release
Reader releases tasks(6)_0000000000E75880
2017-10-28T21:15:26.393212000  6 terminate
2017-10-28T21:15:26.483178000  2 waited
2017-10-28T21:15:26.483208000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:26.493292000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:26.493316000  2 OK
2017-10-28T21:15:26.493325000  2 waiting
2017-10-28T21:15:26.993401000  2 waited
2017-10-28T21:15:26.993437000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:27.003520000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:27.003542000  2 OK
2017-10-28T21:15:27.003550000  2 waiting
2017-10-28T21:15:27.203619000  2 waited
2017-10-28T21:15:27.203647000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:27.213722000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:27.213746000  2 OK
2017-10-28T21:15:27.213754000  2 waiting
2017-10-28T21:15:27.513830000  2 waited
2017-10-28T21:15:27.513855000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:27.523934000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:27.523956000  2 OK
2017-10-28T21:15:27.523964000  2 waiting
2017-10-28T21:15:27.624041000  2 waited
2017-10-28T21:15:27.624061000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:27.634138000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:27.634166000  2 OK
2017-10-28T21:15:27.634175000  2 waiting
2017-10-28T21:15:28.034250000  2 waited
2017-10-28T21:15:28.034286000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:28.044367000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:28.044390000  2 OK
2017-10-28T21:15:28.044398000  2 waiting
2017-10-28T21:15:28.144463000  2 waited
2017-10-28T21:15:28.144477000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:28.154554000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:28.154574000  2 OK
2017-10-28T21:15:28.154582000  2 waiting
2017-10-28T21:15:28.554654000  2 waited
2017-10-28T21:15:28.554694000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:28.564788000  2 get  Read  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:28.564809000  2 OK
2017-10-28T21:15:28.564817000  2 waiting
2017-10-28T21:15:28.964892000  2 waited
2017-10-28T21:15:28.964930000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:28.975011000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:28.975033000  2 OK
2017-10-28T21:15:28.975041000  2 waiting
2017-10-28T21:15:29.375116000  2 waited
2017-10-28T21:15:29.375152000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:29.385233000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:29.385256000  2 OK
2017-10-28T21:15:29.385264000  2 waiting
2017-10-28T21:15:29.585340000  2 waited
2017-10-28T21:15:29.585369000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:29.595450000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:29.595472000  2 OK
2017-10-28T21:15:29.595499000  2 waiting
2017-10-28T21:15:29.995580000  2 waited
2017-10-28T21:15:29.995616000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:30.005699000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:30.005720000  2 OK
2017-10-28T21:15:30.005728000  2 waiting
2017-10-28T21:15:30.405807000  2 waited
2017-10-28T21:15:30.405841000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:30.415924000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:30.415949000  2 OK
2017-10-28T21:15:30.415957000  2 waiting
2017-10-28T21:15:30.916029000  2 waited
2017-10-28T21:15:30.916066000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:30.926148000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:30.926170000  2 OK
2017-10-28T21:15:30.926178000  2 waiting
2017-10-28T21:15:31.026251000  2 waited
2017-10-28T21:15:31.026271000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:31.036349000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:31.036370000  2 OK
2017-10-28T21:15:31.036378000  2 waiting
2017-10-28T21:15:31.436457000  2 waited
2017-10-28T21:15:31.436496000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:31.446579000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:31.446603000  2 OK
2017-10-28T21:15:31.446611000  2 waiting
2017-10-28T21:15:31.746681000  2 waited
2017-10-28T21:15:31.746717000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:31.756798000  2 get  Read  0.5
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:31.756820000  2 OK
2017-10-28T21:15:31.756828000  2 waiting
2017-10-28T21:15:32.056900000  2 waited
2017-10-28T21:15:32.056916000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.066994000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:32.067014000  2 OK
2017-10-28T21:15:32.067022000  2 waiting
2017-10-28T21:15:32.167094000  2 waited
2017-10-28T21:15:32.167110000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.177187000  2 get Write  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Writer has got lock tasks(2)_0000000000E68040
2017-10-28T21:15:32.177207000  2 OK
2017-10-28T21:15:32.177214000  2 waiting
2017-10-28T21:15:32.477286000  2 waited
2017-10-28T21:15:32.477325000  2 release
Writer releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.487402000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:32.487424000  2 OK
2017-10-28T21:15:32.487432000  2 waiting
2017-10-28T21:15:32.687509000  2 waited
2017-10-28T21:15:32.687547000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.697628000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:32.697651000  2 OK
2017-10-28T21:15:32.697659000  2 waiting
2017-10-28T21:15:32.897731000  2 waited
2017-10-28T21:15:32.897745000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:32.907822000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:32.907842000  2 OK
2017-10-28T21:15:32.907850000  2 waiting
2017-10-28T21:15:33.307919000  2 waited
2017-10-28T21:15:33.307952000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:33.318032000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:33.318071000  2 OK
2017-10-28T21:15:33.318080000  2 waiting
2017-10-28T21:15:33.718160000  2 waited
2017-10-28T21:15:33.718215000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:33.728307000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:33.728329000  2 OK
2017-10-28T21:15:33.728337000  2 waiting
2017-10-28T21:15:34.228412000  2 waited
2017-10-28T21:15:34.228445000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:34.238526000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:34.238548000  2 OK
2017-10-28T21:15:34.238556000  2 waiting
2017-10-28T21:15:34.538629000  2 waited
2017-10-28T21:15:34.538647000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:34.548728000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:34.548752000  2 OK
2017-10-28T21:15:34.548761000  2 waiting
2017-10-28T21:15:34.948840000  2 waited
2017-10-28T21:15:34.948878000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:34.958963000  2 get Write  0.2
Read_Write get queueing tasks(2)_0000000000E68040
Writer has got lock tasks(2)_0000000000E68040
2017-10-28T21:15:34.958987000  2 OK
2017-10-28T21:15:34.958995000  2 waiting
2017-10-28T21:15:35.259070000  2 waited
2017-10-28T21:15:35.259088000  2 release
Writer releases tasks(2)_0000000000E68040
2017-10-28T21:15:35.269165000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:35.269186000  2 OK
2017-10-28T21:15:35.269194000  2 waiting
2017-10-28T21:15:35.569274000  2 waited
2017-10-28T21:15:35.569311000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:35.579396000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:35.579420000  2 OK
2017-10-28T21:15:35.579428000  2 waiting
2017-10-28T21:15:35.879506000  2 waited
2017-10-28T21:15:35.879541000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:35.889623000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:35.889644000  2 OK
2017-10-28T21:15:35.889652000  2 waiting
2017-10-28T21:15:36.189721000  2 waited
2017-10-28T21:15:36.189744000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:36.199823000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:36.199844000  2 OK
2017-10-28T21:15:36.199852000  2 waiting
2017-10-28T21:15:36.599930000  2 waited
2017-10-28T21:15:36.599964000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:36.610050000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:36.610076000  2 OK
2017-10-28T21:15:36.610084000  2 waiting
2017-10-28T21:15:37.010162000  2 waited
2017-10-28T21:15:37.010200000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:37.020282000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:37.020305000  2 OK
2017-10-28T21:15:37.020313000  2 waiting
2017-10-28T21:15:37.420390000  2 waited
2017-10-28T21:15:37.420417000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:37.430498000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:37.430519000  2 OK
2017-10-28T21:15:37.430527000  2 waiting
2017-10-28T21:15:37.730596000  2 waited
2017-10-28T21:15:37.730633000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:37.740713000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:37.740754000  2 OK
2017-10-28T21:15:37.740762000  2 waiting
2017-10-28T21:15:38.140840000  2 waited
2017-10-28T21:15:38.140862000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:38.150942000  2 get  Read  0.5
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:38.150963000  2 OK
2017-10-28T21:15:38.150972000  2 waiting
2017-10-28T21:15:38.551046000  2 waited
2017-10-28T21:15:38.551084000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:38.561169000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:38.561193000  2 OK
2017-10-28T21:15:38.561201000  2 waiting
2017-10-28T21:15:38.761271000  2 waited
2017-10-28T21:15:38.761315000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:38.771407000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:38.771429000  2 OK
2017-10-28T21:15:38.771437000  2 waiting
2017-10-28T21:15:39.171511000  2 waited
2017-10-28T21:15:39.171539000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:39.181620000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:39.181645000  2 OK
2017-10-28T21:15:39.181653000  2 waiting
2017-10-28T21:15:39.381735000  2 waited
2017-10-28T21:15:39.381777000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:39.391859000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:39.391881000  2 OK
2017-10-28T21:15:39.391889000  2 waiting
2017-10-28T21:15:39.691968000  2 waited
2017-10-28T21:15:39.692008000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:39.702089000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:39.702111000  2 OK
2017-10-28T21:15:39.702119000  2 waiting
2017-10-28T21:15:40.002188000  2 waited
2017-10-28T21:15:40.002214000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:40.012293000  2 get Write  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Writer has got lock tasks(2)_0000000000E68040
2017-10-28T21:15:40.012314000  2 OK
2017-10-28T21:15:40.012322000  2 waiting
2017-10-28T21:15:40.412390000  2 waited
2017-10-28T21:15:40.412415000  2 release
Writer releases tasks(2)_0000000000E68040
2017-10-28T21:15:40.422496000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:40.422517000  2 OK
2017-10-28T21:15:40.422525000  2 waiting
2017-10-28T21:15:40.822601000  2 waited
2017-10-28T21:15:40.822637000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:40.832719000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:40.832741000  2 OK
2017-10-28T21:15:40.832749000  2 waiting
2017-10-28T21:15:41.132824000  2 waited
2017-10-28T21:15:41.132845000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:41.142924000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:41.142945000  2 OK
2017-10-28T21:15:41.142953000  2 waiting
2017-10-28T21:15:41.443034000  2 waited
2017-10-28T21:15:41.443077000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:41.453160000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:41.453184000  2 OK
2017-10-28T21:15:41.453192000  2 waiting
2017-10-28T21:15:41.753267000  2 waited
2017-10-28T21:15:41.753306000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:41.763387000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:41.763426000  2 OK
2017-10-28T21:15:41.763434000  2 waiting
2017-10-28T21:15:41.863510000  2 waited
2017-10-28T21:15:41.863525000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:41.873605000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:41.873629000  2 OK
2017-10-28T21:15:41.873637000  2 waiting
2017-10-28T21:15:42.273708000  2 waited
2017-10-28T21:15:42.273741000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:42.283819000  2 get  Read  0.3
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:42.283844000  2 OK
2017-10-28T21:15:42.283853000  2 waiting
2017-10-28T21:15:42.583929000  2 waited
2017-10-28T21:15:42.583954000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:42.594034000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:42.594056000  2 OK
2017-10-28T21:15:42.594065000  2 waiting
2017-10-28T21:15:42.794142000  2 waited
2017-10-28T21:15:42.794182000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:42.804264000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:42.804287000  2 OK
2017-10-28T21:15:42.804296000  2 waiting
2017-10-28T21:15:43.104374000  2 waited
2017-10-28T21:15:43.104400000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:43.114481000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:43.114504000  2 OK
2017-10-28T21:15:43.114513000  2 waiting
2017-10-28T21:15:43.314585000  2 waited
2017-10-28T21:15:43.314605000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:43.324684000  2 get  Read  0.0
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:43.324707000  2 OK
2017-10-28T21:15:43.324715000  2 waiting
2017-10-28T21:15:43.724984000  2 waited
2017-10-28T21:15:43.725023000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:43.735103000  2 get  Read -0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:43.735134000  2 OK
2017-10-28T21:15:43.735143000  2 waiting
2017-10-28T21:15:44.035217000  2 waited
2017-10-28T21:15:44.035255000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.045346000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.045369000  2 OK
2017-10-28T21:15:44.045377000  2 waiting
2017-10-28T21:15:44.245450000  2 waited
2017-10-28T21:15:44.245471000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.255551000  2 get  Read  0.5
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.255574000  2 OK
2017-10-28T21:15:44.255582000  2 waiting
2017-10-28T21:15:44.355662000  2 waited
2017-10-28T21:15:44.355703000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.365786000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.365812000  2 OK
2017-10-28T21:15:44.365821000  2 waiting
2017-10-28T21:15:44.565899000  2 waited
2017-10-28T21:15:44.565930000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.576016000  2 get  Read  0.1
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.576041000  2 OK
2017-10-28T21:15:44.576050000  2 waiting
2017-10-28T21:15:44.876120000  2 waited
2017-10-28T21:15:44.876158000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:44.886240000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:44.886281000  2 OK
2017-10-28T21:15:44.886290000  2 waiting
2017-10-28T21:15:45.186362000  2 waited
2017-10-28T21:15:45.186384000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:45.196462000  2 get  Read  0.4
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:45.196483000  2 OK
2017-10-28T21:15:45.196492000  2 waiting
2017-10-28T21:15:45.296562000  2 waited
2017-10-28T21:15:45.296585000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:45.306664000  2 get  Read  0.5
Read_Write get queueing tasks(2)_0000000000E68040
Another reader tasks(2)_0000000000E68040
2017-10-28T21:15:45.306685000  2 OK
2017-10-28T21:15:45.306693000  2 waiting
2017-10-28T21:15:45.706766000  2 waited
2017-10-28T21:15:45.706804000  2 release
Last reader releases tasks(2)_0000000000E68040
2017-10-28T21:15:45.706821000  2 terminate
2017-10-28T21:15:50.729534000 Main Deadlock detected, aborting
2017-10-28T21:15:50.729586000 Main Done

Task 7 did not terminate.
Last report of it was "21:15:21.149875000  7 get  Read  0.2"
At this time, 1 has got the lock for read, 3 is requesting it for write and
the other tasks are queueing for read or write (7 is queueing for read).
When 1 releases the lock: 017-10-28T21:15:21.349976000  1 release
the log of swapping shows that task 4, requesting for write, triggers the
swapping: Start swapping tasks(4)_0000000000E6EC60
At that time, all the queueing tasks are logged as being swapped except 7,
and task 7 seems to be blocked somewhere and is never activated.

Can you reproduce it? On Windows?
Is the bug in the test program, or in the mutex implementation, in Linux, or in Gnat?

Thanks

^ permalink raw reply	[relevance 1%]

* Re: Passing a 2d array into a package and returning the same processed 2d back to main
  @ 2016-10-05 17:19  3%           ` James Brewer
  0 siblings, 0 replies; 200+ results
From: James Brewer @ 2016-10-05 17:19 UTC (permalink / raw)



Well, I thought it worked by I'm just getting 1's for the output.

I'll post the new code if you all are still interested in helping me out.

                 -- Interface of WarshallsPkg

PACKAGE WarshallsPkg IS

   TYPE MY_ARRAY IS ARRAY(INTEGER RANGE <>, INTEGER RANGE <>) OF Boolean;

   PROCEDURE WarshallExecute(Arr : IN OUT MY_ARRAY);

end WarshallsPkg;

                 -- Implementation of WarshallsPkg

PACKAGE BODY WarshallsPkg IS
   PROCEDURE WarshallExecute(Arr : IN OUT My_Array) IS
   BEGIN
      FOR I IN Arr'RANGE LOOP
         FOR J IN Arr'RANGE LOOP
            IF Arr(J,I) THEN --true nodes connected
               FOR K IN Arr'RANGE LOOP
                  Arr(J,K) := Arr(J,K) OR Arr(I,K);
               END LOOP;
            END IF;
         END LOOP;
      END LOOP;
   END WarshallExecute;
END WarshallsPkg;

-- Lab 1 C version read and write to file use package
-- Programmed by James Brewer
-- Version 12

--put this in every program for now
--WITH Ada.Command_Line;
WITH Text_IO; USE Text_IO; -- This gets the IO facility.
WITH Ada.Integer_Text_IO; USE Ada.Integer_Text_IO; -- This gets the integer IO facility.
WITH WarshallsPkg; USE WarshallsPkg; --package setup


-- * main procedure *
PROCEDURE WarshallsMain IS

   Input : File_Type; -- input file declaration
   Output : File_Type; -- output file declaration
   N : Integer := 9; -- max size of array -- why does this overflow if not set?
   YOrN : String(1..1); -- y or n for node connections
   OutputConvertion : Integer; -- used for conversion from true/false to 1/0

   TestString : String(1..1);

-- highlight section in code that creates the array
--   Array2d: ARRAY (1..N, 1..N) OF Boolean; --****** highlight this section ********
   Array2d: WarshallsPkg.MY_ARRAY(1..N,   1..N);



-- * main procedure starts begins*
BEGIN
-- try to use io redirection to pull data from file
-- open input.txt file
   Open (File => Input,
         Mode => In_File,
         Name => "input.txt");


-- output to file creation section
   Create (File => Output,
      Mode => Out_File,
      Name => "output.txt");

-- input node connection data collection
   -- ask for size of array
   Put("How many nodes need to be processed? ");
   TestString := Get_Line (Input); -- get number of nodes
   N := Integer'Value(TestString); -- convert number of nodes to Integer
   put(N); -- display n on screen
--   Get(N); -- ** not used
   New_Line(2);

   FOR X IN 1..N LOOP
      FOR Y IN 1..N LOOP
         Put("Is node");
         Put(X);
         Put(" connected to node ");
         Put(Y);
         Put(" y/n ");
         YOrN := Get_Line(Input);
 --        Get(YOrN); -- ** not used
         put(YOrN); new_line(1); -- display choice on screen
         if yOrN = "y" then
            Array2d(X,Y) := True;
         ELSE Array2d(X,Y) := False;
         END IF;
      END LOOP;
   END LOOP;


-- Warshallpkg implementation

   WarshallExecute(Array2d);
--      FOR I IN 1..N LOOP
--      FOR J IN 1..N LOOP
--         IF Array2d(J,I) = True THEN --true nodes connected
--            FOR K IN 1..N LOOP
--               Array2d(J,K) := Array2d(J,K) OR Array2d(I,K);
--            END LOOP;
--         END IF;
--      END LOOP;
--   END LOOP;


-- print each transaction as it is processed

-- *********** output to file ************

-- column label output
   New_Line(Output, 2);
   Put(Output, "           ");
   FOR I IN 1..N LOOP
      Put(Output, I);
   END LOOP;
   New_Line(Output, 1);

-- data matrix output
   FOR I IN 1..N LOOP
      Put(Output, I);
      FOR J IN 1..N LOOP
         IF Array2d(I,J) = True THEN
            OutputConvertion := 1;
         ELSE
            OutputConvertion := 0;
         END IF;
         Put(Output, OutputConvertion);
      END LOOP;
      New_Line(Output, 1);
   END LOOP;

--close files
   Close (Input);
   Close (Output);
exception
   when End_Error =>
      if Is_Open(Input) then
         Close (Input);
      end if;
      if Is_Open(Output) then
         Close (Output);
      end if;

END WarshallsMain;
-- * main procedure ends *


^ permalink raw reply	[relevance 3%]

* Re: New to Ada need help implementing Warshall's algorithm
  2016-09-25 16:06  7%       ` Stephen Leake
@ 2016-09-26 20:40  6%         ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2016-09-26 20:40 UTC (permalink / raw)


Stephen Leake <stephen_leake@stephe-leake.org> writes:

> On Friday, September 23, 2016 at 10:07:53 AM UTC-5, James Brewer wrote:
>> 
>> It is three diffent sets of data. I think I may try to simplify the
>> input data to a 0,1 2d array for each set, read the set in and then
>> process each set writing it to an output file (the last two I will
>> have to figure out).
>
> Here's a working program that does the IO, to get you started. It
> reads from a file, writes to standard out.

And here's a different one, which works out the size of the matrix by
finding the number of unique names in the input. The structure supports
strings for names, but the implementation only handles single-character
names because I was being lazy.

Input:
e b
a b
b c
b d
d a
d e
c e

Output:
a  3
b  2
c  4
d  5
e  1
01000
00011
01000
10000
10100

Code:
with Ada.Command_Line;
with Ada.Containers.Indefinite_Ordered_Maps;
with Ada.Text_IO; use Ada.Text_IO;

procedure Brewer is

   File : File_Type;

   package Names_To_Indices
     is new Ada.Containers.Indefinite_Ordered_Maps (String, Positive);
   Names : Names_To_Indices.Map;

   procedure Add_If_New (Name : String)
   is
      use type Ada.Containers.Count_Type;
   begin
      if not Names.Contains (Name) then
         Names.Insert (Name, Positive (Names.Length + 1));
      end if;
   end Add_If_New;

begin

   Open (File, In_File, Ada.Command_Line.Argument (1));
   --  each line is to have format Name_1 Name_2, implying there is a
   --  path from Name_1 to Name_2.

   loop
      begin
         declare
            Line : constant String := Get_Line (File);
         begin
            --  I'm being lazy here and assuming single-character Names.
            Add_If_New (Line (1 .. 1));
            Add_If_New (Line (3 .. 3));
         end;
      exception
         when others => exit;
      end;
   end loop;
   Reset (File);

   --  output name-to-index (ordered by name, not index, sorry)
   for J in Names.Iterate loop
      Put_Line (Names_To_Indices.Key (J)
                  & " "
                  & Names_To_Indices.Element (J)'Img);
   end loop;

   --  now we know the size of the matrix
   declare
      Size : constant Positive := Positive (Names.Length);
      Matrix : array (1 .. Size, 1 .. Size) of Boolean
        := (others => (others => False));
   begin
      --  populate the matrix
      loop
         begin
            declare
               Line : constant String   := Get_Line (File);
               From : constant Positive := Names.Element (Line (1 .. 1));
               To   : constant Positive := Names.Element (Line (3 .. 3));
            begin
               Matrix (From, To) := True;
            end;
         exception
            when others => exit;
         end;
      end loop;
      Close (File);

      --  dump the matrix
      for J in Matrix'Range (1) loop
         for K in Matrix'Range (2) loop
            Put (if Matrix (J, K) then '1' else '0');
         end loop;
         New_Line;
      end loop;
   end;

end Brewer;


^ permalink raw reply	[relevance 6%]

* Re: New to Ada need help implementing Warshall's algorithm
  @ 2016-09-25 16:06  7%       ` Stephen Leake
  2016-09-26 20:40  6%         ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: Stephen Leake @ 2016-09-25 16:06 UTC (permalink / raw)


On Friday, September 23, 2016 at 10:07:53 AM UTC-5, James Brewer wrote:
> 
> It is three diffent sets of data. I think I may try to simplify the input data to a 0,1 2d array for each set, read the set in and then process each set writing it to an output file (the last two I will have to figure out).

Here's a working program that does the IO, to get you started. It reads from a file, writes to standard out.

Reading the entire input line from the file, then processing it, simplifies debugging.

with Ada.Command_Line;
with Ada.Text_IO; use Ada.Text_IO;
procedure Warshall
is
   procedure Put_Usage
   is
   begin
      Put_Line ("Usage: warshall <input file name>");
   end Put_Usage;

   File : File_Type;
begin
   Open (File, In_File, Ada.Command_Line.Argument (1));

   loop
      exit when End_Of_File (File);

      declare
         Line : constant String := Get_Line (File);
         --  Each line should have format 'A B' where, A, B => 1 | 0
         A : Boolean;
         B : Boolean;
      begin
         if Line (1) = '0' then
            A := False;
         else
            A := True;
         end if;

         if Line (3) = '0' then
            B := False;
         else
            B := True;
         end if;

         --  FIXME: implement warshall's algorithm

         Put_Line ("A, B: " & Boolean'Image (A) & " " & Boolean'Image (B));
      end;
   end loop;
end Warshall;

given an input file:

0 1
1 0

this produces:

A, B: FALSE TRUE
A, B: TRUE FALSE

I'm happy to hear about an instructor using Ada to teach algorithms!

-- Stephe

^ permalink raw reply	[relevance 7%]

* Re: Ada.Strings.Fixed.Count raises Storage_Error
  @ 2016-06-28 18:25  5%           ` Xavier Petit
  0 siblings, 0 replies; 200+ results
From: Xavier Petit @ 2016-06-28 18:25 UTC (permalink / raw)


Le 27/06/2016 à 06:48, rieachus@comcast.net a écrit :
> On Sunday, June 26, 2016 at 8:51:21 PM UTC-4, Xavier Petit wrote:
>
>> Every parameters of a subprogram should be anticipated and produce a
>> coherent behavior. It’s hard but Ada is especially here to make it easier.
>
> Gödel, Escher, Bach: An Eternal Golden Braid, is a 1979 book by Douglas Hofstadter that is now in its 20th edition.
>
> It tries, among other things to explain the reality revealed by Gödel's proofs.  One of those consequences is that you can't build a perfect compiler.  In fact, the gnat in Ada Core Technologies logo is a cute reminder that every compiler must have at least one bug.  Not, these things are so complex they can never be perfect, but even some very simple software tools are subject to Gödel's findings--no system above a rudimentary complexity (embedding of Peano arithmetic) can be bug-free.
>
> Worse, the Halting Problem is a very simple proof that you cannot write a program that will perfectly determine whether a given software program will halt.  (Or not halt, if you work on embedded systems like I did.)
>
> So trying for perfection in compilers, programming languages, and even many software programs is a mug's game.  You can't do it, you don't know where other corner cases are, and you can't even document all of the bugs.  Yes, it is possible to "prove" software correctness for some programs.  But for those same programs, you have just moved the target, from perfect software to perfect requirements.
>
> The Airbus 320 had a major software bug in spite of the correctness proof tools used.  If a plane cross the last waypoint before the destination, the flight guidance system would put the airplane in the correct glidepath for the chosen runway as quickly as possible, even if that location was under a few thousand feet of granite.  Strasbourg suddenly dove straight down.  Oops! Perfect software implementation of a bad requirement. (https://www.flightglobal.com/news/articles/air-france-ceo-jean-cyril-spinetta-defends-rejection-of-gpws-equipment-on-air-inter-a320-fleet-despite-fatal-1992-st-odile-mountainside-crash-210280/ The obfuscation thrown about by Airbus and the French government still continues.  But at least the bug in "flight path angle mode" in the flight controller got fixed.  This list will show you why I still won't fly on an Airbus 310,20, or 21: https://en.wikipedia.org/wiki/Accidents_and_incidents_involving_the_Airbus_A320_family )
>
>

Thank you for the very interesting informations and explanations, I 
think I understand.

After tests, as you said the performance penalty is very important (from 
5 to 33% depending optimization options) if we do the test inside the loop.

But this is not only a special case, it’s a unique case, so the source 
code solution should be something like :

if Source'Last = Positive'Last and then Pattern'Length = 1 then
     return Boolean'Pos (Source (Source'Last) = Pattern (Pattern'First));
end if;

inserted between the empty pattern exception and the loops of Count.

A function “Count_Wrapper” that has the specification of 
Ada.Strings.Fixed.Count and code :

if Source'Last = Positive'Last and then Pattern'Length = 1 then
    return Boolean'Pos (Source (Source'Last) = Pattern (Pattern'First));
else
    return Ada.Strings.Fixed.Count (Source, Pattern, Mapping);
end if;

On intel64 & cortex A7 (raspberry pi 2), with(out) options, this 
function called with Ada.Command_Line.Argument (1) pattern and hundred 
millions of random size strings sources has no big overhead.

Do you think those unique and limit cases are worth a modification ?

-- 
Xavier Petit


^ permalink raw reply	[relevance 5%]

* An extra CR character when writing to file (in addition to CR LF)
@ 2016-06-05 23:26  7% John Smith
  0 siblings, 0 replies; 200+ results
From: John Smith @ 2016-06-05 23:26 UTC (permalink / raw)


Here is my little example.  The problem that I have with it is that when it comes time to writing to the output file, the newline characters for some reason are CR CR LF.  I'm working in Windows, so I don't understand why I have the extra carriage return.

======================================================================

with Ada.Text_IO.Unbounded_IO;
with Ada.Strings.Unbounded;
with Ada.Command_Line;
with Ada.Directories;
with Ada.Direct_IO;
with Ada.Text_IO;

procedure stuff is
  Original_File : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.To_Unbounded_String(
    Source => "");

  procedure Manipulate_Contents(
    Contents : in out Ada.Strings.Unbounded.Unbounded_String) is

  begin
    Ada.Strings.Unbounded.Append(Contents, "    A hello!");
  end Manipulate_Contents;

  procedure Write_File(
    Contents  : in out Ada.Strings.Unbounded.Unbounded_String;
    File_Name : in Ada.Strings.Unbounded.Unbounded_String) is

    New_File : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.To_Unbounded_String(
      Source => "");

    F_Type : Ada.Text_IO.File_Type;
  begin
    Ada.Text_IO.Put("Enter the name of the new file: ");
    New_File := Ada.Text_IO.Unbounded_IO.Get_Line;

    begin
      Ada.Text_IO.Open(
        File => F_Type,
        Mode => Ada.Text_IO.Out_File,
        Name => Ada.Strings.Unbounded.To_String(New_File));
    exception
      when Ada.Text_IO.Name_Error =>
        Ada.Text_IO.Create(
          File => F_Type,
          Mode => Ada.Text_IO.Out_File,
          Name => Ada.Strings.Unbounded.To_String(New_File));
    end;

    Ada.Text_IO.Put(
      File => F_Type,
      Item => Ada.Strings.Unbounded.To_String(Contents));

    Ada.Text_IO.Close(
      File => F_Type);
  end Write_File;
begin
  if Ada.Command_Line.Argument_Count = 1
  then
    Original_File := Ada.Strings.Unbounded.To_Unbounded_String(Ada.Command_Line.Argument(1));
  else
    Ada.Text_IO.Put_Line(
      File => Ada.Text_IO.Standard_Error,
      Item => "ERROR: Incorrect number of command line arguments passed in.");

    return;
  end if;

  declare
    File_Size : Natural := Natural(Ada.Directories.Size(Ada.Strings.Unbounded.To_String(Original_File)));

    subtype File_String    is String(1 .. File_Size);
    package File_String_IO is new Ada.Direct_IO(File_String);

    F_Type        : File_String_IO.File_Type;
    File_Contents : File_String;

    U_File_Contents : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.To_Unbounded_String("");
  begin
    File_String_IO.Open(
      File => F_Type,
      Mode => File_String_IO.In_File,
      Name => Ada.Strings.Unbounded.To_String(Original_File));

    File_String_IO.Read(
      File => F_Type,
      Item => File_Contents);

    File_String_IO.Close(
      File => F_Type);

    U_File_Contents := Ada.Strings.Unbounded.To_Unbounded_String(File_Contents);

    Manipulate_Contents(
      Contents => U_File_Contents);

    Write_File(
      Contents => U_File_Contents,
      File_Name => Original_File);
  exception
    when Ada.Text_IO.Name_Error =>
      Ada.Text_IO.Put_Line(Ada.Text_IO.Standard_Error, "ERROR:Name_Error: The file does not exist.  Exiting.");

      return;
    when Ada.Text_IO.Status_Error =>
      Ada.Text_IO.Put_Line(Ada.Text_IO.Standard_Error, "ERROR:Status_Error: The file does not exist.  Exiting.");

      return;
    when Ada.Text_IO.Use_Error =>
      Ada.Text_IO.Put_Line(Ada.Text_IO.Standard_Error, "ERROR:Use_Error: The file does not exist.  Exiting.");

      return;
    when others =>
      Ada.Text_IO.Put_Line(Ada.Text_IO.Standard_Error, "Error encountered, exiting.");

      return;
  end;
end stuff;

======================================================================


^ permalink raw reply	[relevance 7%]

* GNAT.Command_Line and -?
@ 2016-04-30 20:49  8% rrr.eee.27
  0 siblings, 0 replies; 200+ results
From: rrr.eee.27 @ 2016-04-30 20:49 UTC (permalink / raw)


In a new project I'd like to use some command line parameters. Among others I have defined:

with GNAT.Command_Line;            use GNAT.Command_Line;

...

Cfg_Pub : Command_Line_Configuration;

...

Define_Switch (Cfg_Pub, Server_Name_Text'Access, "-h:",
               Long_Switch => "--host=",
               Argument    => "FQN|IP",
               Help        => "server name or IP address (default: localhost).");

...

Define_Switch (Cfg_Pub, "-?", Long_Switch => "--help", Help => "show this text");


Using "-?" as a Switch always raises the exception Invalid_Switch. This is probably due to the question mark serving as an indicator of an optional argument.  I don't want to use "-h" for help as that is already used for the host parameter.

Is there a way to define -? as a valid command line option without returning to Ada.Command_Line?

regards
    Rolf 


^ permalink raw reply	[relevance 8%]

* Re: Building an encapsulated library that uses GNAT sockets under Windows
  2016-04-22  8:23  0%   ` Dmitry A. Kazakov
@ 2016-04-23  9:20  0%     ` Ahlan
  0 siblings, 0 replies; 200+ results
From: Ahlan @ 2016-04-23  9:20 UTC (permalink / raw)


On Friday, 22 April 2016 10:23:31 UTC+2, Dmitry A. Kazakov  wrote:
> On 22/04/2016 09:58, ahlan@marriott.org wrote:
> > On Thursday, 21 April 2016 15:00:04 UTC+2, Dmitry A. Kazakov  wrote:
> >> It seems I finally found a way to build it. The solution is quite
> >> perplexing. I would be glad if anybody could shed some light on it.
> >>
> >> An encapsulated library requires that -lws2_32 -lwsock32 appeared *both*
> >> at the beginning and the end of the linker command line. Only then no
> >> "undefined reference" messages appear.
> >>
> >> For this build this program:
> >> --------------------------------------- gcc_wrapper.adb ---
> >> with Ada.Command_Line;  use Ada.Command_Line;
> >> with Ada.Exceptions;    use Ada.Exceptions;
> >> with Ada.Text_IO;       use Ada.Text_IO;
> >> with GNAT.OS_Lib;       use GNAT.OS_Lib;
> >>
> >> procedure GCC_Wrapper is
> >>      Prefix : String_List :=
> >>               (  new String'("-lwsock32"),
> >>                  new String'("-lws2_32")
> >>               );
> >>      Options : String_List (1..Argument_Count);
> >> begin
> >>      for No in 1..Argument_Count loop
> >>         Options (No) := new String'(Argument (No));
> >>      end loop;
> >>      declare
> >>         List : String_List := Prefix & Options & Prefix;
> >>      begin
> >>         Put ("gcc.exe");
> >>         for No in List'Range loop
> >>            Put (" " & List (No).all);
> >>         end loop;
> >>         New_Line;
> >>         Set_Exit_Status (Exit_Status (Spawn ("gcc.exe", List)));
> >>      end;
> >> exception
> >>      when Error : others =>
> >>         Put_Line
> >>         (  Standard_Error,
> >>            "Fault: " & Exception_Information (Error)
> >>         );
> >>         Set_Exit_Status (2);
> >> end GCC_Wrapper;
> >> --------------------------------------- gcc_wrapper.adb ---
> >>
> >> The project file must contain:
> >>
> >>      package Linker is
> >>         for Driver use "<absolute-path-to>/gcc_wrapper.exe";
> >>      end Linker;
> >>
> >> --
> >> Regards,
> >> Dmitry A. Kazakov
> >> http://www.dmitry-kazakov.de
> >
> > Dear Dmitry,
> >
> > Is this perhaps the solution to my question "Using Gnat.Sockets in a Windows DLL" that I posted on 8-Dec-2015?
> 
> Yes, I think it is the same problem you reported. BTW, I built gprbuild 
> from the latest Git sources. That did not fix the problem.
> 
> It looks really weird how GCC linker searches libraries under Windows. 
> Not to mention its abysmal performance. It takes literally an hour to 
> link an executable against 20-30 libraries.
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

Dear Dmitry,
The problem is not in Gprbuild.exe but in libexe/gprbuild/gprlib.exe
Have you tried building Gprlib from the git sources? - that might be a more elegant solution.

MfG
Ahlan

^ permalink raw reply	[relevance 0%]

* Re: Building an encapsulated library that uses GNAT sockets under Windows
  2016-04-22  7:58  0% ` ahlan.marriott
@ 2016-04-22  8:23  0%   ` Dmitry A. Kazakov
  2016-04-23  9:20  0%     ` Ahlan
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2016-04-22  8:23 UTC (permalink / raw)


On 22/04/2016 09:58, ahlan.marriott@gmail.com wrote:
> On Thursday, 21 April 2016 15:00:04 UTC+2, Dmitry A. Kazakov  wrote:
>> It seems I finally found a way to build it. The solution is quite
>> perplexing. I would be glad if anybody could shed some light on it.
>>
>> An encapsulated library requires that -lws2_32 -lwsock32 appeared *both*
>> at the beginning and the end of the linker command line. Only then no
>> "undefined reference" messages appear.
>>
>> For this build this program:
>> --------------------------------------- gcc_wrapper.adb ---
>> with Ada.Command_Line;  use Ada.Command_Line;
>> with Ada.Exceptions;    use Ada.Exceptions;
>> with Ada.Text_IO;       use Ada.Text_IO;
>> with GNAT.OS_Lib;       use GNAT.OS_Lib;
>>
>> procedure GCC_Wrapper is
>>      Prefix : String_List :=
>>               (  new String'("-lwsock32"),
>>                  new String'("-lws2_32")
>>               );
>>      Options : String_List (1..Argument_Count);
>> begin
>>      for No in 1..Argument_Count loop
>>         Options (No) := new String'(Argument (No));
>>      end loop;
>>      declare
>>         List : String_List := Prefix & Options & Prefix;
>>      begin
>>         Put ("gcc.exe");
>>         for No in List'Range loop
>>            Put (" " & List (No).all);
>>         end loop;
>>         New_Line;
>>         Set_Exit_Status (Exit_Status (Spawn ("gcc.exe", List)));
>>      end;
>> exception
>>      when Error : others =>
>>         Put_Line
>>         (  Standard_Error,
>>            "Fault: " & Exception_Information (Error)
>>         );
>>         Set_Exit_Status (2);
>> end GCC_Wrapper;
>> --------------------------------------- gcc_wrapper.adb ---
>>
>> The project file must contain:
>>
>>      package Linker is
>>         for Driver use "<absolute-path-to>/gcc_wrapper.exe";
>>      end Linker;
>>
>> --
>> Regards,
>> Dmitry A. Kazakov
>> http://www.dmitry-kazakov.de
>
> Dear Dmitry,
>
> Is this perhaps the solution to my question "Using Gnat.Sockets in a Windows DLL" that I posted on 8-Dec-2015?

Yes, I think it is the same problem you reported. BTW, I built gprbuild 
from the latest Git sources. That did not fix the problem.

It looks really weird how GCC linker searches libraries under Windows. 
Not to mention its abysmal performance. It takes literally an hour to 
link an executable against 20-30 libraries.

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

^ permalink raw reply	[relevance 0%]

* Re: Building an encapsulated library that uses GNAT sockets under Windows
  2016-04-21 12:59  7% Building an encapsulated library that uses GNAT sockets under Windows Dmitry A. Kazakov
@ 2016-04-22  7:58  0% ` ahlan.marriott
  2016-04-22  8:23  0%   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: ahlan.marriott @ 2016-04-22  7:58 UTC (permalink / raw)


On Thursday, 21 April 2016 15:00:04 UTC+2, Dmitry A. Kazakov  wrote:
> It seems I finally found a way to build it. The solution is quite 
> perplexing. I would be glad if anybody could shed some light on it.
> 
> An encapsulated library requires that -lws2_32 -lwsock32 appeared *both* 
> at the beginning and the end of the linker command line. Only then no 
> "undefined reference" messages appear.
> 
> For this build this program:
> --------------------------------------- gcc_wrapper.adb ---
> with Ada.Command_Line;  use Ada.Command_Line;
> with Ada.Exceptions;    use Ada.Exceptions;
> with Ada.Text_IO;       use Ada.Text_IO;
> with GNAT.OS_Lib;       use GNAT.OS_Lib;
> 
> procedure GCC_Wrapper is
>     Prefix : String_List :=
>              (  new String'("-lwsock32"),
>                 new String'("-lws2_32")
>              );
>     Options : String_List (1..Argument_Count);
> begin
>     for No in 1..Argument_Count loop
>        Options (No) := new String'(Argument (No));
>     end loop;
>     declare
>        List : String_List := Prefix & Options & Prefix;
>     begin
>        Put ("gcc.exe");
>        for No in List'Range loop
>           Put (" " & List (No).all);
>        end loop;
>        New_Line;
>        Set_Exit_Status (Exit_Status (Spawn ("gcc.exe", List)));
>     end;
> exception
>     when Error : others =>
>        Put_Line
>        (  Standard_Error,
>           "Fault: " & Exception_Information (Error)
>        );
>        Set_Exit_Status (2);
> end GCC_Wrapper;
> --------------------------------------- gcc_wrapper.adb ---
> 
> The project file must contain:
> 
>     package Linker is
>        for Driver use "<absolute-path-to>/gcc_wrapper.exe";
>     end Linker;
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

Dear Dmitry,

Is this perhaps the solution to my question "Using Gnat.Sockets in a Windows DLL" that I posted on 8-Dec-2015?

Regards,
Ahlan


^ permalink raw reply	[relevance 0%]

* Building an encapsulated library that uses GNAT sockets under Windows
@ 2016-04-21 12:59  7% Dmitry A. Kazakov
  2016-04-22  7:58  0% ` ahlan.marriott
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2016-04-21 12:59 UTC (permalink / raw)


It seems I finally found a way to build it. The solution is quite 
perplexing. I would be glad if anybody could shed some light on it.

An encapsulated library requires that -lws2_32 -lwsock32 appeared *both* 
at the beginning and the end of the linker command line. Only then no 
"undefined reference" messages appear.

For this build this program:
--------------------------------------- gcc_wrapper.adb ---
with Ada.Command_Line;  use Ada.Command_Line;
with Ada.Exceptions;    use Ada.Exceptions;
with Ada.Text_IO;       use Ada.Text_IO;
with GNAT.OS_Lib;       use GNAT.OS_Lib;

procedure GCC_Wrapper is
    Prefix : String_List :=
             (  new String'("-lwsock32"),
                new String'("-lws2_32")
             );
    Options : String_List (1..Argument_Count);
begin
    for No in 1..Argument_Count loop
       Options (No) := new String'(Argument (No));
    end loop;
    declare
       List : String_List := Prefix & Options & Prefix;
    begin
       Put ("gcc.exe");
       for No in List'Range loop
          Put (" " & List (No).all);
       end loop;
       New_Line;
       Set_Exit_Status (Exit_Status (Spawn ("gcc.exe", List)));
    end;
exception
    when Error : others =>
       Put_Line
       (  Standard_Error,
          "Fault: " & Exception_Information (Error)
       );
       Set_Exit_Status (2);
end GCC_Wrapper;
--------------------------------------- gcc_wrapper.adb ---

The project file must contain:

    package Linker is
       for Driver use "<absolute-path-to>/gcc_wrapper.exe";
    end Linker;

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


^ permalink raw reply	[relevance 7%]

* Re: Re-write a file in Ada
  @ 2016-01-19 12:24  5%       ` Brian Drummond
  0 siblings, 0 replies; 200+ results
From: Brian Drummond @ 2016-01-19 12:24 UTC (permalink / raw)


On Mon, 18 Jan 2016 07:05:55 -0800, gautier_niouzes wrote:

> Le lundi 11 janvier 2016 18:18:48 UTC+1, Brian Drummond a écrit :
> 
>> > raised ADA.IO_EXCEPTIONS.END_ERROR : a-tigeli.adb:96
>> 
>> In outline, when you see this sort of error, find the installation's
>> "Ada include directory" which contains the named file...
>> 
>> locate a-tigeli.adb
>> /usr/lib/gcc/x86_64-linux-gnu/4.9/rts-native/adainclude/a-tigeli.adb
...
>> Looks like we ran out of file somehow. From here on it's usually
>> straightforward.
> 
> Sure - but all that investigation effort brings nothing: the exception's
> name gives already this hint: the end of a file was reached. The fact
> that it raised somewhere in the run-time library is obvious and brings
> zero information for finding the bug: no indication is given about where
> the exception occurred in the program. 

Yes, that is true for End_Error specifically, (assuming you have already 
learned what "End_Error" means. Which may not be obvious to a beginner) 

Other exceptions - Constraint_Error, Storage_Error and so on have a much 
wider range of causes, then this process can be more helpful. I could 
have been clearer that I wanted to make a wider point.

For example, tracing "Constraint_Error" that way, once landed me in the 
Ada.Command_Line package, which made it immediately obvious I wasn't 
trapping command lines with missing arguments.

> It's a shame that GNAT doesn't
> switch on its trace-back by default, IMHO. The current setup is
> disturbing for beginners and cumbersome for people using GNAT for larger
> programs.

Agreed. Traceback would be very helpful. Because I can never remember 
how, I'll outline it here, partly in the hope of memorising it. From

https://gcc.gnu.org/onlinedocs/gnat_ugn/Non-Symbolic-Traceback.html#Non-
Symbolic-Traceback

To enable this feature you must use the `-E' gnatbind's option. 
(And compile with -g for debug information)
gnatmake -g main.adb -bargs -E

A similar point has been made for the "Ada compliant" checking flags, and 
while Gnat has been improved in this area, I think you still need to add 
some flags, giving

gnatmake -g -gnataoE -fstack-check main.adb -bargs -E

-- Brian


^ permalink raw reply	[relevance 5%]

* Re: HELP | function Is_Open (File : File_Type) return Boolean; package ada.text_io
  @ 2015-10-26 20:40  7% ` Niklas Holsti
  0 siblings, 0 replies; 200+ results
From: Niklas Holsti @ 2015-10-26 20:40 UTC (permalink / raw)


On 15-10-26 12:21 , comicfanzine@gmail.com wrote:
> Can someone please post a simple code in which this function is used , i'm lost , thanks .

The following program can be run with or without command-line arguments. 
If, and only if, there are command-line arguments, the program creates 
and writes some text to a file called my_log_file.txt.


with Ada.Command_Line;
with Ada.Text_IO;

procedure Ex_Is_Open
is

    Log_File : Ada.Text_IO.File_Type;
    --
    -- File for log output.
    -- Created only if the program has command-line arguments.


    procedure Log (Text : in String)
    --
    -- Log the Text, if the Log_File is open.
    --
    is
    begin

       if Ada.Text_IO.Is_Open (Log_File) then

          Ada.Text_IO.Put_Line (Log_File, Text);

       end if;

    end Log;


begin  -- Ex_Is_Open

    Log ("This will not appear in the log.");

    if Ada.Command_Line.Argument_Count > 0 then

       Ada.Text_IO.Put_Line ("Creating log file my_log_file.txt.");

       Ada.Text_IO.Create (
          File => Log_File,
          Name => "my_log_file.txt",
          Mode => Ada.Text_IO.Out_File);

    end if;

    Log ("This will appear iff there are command-line arguments.");

    if Ada.Text_IO.Is_Open (Log_File) then
       -- We close the log.
       -- Trying to Close the Log_File if it is not open
       -- raises the exception Ada.Text_IO.Status_Error.

       Ada.Text_IO.Close (Log_File);

    end if;

    Log ("This will not appear in the log.");

end Ex_Is_Open;



-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

^ permalink raw reply	[relevance 7%]

* Re: Exclusive file access
  2015-09-01 14:05  0% ` ahlan
@ 2015-09-01 20:02  0%   ` brbarkstrom
  0 siblings, 0 replies; 200+ results
From: brbarkstrom @ 2015-09-01 20:02 UTC (permalink / raw)


On Tuesday, September 1, 2015 at 10:05:42 AM UTC-4, ah...@marriott.org wrote:
> On Thursday, August 27, 2015 at 3:52:36 PM UTC+2, ah...@marriott.org wrote:
> > Dear All,
> > 
> > Obviously I'm misunderstanding something here.
> > 
> > I thought that if two processes tried to open the same file for write access then the second process would get an exception.
> > 
> > I have a simple example which when compiled using GnatPro 7.3.1 and run under 32-bit Windows XP demonstrates that this is not so.
> > 
> > Which then begs the question on how to detect if the file is in use and abort if it is.
> > This should be simple but obviously too complex for my tiny brain.
> > Does anyone know how to do this from Ada (without resorting to the OS directly)?
> > 
> > My simple test program is
> > 
> > package body Test is
> > 
> >   package Io renames Ada.Text_IO;
> > 
> >   procedure Work is
> >     The_File : Io.File_Type;
> >   begin
> >     Io.Open (The_File, Io.Out_File, "Test.Txt");
> >     for Count in Natural'value(Ada.Command_Line.Argument(1)) .. Natural'value(Ada.Command_Line.Argument(2)) loop
> >       Io.Put_Line (The_File, "Count =" & Count'img);
> >       Io.Put_Line ("Count =" & Count'img);
> >       delay 1.0;
> >     end loop;
> >     Io.Close (The_File);
> >   exception
> >   when others =>
> >     Io.Put_Line ("Exception");
> >   end Work;
> > 
> > end Test;
> > 
> > If I execute this from one process with parameters 1 10 and then when it reaches 8 start the program again from a second process with parameters 3 7 on the same machine, the resultant file is a nice mixture! :-(
> > 
> > Count = 3
> > Count = 4
> > Count = 5
> > Count = 6
> > Count = 7
> > Count = 6
> > Count = 7
> > Count = 8
> > Count = 9
> > Count = 10
> > 
> > This is not what I want. I want what the first instance produces and the second instance to fail. Surely nobody would want otherwise ;-)
> > 
> > Best wishes,
> > Ahlan
> 
> I am not trying to protect the file from other tasks I am trying to protect the file from other processes - ie other programs or utilities - perhaps executing on other computers if the file in question is on a network. I want to open the file in such a way that I am granted exclusive write access. This has absolutely nothing to do with tasking or protected objects etc.
> Bruce B. tells me that there are routines in the package Directories that can be used to check if the file is already open. However that wouldn't be a full solution because there would be nothing to stop any other program from opening the file and messing with it. However it would be a start. If the file was already opened (by some other process) then I could avoid opening it. Unfortunately I couldn't find any such routine in Ada.Directories. Am I going blind?
> So far the only solution I can see is for me to write my own filing system, one that has the ability to open the file for exclusive file access. However I cannot believe that this is what people really do.
> As it stands if I write a program that writes a log to a text file a second occurrence of the program if run concurrently will mess up this log.
> Is there really no way for an Gnat Ada program to open a file for exclusive access against other processes without resorting to the program writing his/her own filing system? (Open/Read/Write/Close that call directly the OS API)

My Linux version of the reference manual is a bit hard to find from my e-mail.
The Ada-2012 version of the RM has a function Is_Open that returns a Boolean
for each of the IO types defined in that document.  For example section A.10.1
has Is_Open as the first function in the description for Text_IO.  I apologize
for not checking Ada.Directories in the RM when I posted my note earlier today.

I'm still not sure why the alternate processes you're referring to wouldn't
be Ada Tasks.  In that case, the appropriate design would embed the information
you want to protect into an object that forces the other tasks to wait until
the task accessing the file ends.  If you are really running multi-language
implementations, you'll probably need to uncover the code to identify which
process is your Ada process and then have code that interfaces with the Ada.

If you try to run concurrent write operations to text files without using
protected objects or some other form of locking, the IO buffer will certainly 
get confused.  As a result, the output will have a strange interleaving of 
characters from the different processes.  This difficulty certainly makes
debugging by printing lines of text more complicated.  

McCormick, et al. have a
very nice (and simple) code example for a package called "Protected_Output"
that uses a pattern called a Semaphore that deals with this problem.  The
code is on pp. 145-146 of their book.  It may be that their web site
<htttp://www.cambridge.org/9780521197168> can provide the source code.
After you open the site, find a tab labelled "Resources".  Then choose
one called "Source Code" and download the zip file.  The Protected_Output
code is from section 4.7 in the book.  I think the driver for this code
is included in the zip file.

I have compiled and run this demo successfully.  I strongly suggest you consult 
McCormick et al. before you try writing your own file system.

I do apologize for not carefully checking the RM for the proper location
and name of the Is_Open function.

Bruce B.

^ permalink raw reply	[relevance 0%]

* Re: Exclusive file access
  2015-08-27 13:52  6% Exclusive file access ahlan
                   ` (3 preceding siblings ...)
  2015-09-01 14:05  0% ` ahlan
@ 2015-09-01 15:31  0% ` ahlan
  4 siblings, 0 replies; 200+ results
From: ahlan @ 2015-09-01 15:31 UTC (permalink / raw)


On Thursday, August 27, 2015 at 3:52:36 PM UTC+2, ah...@marriott.org wrote:
> Dear All,
> 
> Obviously I'm misunderstanding something here.
> 
> I thought that if two processes tried to open the same file for write access then the second process would get an exception.
> 
> I have a simple example which when compiled using GnatPro 7.3.1 and run under 32-bit Windows XP demonstrates that this is not so.
> 
> Which then begs the question on how to detect if the file is in use and abort if it is.
> This should be simple but obviously too complex for my tiny brain.
> Does anyone know how to do this from Ada (without resorting to the OS directly)?
> 
> My simple test program is
> 
> package body Test is
> 
>   package Io renames Ada.Text_IO;
> 
>   procedure Work is
>     The_File : Io.File_Type;
>   begin
>     Io.Open (The_File, Io.Out_File, "Test.Txt");
>     for Count in Natural'value(Ada.Command_Line.Argument(1)) .. Natural'value(Ada.Command_Line.Argument(2)) loop
>       Io.Put_Line (The_File, "Count =" & Count'img);
>       Io.Put_Line ("Count =" & Count'img);
>       delay 1.0;
>     end loop;
>     Io.Close (The_File);
>   exception
>   when others =>
>     Io.Put_Line ("Exception");
>   end Work;
> 
> end Test;
> 
> If I execute this from one process with parameters 1 10 and then when it reaches 8 start the program again from a second process with parameters 3 7 on the same machine, the resultant file is a nice mixture! :-(
> 
> Count = 3
> Count = 4
> Count = 5
> Count = 6
> Count = 7
> Count = 6
> Count = 7
> Count = 8
> Count = 9
> Count = 10
> 
> This is not what I want. I want what the first instance produces and the second instance to fail. Surely nobody would want otherwise ;-)
> 
> Best wishes,
> Ahlan

I have no idea about Linux but it is perfectly possible under Windows. However this doesn't stop people (including Microsoft) from creating lock files that then sometimes get left behind when a program crashes rendering the file locked forever! So the presence of lock files doesn't mean that the opsys can't lock exclusively.
I mentioned a logger not because I want to write a logger but as a simple example of somthing someone might want to write.

^ permalink raw reply	[relevance 0%]

* Re: Exclusive file access
  2015-08-27 13:52  6% Exclusive file access ahlan
                   ` (2 preceding siblings ...)
  2015-09-01 12:37  0% ` brbarkstrom
@ 2015-09-01 14:05  0% ` ahlan
  2015-09-01 20:02  0%   ` brbarkstrom
  2015-09-01 15:31  0% ` ahlan
  4 siblings, 1 reply; 200+ results
From: ahlan @ 2015-09-01 14:05 UTC (permalink / raw)


On Thursday, August 27, 2015 at 3:52:36 PM UTC+2, ah...@marriott.org wrote:
> Dear All,
> 
> Obviously I'm misunderstanding something here.
> 
> I thought that if two processes tried to open the same file for write access then the second process would get an exception.
> 
> I have a simple example which when compiled using GnatPro 7.3.1 and run under 32-bit Windows XP demonstrates that this is not so.
> 
> Which then begs the question on how to detect if the file is in use and abort if it is.
> This should be simple but obviously too complex for my tiny brain.
> Does anyone know how to do this from Ada (without resorting to the OS directly)?
> 
> My simple test program is
> 
> package body Test is
> 
>   package Io renames Ada.Text_IO;
> 
>   procedure Work is
>     The_File : Io.File_Type;
>   begin
>     Io.Open (The_File, Io.Out_File, "Test.Txt");
>     for Count in Natural'value(Ada.Command_Line.Argument(1)) .. Natural'value(Ada.Command_Line.Argument(2)) loop
>       Io.Put_Line (The_File, "Count =" & Count'img);
>       Io.Put_Line ("Count =" & Count'img);
>       delay 1.0;
>     end loop;
>     Io.Close (The_File);
>   exception
>   when others =>
>     Io.Put_Line ("Exception");
>   end Work;
> 
> end Test;
> 
> If I execute this from one process with parameters 1 10 and then when it reaches 8 start the program again from a second process with parameters 3 7 on the same machine, the resultant file is a nice mixture! :-(
> 
> Count = 3
> Count = 4
> Count = 5
> Count = 6
> Count = 7
> Count = 6
> Count = 7
> Count = 8
> Count = 9
> Count = 10
> 
> This is not what I want. I want what the first instance produces and the second instance to fail. Surely nobody would want otherwise ;-)
> 
> Best wishes,
> Ahlan

I am not trying to protect the file from other tasks I am trying to protect the file from other processes - ie other programs or utilities - perhaps executing on other computers if the file in question is on a network. I want to open the file in such a way that I am granted exclusive write access. This has absolutely nothing to do with tasking or protected objects etc.
Bruce B. tells me that there are routines in the package Directories that can be used to check if the file is already open. However that wouldn't be a full solution because there would be nothing to stop any other program from opening the file and messing with it. However it would be a start. If the file was already opened (by some other process) then I could avoid opening it. Unfortunately I couldn't find any such routine in Ada.Directories. Am I going blind?
So far the only solution I can see is for me to write my own filing system, one that has the ability to open the file for exclusive file access. However I cannot believe that this is what people really do.
As it stands if I write a program that writes a log to a text file a second occurrence of the program if run concurrently will mess up this log.
Is there really no way for an Gnat Ada program to open a file for exclusive access against other processes without resorting to the program writing his/her own filing system? (Open/Read/Write/Close that call directly the OS API)


^ permalink raw reply	[relevance 0%]

* Re: Exclusive file access
  2015-08-27 13:52  6% Exclusive file access ahlan
  2015-08-28  5:41  0% ` ahlan
  2015-08-28 17:40  0% ` ahlan
@ 2015-09-01 12:37  0% ` brbarkstrom
  2015-09-01 14:05  0% ` ahlan
  2015-09-01 15:31  0% ` ahlan
  4 siblings, 0 replies; 200+ results
From: brbarkstrom @ 2015-09-01 12:37 UTC (permalink / raw)


On Thursday, August 27, 2015 at 9:52:36 AM UTC-4, ah...@marriott.org wrote:
> Dear All,
> 
> Obviously I'm misunderstanding something here.
> 
> I thought that if two processes tried to open the same file for write access then the second process would get an exception.
> 
> I have a simple example which when compiled using GnatPro 7.3.1 and run under 32-bit Windows XP demonstrates that this is not so.
> 
> Which then begs the question on how to detect if the file is in use and abort if it is.
> This should be simple but obviously too complex for my tiny brain.
> Does anyone know how to do this from Ada (without resorting to the OS directly)?
> 
> My simple test program is
> 
> package body Test is
> 
>   package Io renames Ada.Text_IO;
> 
>   procedure Work is
>     The_File : Io.File_Type;
>   begin
>     Io.Open (The_File, Io.Out_File, "Test.Txt");
>     for Count in Natural'value(Ada.Command_Line.Argument(1)) .. Natural'value(Ada.Command_Line.Argument(2)) loop
>       Io.Put_Line (The_File, "Count =" & Count'img);
>       Io.Put_Line ("Count =" & Count'img);
>       delay 1.0;
>     end loop;
>     Io.Close (The_File);
>   exception
>   when others =>
>     Io.Put_Line ("Exception");
>   end Work;
> 
> end Test;
> 
> If I execute this from one process with parameters 1 10 and then when it reaches 8 start the program again from a second process with parameters 3 7 on the same machine, the resultant file is a nice mixture! :-(
> 
> Count = 3
> Count = 4
> Count = 5
> Count = 6
> Count = 7
> Count = 6
> Count = 7
> Count = 8
> Count = 9
> Count = 10
> 
> This is not what I want. I want what the first instance produces and the second instance to fail. Surely nobody would want otherwise ;-)
> 
> Best wishes,
> Ahlan

When I first read this post, it seemed to me that if the program were
operating sequentially, it would be appropriate to use the Directories
package that already has functions or procedures to detect whether a
file exists and is open.  If you use those functions, you can detect
the problem and throw an exception (or some such).

If you're really wanting to do concurrent operations where different
tasks can access an open file, it seems to me that the appropriate
Ada approach is to embed the content of the file in a protected object
and use that capability to avoid the problems with the second file's
access.  Chapter 4 in McCormick, Singhoff, and Hugues [Building Parallel,
Embedded, and Real-Time Applications with Ada, 2005, Cambridge U Press]
has most of the material that you would need for this approach.

If you have to deal with unreliable components, then Burns and Wellings
book should have a pretty good start on the algorithms in their "Reader
Writer" example.

You might see if these suggestions would make your work a bit easier.

Bruce B.

^ permalink raw reply	[relevance 0%]

* Re: Exclusive file access
  2015-08-27 13:52  6% Exclusive file access ahlan
  2015-08-28  5:41  0% ` ahlan
@ 2015-08-28 17:40  0% ` ahlan
  2015-09-01 12:37  0% ` brbarkstrom
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 200+ results
From: ahlan @ 2015-08-28 17:40 UTC (permalink / raw)


Our working solution was to use the Windows API to open the file and then use Windows API calls to read and write to it.
We did this because using OA there wasn't a way to open files with non-ascii file names.
However it meant that we had to write our own filing system.

Now that we have abandoned OA in favour of Gnat and because Gnat provides a mechanism to open files with non-ascii names I had hoped that we could abandon all this fancy windows stuff and use plain Ada.
The hope was that it would also be platform independent.
From what everyone has written it seems that this is not possible.
It seems that I should somehow lock the file once it has been opened by Ada.
Has anyone any suggestions how best to do that?
Ie How does one write a GNAT Ada program for windows that has exclusive access when opened for write. Surely this must be a common requirement?

On Thursday, August 27, 2015 at 3:52:36 PM UTC+2, ah...@marriott.org wrote:
> Dear All,
> 
> Obviously I'm misunderstanding something here.
> 
> I thought that if two processes tried to open the same file for write access then the second process would get an exception.
> 
> I have a simple example which when compiled using GnatPro 7.3.1 and run under 32-bit Windows XP demonstrates that this is not so.
> 
> Which then begs the question on how to detect if the file is in use and abort if it is.
> This should be simple but obviously too complex for my tiny brain.
> Does anyone know how to do this from Ada (without resorting to the OS directly)?
> 
> My simple test program is
> 
> package body Test is
> 
>   package Io renames Ada.Text_IO;
> 
>   procedure Work is
>     The_File : Io.File_Type;
>   begin
>     Io.Open (The_File, Io.Out_File, "Test.Txt");
>     for Count in Natural'value(Ada.Command_Line.Argument(1)) .. Natural'value(Ada.Command_Line.Argument(2)) loop
>       Io.Put_Line (The_File, "Count =" & Count'img);
>       Io.Put_Line ("Count =" & Count'img);
>       delay 1.0;
>     end loop;
>     Io.Close (The_File);
>   exception
>   when others =>
>     Io.Put_Line ("Exception");
>   end Work;
> 
> end Test;
> 
> If I execute this from one process with parameters 1 10 and then when it reaches 8 start the program again from a second process with parameters 3 7 on the same machine, the resultant file is a nice mixture! :-(
> 
> Count = 3
> Count = 4
> Count = 5
> Count = 6
> Count = 7
> Count = 6
> Count = 7
> Count = 8
> Count = 9
> Count = 10
> 
> This is not what I want. I want what the first instance produces and the second instance to fail. Surely nobody would want otherwise ;-)
> 
> Best wishes,
> Ahlan


^ permalink raw reply	[relevance 0%]

* Re: Exclusive file access
  2015-08-28  5:41  0% ` ahlan
@ 2015-08-28  7:10  0%   ` Georg Bauhaus
  0 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2015-08-28  7:10 UTC (permalink / raw)


On 28.08.15 07:41, ahlan@marriott.org wrote:
> Under Windows files may be opened exclusively or shared.

No, they can't if using any ISO standard language support? You need OS support from Windows
for lock management, be that with ISO C, or with ISO C++, or with ISO Ada. Using Unix and C,
you will require OS services available through open(2)/flock(2), or some additional library
such as POSIX flockfile(3), etc.. On Windows, with C or Ada, as you have mentioned before,
you need to call some OS functions from Win32, not from ANSI C. The LRMs are not saying things
about the OS or about POSIX or file system here, but about internal Ada file objects in relation
to their names. I think that the GNAT RM is is talking about these, too, not about locking
at external levels. (You may have noticed that Use_Error *is* raised on attempt of using
the same full name in different Ada tasks; these may not be processes.)

So, the name of GNAT's Form parameter, "SHARED" could be misleading: it does not refer
to what "shared" might mean in an OS context.

> In fact you can have a mixture such as single writer multiple readers.
> Multiple writers is possible but rarely used, so it is an odd choice for Gnat to have chosen.
> Using form="Shared=no" on the open using Gnat for Windows does not open the file exclusively with regard to other processes.
> Which is what I would have expected and I would have thought 99% of users would require.
> As far as I can see there is no way that a pure Gnat Ada program can open a file for output exclusively.
> If this is true then this is a severe weakness of Gnat.
> ObjectAda did what was expected by default.
>
> On Thursday, August 27, 2015 at 3:52:36 PM UTC+2, ah...@marriott.org wrote:
>> Dear All,
>>
>> Obviously I'm misunderstanding something here.
>>
>> I thought that if two processes tried to open the same file for write access then the second process would get an exception.
>>
>> I have a simple example which when compiled using GnatPro 7.3.1 and run under 32-bit Windows XP demonstrates that this is not so.
>>
>> Which then begs the question on how to detect if the file is in use and abort if it is.
>> This should be simple but obviously too complex for my tiny brain.
>> Does anyone know how to do this from Ada (without resorting to the OS directly)?
>>
>> My simple test program is
>>
>> package body Test is
>>
>>    package Io renames Ada.Text_IO;
>>
>>    procedure Work is
>>      The_File : Io.File_Type;
>>    begin
>>      Io.Open (The_File, Io.Out_File, "Test.Txt");
>>      for Count in Natural'value(Ada.Command_Line.Argument(1)) .. Natural'value(Ada.Command_Line.Argument(2)) loop
>>        Io.Put_Line (The_File, "Count =" & Count'img);
>>        Io.Put_Line ("Count =" & Count'img);
>>        delay 1.0;
>>      end loop;
>>      Io.Close (The_File);
>>    exception
>>    when others =>
>>      Io.Put_Line ("Exception");
>>    end Work;
>>
>> end Test;
>>
>> If I execute this from one process with parameters 1 10 and then when it reaches 8 start the program again from a second process with parameters 3 7 on the same machine, the resultant file is a nice mixture! :-(
>>
>> Count = 3
>> Count = 4
>> Count = 5
>> Count = 6
>> Count = 7
>> Count = 6
>> Count = 7
>> Count = 8
>> Count = 9
>> Count = 10
>>
>> This is not what I want. I want what the first instance produces and the second instance to fail. Surely nobody would want otherwise ;-)
>>
>> Best wishes,
>> Ahlan
>


^ permalink raw reply	[relevance 0%]

* Re: Exclusive file access
  2015-08-27 13:52  6% Exclusive file access ahlan
@ 2015-08-28  5:41  0% ` ahlan
  2015-08-28  7:10  0%   ` Georg Bauhaus
  2015-08-28 17:40  0% ` ahlan
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 200+ results
From: ahlan @ 2015-08-28  5:41 UTC (permalink / raw)


Under Windows files may be opened exclusively or shared.
In fact you can have a mixture such as single writer multiple readers.
Multiple writers is possible but rarely used, so it is an odd choice for Gnat to have chosen.
Using form="Shared=no" on the open using Gnat for Windows does not open the file exclusively with regard to other processes.
Which is what I would have expected and I would have thought 99% of users would require.
As far as I can see there is no way that a pure Gnat Ada program can open a file for output exclusively.
If this is true then this is a severe weakness of Gnat.
ObjectAda did what was expected by default.

On Thursday, August 27, 2015 at 3:52:36 PM UTC+2, ah...@marriott.org wrote:
> Dear All,
> 
> Obviously I'm misunderstanding something here.
> 
> I thought that if two processes tried to open the same file for write access then the second process would get an exception.
> 
> I have a simple example which when compiled using GnatPro 7.3.1 and run under 32-bit Windows XP demonstrates that this is not so.
> 
> Which then begs the question on how to detect if the file is in use and abort if it is.
> This should be simple but obviously too complex for my tiny brain.
> Does anyone know how to do this from Ada (without resorting to the OS directly)?
> 
> My simple test program is
> 
> package body Test is
> 
>   package Io renames Ada.Text_IO;
> 
>   procedure Work is
>     The_File : Io.File_Type;
>   begin
>     Io.Open (The_File, Io.Out_File, "Test.Txt");
>     for Count in Natural'value(Ada.Command_Line.Argument(1)) .. Natural'value(Ada.Command_Line.Argument(2)) loop
>       Io.Put_Line (The_File, "Count =" & Count'img);
>       Io.Put_Line ("Count =" & Count'img);
>       delay 1.0;
>     end loop;
>     Io.Close (The_File);
>   exception
>   when others =>
>     Io.Put_Line ("Exception");
>   end Work;
> 
> end Test;
> 
> If I execute this from one process with parameters 1 10 and then when it reaches 8 start the program again from a second process with parameters 3 7 on the same machine, the resultant file is a nice mixture! :-(
> 
> Count = 3
> Count = 4
> Count = 5
> Count = 6
> Count = 7
> Count = 6
> Count = 7
> Count = 8
> Count = 9
> Count = 10
> 
> This is not what I want. I want what the first instance produces and the second instance to fail. Surely nobody would want otherwise ;-)
> 
> Best wishes,
> Ahlan

^ permalink raw reply	[relevance 0%]

* Exclusive file access
@ 2015-08-27 13:52  6% ahlan
  2015-08-28  5:41  0% ` ahlan
                   ` (4 more replies)
  0 siblings, 5 replies; 200+ results
From: ahlan @ 2015-08-27 13:52 UTC (permalink / raw)


Dear All,

Obviously I'm misunderstanding something here.

I thought that if two processes tried to open the same file for write access then the second process would get an exception.

I have a simple example which when compiled using GnatPro 7.3.1 and run under 32-bit Windows XP demonstrates that this is not so.

Which then begs the question on how to detect if the file is in use and abort if it is.
This should be simple but obviously too complex for my tiny brain.
Does anyone know how to do this from Ada (without resorting to the OS directly)?

My simple test program is

package body Test is

  package Io renames Ada.Text_IO;

  procedure Work is
    The_File : Io.File_Type;
  begin
    Io.Open (The_File, Io.Out_File, "Test.Txt");
    for Count in Natural'value(Ada.Command_Line.Argument(1)) .. Natural'value(Ada.Command_Line.Argument(2)) loop
      Io.Put_Line (The_File, "Count =" & Count'img);
      Io.Put_Line ("Count =" & Count'img);
      delay 1.0;
    end loop;
    Io.Close (The_File);
  exception
  when others =>
    Io.Put_Line ("Exception");
  end Work;

end Test;

If I execute this from one process with parameters 1 10 and then when it reaches 8 start the program again from a second process with parameters 3 7 on the same machine, the resultant file is a nice mixture! :-(

Count = 3
Count = 4
Count = 5
Count = 6
Count = 7
Count = 6
Count = 7
Count = 8
Count = 9
Count = 10

This is not what I want. I want what the first instance produces and the second instance to fail. Surely nobody would want otherwise ;-)

Best wishes,
Ahlan

^ permalink raw reply	[relevance 6%]

* Re: Running a preprocessor from GPS?
  @ 2015-07-30 22:52  4%                               ` Jeffrey R. Carter
  0 siblings, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2015-07-30 22:52 UTC (permalink / raw)


On 07/30/2015 01:53 PM, EGarrulo wrote:
> 
> By "resource" I mean any resource -- like: database connections,
> files, etc. -- that must be relinquished as soon as possible and that is
> shared among different objects, in a way that makes it difficult for each object
> to determine whether such resource is still needed by other objects or not.  Of
> course, this implies a dynamic environment that precludes the possibility of
> creating all the needed resources in advance and then releasing them at the end
> of computation.

I still have no idea what you mean. Sharing a DB connection among objects seems
simple:

declare
   DB : DB_Connection;
begin
   O1.Op (DB => DB);
   O2.Op (DB => DB);
   O3.Op (DB => DB);
end;

and the sharing part remains just as simple if the operations pass the DB to
operations of other objects, and if the code is more complex with multiple paths
and orders of operation invocations. There doesn't seem to be any reason for the
objects to know whether another object will receive the DB after they're through
with it or not, or to be concerned with when it is "relinquished".

> I am not thinking in C++ terms.  I am thinking in terms of patterns
> that I know for managing resources.  So far, I only know the "shared/weak
> pointer" idiom.  If Ada offers something else, besides manual reclamation, I am
> eager to learn about it.

If you only know one idiom, it's not surprising you have difficulty imagining
anything else. "Shared/weak pointer" certainly sounds fairly C/++ oriented to me.

I am perhaps constrained by my Ada experience since I can't image what kind of
problem you're talking about. I wish I could. It reminds me of someone who was
telling me about his experiments with overflowing buffers in C. I said I
preferred to use a language in which that wasn't possible, and he couldn't
conceive of the possibility. He showed me what he was doing, which was something
like

char b[100];

and using strcpy to copy argv[1] into b. He asked how I'd do that with Ada, so I
showed him

B : String := Ada.Command_Line.Argument (1);

He didn't seem to be able to wrap his mind around that. I may be having a
similar problem understanding you.

-- 
Jeff Carter
"Pray that there's intelligent life somewhere up in
space, 'cause there's bugger all down here on earth."
Monty Python's Meaning of Life
61


^ permalink raw reply	[relevance 4%]

* Re: How to get nice with GNAT?
  @ 2014-11-21 12:42  4% ` Björn Lundin
  0 siblings, 0 replies; 200+ results
From: Björn Lundin @ 2014-11-21 12:42 UTC (permalink / raw)


On 2014-11-21 12:41, Natasha Kerensikova wrote:


> As a user, is there something I can do to improve the traceback
> representation on those platforms?
> Or is it completely in the hands of the GNAT packager/maintainer?
>

I run gnat on Aix/win32/linux32/64
and until recently, I tucked everything related
to stacktrace into a package Stacktrace.


package Stacktrace is
  procedure Tracebackinfo(E : Ada.Exceptions.Exception_Occurrence) ;
end Stacktrace;

used as

procedure bla is
...
...
exception
  when E: others =>
  Stacktrace.Tracebackinfo(E);
end ;

where i called
Ada.Exceptions.Exception_Name(E);
Ada.Exceptions.Exception_Message(E);
Ada.Exceptions.Exception_Information(E);

and output them

however, from Gnat GPL 2014 (64) and gnat fsf on debian Jessie
 (gnat 4.9 i think) the Tracebackinfo is not called anymore.

So my current workaround is to print those function directly
like

procedure bla is
...

exception
  when E: others =>
    declare
      Last_Exception_Name     : constant String  :=
Ada.Exceptions.Exception_Name(E);
      Last_Exception_Messsage : constant String  :=
Ada.Exceptions.Exception_Message(E);
      Last_Exception_Info     : constant String  :=
Ada.Exceptions.Exception_Information(E);
    begin
      Log(Last_Exception_Name);
      Log("Message : " & Last_Exception_Messsage);
      Log(Last_Exception_Info);
      Log("addr2line" & " --functions --basenames --exe=" &
           Ada.Command_Line.Command_Name & " " &
Stacktrace.Pure_Hexdump(Last_Exception_Info));
    end ;

end bla;



the function Pure_Hexdump strips away
everything before the first 0x in the string.


final output is like

2014-11-21 13:33:26.278 SQL.NOT_CONNECTED
2014-11-21 13:33:26.278 Message : Sql.Connect: Not_Connected
2014-11-21 13:33:26.278 Exception name: SQL.NOT_CONNECTED
Message: Sql.Connect: Not_Connected
Call stack traceback locations:
0x5be389 0x5cd93c 0x40c988 0x7fca95a8beab 0x40bab7

2014-11-21 13:33:26.278 addr2line --functions --basenames
--exe=/home/bnl/bnlbot/botstart/bot-1-0/target/bin/back_hitrate 0x5be389
0x5cd93c 0x40c988 0x7fca95a8beab 0x40bab7

and running addr2line gives

 addr2line --functions --basenames
--exe=/home/bnl/bnlbot/botstart/bot-1-0/target/bin/back_hitrate 0x5be389
0x5cd93c 0x40c988 0x7fca95a8beab 0x40bab7
sql__connect
sql.adb:432
_ada_back_hitrate
back_hitrate.adb:165
main
b~back_hitrate.adb:761
??
??:0
_start
??:?


A bit clumpsy but good enough for my _hobby_ projects.

--
Björn

^ permalink raw reply	[relevance 4%]

* specification file ads problem
@ 2014-10-05 15:39  5% Stribor40
  0 siblings, 0 replies; 200+ results
From: Stribor40 @ 2014-10-05 15:39 UTC (permalink / raw)


I am trying to put this in spec file...
***********************************************************
generic
  type myType is array (1 ..N-1) of String (1..N);
  N : Integer;
 
package myPackage is
     function tt (a : in String) return myType;
end Neighbours;

************************************************************
Then in body.....

package body myPackage is
 myNewType : myType; 

     function tt (a : in String) return myType is
        begin
      --
      --

      return myNewType;
        end tt;


end myPackage;
*****************************************************************************
actual file that i compile and use to test this,,,

with Ada.Text_IO, Ada.Command_Line, myPackage;
 
  
   procedure testing is
   
  
  begin
   Null;
  end testing;
***************************************************************************

I am getting all these type errors..what am i doing wrong here? How do i spec file specify function return type when my spec file doesnt know about it?
    


^ permalink raw reply	[relevance 5%]

* Re: Preconditions which anyway would be caught?
  @ 2014-08-09 16:08  6% ` Jeffrey Carter
  0 siblings, 0 replies; 200+ results
From: Jeffrey Carter @ 2014-08-09 16:08 UTC (permalink / raw)


On 08/09/2014 08:35 AM, Victor Porton wrote:
> function Inverse (X: Float) is
> begin
>     return 1/X;
> end
>     with Pre => (X /= 0);
>
> Is this precondition superfluous? (it anyway could be caught by erroneous
> 1/X operation)

This won't compile, so you have no problem.

Considering your general question, there are a number of differences between the 2:

Preconditions serve an important documentation purpose, which simply having an 
error caught at run time doesn't fulfill.

Preconditions can be used by tools, which might not be able to use the run-time 
check on division.

The precondition adds a check to every call of the function, and the division is 
not performed if the precondition fails. The division, and any associated check, 
is always performed without the precondition.

An alternative might be to use a subtype

subtype Invertable_Float is Float with
    Dynamic_Predicate => Invertible_Float /= 0.0;

function Invert (X : Invertable_Float) return Float;

Finally, are you sure the division will raise an exception?

with Ada.Command_Line;
with Ada.Text_IO;

procedure Inverse_Test is
    function Inverse (X : Float) return Float is
       -- Empty declarative part
    begin -- Inverse
       return 1.0 / X;
    end Inverse;

    F : constant Float :=
       Inverse (Float'Value (Ada.Command_Line.Argument (1) ) );
begin -- Inverse_Test
    Ada.Text_IO.Put_Line (Item => Float'Image (F) );
end Inverse_Test;

$ gnatmake -gnatano -fstack-check -gnatwa inverse_test.adb
gcc-4.6 -c -gnatano -fstack-check -gnatwa inverse_test.adb
gnatbind -x inverse_test.ali
gnatlink inverse_test.ali -fstack-check
$ ./inverse_test 0.0
  +Inf*******

You might want to review floating-point types and look at the 'Machine_Overflows 
attribute.

-- 
Jeff Carter
"Insufficient laughter--that's grounds for divorce."
Play It Again, Sam
126


^ permalink raw reply	[relevance 6%]

* Re: Lotto simulation
  @ 2014-06-16 11:15  6%         ` Stefan.Lucks
  0 siblings, 0 replies; 200+ results
From: Stefan.Lucks @ 2014-06-16 11:15 UTC (permalink / raw)


[-- Attachment #1: Type: TEXT/PLAIN, Size: 2730 bytes --]

On Mon, 16 Jun 2014, J-P. Rosen wrote:

>> but mathematically, given a uniformly
>> distributed real number F between 0.0 and 1.0, one can get a uniformly
>> distributed discrete D between Low and high: D := Truncate(Low + F *
>> (High-Low + 1)).
> I think it all depends on the definition of "uniformly distributed". If
> it is uniformly distributed among all representable floating point
> numbers (which you get if you take an integer random number and
> unchecked-convert it to Float), you'll get many more values below 0.5
> than above (since the range 0.5..1.0 is represented with only one value
> of the exponent).

Well, do you think the Annotated Reference Manual 
<http://www.ada-auth.org/standards/12aarm/html/AA-A-5-2.html> needs a 
clarification? It explicitely tells

   A sufficiently long sequence of random numbers obtained by successive
   calls to Random is approximately uniformly distributed over the range of
   the result subtype.

From my point of view, "uniformly distributed over the range of the result 
subtype" would seem to imply values > 0.5 to be as often as values < 0.5.

In fact, I would claim that any random generator, choosing floats between 
0.0 and 1.0 with a significant bias towards 0.0 or 1.0 would be plain 
stupid and worse than useless, and a standard which allows that, would 
need urgent repair!

Fortunately, my Ada compiler (gnat) is not such stupid and behaves as I 
had expected:

with Ada.Text_IO, Ada.Numerics.Float_Random, Ada.Command_Line;

procedure Test_Rnd is

    package ANFR renames Ada.Numerics.Float_Random;
    Gen: ANFR.Generator;

    High: Natural := 0;
    Sample_Size: constant Natural := Natural'Value(Ada.Command_Line.Argument(1));
begin
    ANFR.Reset(Gen);
    for I in 1 .. Sample_Size loop
       if ANFR.Random(Gen) > 0.5 then
 	 High := High + 1;
       end if;
    end loop;

    Ada.Text_IO.Put_Line(Integer'Image(High) &" /"& Integer'Image(Sample_Size));
end Test_Rnd;

Compiling and running the above program indicates an even distribution of 
values > 0.5 and <= 0.5 (i.e., there is no statistically significant 
bias):

$ ./test_rnd 100000000
  49999482 / 100000000
$ ./test_rnd 1000000000
  499991845 / 1000000000

Note that the results are biased towards 0.0, but the bias is 
statistically insignificant. (It would be statistically strange, indeed, 
if *exactly* half of the random values would be below 0.5, and the other 
half would be above.)

So long

------  I  love  the  taste  of  Cryptanalysis  in  the morning!  ------
     <http://www.uni-weimar.de/cms/medien/mediensicherheit/home.html>
--Stefan.Lucks (at) uni-weimar.de, Bauhaus-Universität Weimar, Germany--

^ permalink raw reply	[relevance 6%]

* Re: Safety of unprotected concurrent operations on constant objects
  @ 2014-05-11  6:56  5%                                           ` Brad Moore
  0 siblings, 0 replies; 200+ results
From: Brad Moore @ 2014-05-11  6:56 UTC (permalink / raw)


On 10/05/2014 2:27 PM, Dmitry A. Kazakov wrote:
>> If Foo calls Bar, and both Foo and Bar have the Task_Safe aspect, but
>> some time later the maintainer of Bar decides to change its
>> implementation to refer to some global variable or call some other
>> subprogram that doesn't have the Task_Safe aspect, the compiler would
>> force the programmer to remove the Task_Safe aspect from Bar.
>
> But this rule is just wrong. Calling unsafe operation from a safe one will
> be pretty much safe in most cases. The reverse is likely wrong.

This doesn't make sense to me. There should be no such thing as a Safe 
operation that calls unsafe ones. Wouldn't that mean that the operation 
is unsafe (to use concurrently)?

>
> Compare it with protected actions. It is safe to call an operation which
> itself is not protected from a protected operation on the context of a
> protected action.

But thats only true if the operation is only ever called from within 
that same instance of the protected object (Something that could be 
difficult to know without the aspect), and that there is only one 
instance of that protected type of the protected object. Otherwise its 
not safe to call from a protected operation as there could be other 
concurrent calls calling the unsafe operation.

The following program illustrates this. If you run the program with a 
small value of N (specified on the command line), say 100, then chances 
are the program executes correctly to completion. However if you use a 
larger value of N (say 1_000_000, the default), then the program fails,
due to the use of global variables. In Test1, the Unsafe function is 
called directly from multiple tasks.

In Test2, the same Unsafe function is only called from protected 
functions, but it still fails.
.
In both tests, the failures are due to function Unsafe failing its 
Postcondition.

If the Task_Safe attribute existed, the compiler could have issued a 
warning at compile time that the tasks were calling subprograms that 
weren't Task_Safe, and the problems could have been avoided.


with Ada.Text_IO; use Ada.Text_IO;
with Ada.Exceptions; use Ada;
with Ada.Command_Line;

procedure Test_Task_Safety is

    --  Defaults to 1_000_000, but can be specified on command line
    N : constant Natural := (if Command_Line.Argument_Count >= 1 then
                             Natural'Value (Command_Line.Argument (1))
                             else 1_000_000);

    Global_Data : Integer := 0;

    function Unsafe (X : Natural) return Natural
        with Post => Unsafe'Result = X + 1 --,
         --  Task_Safe => False
        ;

    function Unsafe (X : Natural) return Natural is
    begin
       Global_Data := X;
       Global_Data := Global_Data + 1;
       return Global_Data;
    end Unsafe;

begin

    New_Line;
    Put_Line ("******************************** ");
    Put_Line ("****  Test1 : Unsafe calls ***** ");
    Put_Line ("******************************** ");
    New_Line;

    Test1 : declare

       task type T1 is
       end T1;

       task body T1 is
          Result : Natural := 0;
       begin
          for I in 1 .. N loop
             Result := Unsafe (Result);
          end loop;
          Put_Line ("Result =" & Natural'Image (Result));
       exception
          when E : others =>
             Put_Line ("Task_Died" & 
Ada.Exceptions.Exception_Information (E));
       end T1;

       Workers : array (1 .. 10) of T1;
    begin
       null;
    end Test1;

    New_Line;
    Put_Line ("********************************************************");
    Put_Line ("****  Test2 : Unsafe calls from protected objects ***** ");
    Put_Line ("********************************************************");
    New_Line;

    Test2 : declare

       protected PO1 is
          function Foo (X : Natural) return Natural;
       end PO1;

       protected PO2 is
          function Bar (X : Natural) return Natural;
       end PO2;

       protected body PO1 is
          function Foo (X : Natural) return Natural is
          begin
             return Unsafe (X);
          end Foo;
       end PO1;

       protected body PO2 is
          function Bar (X : Natural) return Natural is
          begin
             return Unsafe (X);
          end Bar;
       end PO2;

       task type T1 is
       end T1;

       task body T1 is
          Result : Natural := 0;
       begin
          for I in 1 .. N loop
             Result := PO1.Foo (Result);
          end loop;
          Put_Line ("Result =" & Natural'Image (Result));
       exception
          when E : others =>
             Put_Line ("Task_Died" & 
Ada.Exceptions.Exception_Information (E));
       end T1;

       task type T2 is
       end T2;

       task body T2 is
          Result : Natural := 0;
       begin
          for I in 1 .. N loop
             Result := PO2.Bar (Result);
          end loop;
          Put_Line ("Result =" & Natural'Image (Result));
       exception
          when E : others =>
             Put_Line ("Task_Died" & 
Ada.Exceptions.Exception_Information (E));
       end T2;

       Foo_Workers : array (1 .. 10) of T1;
       Bar_Workers : array (1 .. 10) of T2;

    begin
       null;
    end Test2;

    null;
end Test_Task_Safety;

Output:

********************************
****  Test1 : Unsafe calls *****
********************************

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Result = 1000000

********************************************************
****  Test2 : Unsafe calls from protected objects *****
********************************************************

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Task_DiedException name: SYSTEM.ASSERTIONS.ASSERT_FAILURE
Message: failed postcondition from test_task_safety.adb:15

Result = 1000000

Brad
>
> There is no reasonable rules to verify. Safety of an operation is *not*
> related to the safety of called operations, not transitive nor
> antitransitive.
>

^ permalink raw reply	[relevance 5%]

* Re: Generating an XML DOM tree from scratch withXML/Ada 2013
  @ 2014-03-21 16:12  7% ` J Kimball
  0 siblings, 0 replies; 200+ results
From: J Kimball @ 2014-03-21 16:12 UTC (permalink / raw)


On 03/20/2014 12:00 PM, Marc C wrote:
> After writing up some pathfinding code to simply create a DOM document tree from scratch, add a node, and write it out, I was perplexed that the namespace data I was supplying was not showing up in the document.
>
> Imagine my surprise when looking at the Dom.Core.Create_Document() implementation and seeing that the Namespace_URI (and Qualified_Name) parameters are simply ignored. The comment in the spec simply states "Note that Namespace_URI can be the empty string if you do not want to use namespaces."
>
> Well, I *do* want (and need) to use namespaces.
>
> The implementation of various subprograms reference namespaces and qualified names, and that seems to somehow tie into the SAX Symbol_Table that can be provided to Create_Document.  But it ain't clear what one would have to do in that regard, not to mention I'm not sure I'm even reading the code right about all that.
>
> I've got XML_EZ_Out for outputting XML, but in this instance I preferred to build the DOM tree and manipulate it, then write the whole thing out when I was done.
>
> Anyone used the GNAT GPL 2013 XML/Ada packages for creating DOM trees with namespaces?
>
> Thanks.
>
> Marc A. Criley
>

I have done this. The organization and documentation of XML is perplexing and I've also spent hours banging my head against a wall trying to use namespaces and validation.

Here's a result of my labor. I hope you can make some sense of it. Unfortunately, I couldn't find the input files that i was using to test.

There are two command line arguments. I think the first is the xml file and the second is a valid XSD schema.

Good luck.

--

with Ada.Command_Line;
with Ada.Directories;
with Ada.Direct_IO;
with Ada.Exceptions;
with Ada.Text_IO;

with DOM.Core.Elements;
with DOM.Core.Nodes;
with Input_Sources.File;
with Input_Sources.Strings;
with SAX.Readers;
with Schema.DOM_Readers;
with Schema.Schema_Readers;
with Schema.Validators;
with Unicode.CES.Utf8;

procedure Validate_Message is
    Grammar : Schema.Validators.XML_Grammar;

    Agent_NS : String := "http://example.com/schemas/agent";

    function Get_Message (XML : String) return String is
       Input    : Input_Sources.Strings.String_Input;
       Reader   : Schema.DOM_Readers.Tree_Reader;
       Document : DOM.Core.Document;

       Elements : DOM.Core.Node_List;
    begin
       Input_Sources.Strings.Open (Str => XML, Encoding => Unicode.CES.Utf8.Utf8_Encoding, Input => Input);

       Schema.DOM_Readers.Set_Grammar (Reader, Grammar);

       Schema.DOM_Readers.Set_Feature (Reader, SAX.Readers.Namespace_Prefixes_Feature, True);
       Schema.DOM_Readers.Set_Feature (Reader, SAX.Readers.Namespace_Feature, True);
--      Schema.DOM_Readers.Set_Feature (Reader, SAX.Readers.Validation_Feature, True);

       Schema.DOM_Readers.Parse (Reader, Input);
       Input_Sources.Strings.Close (Input);

       Document := Schema.DOM_Readers.Get_Tree (Reader);

       Schema.DOM_Readers.Free (Reader);

       Elements := DOM.Core.Elements.Get_Elements_By_Tag_Name_NS (Elem => Document, Namespace_URI => Agent_NS, Local_Name => "message");

       return DOM.Core.Nodes.Node_Value (DOM.Core.Nodes.Item (Elements, 0) );
    exception
       when E : others =>
          Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Information (E) );

          raise;
    end Get_Message;

    function Init_Grammar return Schema.Validators.XML_Grammar is
       Reader : Schema.Schema_Readers.Schema_Reader;
       Input  : Input_Sources.File.File_Input;
    begin
       Input_Sources.File.Open (Ada.Command_Line.Argument (2), Input);
       Schema.Schema_Readers.Parse (Reader, Input);
       Input_Sources.File.Close (Input);

       return Schema.Schema_Readers.Get_Grammar (Reader);
    end Init_Grammar;

    File_Size : Ada.Directories.File_Size := Ada.Directories.Size (Ada.Command_Line.Argument (1) );
    subtype File_Input is String (1..Integer (File_Size) );

    package File_IO is new Ada.Direct_IO (Element_Type => File_Input);

    File  : File_IO.File_Type;

    Input : File_Input;
begin
    Schema.Set_Debug_Output (True);
--   Schema.Dump_Internal_XSD := True;

    File_IO.Open (File => File, Mode => File_IO.In_File, Name => Ada.Command_Line.Argument (1) );
    File_IO.Read (File => File, Item => Input);
    File_IO.Close (File => File);

    Grammar := Init_Grammar;

    Ada.Text_IO.Put_Line (Get_Message (Input) );
end Validate_Message;

^ permalink raw reply	[relevance 7%]

* Re: need help learning Ada for a modula-2 programmer
  2014-02-02 15:02  0%       ` agent
@ 2014-02-02 19:48  9%         ` Jeffrey Carter
  0 siblings, 0 replies; 200+ results
From: Jeffrey Carter @ 2014-02-02 19:48 UTC (permalink / raw)


On 02/02/2014 08:02 AM, agent@drrob1.com wrote:
>
> ArgStr and CmdlineFrag are defined at the module level.  The working
> version of this code declares them to be bounded strings.  Brian said
> that he uses fixed length strings almost always.  I am interested in
> how that could be done.
>
> Is it correct that having a function return a fixed string is more
> flexible than a string param in a procedure?  I am getting the sense
> that having a function return the string on the stack works by not
> setting its dimensions in advance, but a param has to set them in
> advance.  So the trick is to use the stack for strings by recursion,
> as you just did?

A String object always has a fixed length, and an [in] out parameter is always 
an object. So if you want the flexibility of a variable-length result, you 
either need an unbounded parameter or a function. When a function result is 
itself made up of an unknown number of pieces concatenated together, recursion 
is a useful technique.

> I don't use recursion in my code.  This is probably because the first
> language I learned was Fortran 66, and I never needed it before.

An iterative version would collect the pieces in an Unbounded_String:

function Command_Line return String is
    Result : Ada.Strings.Unbounded.Unbounded_String;

    use type Ada.Strings.Unbounded.Unbounded_String;
begin -- Command_Line
    All_Arguments : for Arg in 1 .. Ada.Command_Line.Argument_Count loop
       Result := Result & Ada.Command_Line.Argument (Arg);

       if Arg < Ada.Command_Line.Argument_Count then
          Result := Result & ' ';
       end if;
    end loop All_Arguments;

    return Ada.Strings.Unbounded.To_String (Result);
end Command_Line;

> With the single exception of the quicksort algorithm.  Which I copied
> from a book.

I first encountered quick sort in /Software Tools/, which implemented it without 
recursion.

-- 
Jeff Carter
"We'll make Rock Ridge think it's a chicken
that got caught in a tractor's nuts!"
Blazing Saddles
87

^ permalink raw reply	[relevance 9%]

* Re: need help learning Ada for a modula-2 programmer
  2014-02-02  6:09  9%     ` Jeffrey Carter
@ 2014-02-02 15:02  0%       ` agent
  2014-02-02 19:48  9%         ` Jeffrey Carter
  0 siblings, 1 reply; 200+ results
From: agent @ 2014-02-02 15:02 UTC (permalink / raw)


On Sat, 01 Feb 2014 23:09:16 -0700, Jeffrey Carter
<spam.jrcarter.not@spam.not.acm.org> wrote:

>On 02/01/2014 07:47 PM, agent@drrob1.com wrote:
>>
>> PROCEDURE GetCommandLine(CommandLine : OUT String) is
>> BEGIN
>>    n := argument_count;
>>    k := 1;
>>
>>    WHILE k <= n LOOP
>>      move(argument(k),argstr);   -  tried this-
>>      argstr := argument(k);         -- and this.  Neither works.
>
>Where is Argstr defined?
>
>>      cmdlinefrag := cmdlinefrag & argstr;
>
>Same for Cmdlinefrag.
>
>> I don't understand how to get this working using standard strings.
>> This is easy for me using ARRAY OF CHARACTER types in M2 and
>> procedures from the Strings standard module.
>
>The actual length of Commandline is determined by the actual parameter. If you 
>want to return a String of just the right length, you'll either need an out 
>parameter of an (Un)Bounded_String type, or a function that returns String.
>
>For the latter approach, you could use recursion:
>
>function Command_Line return String is
>    function Piece (Arg : in Positive) return String is
>       -- Empty declarative part
>    begin -- Piece
>       if Arg > Ada.Command_Line.Argument_Count then
>          return "";
>       elsif Arg = Ada.Command_Line.Argument_Count then
>          return Ada.Command_Line.Argument (Arg);
>       else
>          return Ada.Command_Line.Argument (Arg) & ' ' & Piece (Arg + 1);
>       end if;
>    end Piece;
>begin -- Command_Line
>    return Piece (1);
>end Command_Line;

ArgStr and CmdlineFrag are defined at the module level.  The working
version of this code declares them to be bounded strings.  Brian said
that he uses fixed length strings almost always.  I am interested in
how that could be done.

Is it correct that having a function return a fixed string is more
flexible than a string param in a procedure?  I am getting the sense
that having a function return the string on the stack works by not
setting its dimensions in advance, but a param has to set them in
advance.  So the trick is to use the stack for strings by recursion,
as you just did?

I don't use recursion in my code.  This is probably because the first
language I learned was Fortran 66, and I never needed it before.

With the single exception of the quicksort algorithm.  Which I copied
from a book.

Thx

^ permalink raw reply	[relevance 0%]

* Re: need help learning Ada for a modula-2 programmer
  @ 2014-02-02  6:09  9%     ` Jeffrey Carter
  2014-02-02 15:02  0%       ` agent
  0 siblings, 1 reply; 200+ results
From: Jeffrey Carter @ 2014-02-02  6:09 UTC (permalink / raw)


On 02/01/2014 07:47 PM, agent@drrob1.com wrote:
>
> PROCEDURE GetCommandLine(CommandLine : OUT String) is
> BEGIN
>    n := argument_count;
>    k := 1;
>
>    WHILE k <= n LOOP
>      move(argument(k),argstr);   -  tried this-
>      argstr := argument(k);         -- and this.  Neither works.

Where is Argstr defined?

>      cmdlinefrag := cmdlinefrag & argstr;

Same for Cmdlinefrag.

> I don't understand how to get this working using standard strings.
> This is easy for me using ARRAY OF CHARACTER types in M2 and
> procedures from the Strings standard module.

The actual length of Commandline is determined by the actual parameter. If you 
want to return a String of just the right length, you'll either need an out 
parameter of an (Un)Bounded_String type, or a function that returns String.

For the latter approach, you could use recursion:

function Command_Line return String is
    function Piece (Arg : in Positive) return String is
       -- Empty declarative part
    begin -- Piece
       if Arg > Ada.Command_Line.Argument_Count then
          return "";
       elsif Arg = Ada.Command_Line.Argument_Count then
          return Ada.Command_Line.Argument (Arg);
       else
          return Ada.Command_Line.Argument (Arg) & ' ' & Piece (Arg + 1);
       end if;
    end Piece;
begin -- Command_Line
    return Piece (1);
end Command_Line;

-- 
Jeff Carter
"I'm particularly glad that these lovely children were
here today to hear that speech. Not only was it authentic
frontier gibberish, it expressed a courage little seen
in this day and age."
Blazing Saddles
88

^ permalink raw reply	[relevance 9%]

* Re: 4 beginner's questions on the PL Ada
  2013-08-10 12:31  7% ` Emanuel Berg
@ 2013-08-10 12:37  0%   ` Emanuel Berg
  0 siblings, 0 replies; 200+ results
From: Emanuel Berg @ 2013-08-10 12:37 UTC (permalink / raw)


Emanuel Berg <embe8573@student.uu.se> writes:

>> 2. How do you get options from the CL? I.e., how do you do the C
>> argv in Ada?
>
> Now, as an example, here is how I would answer my question:
>
> with Ada.Command_Line;
> use  Ada.Command_Line;
> -- ...
> Try_Hit : Boolean := (Argument_Count = 1 and
>                       Argument(1) = "-h");

Holy - isn't Ada short circuited on "and"?

-- 
Emanuel Berg - programmer (hire me! CV below)
computer projects: http://user.it.uu.se/~embe8573
internet activity: http://home.student.uu.se/embe8573


^ permalink raw reply	[relevance 0%]

* Re: 4 beginner's questions on the PL Ada
    2013-08-09 17:09  4% ` Adam Beneschan
@ 2013-08-10 12:31  7% ` Emanuel Berg
  2013-08-10 12:37  0%   ` Emanuel Berg
  1 sibling, 1 reply; 200+ results
From: Emanuel Berg @ 2013-08-10 12:31 UTC (permalink / raw)


Emanuel Berg <embe8573@student.uu.se> writes:

> 2. How do you get options from the CL? I.e., how do you do the C
> argv in Ada?

Now, as an example, here is how I would answer my question:

with Ada.Command_Line;
use  Ada.Command_Line;
-- ...
Try_Hit : Boolean := (Argument_Count = 1 and
                      Argument(1) = "-h");

-- 
Emanuel Berg - programmer (hire me! CV below)
computer projects: http://user.it.uu.se/~embe8573
internet activity: http://home.student.uu.se/embe8573


^ permalink raw reply	[relevance 7%]

* Re: 4 beginner's questions on the PL Ada
  @ 2013-08-09 17:09  4% ` Adam Beneschan
  2013-08-10 12:31  7% ` Emanuel Berg
  1 sibling, 0 replies; 200+ results
From: Adam Beneschan @ 2013-08-09 17:09 UTC (permalink / raw)


On Friday, August 9, 2013 9:50:53 AM UTC-7, Emanuel Berg wrote:
> 1. How do you make a constant in Ada? Can I make one that is
> computed, for example an integer, set to Milliseconds(something)?

   Some_Constant : constant integer := <expression>.  The expression can be any expression that can be computed.

 
> 2. How do you get options from the CL? I.e., how do you do the C 
> argv in Ada?

Ada.Command_Line.  http://www.ada-auth.org/standards/12rm/html/RM-A-15.html

 
> 3. Is it possible to get the task *name* (from the code) into a 
> string, programatically? That way, a generic procedure could be
> used to communicate from tasks, with Put_Line, and without having
> to hard code the task name every time.

No, not really.  One thing to keep in mind is that Ada has task *types*, so that you can declare a task type and then start any number of tasks of that type.  And the tasks don't have to be associated with variables; you can start an array of tasks:

   type Task_Array is array (1 .. 10) of Task_Type;
   T : Task_Array;

will start 10 tasks, and they won't really have names.  Well, I guess you can call them T(1), T(2), ...  But tasks can also be record components, and you can have accesses to tasks, so there really isn't a concept of a "name" for a task.  So if you want to give tasks a name, you'll have to do this in the program.


> 4. How do you exit Ada altogether? For example, if there are 3 
> tasks, and one solves the problem, how can I terminate the whole
> application at once? (Rather than sending messages to all the
> tasks, "OK, we're done looking!")

I don't recommend having one task kill the entire program.  Ada allows you to define types that have finalization procedures associated with them (e.g. for a file, you might want a finalization procedure that makes sure any remaining data is flushed to the file).  Ada makes sure that when a procedure or task is exited, anything that needs to be finalized will be finalized.  Performing an operation that just exits the program suddenly will subvert that.  There's an "abort" statement to allow one task to terminate other tasks; that *does* ensure that finalization takes place.  But overall, I think it's better to do things cleanly; one way is to send a message to the other tasks with entry calls, but you can also create a variable (or a protected object) that's accessible to all tasks that they can check at certain points to see if they can quit.

                               -- Adam

^ permalink raw reply	[relevance 4%]

* Re: Where would you start debugging?
  2013-06-27 14:33  5% ` G.B.
@ 2013-06-28 10:35  0%   ` Peter Brooks
  0 siblings, 0 replies; 200+ results
From: Peter Brooks @ 2013-06-28 10:35 UTC (permalink / raw)


G.B. <rm-dash-bau-haus@dash.futureapps.de> wrote:
> Will 'Value do?
> 
>    type Enum is (Yeah, Bee, See);
> 
>    ...
> 
>    declare
>       use Ada.Command_Line;
>       Test : Enum;
>    begin
>       Test := Enum'Value (Argument (1));
>       Text_IO.Put_Line (Natural'Image (Enum'Pos (Test)));
>    exception
>       when Constraint_Error =>
>          -- ...
>    end;
> 
Perfect - thank you!

^ permalink raw reply	[relevance 0%]

* Re: Where would you start debugging?
  @ 2013-06-27 14:33  5% ` G.B.
  2013-06-28 10:35  0%   ` Peter Brooks
  0 siblings, 1 reply; 200+ results
From: G.B. @ 2013-06-27 14:33 UTC (permalink / raw)


On 27.06.13 15:53, Peter Brooks wrote:
> I've written a small package, there's not much point in putting it here. The moment I run it it is giving me this error:
>
> raised CONSTRAINT_ERROR : erroneous memory access
>
> I'm using gnat on a Mac. The odd thing is that this happens when the calling program simply has a 'with' statement mentioning the package, there's no need to call it.
>
> So, it's clearly part of the iniitalisation of the package.
>
> Where should I start debugging?

If the with-ed package is yours, -gnatVa, -gnatwa, -fstack-check,
and -gnato could help as they add more checks and warnings.
-gnatE and -gnata might also help.

In case the with-ed package is from the run-time system or similar,
I'd add GNAT switches -x, -a, and possibly -m to the above.

Before starting gdb, I'd try a tool like valgrind (of which XCode
has an equivalent IIRC.)

>  should I forget this method and just parse the string manually?

Will 'Value do?

    type Enum is (Yeah, Bee, See);

    ...

    declare
       use Ada.Command_Line;
       Test : Enum;
    begin
       Test := Enum'Value (Argument (1));
       Text_IO.Put_Line (Natural'Image (Enum'Pos (Test)));
    exception
       when Constraint_Error =>
          -- ...
    end;



^ permalink raw reply	[relevance 5%]

* Gnat Version 4.5.4 v protected objects v tasking
@ 2013-04-23 20:30  5% stvcook53
  0 siblings, 0 replies; 200+ results
From: stvcook53 @ 2013-04-23 20:30 UTC (permalink / raw)


Please consider sample code and comment to remedy failure in code sample or compiler.

Tried several versions of GPL Gnat Ada this year to build under x86_64 RHEL5 OS where previously succeeded with i386 OS.  Fortunately, the 4.5.4 libre gnat builds all my source code, but exhibits strange run-time symptoms using a sample that worked with older Gnat versions.  

Symptoms out of 4.5.4 relate to the tasking portion of the Ada run-time system, and relate to protected objects when located outside the main program.  Symptoms manifest as a silent hang when a program is run that includes the tasking portion of the runtime system.  The gdb debugger exhibits a SIGSEGV while in the run-time package System.Secondary_Stack.  Symptom occurs at the end of elaboration before control enters main program.  Please comment on sample code or planned, related Gnat updates.

Note: Internal compilation errors are common when trying to build my larger code using older Gnat versions in x86_64 configuration.  This includes 3.1.6, 4.1.0, and 4.3.6.  Emphasis on run-time in latest Gnat is derived from its success at building other code.

Sample code is summarized as follows:

main(Test_Protected_Object)
  with Contrived;

spec(Contrived)
body(Contrived) note: 3 types
    1. no tasking
    2. protected object
    3. task

Detailed code follows:
--main***
--Simple program to attempt to reproduce segmentation fault.

with Ada.Text_IO;
with Ada.Exceptions;
with Ada.Command_Line;

with Contrived; -- add code actually involved in segmentation fault

procedure Test_Protected_Object is

begin  --Test_Protected_Object

   Ada.Text_IO.Put_Line("Test_Protected_Object: ");

   Ada.Text_IO.Put_Line("  The program name is "
                        & Ada.Command_Line.Command_Name);

   Ada.Text_IO.Put_Line("** before referencing protected object: ");
   Contrived.Print_This;
   Ada.Text_IO.Put_Line("*** after referencing protected object: ");

exception
 when E:others =>
   Ada.Text_IO.Put_Line("** unexpected exception "
                        & Ada.Exceptions.Exception_Name(E));
end Test_Protected_Object;

--spec(Contrived) ***
-------------------------------------------------------------------------------
-- Contrived package containing:
--   a.  no tasking
--   b.  a protected object
--   c.  a task
-- in the package body, depending upon which configuration I which to test.
-------------------------------------------------------------------------------

package Contrived is

   procedure Print_This;

end Contrived;

--body(Contrived - Option A no symptom) ***
-------------------------------------------------------------------------------
-- Contrived package containing:
--   a.  no tasking
--   b.  a protected object
--   c.  a task
-- in the package body, depending upon which configuration I which to test.
-------------------------------------------------------------------------------

-- this is configuration a.
with Ada.Text_IO;

package body Contrived is

   procedure Print_This is
   begin
      Ada.Text_IO.Put_Line("Contrived:  Print_This");
   end Print_This;

end Contrived;

--body(Contrived - Option B symptom) ***
-------------------------------------------------------------------------------
-- Contrived package containing:
--   a.  no tasking
--   b.  a protected object
--   c.  a task
-- in the package body, depending upon which configuration I which to test.
-------------------------------------------------------------------------------

-- this is configuration b.
with Ada.Text_IO;

package body Contrived is

   protected Object is
      procedure Print_That;
   end Object;

   protected body Object is
      procedure Print_That is
      begin
         Ada.Text_IO.Put_Line("Contrived.Object.Print_That");
      end Print_That;
   end Object;

   procedure Print_This is
   begin
      Ada.Text_IO.Put_Line("Contrived:  Print_This");
      Object.Print_That;
   end Print_This;

end Contrived;

--body(Contrived - Option C same symptom) ***
-------------------------------------------------------------------------------
-- Contrived package containing:
--   a.  no tasking
--   b.  a protected object
--   c.  a task
-- in the package body, depending upon which configuration I which to test.
-------------------------------------------------------------------------------

-- this is configuration c.
with Ada.Text_IO;

package body Contrived is

   task Object is
      entry Print_That;
   end Object;

   task body Object is
   begin
      loop
         select
            accept Print_That;
            Ada.Text_IO.Put_Line("Contrived.Object.Print_That");
         or
            terminate;
         end select;
      end loop;
   end Object;

   procedure Print_This is
   begin
      Ada.Text_IO.Put_Line("Contrived:  Print_This");
      Object.Print_That;
   end Print_This;

end Contrived;



^ permalink raw reply	[relevance 5%]

* Re: Ada and OpenMP
  @ 2013-03-08 21:37  8%   ` Brad Moore
  0 siblings, 0 replies; 200+ results
From: Brad Moore @ 2013-03-08 21:37 UTC (permalink / raw)


On 07/03/2013 3:52 PM, Simon Wright wrote:
> "Rego, P." <pvrego@gmail.com> writes:
>
>> I'm trying some exercises of parallel computing using that pragmas
>> from OpenMP in C, but it would be good to use it also in Ada. Is it
>> possible to use that pragmas from OpenMP in Ada? And...does gnat gpl
>> supports it?
>
> GNAT doesn't support OpenMP pragmas.
>
> But you might take a look at Paraffin:
> http://sourceforge.net/projects/paraffin/
>

To give an example using Paraffin libraries,

The following code shows the same problem executed sequentially, and
then executed with Paraffin libraries.

with Ada.Real_Time;    use Ada.Real_Time;
with Ada.Command_Line;
with Ada.Text_IO; use Ada.Text_IO;
with Parallel.Iteration.Work_Stealing;

procedure Test_Loops is

    procedure Integer_Loops is new
      Parallel.Iteration.Work_Stealing (Iteration_Index_Type => Integer);

    Start : Time;

    Array_Size : Natural := 50;
    Iterations : Natural := 10_000_000;

begin

    --  Allow first command line parameter to override default iteration 
count
    if Ada.Command_Line.Argument_Count >= 1 then
       Iterations := Integer'Value (Ada.Command_Line.Argument (1));
    end if;

    --  Allow second command line parameter to override default array size
    if Ada.Command_Line.Argument_Count >= 2 then
       Array_Size := Integer'Value (Ada.Command_Line.Argument (2));
    end if;

    Data_Block : declare
       Data : array (1 .. Array_Size) of Natural := (others => 0);
    begin

       --  Sequential Version of the code, any parallelization must be auto
       --  generated by the compiler

       Start := Clock;

       for I in Data'Range loop
          for J in 1 .. Iterations loop
             Data (I) := Data (I) + 1;
          end loop;
       end loop;

       Put_Line ("Sequential Elapsed=" & Duration'Image (To_Duration 
(Clock - Start)));

       Data := (others => 0);
       Start := Clock;

       --  Parallel Version of the code, explicitly parallelized using 
Paraffin
       declare

          procedure Iterate (First : Integer; Last : Integer) is
          begin
             for I in First .. Last loop
                for J in 1 .. Iterations loop
                   Data (I) := Data (I) + 1;
                end loop;
             end loop;
          end Iterate;

       begin
          Integer_Loops (From         => Data'First,
                         To           => Data'Last,
                         Worker_Count => 4,
                         Process      => Iterate'Access);
       end;

       Put_Line ("Parallel Elapsed=" & Duration'Image (To_Duration 
(Clock - Start)));

    end Data_Block;

end Test_Loops;

When run on my machine AMD Quadcore with parameters 100_000 100_000, 
with full optimization turned on with -ftree-vectorize, I get.

Sequential Elapsed= 6.874298000
Parallel Elapsed= 6.287230000

With optimization turned off, I get

Sequential Elapsed= 32.428908000
Parallel Elapsed= 8.424717000

gcc with GNAT does a good job of optimization when its enabled, for 
these cases as shown, but the differences between optimization and using 
Paraffin can be more pronounced in other cases that are more complex, 
such as loops that involve reduction (e.g. calculating a sum)

Brad



^ permalink raw reply	[relevance 8%]

* Re: platform specific question
  2012-12-09 15:11  0%     ` Bill Findlay
@ 2012-12-10 11:36  0%       ` Hans Vlems
  0 siblings, 0 replies; 200+ results
From: Hans Vlems @ 2012-12-10 11:36 UTC (permalink / raw)


On 9 dec, 16:11, Bill Findlay <yaldni...@blueyonder.co.uk> wrote:
> On 09/12/2012 13:50, in article
> 03f19861-e90d-4664-8f1b-02580aea8...@e25g2000vbm.googlegroups.com, "Hans
>
>
>
>
>
> Vlems" <hvl...@freenet.de> wrote:
> > On 7 dec, 19:29, Jeffrey Carter <spam.jrcarter....@spam.not.acm.org>
> > wrote:
> >> On 12/07/2012 11:14 AM, Hans Vlems wrote:
>
> >>> C programs have easy access to commandline arguments and "environment
> >>> variables".
> >>> Is there a way to interpret the environment variables on a Windows
> >>> (2008 Server R2) platform?
> >>> What I'm looking for is the usercode that executes the program. Some
> >>> programs offer different functionality which is now derived from a
> >>> table that is organised by username/usercode.
>
> >> For command-line arguments, there's package Ada.Command_Line (ARM
> >> A.15,http://www.adaic.org/resources/add_content/standards/05rm/html/RM-A-1...
> >> for environment variables, package Ada.Environment_Variables (ARM
> >> A.17,http://www.adaic.org/resources/add_content/standards/05rm/html/RM-A-1...
> >> ).
>
> >> Ada.Command_Line has existed since 1995; Ada.Environment_Variables came along
> >> in
> >> 2007.
>
> >> --
> >> Jeff Carter
> >> "I like it when the support group complains that they have
> >> insufficient data on mean time to repair bugs in Ada software."
> >> Robert I. Eachus
> >> 91
>
> > Jeff, thanks for the pointers.
> > I stopped using ADA in 1984 or so and have only recently returned to
> > the language.
> > If only to discover that ADA has changed a lot in the mean time.
>
> Indeed, but just as back in 1984, it is still named Ada, not ADA.
>
> --
> Bill Findlay
> with blueyonder.co.uk;
> use  surname & forename;- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -

Sure, especially today!



^ permalink raw reply	[relevance 0%]

* Re: platform specific question
  2012-12-09 13:50  0%   ` Hans Vlems
@ 2012-12-09 15:11  0%     ` Bill Findlay
  2012-12-10 11:36  0%       ` Hans Vlems
  0 siblings, 1 reply; 200+ results
From: Bill Findlay @ 2012-12-09 15:11 UTC (permalink / raw)


On 09/12/2012 13:50, in article
03f19861-e90d-4664-8f1b-02580aea84c0@e25g2000vbm.googlegroups.com, "Hans
Vlems" <hvlems@freenet.de> wrote:

> On 7 dec, 19:29, Jeffrey Carter <spam.jrcarter....@spam.not.acm.org>
> wrote:
>> On 12/07/2012 11:14 AM, Hans Vlems wrote:
>> 
>>> C programs have easy access to commandline arguments and "environment
>>> variables".
>>> Is there a way to interpret the environment variables on a Windows
>>> (2008 Server R2) platform?
>>> What I'm looking for is the usercode that executes the program. Some
>>> programs offer different functionality which is now derived from a
>>> table that is organised by username/usercode.
>> 
>> For command-line arguments, there's package Ada.Command_Line (ARM
>> A.15,http://www.adaic.org/resources/add_content/standards/05rm/html/RM-A-1...
>> for environment variables, package Ada.Environment_Variables (ARM
>> A.17,http://www.adaic.org/resources/add_content/standards/05rm/html/RM-A-1...
>> ).
>> 
>> Ada.Command_Line has existed since 1995; Ada.Environment_Variables came along
>> in
>> 2007.
>> 
>> --
>> Jeff Carter
>> "I like it when the support group complains that they have
>> insufficient data on mean time to repair bugs in Ada software."
>> Robert I. Eachus
>> 91
> 
> Jeff, thanks for the pointers.
> I stopped using ADA in 1984 or so and have only recently returned to
> the language.
> If only to discover that ADA has changed a lot in the mean time.


Indeed, but just as back in 1984, it is still named Ada, not ADA.

-- 
Bill Findlay
with blueyonder.co.uk;
use  surname & forename;





^ permalink raw reply	[relevance 0%]

* Re: platform specific question
  2012-12-07 18:29  7% ` Jeffrey Carter
@ 2012-12-09 13:50  0%   ` Hans Vlems
  2012-12-09 15:11  0%     ` Bill Findlay
  0 siblings, 1 reply; 200+ results
From: Hans Vlems @ 2012-12-09 13:50 UTC (permalink / raw)


On 7 dec, 19:29, Jeffrey Carter <spam.jrcarter....@spam.not.acm.org>
wrote:
> On 12/07/2012 11:14 AM, Hans Vlems wrote:
>
> > C programs have easy access to commandline arguments and "environment
> > variables".
> > Is there a way to interpret the environment variables on a Windows
> > (2008 Server R2) platform?
> > What I'm looking for is the usercode that executes the program. Some
> > programs offer different functionality which is now derived from a
> > table that is organised by username/usercode.
>
> For command-line arguments, there's package Ada.Command_Line (ARM A.15,http://www.adaic.org/resources/add_content/standards/05rm/html/RM-A-1...
> for environment variables, package Ada.Environment_Variables (ARM A.17,http://www.adaic.org/resources/add_content/standards/05rm/html/RM-A-1...).
>
> Ada.Command_Line has existed since 1995; Ada.Environment_Variables came along in
> 2007.
>
> --
> Jeff Carter
> "I like it when the support group complains that they have
> insufficient data on mean time to repair bugs in Ada software."
> Robert I. Eachus
> 91

Jeff, thanks for the pointers.
I stopped using ADA in 1984 or so and have only recently returned to
the language.
If only to discover that ADA has changed a lot in the mean time.
Hans



^ permalink raw reply	[relevance 0%]

* Re: platform specific question
  @ 2012-12-07 18:29  7% ` Jeffrey Carter
  2012-12-09 13:50  0%   ` Hans Vlems
  0 siblings, 1 reply; 200+ results
From: Jeffrey Carter @ 2012-12-07 18:29 UTC (permalink / raw)


On 12/07/2012 11:14 AM, Hans Vlems wrote:
> C programs have easy access to commandline arguments and "environment
> variables".
> Is there a way to interpret the environment variables on a Windows
> (2008 Server R2) platform?
> What I'm looking for is the usercode that executes the program. Some
> programs offer different functionality which is now derived from a
> table that is organised by username/usercode.

For command-line arguments, there's package Ada.Command_Line (ARM A.15, 
http://www.adaic.org/resources/add_content/standards/05rm/html/RM-A-15.html); 
for environment variables, package Ada.Environment_Variables (ARM A.17, 
http://www.adaic.org/resources/add_content/standards/05rm/html/RM-A-17.html).

Ada.Command_Line has existed since 1995; Ada.Environment_Variables came along in 
2007.

-- 
Jeff Carter
"I like it when the support group complains that they have
insufficient data on mean time to repair bugs in Ada software."
Robert I. Eachus
91



^ permalink raw reply	[relevance 7%]

* Re: Ada.Storage_IO: applied example?
  @ 2012-10-24 14:03  5%             ` Georg Bauhaus
  0 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2012-10-24 14:03 UTC (permalink / raw)


On 24.10.12 13:51, Yannick Duchêne (Hibou57) wrote:
> Le Wed, 24 Oct 2012 12:28:00 +0200, Dmitry A. Kazakov
> <mailbox@dmitry-kazakov.de> a écrit:
> 
>> On Wed, 24 Oct 2012 02:49:02 -0700 (PDT), AdaMagica wrote:
>>
>>> See AARM A.9(1.a):
>>> Reason: This package exists to allow the portable construction of
>>> user-defined direct-access-oriented input-output packages.
>>
>>    portable construction of X /= construction of portable X
>>
>> The package cannot be used to write files in a way that an application
>> compiled by one compiler X1 under OS Y1 could write a file readable for
>> compiler X2 under OS Y2.
>>
>> In order to be portable they should have defined the exact representation
>> of the object in the file. Yes, nobody would do that, but then they should
>> not include useless packages into the standard either.
> 
> What about private persistent storage?
> 

If traditional Ada I/O is good for your Ada program, you
can use Storage_IO in conventional algorithms this way. The
setup can employ static polymorphism that allows selecting
instances of Storage_IO or Direct_IO as needed.
Either at startup or later.

<rant>
The solution, using the egregious generic mechanisms of Ada,
will suffer from all the advantages of lack of an unused
tagged parameter.

The whole approach of stating requirements as generic formals
suffers from good opportunities for compilers to perform
optimization.

It suffers from the fact that stored internal program
data is not being stored in an ISO-approved form ready for
inspection by non-generic programs of an unrelated make
and purpose.

It also suffers from the problem that it still cannot make
the external world an Ada object, which could mollify the
previously argued flaw.

It suffers from lack of opportunities to control I/O of
octets algorithmically, thus preventing emulation of nice
per-program Storage_IO objects in DIY fashion.

It also suffers from not being a silver bullet.

But other than that ...</rant>

with Ada.Direct_IO;
with Ada.Storage_IO;
with Ada.Command_Line;  use Ada.Command_Line;

procedure Lookahead is
   use Ada;

   type Sentence (Length : Positive := 100) is record
      Text : Wide_String (1 .. 100);
   end record;

   subtype Name is Wide_String (1 .. 20);

   type Big is record   -- objects that will be processed
      First, Last : Name;
      Age : Natural;
      Motto : Sentence;
   end record;

   generic
      with procedure Store_Single_Item (Item : in Big);
      with procedure Fetch_Single_Item (Item : out Big);
   procedure Process_Records;

   procedure Process_Records is separate;
begin
   if Natural'Value (Argument(1)) = 0 then
      declare
         package Volatile is
            procedure Store (Item : in Big);
            procedure Fetch (Item : out Big);
         end Volatile;
         package body Volatile is
            package Undo_Buffer is new Storage_IO (Big);
            Storage : Undo_Buffer.Buffer_Type;
            procedure Fetch (Item : out Big) is
            begin
               Undo_Buffer.Read (Storage, Item);
            end Fetch;
            procedure Store (Item : in Big) is
            begin
               Undo_Buffer.Write (Storage, Item);
            end Store;
         end Volatile;
         procedure Run is new Process_Records
           (Store_Single_Item => Volatile.Store,
            Fetch_Single_Item => Volatile.Fetch);
      begin
         Run;
      end;
   else
      declare
         package Permanent is
            procedure Store (Item : in Big);
            procedure Fetch (Item : out Big);
         end Permanent;
         package body Permanent is
            package Undo_Buffer is new Direct_IO (Big);
            Storage : Undo_Buffer.File_Type;
            procedure Fetch (Item : out Big) is
            begin
               Undo_Buffer.Read (Storage, Item);
            end Fetch;
            procedure Store (Item : in Big) is
            begin
               Undo_Buffer.Write (Storage, Item);
            end Store;
            use Undo_Buffer;
         begin
            open (storage, Inout_File, "item.sto");
         end Permanent;
         procedure Run is new Process_Records
           (Store_Single_Item => Permanent.Store,
            Fetch_Single_Item => Permanent.Fetch);
      begin
         Run;
      end;
   end if;

end Lookahead;

separate (Lookahead)
procedure Process_Records is
   package Rec_IO is new Direct_IO (Big); use Rec_IO;
   Current: Big := (Age => Natural'Last, others => <>);
   input : File_Type;
   output : File_Type;
begin
   open (input, In_File, "records.all");
   open (output, Out_File, "records.flt");
   loop
      Store_Single_Item (Current);
      Read (input, current);
      -- ... filter based on pairs ...
         write (output, current);
   end loop;
end Process_Records;




^ permalink raw reply	[relevance 5%]

* Re: Ada  "library only" compiler ?
  2012-07-21 16:47  5%     ` Niklas Holsti
@ 2012-07-21 17:47  3%       ` Patrick
  0 siblings, 0 replies; 200+ results
From: Patrick @ 2012-07-21 17:47 UTC (permalink / raw)


Hi Again Niklas

Thanks for spending so much time with me on this.

"So? The package Ada.Command_Line is unlikely to be linked into your Ada
program if you don't use it explicitly. And the mere existence of this
package is a trivial burden on the compiler. And I would bet that the
code in this package is of trivial size."

Good point, I'm totally wrong here

I only meant that the Ada language is huge, I didn't mean to say anything bad about the final executable.

Thanks for explaining GCC to me, I was mixed up. I assumed that each compiler(C, Ada, C++) got the code down to ASM to be passed off to GAS and GCC was a dispatcher to full blown compilers that could exist on their own if used with an ASM compiler.

I am such a poor writer, I do seem to be having trouble explaining myself, let me try again.

So I spent a couple of years with Lua and my experience with it was that it is a language being pulled in two directions. The Lua team seem to think it is best used for extending and embedding in C but the community also want more libraries written in lua itself. The Lua team does not bless more then a tiny set of libraries(just a few thousand lines) and there is no official way to do many things such as serializing data.

My Lua experience has left me shell-shocked and worried about using a lot of the Ada libraries. It took a lot of time to learn various Lua libraries and after finding two or three crappy ones in a row, it got frustrating. I am not saying that the same thing will be true for Ada but it might be nice if all the Ada binding code was in a certain place. I like Lua still but if I am going to use it again, I am going to mix C libraries and Lua and pretty much forego the Lua libraries. It's easy enough to do this as Lua and it's tiny libraries are easy to keep separate.

If GNAT had a clearer separation of concerns between C and Ada, I could do the same with Ada or use Ada libraries when I want to but right now a lot seems to be bundled together and it is hard to tell what is binding and what is not.


I think Ada the language itself is perfect and don't have any interest in changing it in any way, it's the C portion I would like to tinker more with.  If GNAT had C split off somewhere and that code was "withed" into Ada code later, I might have a better understand of how it interacts with the OS and other topics.

Right now I don't know where the runtimes live or even what language they are written in. I don't know how they act on bare metal or with an OS. Keeping the syntax translation of Ada separate from interaction with everything else might give people like me a fighting chance of understand what is going on and perhaps even moving the language to new targets.

Thanks again-Patrick




^ permalink raw reply	[relevance 3%]

* Re: Ada  "library only" compiler ?
  @ 2012-07-21 16:47  5%     ` Niklas Holsti
  2012-07-21 17:47  3%       ` Patrick
  0 siblings, 1 reply; 200+ results
From: Niklas Holsti @ 2012-07-21 16:47 UTC (permalink / raw)


On 12-07-21 02:30 , Patrick wrote:
> Hi Niklas
>
> ...
>
> So just to clarify, I am not advocating an Ada interpreter, it's just
> that Lua's developers are quite resistant to implementing more then
> the tiniest set of standard libraries. Lua and all the standard
> libraries are less then 18K lines of code and they are determined to
> keep it that way. Lua programmers are supposed to rely on C.

Lua is explicitely meant to be an "extension language", to make some 
application "scriptable". The heavy application functions are meant to 
be implemented in C (or whatever the host application language is), with 
calls from and to Lua code to add flexibility.

I don't think that C libraries can be used easily to extend "Lua the 
language" with more language features.

Ada is not meant to be an extension language, but to be a full language 
in which one can implement entire applications.

So I don't quite understand why you are using Lua as a comparison. 
Perhaps we can approach this in another way, by asking you why you would 
prefer to use Ada rather than Lua? Which features of Ada are absent from 
Lua, or are better than the corresponding features in Lua? We can then 
discuss if and how these features could be implemented in the same way 
that Lua is currently implemented.

> Ada is huge

That is debatable. But even if you consider "Ada the language" to be 
huge, this just means that an Ada compiler has a lot to do, so the 
compilers are "huge" and hard to write. This is in harmony with the 
goals of the Ada language: to allow lots of compile-time checking. The 
generated code is not necessarily huge.

> and I am not proposing some sort of limit like this but I
> do think that a strategic retreat might be in order, at least for
> some of us and Lua is an example of this. There are not really that
> many libraries and bindings relative to C. If someone had a small Ada
> compiler that they knew had to be supplemented with C that might
> offer a little more clarity of purpose and perhaps leaning on C for
> library support is the better way to go for some people and a toolset
> tailor made for this might be good. Again I don't mean to bash Ada, I
> do like it a lot.

Which parts of "Ada the language" would you omit and replace by "library 
support"?

Historically, some Ada developers avoided the tasking features and 
instead used some non-Ada real-time kernel. Instead of creating 
tasks/threads with the Ada "task" keyword, they would call a kernel 
function to create the thread at run-time, providing some ordinary Ada 
subprogram as the "main function" of the thread. This can be seen as an 
example of replacing Ada language features with libraries (and, I regret 
to say, this practice still goes on in some places).

It is not so clear what other language features could profitably be 
replaced in this way. At the moment, only the fixed-point types come to 
my mind. An Ada program could avoid the Ada fixed-point types and 
instead call some fixed-point library, much like some Ada programs now 
use libraries for unbounded numbers ("bignums"). It seems to me that 
removing fixed-point types from Ada would simplify the compilers -- but 
probably not by much.

> So for instance it looks like Ada has a library to retrieve command
> line arguments.

Yes, Ada.Command_Line, a standard predefined package.

> However it looks to be just thin wrapper over ARGV and ARGC.

The services of Ada.Command_Line are similar to ARGV/ARGC, yes. This was 
a natural minimum level to provide. However, Ada.Command_Line can be 
implemented on systems that have a different method to access 
command-line parameters.

> If someone wanted to use something a little higher up like
> getopts, they could rework ARGV/ARGC out this part of their C
> boilerplate code.

An Ada program can certainly use the getopt() library function, although 
it may have to provide a C "main" function to do so (and how that is 
done depends on the Ada compiler).

> At the moment the Ada binding is there whether or
> not you use it.

So? The package Ada.Command_Line is unlikely to be linked into your Ada 
program if you don't use it explicitly. And the mere existence of this 
package is a trivial burden on the compiler. And I would bet that the 
code in this package is of trivial size.

> I am assuming there will be many more examples of
> this.

Examples of what, exactly?

If you look at the rest of the Ada predefined standard library packages, 
they either provide substantial functionality that is not standard in C 
(e.g. Ada.Calendar, Ada.Strings.Unbounded, Ada.Containers.*), or they 
are simple wrappers (e.g. Ada.Characters.Handling) for C or POSIX 
functions. The former can mostly be implemented in Ada itself, in a 
portable way; the latter can be implemented by calling system functions 
or libraries, in C or other languages. So I don't believe that the 
library packages are a significant obstacle to making Ada available on 
more devices, in particular since one can just say "sorry, my compiler 
does not (yet) support package X".

> However also as an example of my ignorance, I tried this to see if I
> could generate ASM from gnat: gnatmake -S first_procedure.adb
>
> It calls GCC right away: gcc -c -S first_procedure.adb gnatmake:
> "first_procedure.ali" WARNING: ALI or object file not found after
> compile gnatmake: "first_procedure.adb" compilation erro

GCC does not mean "GNU C Compiler", it means "GNU Compiler Collection" 
or "GNU Compiler Caller". The "gcc" program is a driver that parses the 
arguments and then calls the real compiler programs according to the 
chosen or deduced source language. The program "gnat1" is the real GNAT 
Ada compiler and gcc will call it eventually. (The program "cc1" is the 
real GNU C compiler.)

> It looks like GNAT does not generate it's own ASM but relies on GCC
> for this, so the idea of reworking GNAT into an Ada to ASM converter
> is certainly false, they must interact with an internal
> representation.

Your understanding of how GNAT and GCC work is a bit confused.

The principle is that the GNU compilers are separated into a "front end" 
part, distinct for each language, and a "back end" part that is distinct 
for each target processor. The front end for language X translates the X 
source code into the GCC internal representation; the back end for 
processor P translates the internal representation into 
assembly-language source code for P. The assembler for P then translates 
the assembly-language source code into binary machine code for P.

The Ada-specific part of GNAT is in the front end, which (as I 
understand it) is the "gnat1" program. But perhaps I should not say 
more, since I really don't know the details.

 > So at best it would be an Ada to GCC IR converter and
 > then other then a simpler to understand compiler, i guess the
 > proposal really doesn't offer much.

The core of GNAT is already an Ada-to-GCC-IR converter.

But the main point is that much of what an Ada compiler does, and most 
of what is due to the "hugeness" of Ada, does not depend on the target 
processor. When an Ada compiler sees "I+J", where I and J are some 
integer variables, it does not immediately decide to use a specific ADD 
instruction from the target processor's instruction set. Instead, after 
many checks on the legality of the expression, and after deciding which 
function called "+" is meant, the expression "I+J" is translated into 
the compiler's intermediate language and passed to the back end, which 
chooses the instructions. It may well be that the instructions chosen to 
compute I+J are quite different when the expression is used in a 
statement like K:=I+J, and when it is used in an expression like 
K:=Some_Array(I+J).

To conclude, if the goal is to make Ada available on some device D that 
is supported by the GCC back-end, then:
- most of the Ada-specific work is already done in GNAT, and
- most of the D-specific work is already done in GCC.

What is left to do is to take care of the details (where the devil is, 
of course), and implement the run-time support for Ada on device D. As 
can be seen from the AVR-Ada example, the compiler can be useful even 
with rudimentary run-time support.

If performance is not important, an alternative is to choose some 
virtual machine V, add support for that virtual machine to the GCC 
back-end, and port GNAT into an Ada-to-V compiler. The run-time system 
could then be written once, for V, and the V simulator could probably be 
written in a fairly portable way, to run on several devices with small 
adaptations. This was the JGNAT route (GNAT ported to compile Ada into 
byte code for the Java Virtual Machine). I'm not sure if JGNAT is still 
with us; it seems it had few users.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .





^ permalink raw reply	[relevance 5%]

* Re: GNAT (GCC) Profile Guided Compilation
  2012-07-01 17:45  4%           ` Georg Bauhaus
@ 2012-07-01 22:57  0%             ` Keean Schupke
  0 siblings, 0 replies; 200+ results
From: Keean Schupke @ 2012-07-01 22:57 UTC (permalink / raw)


On Sunday, 1 July 2012 18:45:22 UTC+1, Georg Bauhaus  wrote:
> On 29.06.12 19:03, Keean Schupke wrote:
> > Note: this is not really answering my question about the lack of improvement due to profile-guided compilation - but perhaps that side of things is more a compiler issue. Does anyone have any ideas about that side of things?
> 
> Some more observations, collected with the help of the simple
> two example programs appended below.
> 
> For Ada and GNAT at least, any advantages to be had from profile-guided
> compilation seem to vary with optimization options and sizes of data.
> The same is true about a 1D approach vs a 2D approach.
> 
> Among the various arrangements, one of the best I have got
> from both GNAT GPL 2012, and from an FSF GNAT as of June 2012
> uses
> *) -O2 -funroll-loops -gnatp
> *)  the 2D approach
> 
> (If it means a anything, adding -ftree-vectorize to the -O2 set
> produces only the second best Ada result, the same as the -O3 times
> listed below. I had chosen -ftree-vectorize as this switch is in the
> O3 set.) Trying profile guided compilation at higher optimization
> levels consistently slowed the Ada program down (other Ada programs
> were faster after profile guided compilation, as mentioned elsewhere).
> 
> The result at -O2 seems nice, though, in that the 2D approach is
> natural, the compiler switches are the ones that the manual recommends.
> and this combination produces the fastest Ada program.
> 
> In short, from worst to best 1D / 2D, Runs = 100:
> 
> Ada profile guided -> .88 / .80   (this program only!)
> Ada at -O3         -> .68 / .66
> C++ at -O3         -> .66
> Ada at -O2 -funr.. -> .68 / .47
> C++ profile guided -> .31
> 
> 
> Some differences seem to vary with hardware, too.
> On one computer I have seen a minor speedup, on another
> a very small slowdown, and a different ratio of 1D / 2D.
> 
> For the C++ case I have tested a 1D approach only, not
> knowing how to write 2D arrays in C++ using C style arrays.
> I'm not a C++ programmer, apologies for my C++.
> 
> 
> Ada at -O2 -funroll-loops -gnatp -mtune=native
> 1D:  0.680750000 27303
> 2D:  0.469094000 27303  <-- Best for Ada!
> 
> Ada at -O3 -gnatNp -fomit-frame-pointer -mtune=native
> 1D:  0.676616000 27303
> 2D:  0.664194000 27303
> 
> previous with profile-guided compilation
> 1D:  0.888206000 27303
> 2D:  0.806196000 27303
> 
> C++ at -O3 -mtune=native
> 1D: 0.681721 0
> 
> previous with profile-guided compilation
> 1D: 0.31165 0
> 
> Clang++
> 1D: 0.611522 0
> 
> The GNU C++ compiler is from the GNAT GPL 2012 distribution for Mac OS X,
> Clang++ is Apple's v 3.1.
> 
> 
> === 8< === 8< === 8< === 8< ===
> 
> package Fringes is
> 
>     pragma Pure (Fringes);
> 
>     type Full_Index is mod 2**32;
>     subtype Num is Full_Index Range 0 .. 100_000;
>     subtype Index is Full_Index range 0 .. 1000;
>     Len : constant Full_Index := Index'Last - Index'First + 1;
> 
>     type Matrix_1D is
>       array (Index'First .. Index'First + Len * Len - 1) of Num;
>     type Matrix_2 is array (Index, Index) of Num;
> 
>     procedure Compute_1D (A : in out Matrix_1D);
>     procedure Compute_2  (A : in out Matrix_2);
> 
> end Fringes;
> 
> package body Fringes is
> 
>     --
>     --  Each Compute procedure has A pointless loop that assigns each
>     --  inner field the sum of non-diagonal neighbors modulo Num'Last
>     --
> 
>     procedure NOT_USED_Compute_1D_Slow (A : in out Matrix_1D) is
>        J : Full_Index;
>     begin
>        J := A'First + Len;
>        loop
>          exit when J > A'Last - Len;
>          for K in J + 1 .. J + Len - 1 - 1 loop
>             A (K) := (A(K + 1)
>                       + A(K - Len)
>                       + A(K - 1)
>                       + A(K + Len)) mod Num'Last;
>          end loop;
>          J := J + Len;
>        end loop;
>     end NOT_USED_Compute_1D_Slow;
> 
>     procedure Compute_1D (A : in out Matrix_1D) is
>     begin
>        for K in A'First + Len + 1 .. A'Last - Len - 1 loop
>           case K mod Len is
>           when 0 | Len - 1 => null;
>           when others =>
>              A (K) := (A(K + 1)
>                        + A(K - Len)
>                        + A(K - 1)
>                        + A(K + Len)) mod Num'Last;
>           end case;
>        end loop;
>     end Compute_1D;
> 
>     procedure Compute_2 (A : in out Matrix_2) is
>     begin
>        for J in A'First(1) + 1 .. A'Last(1) - 1 loop
>           for K in A'First(2) + 1 .. A'Last(2) - 1 loop
>              A (J, K) := (A(J, K + 1)
>                           + A(j - 1, K)
>                           + A(J, K - 1)
>                           + A(j + 1, K)) mod Num'Last;
>           end loop;
>        end loop;
>     end Compute_2;
> 
> end Fringes;
> 
> 
> with Fringes;
> with Ada.Command_Line, Ada.Real_Time;
> procedure Test_Fringes is
> 
>     use Ada.Real_Time;
> 
>     Runs : constant Natural :=
>       Natural'Value (Ada.Command_Line.Argument(1));
> 
>     Start, Stop: Time;
> 
>     package Os_Or_Gnat_Stacksize_Nuisance is
>        use Fringes;
>        type P1 is access Matrix_1D;
>        type P2 is access Matrix_2;
>        M1P : constant P1 := new Matrix_1D'(others => 123);
>        M2p : constant P2 := new Matrix_2'(Index => (Index => 123));
>        M1D : Matrix_1D renames M1P.all;
>        M2 : Matrix_2 renames M2P.all;
>     end Os_Or_Gnat_Stacksize_Nuisance;
>     use Os_Or_Gnat_Stacksize_Nuisance;
> 
>     procedure Print_Timing (Part : String; N : Fringes.Num) is separate;
>     use type Fringes.Full_Index;
> begin
>     Start := Clock;
>     for Run in 1 .. Runs loop
>        Fringes.Compute_1D (M1D);
>     end loop;
>     Stop := Clock;
>     Print_Timing ("1D", M1D ((M1D'First + 1 * Fringes.Len) + (2)));
> 
>     Start := Clock;
>     for Run in 1 .. Runs loop
>        Fringes.Compute_2 (M2);
>     end loop;
>     Stop := Clock;
>     Print_Timing ("2D", M2 (1, 2));
> end Test_Fringes;
> 
> with Ada.Text_IO;
> separate (Test_Fringes)
> procedure Print_Timing (Part : String; N : Fringes.Num) is
>     use Ada.Text_IO;
> begin
>     Put (Part);
>     Put (": ");
>     Put (Duration'Image (To_Duration(Stop - Start)));
>     Put (Fringes.Num'Image (N));
>     New_Line;
> end print_timing;
> 
> 
> === 8< === 8< === 8< === 8< ===
> 
> #include <stdint.h>
> 
> namespace Fringes {
> 
>      typedef  uint32_t Full_Index;
> #define Num_Last 100000
>      typedef Full_Index Num;
> #define Index_Last 1000
>      typedef Full_Index Index;
>      const Full_Index Len = Index_Last + 1;
> 
> #define A_Last ((Len * Len) - 1)
>      typedef Num Matrix_1D[A_Last + 1];
> 
>      void Compute_1D (Matrix_1D&  A);
>      //  Each Compute procedure has a pointless loop that assigns each
>      //  inner field the sum of non-diagonal neighbors modulo Num_Last
>      void Compute_1D (Matrix_1D&  A) {
> 
>          for (Full_Index K = Len + 1; K < A_Last - Len - 1; ++K) {
>              switch (K % Len) {
>              case 0: case Len - 1: break;
>              default:
>                  A [K] = (A[K + 1]
>                            + A[K - Len]
>                            + A[K - 1]
>                            + A[K + Len]) % Num_Last;
>              }
>          }
>      }
> }
> 
> #include <sys/time.h>
> #include <string>
> 
> class Reporter {
>      struct timeval Start, Stop;
> public:
>      void logStart();
>      void logStop();
>      void Print_Timing (const std::string Part, const Fringes::Num N);
> };
> 
> 
> #include <sstream>
> 
> int main(int argc, char* argv[]) {
>      using namespace Fringes;
> 
>      int Runs;
>      Matrix_1D* M1D = new Matrix_1D[Len];
>      Reporter history;
> 
>      if (argc == 0) {
>          throw "usage";
>      } else {
>          std::istringstream converter(argv[1]);
> 
>          if (! ((converter >> Runs) && (Runs >= 0))) {
>              throw "argument error?";
>          }
>      }
>      
>      history.logStart();
>      for (int Run = 1; Run <= Runs; ++Run) {
>          Compute_1D (*M1D);
>      }
>      history.logStop();
>      history.Print_Timing ("1D", (*M1D) [(1 * Len) + (2)]);
> }
> 
> 
> #include <iostream>
> #include <sys/time.h>
> 
> void Reporter::Print_Timing (const std::string Part, const Fringes::Num N) {
>      double difference = (Stop.tv_sec - Start.tv_sec) * 1000000
>              + (Stop.tv_usec - Start.tv_usec);
>      std::cout << Part << ": ";
>      std::cout << (difference / 1000000.0) << " " << N;
>      std::cout << '\n';
> }
> 
> void Reporter::logStart() {
>      gettimeofday(&this->Start, 0);
> }
> 
> void Reporter::logStop() {
>      gettimeofday(&this->Stop, 0);
> }

On Sunday, 1 July 2012 18:45:22 UTC+1, Georg Bauhaus  wrote:
> On 29.06.12 19:03, Keean Schupke wrote:
> > Note: this is not really answering my question about the lack of improvement due to profile-guided compilation - but perhaps that side of things is more a compiler issue. Does anyone have any ideas about that side of things?
> 
> Some more observations, collected with the help of the simple
> two example programs appended below.
> 
> For Ada and GNAT at least, any advantages to be had from profile-guided
> compilation seem to vary with optimization options and sizes of data.
> The same is true about a 1D approach vs a 2D approach.
> 
> Among the various arrangements, one of the best I have got
> from both GNAT GPL 2012, and from an FSF GNAT as of June 2012
> uses
> *) -O2 -funroll-loops -gnatp
> *)  the 2D approach
> 
> (If it means a anything, adding -ftree-vectorize to the -O2 set
> produces only the second best Ada result, the same as the -O3 times
> listed below. I had chosen -ftree-vectorize as this switch is in the
> O3 set.) Trying profile guided compilation at higher optimization
> levels consistently slowed the Ada program down (other Ada programs
> were faster after profile guided compilation, as mentioned elsewhere).
> 
> The result at -O2 seems nice, though, in that the 2D approach is
> natural, the compiler switches are the ones that the manual recommends.
> and this combination produces the fastest Ada program.
> 
> In short, from worst to best 1D / 2D, Runs = 100:
> 
> Ada profile guided -> .88 / .80   (this program only!)
> Ada at -O3         -> .68 / .66
> C++ at -O3         -> .66
> Ada at -O2 -funr.. -> .68 / .47
> C++ profile guided -> .31
> 
> 
> Some differences seem to vary with hardware, too.
> On one computer I have seen a minor speedup, on another
> a very small slowdown, and a different ratio of 1D / 2D.
> 
> For the C++ case I have tested a 1D approach only, not
> knowing how to write 2D arrays in C++ using C style arrays.
> I'm not a C++ programmer, apologies for my C++.
> 
> 
> Ada at -O2 -funroll-loops -gnatp -mtune=native
> 1D:  0.680750000 27303
> 2D:  0.469094000 27303  <-- Best for Ada!
> 
> Ada at -O3 -gnatNp -fomit-frame-pointer -mtune=native
> 1D:  0.676616000 27303
> 2D:  0.664194000 27303
> 
> previous with profile-guided compilation
> 1D:  0.888206000 27303
> 2D:  0.806196000 27303
> 
> C++ at -O3 -mtune=native
> 1D: 0.681721 0
> 
> previous with profile-guided compilation
> 1D: 0.31165 0
> 
> Clang++
> 1D: 0.611522 0
> 
> The GNU C++ compiler is from the GNAT GPL 2012 distribution for Mac OS X,
> Clang++ is Apple's v 3.1.
> 
> 
> === 8< === 8< === 8< === 8< ===
> 
> package Fringes is
> 
>     pragma Pure (Fringes);
> 
>     type Full_Index is mod 2**32;
>     subtype Num is Full_Index Range 0 .. 100_000;
>     subtype Index is Full_Index range 0 .. 1000;
>     Len : constant Full_Index := Index'Last - Index'First + 1;
> 
>     type Matrix_1D is
>       array (Index'First .. Index'First + Len * Len - 1) of Num;
>     type Matrix_2 is array (Index, Index) of Num;
> 
>     procedure Compute_1D (A : in out Matrix_1D);
>     procedure Compute_2  (A : in out Matrix_2);
> 
> end Fringes;
> 
> package body Fringes is
> 
>     --
>     --  Each Compute procedure has A pointless loop that assigns each
>     --  inner field the sum of non-diagonal neighbors modulo Num'Last
>     --
> 
>     procedure NOT_USED_Compute_1D_Slow (A : in out Matrix_1D) is
>        J : Full_Index;
>     begin
>        J := A'First + Len;
>        loop
>          exit when J > A'Last - Len;
>          for K in J + 1 .. J + Len - 1 - 1 loop
>             A (K) := (A(K + 1)
>                       + A(K - Len)
>                       + A(K - 1)
>                       + A(K + Len)) mod Num'Last;
>          end loop;
>          J := J + Len;
>        end loop;
>     end NOT_USED_Compute_1D_Slow;
> 
>     procedure Compute_1D (A : in out Matrix_1D) is
>     begin
>        for K in A'First + Len + 1 .. A'Last - Len - 1 loop
>           case K mod Len is
>           when 0 | Len - 1 => null;
>           when others =>
>              A (K) := (A(K + 1)
>                        + A(K - Len)
>                        + A(K - 1)
>                        + A(K + Len)) mod Num'Last;
>           end case;
>        end loop;
>     end Compute_1D;
> 
>     procedure Compute_2 (A : in out Matrix_2) is
>     begin
>        for J in A'First(1) + 1 .. A'Last(1) - 1 loop
>           for K in A'First(2) + 1 .. A'Last(2) - 1 loop
>              A (J, K) := (A(J, K + 1)
>                           + A(j - 1, K)
>                           + A(J, K - 1)
>                           + A(j + 1, K)) mod Num'Last;
>           end loop;
>        end loop;
>     end Compute_2;
> 
> end Fringes;
> 
> 
> with Fringes;
> with Ada.Command_Line, Ada.Real_Time;
> procedure Test_Fringes is
> 
>     use Ada.Real_Time;
> 
>     Runs : constant Natural :=
>       Natural'Value (Ada.Command_Line.Argument(1));
> 
>     Start, Stop: Time;
> 
>     package Os_Or_Gnat_Stacksize_Nuisance is
>        use Fringes;
>        type P1 is access Matrix_1D;
>        type P2 is access Matrix_2;
>        M1P : constant P1 := new Matrix_1D'(others => 123);
>        M2p : constant P2 := new Matrix_2'(Index => (Index => 123));
>        M1D : Matrix_1D renames M1P.all;
>        M2 : Matrix_2 renames M2P.all;
>     end Os_Or_Gnat_Stacksize_Nuisance;
>     use Os_Or_Gnat_Stacksize_Nuisance;
> 
>     procedure Print_Timing (Part : String; N : Fringes.Num) is separate;
>     use type Fringes.Full_Index;
> begin
>     Start := Clock;
>     for Run in 1 .. Runs loop
>        Fringes.Compute_1D (M1D);
>     end loop;
>     Stop := Clock;
>     Print_Timing ("1D", M1D ((M1D'First + 1 * Fringes.Len) + (2)));
> 
>     Start := Clock;
>     for Run in 1 .. Runs loop
>        Fringes.Compute_2 (M2);
>     end loop;
>     Stop := Clock;
>     Print_Timing ("2D", M2 (1, 2));
> end Test_Fringes;
> 
> with Ada.Text_IO;
> separate (Test_Fringes)
> procedure Print_Timing (Part : String; N : Fringes.Num) is
>     use Ada.Text_IO;
> begin
>     Put (Part);
>     Put (": ");
>     Put (Duration'Image (To_Duration(Stop - Start)));
>     Put (Fringes.Num'Image (N));
>     New_Line;
> end print_timing;
> 
> 
> === 8< === 8< === 8< === 8< ===
> 
> #include <stdint.h>
> 
> namespace Fringes {
> 
>      typedef  uint32_t Full_Index;
> #define Num_Last 100000
>      typedef Full_Index Num;
> #define Index_Last 1000
>      typedef Full_Index Index;
>      const Full_Index Len = Index_Last + 1;
> 
> #define A_Last ((Len * Len) - 1)
>      typedef Num Matrix_1D[A_Last + 1];
> 
>      void Compute_1D (Matrix_1D&  A);
>      //  Each Compute procedure has a pointless loop that assigns each
>      //  inner field the sum of non-diagonal neighbors modulo Num_Last
>      void Compute_1D (Matrix_1D&  A) {
> 
>          for (Full_Index K = Len + 1; K < A_Last - Len - 1; ++K) {
>              switch (K % Len) {
>              case 0: case Len - 1: break;
>              default:
>                  A [K] = (A[K + 1]
>                            + A[K - Len]
>                            + A[K - 1]
>                            + A[K + Len]) % Num_Last;
>              }
>          }
>      }
> }
> 
> #include <sys/time.h>
> #include <string>
> 
> class Reporter {
>      struct timeval Start, Stop;
> public:
>      void logStart();
>      void logStop();
>      void Print_Timing (const std::string Part, const Fringes::Num N);
> };
> 
> 
> #include <sstream>
> 
> int main(int argc, char* argv[]) {
>      using namespace Fringes;
> 
>      int Runs;
>      Matrix_1D* M1D = new Matrix_1D[Len];
>      Reporter history;
> 
>      if (argc == 0) {
>          throw "usage";
>      } else {
>          std::istringstream converter(argv[1]);
> 
>          if (! ((converter >> Runs) && (Runs >= 0))) {
>              throw "argument error?";
>          }
>      }
>      
>      history.logStart();
>      for (int Run = 1; Run <= Runs; ++Run) {
>          Compute_1D (*M1D);
>      }
>      history.logStop();
>      history.Print_Timing ("1D", (*M1D) [(1 * Len) + (2)]);
> }
> 
> 
> #include <iostream>
> #include <sys/time.h>
> 
> void Reporter::Print_Timing (const std::string Part, const Fringes::Num N) {
>      double difference = (Stop.tv_sec - Start.tv_sec) * 1000000
>              + (Stop.tv_usec - Start.tv_usec);
>      std::cout << Part << ": ";
>      std::cout << (difference / 1000000.0) << " " << N;
>      std::cout << '\n';
> }
> 
> void Reporter::logStart() {
>      gettimeofday(&this->Start, 0);
> }
> 
> void Reporter::logStop() {
>      gettimeofday(&this->Stop, 0);
> }


Interesting stuff, I need a bit more time to read and digest, but I did notice one thing that I think is worth pointing out. 

The real benefit (and performance gains) from profile guided compilation come from correcting branch prediction. As such the gains will be most apparent when there is an 'if' statement in the inner loop of the code. Try something where you are taking the sign of an int in the formula and have three cases <0 =0 >0.

The other point is that for any single branch there is at least a 50% chance it is already optimal, for example:

if x > 0 then
    y := 1 + y;
else
    y := 1 - y;
end if;

will get implemented in assembly as something like:

 tst rx
 ble xyz
 ld #1, r0
 sub r0, ry
 bra zyx
.xyz
 add #1, ry
.zyx

OR

 tst rx
 bgt xyz
 add #1, ry
 bra zyx
.xyz
 ld #1, r0
 sub r0, ry
.zyx

whether this is optimal depends on the number of times x <= 0 and on what the CPU's branch predictor guesses for 'ble xyz'. Most branch predictors start with the assumption that a backwards branch will be taken (looping) and a forward branch will not be taken, but then they also build statistical tables based on the address of the branch instruction to improve that guess on future iterations.

The speed difference can be large because a branch predict failure can have a high penalty - a CPU pipe stall. Modern CPUs use speculative execution (they keep the pipe filled by using branch-predict to assume whether the branch will or will not be taken) so if the branch predict guesses correctly there is no pipe stall and the CPU continues through the code at full speed. A pipe stall can cost 10s or 100s of clock cycles each time it happens. 

I initially expected the dynamic branch predictor would be doing a good job and changing the order of the 'if' statements would have no effect, but benchmarking on 64bit x86 hardware showed a strong effect for changing the order of branches.

Anyway the point is, even if you have an 'if' statement in the inner loop, you may be lucky and already have it the 'faster' way round.

So you need to benchmark:

if x > 0 then
    y := 1 + y;
else
    y := 1 - y;
end if;

AND

if x <= 0 then
    y := 1 - y;
else
    y := 1 + y;
end if;

Then you can confirm that profile guided compilation gives you the faster of the two benchmark times, no matter which way round the if statement is written in the code.

Obviously for one if statement in the inner loop you can practically benchmark both alternatives and chose the fastest.

With my Monte-Carlo simulation, the inner loop logic is a complex state-machine, and it would be impractical to try all possibly combinations (due to the explosion of combinations at the speed of 2^N, just 8 branches would require 256 code change and rebuild-cycles, 16 = 65536 etc...

This is where profile-guided compilation is a valuable tool. Both the Ada code and C++ code share the same branching in the state machine, and both have the same initial performance now (approx 40k simulations per second). However the C++ compiler gains 25% from the profile guided compilation (by changing branch orders and re-ordering functions). This gain should be available to the Ada compiler too, as the same branches are getting generated in the output assembly - but its just not working as well.

My latest results are better, I now have both C++ and Ada running from the same GCC-4.7.1 compiler and my latest performance figures are:

Just so its clear, you first build with '-fprofile-generate' then you run the code to build the .gcda profile files, then you build again with '-fprofile-use' to build the 'profile-guided' version. My code runs 1,000,000 iterations between the 'generate' and the 'use' steps.


C++ first compile: 39k
C++ profile guided: 55k

Ada first compile: 41k
Ada profile guided: 46k


So gcc-4.7.1 seems to improve the results slightly for Ada, but it seems to be still falling short of the potential improvement. I am becoming more convinced that there is nothing in the Ada code itself that is causing this, but more likely something about the Ada GCC front-end itself not using the profiling information as effectively as C++. 


Cheers,
Keean.



^ permalink raw reply	[relevance 0%]

* Re: GNAT (GCC) Profile Guided Compilation
  @ 2012-07-01 17:45  4%           ` Georg Bauhaus
  2012-07-01 22:57  0%             ` Keean Schupke
  0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2012-07-01 17:45 UTC (permalink / raw)


On 29.06.12 19:03, Keean Schupke wrote:
> Note: this is not really answering my question about the lack of improvement due to profile-guided compilation - but perhaps that side of things is more a compiler issue. Does anyone have any ideas about that side of things?

Some more observations, collected with the help of the simple
two example programs appended below.

For Ada and GNAT at least, any advantages to be had from profile-guided
compilation seem to vary with optimization options and sizes of data.
The same is true about a 1D approach vs a 2D approach.

Among the various arrangements, one of the best I have got
from both GNAT GPL 2012, and from an FSF GNAT as of June 2012
uses
*) -O2 -funroll-loops -gnatp
*)  the 2D approach

(If it means a anything, adding -ftree-vectorize to the -O2 set
produces only the second best Ada result, the same as the -O3 times
listed below. I had chosen -ftree-vectorize as this switch is in the
O3 set.) Trying profile guided compilation at higher optimization
levels consistently slowed the Ada program down (other Ada programs
were faster after profile guided compilation, as mentioned elsewhere).

The result at -O2 seems nice, though, in that the 2D approach is
natural, the compiler switches are the ones that the manual recommends.
and this combination produces the fastest Ada program.

In short, from worst to best 1D / 2D, Runs = 100:

Ada profile guided -> .88 / .80   (this program only!)
Ada at -O3         -> .68 / .66
C++ at -O3         -> .66
Ada at -O2 -funr.. -> .68 / .47
C++ profile guided -> .31


Some differences seem to vary with hardware, too.
On one computer I have seen a minor speedup, on another
a very small slowdown, and a different ratio of 1D / 2D.

For the C++ case I have tested a 1D approach only, not
knowing how to write 2D arrays in C++ using C style arrays.
I'm not a C++ programmer, apologies for my C++.


Ada at -O2 -funroll-loops -gnatp -mtune=native
1D:  0.680750000 27303
2D:  0.469094000 27303  <-- Best for Ada!

Ada at -O3 -gnatNp -fomit-frame-pointer -mtune=native
1D:  0.676616000 27303
2D:  0.664194000 27303

previous with profile-guided compilation
1D:  0.888206000 27303
2D:  0.806196000 27303

C++ at -O3 -mtune=native
1D: 0.681721 0

previous with profile-guided compilation
1D: 0.31165 0

Clang++
1D: 0.611522 0

The GNU C++ compiler is from the GNAT GPL 2012 distribution for Mac OS X,
Clang++ is Apple's v 3.1.


=== 8< === 8< === 8< === 8< ===

package Fringes is

    pragma Pure (Fringes);

    type Full_Index is mod 2**32;
    subtype Num is Full_Index Range 0 .. 100_000;
    subtype Index is Full_Index range 0 .. 1000;
    Len : constant Full_Index := Index'Last - Index'First + 1;

    type Matrix_1D is
      array (Index'First .. Index'First + Len * Len - 1) of Num;
    type Matrix_2 is array (Index, Index) of Num;

    procedure Compute_1D (A : in out Matrix_1D);
    procedure Compute_2  (A : in out Matrix_2);

end Fringes;

package body Fringes is

    --
    --  Each Compute procedure has A pointless loop that assigns each
    --  inner field the sum of non-diagonal neighbors modulo Num'Last
    --

    procedure NOT_USED_Compute_1D_Slow (A : in out Matrix_1D) is
       J : Full_Index;
    begin
       J := A'First + Len;
       loop
         exit when J > A'Last - Len;
         for K in J + 1 .. J + Len - 1 - 1 loop
            A (K) := (A(K + 1)
                      + A(K - Len)
                      + A(K - 1)
                      + A(K + Len)) mod Num'Last;
         end loop;
         J := J + Len;
       end loop;
    end NOT_USED_Compute_1D_Slow;

    procedure Compute_1D (A : in out Matrix_1D) is
    begin
       for K in A'First + Len + 1 .. A'Last - Len - 1 loop
          case K mod Len is
          when 0 | Len - 1 => null;
          when others =>
             A (K) := (A(K + 1)
                       + A(K - Len)
                       + A(K - 1)
                       + A(K + Len)) mod Num'Last;
          end case;
       end loop;
    end Compute_1D;

    procedure Compute_2 (A : in out Matrix_2) is
    begin
       for J in A'First(1) + 1 .. A'Last(1) - 1 loop
          for K in A'First(2) + 1 .. A'Last(2) - 1 loop
             A (J, K) := (A(J, K + 1)
                          + A(j - 1, K)
                          + A(J, K - 1)
                          + A(j + 1, K)) mod Num'Last;
          end loop;
       end loop;
    end Compute_2;

end Fringes;


with Fringes;
with Ada.Command_Line, Ada.Real_Time;
procedure Test_Fringes is

    use Ada.Real_Time;

    Runs : constant Natural :=
      Natural'Value (Ada.Command_Line.Argument(1));

    Start, Stop: Time;

    package Os_Or_Gnat_Stacksize_Nuisance is
       use Fringes;
       type P1 is access Matrix_1D;
       type P2 is access Matrix_2;
       M1P : constant P1 := new Matrix_1D'(others => 123);
       M2p : constant P2 := new Matrix_2'(Index => (Index => 123));
       M1D : Matrix_1D renames M1P.all;
       M2 : Matrix_2 renames M2P.all;
    end Os_Or_Gnat_Stacksize_Nuisance;
    use Os_Or_Gnat_Stacksize_Nuisance;

    procedure Print_Timing (Part : String; N : Fringes.Num) is separate;
    use type Fringes.Full_Index;
begin
    Start := Clock;
    for Run in 1 .. Runs loop
       Fringes.Compute_1D (M1D);
    end loop;
    Stop := Clock;
    Print_Timing ("1D", M1D ((M1D'First + 1 * Fringes.Len) + (2)));

    Start := Clock;
    for Run in 1 .. Runs loop
       Fringes.Compute_2 (M2);
    end loop;
    Stop := Clock;
    Print_Timing ("2D", M2 (1, 2));
end Test_Fringes;

with Ada.Text_IO;
separate (Test_Fringes)
procedure Print_Timing (Part : String; N : Fringes.Num) is
    use Ada.Text_IO;
begin
    Put (Part);
    Put (": ");
    Put (Duration'Image (To_Duration(Stop - Start)));
    Put (Fringes.Num'Image (N));
    New_Line;
end print_timing;


=== 8< === 8< === 8< === 8< ===

#include <stdint.h>

namespace Fringes {

     typedef  uint32_t Full_Index;
#define Num_Last 100000
     typedef Full_Index Num;
#define Index_Last 1000
     typedef Full_Index Index;
     const Full_Index Len = Index_Last + 1;

#define A_Last ((Len * Len) - 1)
     typedef Num Matrix_1D[A_Last + 1];

     void Compute_1D (Matrix_1D&  A);
     //  Each Compute procedure has a pointless loop that assigns each
     //  inner field the sum of non-diagonal neighbors modulo Num_Last
     void Compute_1D (Matrix_1D&  A) {

         for (Full_Index K = Len + 1; K < A_Last - Len - 1; ++K) {
             switch (K % Len) {
             case 0: case Len - 1: break;
             default:
                 A [K] = (A[K + 1]
                           + A[K - Len]
                           + A[K - 1]
                           + A[K + Len]) % Num_Last;
             }
         }
     }
}

#include <sys/time.h>
#include <string>

class Reporter {
     struct timeval Start, Stop;
public:
     void logStart();
     void logStop();
     void Print_Timing (const std::string Part, const Fringes::Num N);
};


#include <sstream>

int main(int argc, char* argv[]) {
     using namespace Fringes;

     int Runs;
     Matrix_1D* M1D = new Matrix_1D[Len];
     Reporter history;

     if (argc == 0) {
         throw "usage";
     } else {
         std::istringstream converter(argv[1]);

         if (! ((converter >> Runs) && (Runs >= 0))) {
             throw "argument error?";
         }
     }
     
     history.logStart();
     for (int Run = 1; Run <= Runs; ++Run) {
         Compute_1D (*M1D);
     }
     history.logStop();
     history.Print_Timing ("1D", (*M1D) [(1 * Len) + (2)]);
}


#include <iostream>
#include <sys/time.h>

void Reporter::Print_Timing (const std::string Part, const Fringes::Num N) {
     double difference = (Stop.tv_sec - Start.tv_sec) * 1000000
             + (Stop.tv_usec - Start.tv_usec);
     std::cout << Part << ": ";
     std::cout << (difference / 1000000.0) << " " << N;
     std::cout << '\n';
}

void Reporter::logStart() {
     gettimeofday(&this->Start, 0);
}

void Reporter::logStop() {
     gettimeofday(&this->Stop, 0);
}





^ permalink raw reply	[relevance 4%]

* Re: Debugging Ada
  @ 2011-12-21 17:18  6%     ` Ludovic Brenta
  0 siblings, 0 replies; 200+ results
From: Ludovic Brenta @ 2011-12-21 17:18 UTC (permalink / raw)


awdorrin wrote on comp.lang.ada:
> That is what I believe is happening as well.
>
> Is there some way I can force the compiler to not do this, but execute
> the code at elaboration time instead?
>
> I've been looking at the GNAT docs and haven't stumbled across
> anything yet...

Make sure that in the statement

LAN_CFG_FILE : constant String := SysConfig.Cfg_Filename( LAN_CFG );

the value of LAN_CFG is not itself preelaborated. For example, make it
the result of calling Ada.Command_Line.Argument (1) or
GNAT.OS_Lib.Getenv.

--
Ludovic Brenta.



^ permalink raw reply	[relevance 6%]

* Re: Why no Ada.Wide_Directories?
  @ 2011-10-18  4:07  5%       ` Michael Rohan
  0 siblings, 0 replies; 200+ results
From: Michael Rohan @ 2011-10-18  4:07 UTC (permalink / raw)


Hi,

Just to confirm "ytomino" take on things: while I started this on Ada.Directories, I have fallen into the practice of simply doing From_UTF8 on anything coming from the environment (Ada.Command_Line, Ada.Environment_Variables, etc) and To_UTF8 on the way out.  This works for my Linux system (en-US, Latin-1, no surprise), but using Wide_String internally, the external/internal interface Strings need to be converted somehow and UTF8 is as reasonable option.

As to the use of the Form parameter, additional standardization might be needed.  With GNAT, the Form (for Open at least) can be used to define the encoding of the file contents but not of the file name.

Take care,
Michael.



^ permalink raw reply	[relevance 5%]

* Re: Why no Ada.Wide_Directories?
  2011-10-18  1:10  0%       ` Adam Beneschan
@ 2011-10-18  2:32  4%         ` ytomino
  0 siblings, 0 replies; 200+ results
From: ytomino @ 2011-10-18  2:32 UTC (permalink / raw)


On Oct 18, 10:10 am, Adam Beneschan <a...@irvine.com> wrote:
> On Oct 17, 4:47 pm, ytomino <aghi...@gmail.com> wrote:
>
>
>
>
>
>
>
>
>
> > On Oct 18, 6:33 am, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
>
> > > Say what?
>
> > > Ada.Strings.Encoding (new in Ada 2012) uses a subtype of String to store
> > > UTF-8 encoded strings. As such, I'd find it pretty surprising if doing so
> > > was "a violation of the standard".
>
> > > The intent has always been that Open, Ada.Directories, etc. take UTF-8
> > > strings as an option. Presumably the implementation would use a Form to
> > > specify that the file names in UTF-8 form rather than Latin-1. (I wasn't
> > > able to find a reference for this in a quick search, but I know it has been
> > > talked about on several occasions.)
>
> > > One of the primary reasons that Ada.Strings.Encoding uses a subtype of
> > > String rather than a separate type is so that it can be passed to Open and
> > > the like.
>
> > > It's probably true that we should standardize on the Form needed to use
> > > UTF-8 strings in these contexts, or at least come up with Implementation
> > > Advice on that point.
>
> > >                                        Randy.
>
> > Good news. Thanks for letting know.
> > My worry is decreased a little.
>
> > However, even if that is right, Form parameters are missing for many
> > subprograms.
> > Probably, All subprograms in Ada.Directories,
> > Ada.Directories.Hierarchical_File_Names, Ada.Command_Line,
> > Ada.Environment_Variables and other subprograms having Name parameter
> > or returning a file name should have Form parameter.
> > (For example, I do Open (X, Form => "UTF-8"). Which does Name (X)
> > returns UTF-8 or Latin-1?)
>
> > Moreover, in the future, we will always use I/O subprograms as UTF-8
> > mode if what you say is realized.
> > But other libraries in the standard are explicitly defined as Latin-1.
> > It's certain that Ada.Character.Handling.To_Upper breaks UTF-8.
>
> I have a feeling you're fundamentally confused about what UTF-8 is, as
> compared to "Latin-1".  Latin-1 is a character mapping.  It defines,
> for all integers in the range 0..255, what character that integer
> represents (e.g. 77 represents 'M', etc.).  Unicode is a character
> mapping that defines characters for a much larger integer range.  For
> integers in the range 0..255, the character represented in Unicode is
> the same as that in Latin-1; higher integers represent characters in
> other alphabets, other symbols, etc.  Those mappings just tell you
> what symbols go with what numbers, and they don't say anything about
> how the numbers are supposed to be stored.
>
> UTF-8 is an encoding (representation).  It defines, for each non-
> negative integer up to a certain point, what bits are used to
> represent that integer.  The number of bits is not fixed.  So even if
> you're working with characters all in the 0..255 range, some of those
> characters will be represented in 8 bits (one byte) and some will take
> 16 bits (two bytes).
>
> Because of this, it is not feasible to work with strings or characters
> in UTF-8 encoding.  Suppose you declare a string
>
>    S : String (1 .. 100);
>
> but you want it to be a UTF-8 string.  How would that work?  If you
> want to look at S(50), the computer would have to start at the
> beginning of the string and figure out whether each character is
> represented as 1 or 2 bytes.  Nobody wants that.
>
> The only sane way to work with strings in memory is to use a format
> where every character is the same size (String if all your characters
> are in the 0..255 range, Wide_String for 0..65535, Wide_Wide_String
> for 0..2**32-1).  Then, if you have a string of bytes in UTF-8 format,
> you convert it to a regular (Wide_)(Wide_)String with routines in
> Ada.Strings.UTF_Encoding; and it also has routines for converting
> regular strings to UTF-8 format.  But you don't want to *keep* strings
> in memory and work with them in UTF-8 format.  That's why it doesn't
> make sense to have string routines (like
> Ada.Strings.Equal_Case_Insensitive or Ada.Character_Handling.To_Upper)
> that work with UTF-8.
>
> Hope this solves your problem.
>
>                              -- Adam

I'm not confused. Your misreading.

Of course, if applications always hold file names as Wide_Wide_String,
and encode to UTF-8 only/every calling I/O subprograms as what you
say, so it's very simple and it is perhaps intended method. I
understand it.

But, where do these file names come from?
These are usually told by command-line or configuration file (written
by user).
It is probably encoded UTF-8 if the locale setting of OS is UTF-8.
So Form parameters of subprograms in Ada.Command_Line are necessary
and it's natural keeping UTF-8.

(Some file systems like Linux accept broken code as correct file name.
Applications must not (can not?) decode/encode file names in this
case.
Broken file name may be right file name if user sets LANG variable.
Same thing is in NTFS/NFS+. These file systems can accept broken
UTF-16. Strictly speaking, always, an application should not encode/
decode file names. But, Ada decides file names are stored into String
(as long as Randy says). So we have to give up about UTF-16 file
systems.)

And, it's popular that text processing functions keep encoded strings
in many other libraries or languages. I do not necessarily want to
deny the way of Ada, but I feel your opinion is prejudiced. It is not
so difficult as you say in fact.



^ permalink raw reply	[relevance 4%]

* Re: Why no Ada.Wide_Directories?
  2011-10-17 23:47  5%     ` ytomino
@ 2011-10-18  1:10  0%       ` Adam Beneschan
  2011-10-18  2:32  4%         ` ytomino
  0 siblings, 1 reply; 200+ results
From: Adam Beneschan @ 2011-10-18  1:10 UTC (permalink / raw)


On Oct 17, 4:47 pm, ytomino <aghi...@gmail.com> wrote:
> On Oct 18, 6:33 am, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
>
>
>
>
>
>
>
> > Say what?
>
> > Ada.Strings.Encoding (new in Ada 2012) uses a subtype of String to store
> > UTF-8 encoded strings. As such, I'd find it pretty surprising if doing so
> > was "a violation of the standard".
>
> > The intent has always been that Open, Ada.Directories, etc. take UTF-8
> > strings as an option. Presumably the implementation would use a Form to
> > specify that the file names in UTF-8 form rather than Latin-1. (I wasn't
> > able to find a reference for this in a quick search, but I know it has been
> > talked about on several occasions.)
>
> > One of the primary reasons that Ada.Strings.Encoding uses a subtype of
> > String rather than a separate type is so that it can be passed to Open and
> > the like.
>
> > It's probably true that we should standardize on the Form needed to use
> > UTF-8 strings in these contexts, or at least come up with Implementation
> > Advice on that point.
>
> >                                        Randy.
>
> Good news. Thanks for letting know.
> My worry is decreased a little.
>
> However, even if that is right, Form parameters are missing for many
> subprograms.
> Probably, All subprograms in Ada.Directories,
> Ada.Directories.Hierarchical_File_Names, Ada.Command_Line,
> Ada.Environment_Variables and other subprograms having Name parameter
> or returning a file name should have Form parameter.
> (For example, I do Open (X, Form => "UTF-8"). Which does Name (X)
> returns UTF-8 or Latin-1?)
>
> Moreover, in the future, we will always use I/O subprograms as UTF-8
> mode if what you say is realized.
> But other libraries in the standard are explicitly defined as Latin-1.
> It's certain that Ada.Character.Handling.To_Upper breaks UTF-8.

I have a feeling you're fundamentally confused about what UTF-8 is, as
compared to "Latin-1".  Latin-1 is a character mapping.  It defines,
for all integers in the range 0..255, what character that integer
represents (e.g. 77 represents 'M', etc.).  Unicode is a character
mapping that defines characters for a much larger integer range.  For
integers in the range 0..255, the character represented in Unicode is
the same as that in Latin-1; higher integers represent characters in
other alphabets, other symbols, etc.  Those mappings just tell you
what symbols go with what numbers, and they don't say anything about
how the numbers are supposed to be stored.

UTF-8 is an encoding (representation).  It defines, for each non-
negative integer up to a certain point, what bits are used to
represent that integer.  The number of bits is not fixed.  So even if
you're working with characters all in the 0..255 range, some of those
characters will be represented in 8 bits (one byte) and some will take
16 bits (two bytes).

Because of this, it is not feasible to work with strings or characters
in UTF-8 encoding.  Suppose you declare a string

   S : String (1 .. 100);

but you want it to be a UTF-8 string.  How would that work?  If you
want to look at S(50), the computer would have to start at the
beginning of the string and figure out whether each character is
represented as 1 or 2 bytes.  Nobody wants that.

The only sane way to work with strings in memory is to use a format
where every character is the same size (String if all your characters
are in the 0..255 range, Wide_String for 0..65535, Wide_Wide_String
for 0..2**32-1).  Then, if you have a string of bytes in UTF-8 format,
you convert it to a regular (Wide_)(Wide_)String with routines in
Ada.Strings.UTF_Encoding; and it also has routines for converting
regular strings to UTF-8 format.  But you don't want to *keep* strings
in memory and work with them in UTF-8 format.  That's why it doesn't
make sense to have string routines (like
Ada.Strings.Equal_Case_Insensitive or Ada.Character_Handling.To_Upper)
that work with UTF-8.

Hope this solves your problem.

                             -- Adam



^ permalink raw reply	[relevance 0%]

* Re: Why no Ada.Wide_Directories?
  @ 2011-10-17 23:47  5%     ` ytomino
  2011-10-18  1:10  0%       ` Adam Beneschan
    1 sibling, 1 reply; 200+ results
From: ytomino @ 2011-10-17 23:47 UTC (permalink / raw)


On Oct 18, 6:33 am, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
>
> Say what?
>
> Ada.Strings.Encoding (new in Ada 2012) uses a subtype of String to store
> UTF-8 encoded strings. As such, I'd find it pretty surprising if doing so
> was "a violation of the standard".
>
> The intent has always been that Open, Ada.Directories, etc. take UTF-8
> strings as an option. Presumably the implementation would use a Form to
> specify that the file names in UTF-8 form rather than Latin-1. (I wasn't
> able to find a reference for this in a quick search, but I know it has been
> talked about on several occasions.)
>
> One of the primary reasons that Ada.Strings.Encoding uses a subtype of
> String rather than a separate type is so that it can be passed to Open and
> the like.
>
> It's probably true that we should standardize on the Form needed to use
> UTF-8 strings in these contexts, or at least come up with Implementation
> Advice on that point.
>
>                                        Randy.

Good news. Thanks for letting know.
My worry is decreased a little.

However, even if that is right, Form parameters are missing for many
subprograms.
Probably, All subprograms in Ada.Directories,
Ada.Directories.Hierarchical_File_Names, Ada.Command_Line,
Ada.Environment_Variables and other subprograms having Name parameter
or returning a file name should have Form parameter.
(For example, I do Open (X, Form => "UTF-8"). Which does Name (X)
returns UTF-8 or Latin-1?)

Moreover, in the future, we will always use I/O subprograms as UTF-8
mode if what you say is realized.
But other libraries in the standard are explicitly defined as Latin-1.
It's certain that Ada.Character.Handling.To_Upper breaks UTF-8.
So we can not use almost subprograms in Ada.Characters and Ada.Strings
for handling file names.
(For example, Ada.Directories.Name_Case_Equivalence returns
Case_Insensitive. We can not use Ada.Strings.Equal_Case_Insensitive to
compare two file names.)
It means standard libraries are separated UTF-8 from Latin-1.
It's not reasonable.

I wish it be solved.



^ permalink raw reply	[relevance 5%]

* Re: Eigenvalues to find roots of polynomials
  @ 2011-07-26 15:40  7%   ` marius63
  0 siblings, 0 replies; 200+ results
From: marius63 @ 2011-07-26 15:40 UTC (permalink / raw)


And the winner is...

> <http://home.roadrunner.com/~jbmatthews/misc/groots.html>

John B. Matthews Ada...Generic_Roots works like a charm.
It passed the simple test case, and solved my quintic problem x^5 -
4178x + 4177

$ ./find_roots_mathews 1 0 0 0 -4178 4177
Index =>  0, Position =>  6, Value => 4177
Index =>  1, Position =>  5, Value => -4178
Index =>  2, Position =>  4, Value => 0
Index =>  3, Position =>  3, Value => 0
Index =>  4, Position =>  2, Value => 0
Index =>  5, Position =>  1, Value => 1
Root 1 => (Re=> 1.00000000000000E+00, Im=> 0.00000000000000E+00)
Root 2 => (Re=>-2.47582467311450E-01, Im=>-8.05881611194044E+00)
Root 3 => (Re=> 7.76752669636581E+00, Im=>-1.40129846432482E-45)
Root 4 => (Re=>-2.47582467311450E-01, Im=> 8.05881611194044E+00)
Root 5 => (Re=>-8.27236176174291E+00, Im=> 0.00000000000000E+00)

I know from previous mathematical derivation (the polynomial comes
from extracting a variable in a summation), that the solution is a non-
negative scalar different from one, so Root 3 is my number, with the
non-zero but very small value of the imaginary part certainly only a
residue of computation done inside Matthews's magic machine. Thanks a
very great lot. Source code follows. Sorry for the mispelling,
"Mathews".

--  Trying to compute the roots of a polynomial using John Mathews
procedure.

with Ada.Command_Line;
with Ada.Numerics.Generic_Real_Arrays;
with Ada.Text_IO;
with Ada.Numerics.Generic_Complex_Types;
with Ada.Numerics.Generic_Complex_Arrays;
with Ada.Numerics.Generic_Complex_Arrays.Generic_Roots;

procedure Find_Roots_Mathews is
   type Real is digits 15;
   package Real_Arrays is new Ada.Numerics.Generic_Real_Arrays (Real);
   package Complex_Types is new Ada.Numerics.Generic_Complex_Types
(Real);
   package Complex_Arrays is new Ada.Numerics.Generic_Complex_Arrays
(Real_Arrays, Complex_Types);
   procedure Complex_Roots is new Complex_Arrays.Generic_Roots;
   M, N : Natural;
begin
   M := Ada.Command_Line.Argument_Count;
   N := M - 1;
   --  N = number of arguments = degree of the polynomial + 1.
   --  The input consists of all coficients in descending degree,
   --  e.g. for polynomial
   --     x^3 - 2x^2 - x + 2
   --  the input is
   --     1 -2 -1 2
   --  Roots of the above (for testing):
   --     -1, 1, 2

   declare
      P : Complex_Arrays.Complex_Vector (0 .. N);
      R : Complex_Arrays.Complex_Vector (1 .. N);
      use Ada.Text_IO;
   begin
      for I in 0 .. N loop
         Put_Line ("Index => " & I'img &
                   ", Position => " & Integer'Image(M - I) &
                   ", Value => " & Ada.Command_Line.Argument (M - I));
         P (I) := (Re => Real'Value (Ada.Command_Line.Argument (M -
I)), Im => 0.0);
      end loop;
      Complex_Roots (P, R);
      for I in R'Range loop
         Put_Line ("Root" & I'img &
                   " => (Re=>" & R(I).Re'img &
                   ", Im=>" & R(I).Im'img & ")");
      end loop;
   end;
end;



^ permalink raw reply	[relevance 7%]

* Eigenvalues to find roots of polynomials
@ 2011-07-25 17:36  7% marius63
    0 siblings, 1 reply; 200+ results
From: marius63 @ 2011-07-25 17:36 UTC (permalink / raw)


I am trying to use Eigenvalues methods to find the roots of
polynomials... and failing miserably!
My math ability is not stellar. I used the information at

(1)
http://mathworld.wolfram.com/PolynomialRoots.html (equation 12)

and

(2)
http://en.wikipedia.org/wiki/Root_finding
(One possibility is to form the companion matrix of the polynomial.
Since the eigenvalues of this matrix coincide with the roots of the
polynomial, one can use any eigenvalue algorithm to find the roots of
the polynomial.)
http://en.wikipedia.org/wiki/Companion_matrix

I tried both schemes with the test data in (1). The output is first
the matrix, for verification, then the (wrong) roots (they should be
-1, 1, 2) and the result of applying them to the polynomial (and
yielding miserably non-zero values of course). The source code
follows. What am I missing? Thanks a lot.

$ ./find_roots 1 -2 -1 2
 5.00000E-01 1.00000E+00-5.00000E-01
 1.00000E+00 0.00000E+00 0.00000E+00
 0.00000E+00 1.00000E+00 0.00000E+00
-7.6156E-01=> 4.2003E-01
 4.1249E+00=>-1.6015E+01
 6.3667E-01=> 5.9465E-01

$ ./find_roots_wikipedia -2 -1 2
 0.00000000000000E+00,  0.00000000000000E+00, -2.00000000000000E+00,
 1.00000000000000E+00,  0.00000000000000E+00,  1.00000000000000E+00,
 0.00000000000000E+00,  1.00000000000000E+00,  2.00000000000000E+00,
-1.17008648662603E+00 => -3.38499151386795E-02
 6.88892182534018E-01 =>  1.96496630422799E+00
 2.48119430409202E+00 =>  3.00688836109107E+01


--  Trying to compute the roots of a polynomial using the method
--  described in eq. (12) of http://mathworld.wolfram.com/PolynomialRoots.html
--  (consulted July 2011)

with Ada.Command_Line;
with Ada.Numerics.Generic_Real_Arrays;
with Ada.Text_IO;
with Ada.Numerics.Generic_Complex_Types;
with Ada.Numerics.Generic_Complex_Arrays;

procedure Find_Roots is
   type Real is digits 5;
   package Real_Arrays is new Ada.Numerics.Generic_Real_Arrays (Real);
   package Complex_Types is new Ada.Numerics.Generic_Complex_Types
(Real);
   package Complex_Arrays is new Ada.Numerics.Generic_Complex_Arrays
(Real_Arrays, Complex_Types);
   N, M : Natural;
begin
   N := Ada.Command_Line.Argument_Count;
   --  N = number of arguments = degree of the polynomial.
   --  The input consists of all coficients in descending degree,
   --  e.g. for polynomial
   --     x^3 - 2x^2 - x + 2
   --  the input is
   --     1 -2 -1 2
   --  Roots of the above (for testing):
   --     -1, 1, 2

   declare
      C : Complex_Arrays.Complex_Matrix (1 .. N - 1, 1 .. N - 1) :=
(others => (others => (0.0, 0.0)));
      --  Using a complex matrix because real matrices for eigenvalues
must be symmetric.
      --  Below we convert all real values to complex (with null Im
part).
      --  The complex matrix must be Hamiltonian;
      --  I thought a non-symmetric converted to complex would
      --  yield a non-Hamiltonian matrix, but I tried and it
worked :-)... hmm... NOT :-(
      A0 : Real := Real'Value (Ada.Command_Line.Argument (N));
      use Ada.Text_IO;
   begin
      for I in 1 .. N - 1 loop
         C (1, I).Re := - Real'Value (Ada.Command_Line.Argument (N -
I)) / A0;
         if I < N - 1 then
            C (I + 1, I).Re := 1.0;
         end if;
      end loop;

      --  inspect matrix
      for i in c'range(1) loop
         for j in c'range(2) loop
            put (c(i,j).re'img);
         end loop;
         new_line;
      end loop;

      declare
         V : Real_Arrays.Real_Vector := Complex_Arrays.Eigenvalues
(C);
         use Real_Arrays;
         Z : Real;
         use Ada.Text_IO;
      begin
         for I in V'Range loop
            V (I) := 1.0 / V (I);
            Put (Real'Image (V (I)));
            Z := 0.0;
            for J in 1 .. N - 1 loop
               Z := Z + C (1, J).Re * V (I) ** J;
            end loop;
            Put ("=>" & Real'Image (Z));
            New_Line;
         end loop;
      end;
   end;
end;

--  Build with:
--  gnatmake find_roots -largs /Developer/SDKs/MacOSX10.4u.sdk/usr/lib/
libblas.dylib /Developer/SDKs/MacOSX10.4u.sdk/usr/lib/liblapack.dylib


--  Given an Nth degree polynomial A(N)X**N + ... + A(1)X + A(0),
--  the roots can be found by finding the eigenvalues L(I) of the
matrix
--     _                                                           _
--    |   -A(1)/A(0)   -A(2)/A(0)   -A(3)/A(0)   ...   -A(N)/A(0)   |
--    |        1            0            0       ...        0       |
--    |        0            1            0       ...        0       |
--    |       ...          ...           1       ...        0       |
--    |_       0            0            0       ...        0      _|
--
--  and taking R(i) = 1/L(I). This method can be computationally
expensive,
--  but is fairly robust at finding close and multiple roots.
--    (wolphram)


--  This program computes the roots of a polynomial using the method
--  described in http://en.wikipedia.org/wiki/Companion_matrix

--  This method is for monic polynomials, i.e. with coficient of the
term
--  of greater degree equal to 1, so the input is for the remainder
terms,
--  in descending order e.g. for polynomial
--     x^3 - 2x^2 - x + 2
--  the input is
--     -2 -1 2

with Ada.Command_Line;
with Ada.Numerics.Generic_Real_Arrays;
with Ada.Text_IO;
with Ada.Numerics.Generic_Complex_Types;
with Ada.Numerics.Generic_Complex_Arrays;

procedure Find_Roots_Wikipedia is
   type Real is digits 15;
   package Real_Arrays is new Ada.Numerics.Generic_Real_Arrays (Real);
   package Complex_Types is new Ada.Numerics.Generic_Complex_Types
(Real);
   package Complex_Arrays is new Ada.Numerics.Generic_Complex_Arrays
(Real_Arrays, Complex_Types);
   N : Natural;
begin
   N := Ada.Command_Line.Argument_Count;
   declare
      C : Complex_Arrays.Complex_Matrix (1 .. N, 1 .. N) := (others =>
(others => (0.0, 0.0)));
      --  Using a complex matrix because real matrices for eigenvalues
must be symmetric.
      --  Below we convert all real values to complex (with null Im
part).
      --  (Still, the complex matrix must be Hamiltonian...)
      use Ada.Text_IO;
   begin
      for I in 1 .. N loop
         C (I, N).Re := - Real'Value (Ada.Command_Line.Argument (N - I
+ 1));
         if I > 1 then
            C (I, I - 1).Re := 1.0;
         end if;
      end loop;

      --  inspect matrix
      for i in c'range(1) loop
         for j in c'range(2) loop
            put (c(i,j).re'img & ", ");
         end loop;
         new_line;
      end loop;

      declare
         V : Real_Arrays.Real_Vector := Complex_Arrays.Eigenvalues
(C);
         use Real_Arrays;
         Z : Real;
         use Ada.Text_IO;
      begin
         for I in V'Range loop
            Put (Real'Image (V (I)));
            Z := V (I) ** N;
            for J in 1 .. N loop
               Z := Z + C (N, J).Re * V (I) ** (J - 1);
            end loop;
            Put (" => " & Real'Image (Z));
            New_Line;
         end loop;
      end;
   end;
end;

--  Build with:
--  gnatmake find_roots_wikipedia -largs /Developer/SDKs/
MacOSX10.4u.sdk/usr/lib/libblas.dylib /Developer/SDKs/MacOSX10.4u.sdk/
usr/lib/liblapack.dylib



^ permalink raw reply	[relevance 7%]

* Re: Passing shell arguments to Ada programs the Linux way
  2011-07-03  5:44  7%   ` anon
@ 2011-07-04 16:59  0%     ` Oliver Kleinke
  0 siblings, 0 replies; 200+ results
From: Oliver Kleinke @ 2011-07-04 16:59 UTC (permalink / raw)


Err, excuse me but nanos gigantium humeris insidentes?


Am Sun, 3 Jul 2011 05:44:07 +0000 (UTC)
schrieb anon@att.net:

> Ada is defined as an "Operating System independent" language. Which
> means if it works in Linux it MUST work for all Operating Systems not
> just Linux.
> 
> And most want their programs to work in Linux, Windows, etc. So, for
> Ada users we process the "command line" by the definition set in the
> RM by using the package "Ada.Command_Line".
> 
> In other way, is a waste of time for Ada users.
> 
> Note: As for "GNAT.Command_Line", well it can only be found in
> Adacore's GNAT Ada. Which some will say it not a standard RM Ada
> package, so why use it. because it might disappear next year. Which
> means the programmer may have to support that package that they do
> not fully understand. The problem with Adacore's non RM packages
> (GNAT.*, and a lot of System.*) is that they are to "Operating
> System" dependant. 
> 
> Also, "Ada.Command_Line" will work for Linux 3.x. Will these others 
> packages, that's the question. This is the problem when designing
> packages for Linux at the end of a major design steam such as Linux
> 0.x, 1.x and 2,x and now 3.x. 
> 
> 
> In <m2zkkwy9l0.fsf@pushface.org>, Simon Wright <simon@pushface.org>
> writes:
> >A famous IT technical writer <Philippe.vouters@laposte.net> writes:
> >
> >> You may find a solution on how to pass shell arguments to an Ada
> >> program the Linux way. The code has been tested on Linux. As it
> >> makes use of the GCC suite, the code is usable under any operating
> >> system which implements the GCC suite.
> >
> >GNAT users could also look at GNAT.Command_Line.
> 





^ permalink raw reply	[relevance 0%]

* Re: Passing shell arguments to Ada programs the Linux way
  @ 2011-07-03  5:44  7%   ` anon
  2011-07-04 16:59  0%     ` Oliver Kleinke
  0 siblings, 1 reply; 200+ results
From: anon @ 2011-07-03  5:44 UTC (permalink / raw)


Ada is defined as an "Operating System independent" language. Which means 
if it works in Linux it MUST work for all Operating Systems not just Linux.

And most want their programs to work in Linux, Windows, etc. So, for Ada 
users we process the "command line" by the definition set in the RM by 
using the package "Ada.Command_Line".

In other way, is a waste of time for Ada users.

Note: As for "GNAT.Command_Line", well it can only be found in Adacore's 
GNAT Ada. Which some will say it not a standard RM Ada package, so why 
use it. because it might disappear next year. Which means the programmer 
may have to support that package that they do not fully understand. The 
problem with Adacore's non RM packages (GNAT.*, and a lot of System.*) 
is that they are to "Operating System" dependant. 

Also, "Ada.Command_Line" will work for Linux 3.x. Will these others 
packages, that's the question. This is the problem when designing packages 
for Linux at the end of a major design steam such as Linux 0.x, 1.x and 2,x 
and now 3.x. 


In <m2zkkwy9l0.fsf@pushface.org>, Simon Wright <simon@pushface.org> writes:
>A famous IT technical writer <Philippe.vouters@laposte.net> writes:
>
>> You may find a solution on how to pass shell arguments to an Ada
>> program the Linux way. The code has been tested on Linux. As it makes
>> use of the GCC suite, the code is usable under any operating system
>> which implements the GCC suite.
>
>GNAT users could also look at GNAT.Command_Line.




^ permalink raw reply	[relevance 7%]

* Re: Need some light on using Ada or not
  2011-02-21 12:52  5%                 ` Brian Drummond
  2011-02-21 13:44  5%                   ` Simon Wright
@ 2011-02-22  2:15  3%                   ` Shark8
  1 sibling, 0 replies; 200+ results
From: Shark8 @ 2011-02-22  2:15 UTC (permalink / raw)


On Feb 21, 4:52 am, Brian Drummond <brian_drumm...@btconnect.com>
wrote:
>
> As this is my first experiment with tasking, comments are welcome (and I'd be
> interested to see your version). If people think this is worth submitting to the
> shootout, I'll go ahead.
>
> - Brian

I used arrays for the most part, and then expanded it out to a
recursive-definition for the trees which would be too large for
the stack during creation.

It may be going against the spirit of the competition, but nothing
there said that we couldn't use arrays as binary-trees.


-- Package B_Tree
-- by Joey Fish

Package B_Tree is


   -- Contest rules state:
   --	define a tree node class and methods, a tree node record and
procedures,
   --	or an algebraic data type and functions.
   --
   -- B_Tree is the definition of such a record and procedures.

   Type Binary_Tree is Private;

   Function  Build_Tree	(Item : Integer; Depth : Natural)    Return
Binary_Tree;
   Function  Subtree	(Tree : Binary_Tree; Left : Boolean) Return
Binary_Tree;
   Function  Item_Check	(This : Binary_Tree)		     Return Integer;
   Procedure Free	(Tree : In Out Binary_Tree);

Private

   Type Node_Data;
   Type Data_Access		is Access Node_Data;
   SubType Not_Null_Data_Access	is Not Null Data_Access;

   Function Empty Return Not_Null_Data_Access;
   Type Binary_Tree( Extension : Boolean:= False ) is Record
      Data   :  Not_Null_Data_Access:= Empty;
   End Record;

End B_Tree;

--- B_Trees body
with
Ada.Text_IO,
--Ada.Numerics.Generic_Elementary_Functions,
Unchecked_Deallocation;

Package Body B_Tree is

   -- In some cases the allocataion of the array is too large, so we
can split
   -- that off into another tree, for that we have Tree_Array, which
is a
   -- Boolean-indexed array. {The Index is also shorthand for Is_left
on such.}
   Type Tree_Array	is Array (Boolean) of Binary_Tree;

   -- For trees of up to 2**17 items we store the nodes as a simple
array.
   Type Integer_Array	is Array (Positive Range <>) of Integer;
   Type Access_Integers	is Access Integer_Array;
   Type Node_Data(Extended : Boolean:= False) is Record
      Case Extended is
         When False => A : Not Null Access_Integers;
         When True  => B : Tree_Array;
      end Case;
   End Record;


   --  Returns the Empty List's Data.
   Function Empty Return Not_Null_Data_Access is
   begin
      Return New Node_Data'( A => New Integer_Array'(2..1 => 0),
Others => <> );
   end Empty;



      -- We'll need an integer-version of logrithm in base-2
      Function lg( X : In Positive ) Return Natural is
         --------------------------------------------
         --  Base-2 Log with a jump-table for the  --
         --  range 1..2**17-1 and a recursive call --
         --  for all values greater.		   --
         --------------------------------------------
      begin
         Case X Is
            When 2**00..2**01-1	=> Return  0;
            When 2**01..2**02-1	=> Return  1;
            When 2**02..2**03-1	=> Return  2;
            When 2**03..2**04-1	=> Return  3;
            When 2**04..2**05-1	=> Return  4;
            When 2**05..2**06-1	=> Return  5;
            When 2**06..2**07-1	=> Return  6;
            When 2**07..2**08-1	=> Return  7;
            When 2**08..2**09-1	=> Return  8;
            When 2**09..2**10-1	=> Return  9;
            When 2**10..2**11-1	=> Return 10;
            When 2**11..2**12-1	=> Return 11;
            When 2**12..2**13-1	=> Return 12;
            When 2**13..2**14-1	=> Return 13;
            When 2**14..2**15-1	=> Return 14;
            When 2**15..2**16-1	=> Return 15;
            When 2**16..2**17-1	=> Return 16;
            When Others		=> Return 16 + lg( X / 2**16 );
         End Case;
      end lg;

   Function Build_Tree (Item : Integer; Depth : Natural) Return
Binary_Tree is
      -- Now we need a function to allow the calculation of a node's
value
      -- given that node's index.
      Function Value( Index : Positive ) Return Integer is
	Level : Integer:= lg( Index );
	-- Note: That is the same as
	--	Integer( Float'Truncation( Log( Float(Index),2.0 ) ) );
	-- but without the Integer -> Float & Float -> Integer conversions.
      begin
         Return (-2**(1+Level)) + 1 + Index;
      end;

   Begin
      If Depth < 17 then
         Return Result : Binary_Tree do
            Result.Data:= New Node_Data'
		( A => New Integer_Array'(1..2**Depth-1 => <>), Others => <> );
            For Index in Result.Data.A.All'Range Loop
		Result.Data.All.A.All( Index ):= Value(Index) + Item;
            End Loop;
         End Return;
      else
         Return Result : Binary_Tree do
            Result.Data:= New Node_Data'
              ( B =>
                (True => Build_Tree(-1,Depth-1), False =>
Build_Tree(0,Depth-1)),
               Extended => True );
         End Return;

      end if;
   End Build_Tree;

   Function Subtree (Tree : Binary_Tree; Left : Boolean) Return
Binary_Tree is
   Begin
      if Tree.Data.Extended then
         -- If it is a large enough tree, then we already have it
split.
         Return Tree.Data.B(Left);
      else
         -- If not then we just need to calculate the middle and
return the
         -- proper half [excluding the first (root) node.
         Declare
            Data	  : Integer_Array Renames Tree.Data.All.A.All;
            Data_Length : Natural:= Data'Length;

            Mid_Point : Positive:= (Data_Length/2) + 1;
            SubType LeftTree is Positive Range
              Positive'Succ(1)..Mid_Point;
            SubType RightTree is Positive Range
              Positive'Succ(Mid_Point)..Data_Length;
         Begin
            Return Result : Binary_Tree Do
               if Left then
                  Result.Data:= New Node_Data'
                    ( A => New Integer_Array'( Data(LeftTree)  ),
Others => <> );
               else
                  Result.Data:= New Node_Data'
                    ( A => New Integer_Array'( Data(RightTree) ),
Others => <> );
               end if;
            End Return;
         End;
      end if;
   End Subtree;

   Function Check_Sum(	Data: In Integer_Array	) Return Integer is
      Depth : Natural:= lg(Data'Length);
      SubType Internal_Nodes is Positive Range 1..2**Depth-1;
   begin
      Return Result : Integer:= 0 do
         For Index in Internal_Nodes Loop
            Declare
               Left	: Positive:= 2*Index;
               Right	: Positive:= Left+1;
            Begin
               If Index mod 2 = 1 then
                  Result:= Result - Right + Left;
               else
                  Result:= Result + Right - Left;
               end if;
            End;
         End Loop;
      End Return;
   end Check_Sum;

   Function Item_Check	(This : Binary_Tree) Return Integer is
      -- For large trees this function calls itself recursively until
the
      -- smaller format is encountered; otherwise, for small trees, it
acts as
      -- a pass-througn to Check_Sum.
   Begin
      If This.Data.Extended then
         Declare

         Begin
            Return Result: Integer:= -1 do
               Result:=   Result
			+ Item_Check( This.Data.B(False) )
			- Item_Check( This.Data.B(True ) );
            End Return;
         End;
      else
         Declare
            Data : Integer_Array Renames This.Data.All.A.All;
         Begin
            Return Check_Sum( Data );
         End;
      end if;
   End Item_Check;

   Procedure Free	(Tree : In Out Binary_Tree) is
      procedure Deallocate is new
		Unchecked_Deallocation(Integer_Array, Access_Integers);
      procedure Deallocate is new
		Unchecked_Deallocation(Node_Data, Data_Access);

      Procedure Recursive_Free	(Tree : In Out Binary_Tree) is
      begin
         if Tree.Data.All.Extended then
            Recursive_Free( Tree.Data.B(True ) );
            Recursive_Free( Tree.Data.B(False) );
            Declare
               Data : Data_Access;
               For Data'Address Use Tree.Data'Address;
               Pragma Import( Ada, Data );
            Begin
               Deallocate(Data);
            End;
         else
            Declare
               Data : Data_Access;
               For Data'Address Use Tree.Data.All.A'Address;
               Pragma Import( Ada, Data );
            Begin
               Deallocate( Data );
               Data:= Empty;
            End;
         end if;
      end Recursive_Free;

   begin
      Recursive_Free( Tree );
      Tree.Data:= Empty;
   end Free;

Begin
   Null;
End B_Tree;

-- BinaryTrees.adb
-- by Jim Rogers
-- modified by Joey Fish

With
B_Tree,
Ada.Text_Io,
Ada.Real_Time,
Ada.Command_Line,
Ada.Characters.Latin_1,
;

Use
B_Tree,
Ada.Text_Io,
Ada.Command_Line,
Ada.Integer_Text_Io,
Ada.Characters.Latin_1
;

procedure BinaryTrees is
   --Depths
   Min_Depth	: Constant Positive := 4;
   Max_Depth	: Positive;
   Stretch_Depth: Positive;
   N		: Natural := 1;

   -- Trees
   Stretch_Tree,
   Long_Lived_Tree	: Binary_Tree;


   Check,
   Sum		: Integer;
   Depth	: Natural;
   Iterations	: Positive;

   Package Fn is New
Ada.Numerics.Generic_Elementary_Functions( Float );
   Function Value( Index : Positive ) Return Integer is
      Level : Integer:=
	Integer( Float'Truncation( Fn.Log( Float(Index),2.0 ) ) );
   begin
      Return (-2**(1+Level)) + 1 + Index;
   end;


begin
--     For Index in 1..2**3-1 loop
--        Put_Line( Value(Index)'img );
--     end loop;

--     Declare
--        -- allocate new memory:
--        Short_Lived_Tree_1: Binary_Tree:= Build_Tree(0, 20);
--     Begin
--        Sum:= Item_Check (Short_Lived_Tree_1);
--  --        Check := Check + Sum;
--  --        Free( Short_Lived_Tree_1 );
--        Put(Check'Img);
--     End;


   if Argument_Count > 0 then
      N := Positive'Value(Argument(1));
   end if;
   Max_Depth := Positive'Max(Min_Depth + 2, N);
   Stretch_Depth := Max_Depth + 1;
   Stretch_Tree := Build_Tree(0, Stretch_Depth);
   Check:= Item_Check(Stretch_Tree);
   Put("stretch tree of depth ");
   Put(Item => Stretch_Depth, Width => 1);
   Put(Ht & " check: ");
   Put(Item => Check, Width => 1);
   New_Line;

   Long_Lived_Tree := Build_Tree(0, Max_Depth);

   Depth := Min_Depth;
   while Depth <= Max_Depth loop
      Iterations := 2**(Max_Depth - Depth + Min_Depth);
      Check := 0;
      for I in 1..Iterations loop
         Declare
            Short_Lived_Tree_1: Binary_Tree:= Build_Tree(I, Depth);
         Begin
            Sum:= Item_Check (Short_Lived_Tree_1);
            Check := Check + Sum;
            Free( Short_Lived_Tree_1 );
         End;


         Declare
            Short_Lived_Tree_2: Binary_Tree:= Build_Tree(-I, Depth);
         Begin
            Sum:= Item_Check (Short_Lived_Tree_2);
            Check := Check + Sum;
            Free( Short_Lived_Tree_2 );
         End;
      end loop;

      Put(Item => Iterations * 2, Width => 0);
      Put(Ht & " trees of depth ");
      Put(Item => Depth, Width => 0);
      Put(Ht & " check: ");
      Put(Item => Check, Width => 0);
      New_Line;
      Depth := Depth + 2;
   end loop;
   Put("long lived tree of depth ");
   Put(Item => Max_Depth, Width => 0);
   Put(Ht & " check: ");
   check:= Item_Check(Long_Lived_Tree);
   Put(Item => Check, Width => 0);
   New_Line;

end BinaryTrees;




^ permalink raw reply	[relevance 3%]

* Re: Need some light on using Ada or not
  2011-02-21 12:52  5%                 ` Brian Drummond
@ 2011-02-21 13:44  5%                   ` Simon Wright
  2011-02-22  2:15  3%                   ` Shark8
  1 sibling, 0 replies; 200+ results
From: Simon Wright @ 2011-02-21 13:44 UTC (permalink / raw)


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

Brian Drummond <brian_drummond@btconnect.com> writes:

> As this is my first experiment with tasking, comments are welcome (and
> I'd be interested to see your version).

See end.

> If people think this is worth submitting to the shootout, I'll go
> ahead.

I think it definitely is: the only Ada code for binary-trees is
single-threaded, so looks needlessly poor.


[-- Attachment #2: simple multi-thread version of binary trees benchmark --]
[-- Type: text/plain, Size: 5283 bytes --]

----------------------------------------------------------------
-- BinaryTrees
--
-- Ada 95 (GNAT)
--
-- Contributed by Jim Rogers
-- Modified by Simon Wright
----------------------------------------------------------------
with Tree_Nodes; use Tree_Nodes;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
with System;

procedure Binarytrees is
   Min_Depth : constant Positive := 4;
   N : Natural := 1;
   Stretch_Tree : Tree_Node;
   Long_Lived_Tree : Tree_Node;
   Max_Depth : Positive;
   Stretch_Depth : Positive;

   task type Check_Tree is
      pragma Priority (System.Default_Priority - 1);
      entry Start (Iterations : Positive; Depth : Positive);
      entry Sum (Result : out Integer);
   end Check_Tree;

   task body Check_Tree is
      Iterations : Positive;
      Depth : Positive;
      Tree : Tree_Node;
      Check : Integer := 0;
   begin
      accept Start (Iterations : Positive; Depth : Positive) do
         Check_Tree.Iterations := Iterations;
         Check_Tree.Depth := Depth;
      end Start;
      for J in 1 .. Iterations loop
         Tree := Bottom_Up_Tree (J, Depth);
         Check := Check + Item_Check (Tree);
         Delete_Tree (Tree);
         Tree := Bottom_Up_Tree (-J, Depth);
         Check := Check + Item_Check (Tree);
         Delete_Tree (Tree);
      end loop;
      accept Sum (Result : out Integer) do
         Result := Check;
      end Sum;
   end Check_Tree;

begin

   if Argument_Count > 0 then
      N := Positive'Value (Argument (1));
   end if;

   Max_Depth := Positive'Max (Min_Depth + 2, N);
   Stretch_Depth := Max_Depth + 1;

   Stretch_Tree := Bottom_Up_Tree (0, Stretch_Depth);
   Put ("stretch tree of depth ");
   Put (Item => Stretch_Depth, Width => 1);
   Put (Ht & " check: ");
   Put (Item => Item_Check (Stretch_Tree), Width => 1);
   New_Line;
   Delete_Tree (Stretch_Tree);

   Long_Lived_Tree := Bottom_Up_Tree (0, Max_Depth);

   declare
      subtype Check_Trees_Array_Range
      is Natural range 0 .. (Max_Depth - Min_Depth) / 2;
      Check_Trees : array (Check_Trees_Array_Range) of Check_Tree;
      function Depth (For_Entry : Check_Trees_Array_Range) return Natural
      is
      begin
         return For_Entry  * 2 + Min_Depth;
      end Depth;
      function Iterations (For_Entry : Check_Trees_Array_Range) return Positive
      is
      begin
         return 2 ** (Max_Depth - Depth (For_Entry) + Min_Depth);
      end Iterations;
   begin
      for D in Check_Trees'Range loop
         Check_Trees (D).Start (Iterations => Iterations (D),
                                Depth => Depth (D));
      end loop;
      for D in Check_Trees'Range loop
         Put (Item => Iterations (D) * 2, Width => 0);
         Put (Ht & " trees of depth ");
         Put (Item => Depth (D), Width => 0);
         declare
            Check : Integer;
         begin
            Check_Trees (D).Sum (Result => Check);
            Put (Ht & " check: ");
            Put (Item => Check, Width => 0);
         end;
         New_Line;
      end loop;
   end;

   Put ("long lived tree of depth ");
   Put (Item => Max_Depth, Width => 0);
   Put (Ht & " check: ");
   Put (Item => Item_Check (Long_Lived_Tree), Width => 0);
   New_Line;
   Delete_Tree (Long_Lived_Tree);

end BinaryTrees;
----------------------------------------------------------------
-- BinaryTrees
--
-- Ada 95 (GNAT)
--
-- Contributed by Jim Rogers
-- Modified by Simon Wright
----------------------------------------------------------------

with Ada.Unchecked_Deallocation;

package body Tree_Nodes is

   function Bottom_Up_Tree (Item : Integer; Depth : Natural) return Tree_Node
   is
   begin
      if Depth > 0 then
         return new Node'(Bottom_Up_Tree (2 * Item - 1, Depth - 1),
                          Bottom_Up_Tree (2 * Item, Depth - 1),
                          Item);
      else
         return new Node'(null, null, Item);
      end if;
   end Bottom_Up_Tree;

   function Item_Check (This : Tree_Node) return Integer
   is
   begin
      if This.Left = null then
         return This.Item;
      else
         return This.Item + Item_Check (This.Left) - Item_Check (This.Right);
      end if;
   end Item_Check;

   procedure Delete_Tree (This : in out Tree_Node)
   is
      procedure Free is new Ada.Unchecked_Deallocation (Node, Tree_Node);
   begin
      if This /= null then
         Delete_Tree (This.Left);
         Delete_Tree (This.Right);
         Free (This);
      end if;
   end Delete_Tree;

end Tree_Nodes;
----------------------------------------------------------------
-- BinaryTrees
--
-- Ada 95 (GNAT)
--
-- Contributed by Jim Rogers
-- Modified by Simon Wright
----------------------------------------------------------------

package Tree_Nodes is
   type Tree_Node is private;
   function Bottom_Up_Tree (Item : Integer; Depth : Natural) return Tree_Node;
   function Item_Check (This : Tree_Node) return Integer;
   procedure Delete_Tree (This : in out Tree_Node);
private
   type Node;
   type Tree_Node is access Node;
   type Node is record
      Left  : Tree_Node;
      Right : Tree_Node;
      Item  : Integer := 0;
   end record;
end Tree_Nodes;

^ permalink raw reply	[relevance 5%]

* Re: Need some light on using Ada or not
  @ 2011-02-21 12:52  5%                 ` Brian Drummond
  2011-02-21 13:44  5%                   ` Simon Wright
  2011-02-22  2:15  3%                   ` Shark8
  0 siblings, 2 replies; 200+ results
From: Brian Drummond @ 2011-02-21 12:52 UTC (permalink / raw)


On Sun, 20 Feb 2011 22:47:05 +0000, Simon Wright <simon@pushface.org> wrote:

>Brian Drummond <brian_drummond@btconnect.com> writes:
>
>> the 100% overhead (on this test case) imposed by the pthread library
>> (which I think is how Gnat implements its tasking)
>
>Here (Mac OS X, GCC 4.6.0 x86_64 experimental), I tried modifying the
>Ada code to use the same tasking (threading) structure as the C GNU GCC
>#5 version. Result (I only checked with parameter 16):
>
>C:           real 5.1 user 9.0
>GNAT (orig): real 6.0 user 5.8
>GNAT (mod):  real 5.3 user 9.4
>
>(the 'user' value, which is what time(1) reports, is apparently the
>total CPU time, while the 'real' time is the elapsed time; this machine
>has 2 cores, both it seems running at about 90% in the test).

So again, there is an overhead (maybe 80%) imposed by tasking, and significant
improvements won't appear until >2 processors.

I can't be sure I'm reading the C correctly, but it looks as if it's creating a
new pthread (task) for each depth step, similar to my first attempt.

I have now decoupled the number of tasks from the problem, to simplify
experiments with different numbers of tasks, and improve load balancing.
It runs approx. 4x as fast with 4 or 8 tasks as it does with 1 task (on a 4-core
machine!), therefore only about 2x as fast as it does without tasking.

As this is my first experiment with tasking, comments are welcome (and I'd be
interested to see your version). If people think this is worth submitting to the
shootout, I'll go ahead.

- Brian

----------------------------------------------------------------
-- BinaryTrees
--
-- Ada 95 (GNAT)
--
-- Contributed by Jim Rogers
-- Tasking experiment : Brian Drummond
----------------------------------------------------------------
with Treenodes; use Treenodes;
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;

procedure Binarytrees_tasking is
   -- Change "CPUs" to control number of tasks created
   CPUs : constant Positive := 8;
   BlockSize : Positive;
   Min_Depth : constant Positive := 4;
   N : Natural := 1;
   Stretch_Tree : TreeNode;
   Long_Lived_Tree : TreeNode;
   Max_Depth : Positive;
   Stretch_Depth : Positive;
   Iteration : Positive;
   Iterations : Positive;
   Sum : Integer;
   Check : Integer;
   Depth : Natural;

   task type check_this_depth is
      entry Start(Iteration, Size : Positive; To_Depth :in Natural);
      entry Complete(Result : out Integer);
   end check_this_depth;

   task body check_this_depth is
      Check : Integer;
      Sum : Integer;
      Depth : Natural;
      First : Positive;
      Last : Positive;
      Short_Lived_Tree_1 : TreeNode;
      Short_Lived_Tree_2 : TreeNode;

   begin
      loop
         select
            accept Start(Iteration, Size : Positive; To_Depth :in Natural) do
               First := Iteration;
               Last := Iteration + Size - 1;
               Depth := To_Depth;
            end Start;
            Check := 0;
            for I in First .. Last loop
               Short_Lived_Tree_1 := Bottom_Up_Tree(Item => I, Depth => Depth);
               Short_Lived_Tree_2 := Bottom_Up_Tree(Item =>-I, Depth => Depth);
               Item_Check(Short_Lived_Tree_1, Sum);
               Check := Check + Sum;
               Item_Check(Short_Lived_Tree_2, Sum);
               Check := Check + Sum;
            end loop;
            accept Complete(Result : out Integer) do
               Result := Check;
            end Complete;
         or
            Terminate;
         end select;
      end loop;
   end check_this_depth;

   subtype Task_Count is positive range 1 .. CPUs;	
   Tasks : array (Task_Count) of check_this_depth;

begin
   if Argument_Count > 0 then
      N := Positive'Value(Argument(1));
   end if;
   Max_Depth := Positive'Max(Min_Depth + 2, N);
   Stretch_Depth := Max_Depth + 1;
   Stretch_Tree := Bottom_Up_Tree(0, Stretch_Depth);
   Item_Check(Stretch_Tree, Check);
   Put("stretch tree of depth ");
   Put(Item => Stretch_Depth, Width => 1);
   Put(Ht & " check: ");
   Put(Item => Check, Width => 1);
   New_Line;
   
   Long_Lived_Tree := Bottom_Up_Tree(0, Max_Depth);
   
   Depth := Min_Depth;
   while Depth <= Max_Depth loop
      Iterations := 2**(Max_Depth - Depth + Min_Depth);
      Check := 0;

-- Setup tasking parameters for reasonable task granularity
-- Too large and we can't balance CPU loads
-- Too small and we waste time in task switches
-- Not very critical - anything more complex is probably a waste of effort
      
      BlockSize := 2**10;
      if Iterations < BlockSize * CPUs then
         BlockSize := 1;
      end if;
  
-- Check that Iterations is a multiple of Blocksize * CPUs
-- Error out otherwise (dealing with remainder is trivial but tedious)
      Pragma Assert(Iterations mod( BlockSize * CPUs) = 0, 
                            "Iteration count not supported!");

      -- for I in 1..Iterations loop  
      Iteration := 1;   
      while Iteration <= Iterations loop
         for j in Task_Count loop
            Tasks(j).Start(Iteration, Blocksize, Depth);
            Iteration := Iteration + BlockSize;
         end loop;
         for j in Task_Count loop
            Tasks(j).Complete(Sum);
            Check := Check + Sum;
         end loop;
      end loop;
      Put(Item => Iterations * 2, Width => 0);
      Put(Ht & " trees of depth ");
      Put(Item => Depth, Width => 0);
      Put(Ht & " check: ");
      Put(Item => Check, Width => 0);
      New_Line;
      Depth := Depth + 2;
   end loop;
   Put("long lived tree of depth ");
   Put(Item => Max_Depth, Width => 0);
   Put(Ht & " check: ");
   Item_Check(Long_Lived_Tree, Check);
   Put(Item => Check, Width => 0);
   New_Line;
end BinaryTrees_tasking;




^ permalink raw reply	[relevance 5%]

* Re: Need some light on using Ada or not
  @ 2011-02-20 14:34  5%       ` Brian Drummond
    0 siblings, 1 reply; 200+ results
From: Brian Drummond @ 2011-02-20 14:34 UTC (permalink / raw)


On Sat, 19 Feb 2011 18:25:44 +0000, Brian Drummond
<brian_drummond@btconnect.com> wrote:

>On Sat, 19 Feb 2011 15:36:45 +0100, Georg Bauhaus
><rm-host.bauhaus@maps.futureapps.de> wrote:
>
>>On 2/19/11 2:07 PM, Brian Drummond wrote:
>>> On 18 Feb 2011 22:52:38 GMT, "Luis P. Mendes"<luislupeXXX@gmailXXX.com>  wrote:
>>
>>>> I have some questions, however, that I'd like to be answered:
>>>> 1. If Ada is more type safe and restricted than C++, how can it be
>>>> significantly slower?
>>> Two possible reasons; both come down to the relative number of people developing
>>> for both languages.

[using tasking for the binary_trees benchmark, which currently uses a single
task...]
>>I vaguely remember that it has been tried before, but so far there
>>is no better solution.

>I have broken down and finally started to learn Ada's tasking. So far I have
>gone from 56s (CPU) 56s (elapsed) with one task, to 120s (CPU), 64s(elapsed)
>with multiple tasks (on a smallish 2-core laptop)... 
>
>Disappointing.
>
>(If anybody's interested, I am using 9 tasks, one per "Depth" value in the main
>while loop. 

Further odd results. I re-structured the tasking so that I could modify the
number of tasks, from 1, 2, 4, etc. The "CPU" utilisation remains virtually
identical, at 2 minutes; the elapsed time is 2 minutes with 1 task, or 1 minute
with 2 or more (on a 2-core laptop. I'll report on a 4-core later).

Moving from GCC4.5.0 (FSF) to Adacore Libre 2010 makes no significant
difference. (OpenSuse 11.3, 64-bit, 2-core laptop)

Doubling the CPU time with a single task is suspicious, so I tried the following
experiment : source code below - main program only. For the rest, and the
original version, see
http://shootout.alioth.debian.org/u64q/performance.php?test=binarytrees

I removed virtually the entire body of the program into a single task.
This change alone doubles the "CPU" time. There appears to be a 100% penalty
associated simply with running the original program from within a second task.

Anyone see what I'm doing wrong?
Any pitfalls to using tasking that I may have missed?

I suspect storage [de]allocation since that's under stress in this test, and
other benchmarks (e.g. Mandelbrot) don't see this penalty.
Should the task have its own separate storage pool, to avoid difficulties
synchronising with the main pool (even though the main program no longer uses
it?


----------------------------------------------------------------
-- BinaryTrees experimental version
--
-- Ada 95 (GNAT)
--
-- Contributed by Jim Rogers
-- Tasking experiment:  Brian Drummond
----------------------------------------------------------------
with Treenodes; use Treenodes;
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;

procedure Binarytrees_tasktest is

   N : Natural := 1;

   task the_work is
      entry Start(Count :in Natural);
      entry Complete;
   end the_work;

   task body the_work is
      Min_Depth : constant Positive := 4;
      Stretch_Tree : TreeNode;
      Long_Lived_Tree : TreeNode;
      Short_Lived_Tree_1 : TreeNode;
      Short_Lived_Tree_2 : TreeNode;
      Max_Depth : Positive;
      Stretch_Depth : Positive;
      Check : Integer;
      Sum : Integer;
      Depth : Natural;
      Iterations : Positive;
   begin

      accept Start(Count :in Natural) do
         N := Count;
      end Start;

      Max_Depth := Positive'Max(Min_Depth + 2, N);
      Stretch_Depth := Max_Depth + 1;
      Stretch_Tree := Bottom_Up_Tree(0, Stretch_Depth);
      Item_Check(Stretch_Tree, Check);
      Put("stretch tree of depth ");
      Put(Item => Stretch_Depth, Width => 1);
      Put(Ht & " check: ");
      Put(Item => Check, Width => 1);
      New_Line;
   
      Long_Lived_Tree := Bottom_Up_Tree(0, Max_Depth);
   
      Depth := Min_Depth;
      while Depth <= Max_Depth loop
         Iterations := 2**(Max_Depth - Depth + Min_Depth);
         Check := 0;
         for I in 1..Iterations loop
            Short_Lived_Tree_1 := Bottom_Up_Tree(Item => I, Depth => Depth);
            Short_Lived_Tree_2 := Bottom_Up_Tree(Item =>-I, Depth => Depth);
            Item_Check(Short_Lived_Tree_1, Sum);
            Check := check + Sum;
            Item_Check(Short_Lived_Tree_2, Sum);
            Check := Check + Sum;
         end loop;
         Put(Item => Iterations * 2, Width => 0);
         Put(Ht & " trees of depth ");
         Put(Item => Depth, Width => 0);
         Put(Ht & " check: ");
         Put(Item => Check, Width => 0);
         New_Line;
         Depth := Depth + 2;
      end loop;
      Put("long lived tree of depth ");
      Put(Item => Max_Depth, Width => 0);
      Put(Ht & " check: ");
      Item_Check(Long_Lived_Tree, Check);
      Put(Item => Check, Width => 0);
      New_Line;
      accept Complete;
   end the_work;

begin
   if Argument_Count > 0 then
      N := Positive'Value(Argument(1));
   end if;
   the_work.start(N);
   the_work.complete;
end BinaryTrees_tasktest;

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



^ permalink raw reply	[relevance 5%]

* Re: Problems with String processing
  2010-10-23 20:16  9% Problems with String processing George
  2010-10-23 20:24  6% ` Niklas Holsti
  2010-10-23 20:25  6% ` Dmitry A. Kazakov
@ 2010-10-23 23:59  0% ` Jeffrey Carter
  2 siblings, 0 replies; 200+ results
From: Jeffrey Carter @ 2010-10-23 23:59 UTC (permalink / raw)


On 10/23/2010 01:16 PM, George wrote:
>
> begin
> -- Ada.Command_Line.Argument_Count is "0" if
> -- a) Command_Line.Argument_Count is not implemented (Compiler, OS)
> -- b) no arguments given
> if Ada.Command_Line.Argument_Count>  0 then
>     for counter in 1..Ada.Command_Line.Argument_Count loop

Unrelated to your question, which others have answered, this "if" is not needed. 
The loop will execute zero times if Argument_Count < 1.

-- 
Jeff Carter
"Unix and C are the ultimate computer viruses."
Richard Gabriel
99



^ permalink raw reply	[relevance 0%]

* Re: Wrong program structure
  2010-10-23 21:08  9% Wrong program structure George
@ 2010-10-23 21:16  0% ` Vinzent Hoefler
  0 siblings, 0 replies; 200+ results
From: Vinzent Hoefler @ 2010-10-23 21:16 UTC (permalink / raw)


On Sat, 23 Oct 2010 23:08:32 +0200, George <mail2george@gmx-topmail.de> wrote:

> GNAT is complaining about "begin" being used as identifier and a missing
> "begin" for procedure "keywords4". The progam structure is like this:
>
[...]
> begin
> -- Ada.Command_Line.Argument_Count is "0" if
> -- a) Command_Line.Argument_Count is not implemented (Compiler, OS)
> -- b) no arguments given
> if Ada.Command_Line.Argument_Count > 0 then
>    for counter in 1..Ada.Command_Line.Argument_Count loop
>       declare
>       Arg : constant String := Ada.Characters.Handling.To_Upper
> (Ada.Command_Line.Argument(counter));

begin

>      -- some commands

end;

>    end loop;
> else -- if Argument_Count = 0 print help
>    -- some commands
> end if;
> end keywords4;

You are declaring a block, but its "end" is missing.


Vinzent.

-- 
There is no signature.



^ permalink raw reply	[relevance 0%]

* Wrong program structure
@ 2010-10-23 21:08  9% George
  2010-10-23 21:16  0% ` Vinzent Hoefler
  0 siblings, 1 reply; 200+ results
From: George @ 2010-10-23 21:08 UTC (permalink / raw)


Hi All,

GNAT is complaining about "begin" being used as identifier and a missing 
"begin" for procedure "keywords4". The progam structure is like this:

with Ada.Text_IO;
with Ada.Command_Line;
with Ada.Characters.Handling;

procedure keywords4 is

procedure Ada83 is
begin
-- some string output
end Ada83;

procedure Ada95 is
begin
-- some string output
end Ada95;

procedure Ada2005 is
begin
-- some string output
end Ada2005;

procedure Attributes is
begin
-- some string output
end Attributes;

procedure Sources is
begin
-- some string output
end Sources;

procedure Author is
begin
-- some string output
end Author;

begin
-- Ada.Command_Line.Argument_Count is "0" if
-- a) Command_Line.Argument_Count is not implemented (Compiler, OS)
-- b) no arguments given
if Ada.Command_Line.Argument_Count > 0 then
   for counter in 1..Ada.Command_Line.Argument_Count loop
      declare
      Arg : constant String := Ada.Characters.Handling.To_Upper
(Ada.Command_Line.Argument(counter));
     -- some commands
   end loop;
else -- if Argument_Count = 0 print help
   -- some commands
end if;
end keywords4;

I nested the procedures Ada83, Ada95, etc. into keywords4 because I can 
not have multiple compilation units. I tried defining a package but when 
executing the program the runtime library came back with the message that 
the code could not be executed.

Maybe I am asking simple questions. Its because I am new to Ada and try 
get used to the language.

What is the problem with the above code?

Regards

George



^ permalink raw reply	[relevance 9%]

* Re: Problems with String processing
  2010-10-23 20:16  9% Problems with String processing George
  2010-10-23 20:24  6% ` Niklas Holsti
@ 2010-10-23 20:25  6% ` Dmitry A. Kazakov
  2010-10-23 23:59  0% ` Jeffrey Carter
  2 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2010-10-23 20:25 UTC (permalink / raw)


On 23 Oct 2010 20:16:53 GMT, George wrote:

> begin
> -- Ada.Command_Line.Argument_Count is "0" if
> -- a) Command_Line.Argument_Count is not implemented (Compiler, OS)
> -- b) no arguments given
> if Ada.Command_Line.Argument_Count > 0 then
>    for counter in 1..Ada.Command_Line.Argument_Count loop

declare
   Arg : constant String :=  Ada.Characters.Handling.
       To_Upper (Ada.Command_Line.Argument (Counter)); 
begin
>       if Arg = "ADA83" then
>          Ada83;
>       elsif Arg = "ADA95" then
>          Ada95;
>       elsif Arg = "ADA2005" then
>          Ada2005;
>       elsif Arg = "ATTRIBUTES" then
>          Attributes;
>       elsif Arg = "ALL" then
>          Ada83;
>          Ada95;
>          Ada2005;
>          Attributes;
>          Sources;
>          Author;
>       else -- unknown argument
>          Ada.Text_IO.put_line("Given Argument is unknown!");
>       end if;

end;

>    end loop;

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



^ permalink raw reply	[relevance 6%]

* Re: Problems with String processing
  2010-10-23 20:16  9% Problems with String processing George
@ 2010-10-23 20:24  6% ` Niklas Holsti
  2010-10-23 20:25  6% ` Dmitry A. Kazakov
  2010-10-23 23:59  0% ` Jeffrey Carter
  2 siblings, 0 replies; 200+ results
From: Niklas Holsti @ 2010-10-23 20:24 UTC (permalink / raw)


George wrote:
> Hi All,
> 
> I have some problems with string processing. My program looks like this:
> 
> begin
> -- Ada.Command_Line.Argument_Count is "0" if
> -- a) Command_Line.Argument_Count is not implemented (Compiler, OS)
> -- b) no arguments given
> if Ada.Command_Line.Argument_Count > 0 then
>    for counter in 1..Ada.Command_Line.Argument_Count loop
>       Arg = Ada.Characters.Handling.To_Upper(Ada.Command_Line.Argument
> (counter)); -- this assignment is the problem

Firstly, that isn't an assignment, since you wrote "=". You should write 
":=" for an assignment.

Secondly, as you have now learned, the Ada String type is a fixed-length 
string. The simplest solution is to declare the Arg variable as a 
constant String that is given its value (and length) in the declaration 
itself:

    declare
       Arg : constant String := Ada.Characters.Handling.To_Upper (
          Ada.Command_Line.Argument (counter));
    begin

>       if Arg = "ADA83" then
>          Ada83;
>       elsif Arg = "ADA95" then
>          Ada95;
>       elsif Arg = "ADA2005" then
>          Ada2005;
>       elsif Arg = "ATTRIBUTES" then
>          Attributes;
>       elsif Arg = "ALL" then
>          Ada83;
>          Ada95;
>          Ada2005;
>          Attributes;
>          Sources;
>          Author;
>       else -- unknown argument
>          Ada.Text_IO.put_line("Given Argument is unknown!");
>       end if;

    end;

>    end loop;
> 
> The assignment Arg = Ada.Characters.Handling.To_Upper
> (Ada.Command_Line.Argument(counter)); will not work due to a CONSTRAINT 
> ERROR. The problem is that the command line arguments given are of 
> different length. Ada expects the string to match exactly the length of 
> the defined variable "Arg" with 10 characters.
> 
> How could I solve that problem?

Another solution is to use Ada.Strings.Unbounded.Unbounded_String, which 
is the main Ada type for variable-length strings.

HTH,

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



^ permalink raw reply	[relevance 6%]

* Problems with String processing
@ 2010-10-23 20:16  9% George
  2010-10-23 20:24  6% ` Niklas Holsti
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: George @ 2010-10-23 20:16 UTC (permalink / raw)


Hi All,

I have some problems with string processing. My program looks like this:

begin
-- Ada.Command_Line.Argument_Count is "0" if
-- a) Command_Line.Argument_Count is not implemented (Compiler, OS)
-- b) no arguments given
if Ada.Command_Line.Argument_Count > 0 then
   for counter in 1..Ada.Command_Line.Argument_Count loop
      Arg = Ada.Characters.Handling.To_Upper(Ada.Command_Line.Argument
(counter)); -- this assignment is the problem
      if Arg = "ADA83" then
         Ada83;
      elsif Arg = "ADA95" then
         Ada95;
      elsif Arg = "ADA2005" then
         Ada2005;
      elsif Arg = "ATTRIBUTES" then
         Attributes;
      elsif Arg = "ALL" then
         Ada83;
         Ada95;
         Ada2005;
         Attributes;
         Sources;
         Author;
      else -- unknown argument
         Ada.Text_IO.put_line("Given Argument is unknown!");
      end if;
   end loop;

The assignment Arg = Ada.Characters.Handling.To_Upper
(Ada.Command_Line.Argument(counter)); will not work due to a CONSTRAINT 
ERROR. The problem is that the command line arguments given are of 
different length. Ada expects the string to match exactly the length of 
the defined variable "Arg" with 10 characters.

How could I solve that problem?

Regards

George



^ permalink raw reply	[relevance 9%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-09-02 19:08  5%                                                       ` Randy Brukardt
@ 2010-09-02 20:48  5%                                                         ` Georg Bauhaus
  0 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2010-09-02 20:48 UTC (permalink / raw)


On 9/2/10 9:08 PM, Randy Brukardt wrote:

>> 2. do with the names what I want after they have been read:
>
> Why is such a Matcher routine necessary?

Not really, my overloaded subp was a quick attempt at removing
implementation-defined and replacing it with something
that allows all kinds of control over the results, i.e. the
next file name is good or not. The callback should just place
the file name testing loop inside (Start_)Search, as a way to keep
the directory searching loop free from the matching stuff
(like Pattern, only with more power).

OTOH, much of my argument in favor of full power String matching
is based on the (presumed) fact that file system names are
basically like vegetables. There will be specks, some rotten,
and molds, as mentioned. But you still want to eat them, without
exception, when you are hungry and they represent the notion
of edible food.[*]  That leaves the question why having implementation-
defined stuff isn't called for anyway.
(Any I rarely hope for the bits returned by the files system routines
to always permit 1:1 mappings to Unicode character sequences in
whatever representation. )
  
File systems capable of optimizing directory scanning when they
know part or the file name add to an argument in favor of
implementation defined.

So for me, the heated discussion boils down to a callback
(or generic formal function) that might or might not express a
file name filter well---one nesting level less if you compare  it
to a loop with a filtering conditional in it.


Georg

[*] http://www.fsis.usda.gov/factsheets/molds_on_food/#2




^ permalink raw reply	[relevance 5%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-09-02 19:25  5%                                                         ` Randy Brukardt
@ 2010-09-02 20:47  5%                                                           ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2010-09-02 20:47 UTC (permalink / raw)


On Thu, 2 Sep 2010 14:25:46 -0500, Randy Brukardt wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
> news:198k7jlp1nvhi$.1mq6mu1iorkpi$.dlg@40tude.net...
> ...
>> There are other self-evident requirements. But since it seems that nobody
>> actually uses Ada.Directories, there will be no pressure on the ARG to fix
>> it any soon.
> 
> This is getting silly. I use Ada.Directories heavily in all of my programs; 
> and I used Claw.Directories (on which it is based) for years before that.

That wonders me, because I really see no task, which could be accomplished
with Ada.Directories in a portable way. This is an important point, because
if I would not care about portability I just would use Windows or Linux API
rather than Ada.Directories. I have no idea if GNAT Ada.Directories
actually works under, say, Russian Windows with UCS-2, or for German
Windows with files named in Chinese UTF-16, but I am almost sure that
nobody even tried that.

> Perhaps there is no pressure to change it much because most 
> users don't see any significant problems?

Yes, they see no problems because they don't use it.

> Using a private type for file names would be possible, but it would be way 
> too hard to use;

I don't think so. It could be designed with an appropriate set of
operations like:

   function "/" (Directory : Relative_Path; Name : Wide_Wide_String)
      return Relative_Path;

etc. "a"/"b"/"c" is not much harder than "a/b/c". Anyway hard coded file
names appear only in sample programs. In production code a literal path
were unusable anyway, because it is non-portable. So it should be

   Create (File, My_Documents_Directory / "text" / Text_Content);

which under Windows would yield file path encoded UTF-16:

   "C:\Documents and Settings\Winnie the Pooh\My Documents\text.txt"

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



^ permalink raw reply	[relevance 5%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-26  8:49  6%                                                       ` Dmitry A. Kazakov
@ 2010-09-02 19:25  5%                                                         ` Randy Brukardt
  2010-09-02 20:47  5%                                                           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Randy Brukardt @ 2010-09-02 19:25 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:198k7jlp1nvhi$.1mq6mu1iorkpi$.dlg@40tude.net...
...
> There are other self-evident requirements. But since it seems that nobody
> actually uses Ada.Directories, there will be no pressure on the ARG to fix
> it any soon.

This is getting silly. I use Ada.Directories heavily in all of my programs; 
and I used Claw.Directories (on which it is based) for years before that. It 
works great for what it is intended for. You seem to want to use it for 
things for which it was never intended (and indeed things that defy 
abstraction). Perhaps there is no pressure to change it much because most 
users don't see any significant problems?

The encoding of file names as Strings is less than ideal, but it is 
something that we inherited from Ada 83, and cannot change without breaking 
virtually all existing Ada programs. In order to do that, we'd need to add 
overloaded Opens that take Wide_Wide_Character file names:
             procedure Open (File : in out File_Type; Mode : in File_Mode;
                                        Name : in Wide_Wide_String; Form : 
in Wide_Wide_String := "");
But then any calls on Open using literal file names (which are very common) 
would be ambiguous and fail to compile. For instance,
            Open (My_Std_Error, Name => "err:", Mode => Out_File);

Thus, this isn't happening.

Using a private type for file names would be possible, but it would be way 
too hard to use; harder than Unbounded_Strings which is already too hard to 
use regularly.

                               Randy.






^ permalink raw reply	[relevance 5%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-26  0:59  3%                                                     ` Georg Bauhaus
  2010-08-26  8:49  6%                                                       ` Dmitry A. Kazakov
@ 2010-09-02 19:08  5%                                                       ` Randy Brukardt
  2010-09-02 20:48  5%                                                         ` Georg Bauhaus
  1 sibling, 1 reply; 200+ results
From: Randy Brukardt @ 2010-09-02 19:08 UTC (permalink / raw)


"Georg Bauhaus" <rm-host.bauhaus@maps.futureapps.de> wrote in message 
news:4c75bc6d$0$6973$9b4e6d93@newsspool4.arcor-online.net...
...
> You said, "You just do not need patterns in directory search."
> Did this refer to the Pattern : String parameter of
> (Start_)Search?   If so, I fully agree.
>
> Here is what I wanted Matcher : access function (...) to be.
>
> 1. get rid of implementation-defined Pattern : String

It's not implementation-defined if it is null; that is defined to match 
everything (always).

I'm not sure why we didn't give it a null string default (that seems like 
the logical thing to have done, since you often want to return everything). 
(I thought we had given it such a default, but that is definitely not the 
case.)

> 2. do with the names what I want after they have been read:

Why is such a Matcher routine necessary? You might as well just test the 
file name returned; there is going to be more overhead in the callback 
routine than in a direct test, and there is no way for the OS to help.

The reason there is an implementation-defined pattern parameter is that some 
OSes (Windows, for instance) can take the pattern directly and only return 
matches -- in this case, the Ada runtime can potentially be more efficient 
than writing the code explicitly. If the code has to be written explicitly, 
it might as well be part of the user program. There wasn't any intent to 
support anything here that the OS doesn't support directly (on POSIX 
systems, it would make sense to only support the null string pattern, 
although I think actual implementations do more). Programs that want to be 
as portable as possible ought to only use Pattern => "" in Start_Search.

                                Randy.








^ permalink raw reply	[relevance 5%]

* Re: Ada compilers and Ada 2005 (was: What about a glob standard method in Ada.Command_Line ?)
  2010-08-27 12:10  6%           ` J-P. Rosen
@ 2010-09-01  8:08  6%             ` Georg Bauhaus
  0 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2010-09-01  8:08 UTC (permalink / raw)


On 8/27/10 2:10 PM, J-P. Rosen wrote:
> Le 26/08/2010 18:29, anon@att.net a �crit :
>
> Plain wrong again:
>> IBM just upgrades the compiler but they chose not to have a
>> direct say in the design of Ada 2007 (2005)
> Pascal Leroy, who chaired the ARG during the making of Ada2005 was an
> employee of IBM at that time

Just to add to the picture of compilers supporting Ada 2005,re
this is text from AI05-0096, sent in November 2007:

"... who has implemented all of the other container generics
for IBM/Rational ..."

The message is about the new Holder container, so it seems clear
that the quote is referring to Ada 2005 containers in IBM/Rational Ada.


On a related issue, the wikipedia entry has this  about Ada:

"Designed by

  Ada1983: Jean Ichbiah;
  Ada1995: Tucker Taft;
  Ada2005: Tucker Taft"

Shouldn't Pascal Leroy be listed for Ada 2005?



Georg



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-26 16:29  3%         ` anon
  2010-08-26 20:34  3%           ` Yannick Duchêne (Hibou57)
@ 2010-08-27 12:10  6%           ` J-P. Rosen
  2010-09-01  8:08  6%             ` Ada compilers and Ada 2005 (was: What about a glob standard method in Ada.Command_Line ?) Georg Bauhaus
  1 sibling, 1 reply; 200+ results
From: J-P. Rosen @ 2010-08-27 12:10 UTC (permalink / raw)


Le 26/08/2010 18:29, anon@att.net a �crit :

Plain wrong again:
> IBM just upgrades the compiler but they chose not to have a 
> direct say in the design of Ada 2007 (2005)
Pascal Leroy, who chaired the ARG during the making of Ada2005 was an
employee of IBM at that time
-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-26 20:34  3%           ` Yannick Duchêne (Hibou57)
@ 2010-08-27  4:40  4%             ` Yannick Duchêne (Hibou57)
  0 siblings, 0 replies; 200+ results
From: Yannick Duchêne (Hibou57) @ 2010-08-27  4:40 UTC (permalink / raw)


Le Thu, 26 Aug 2010 22:34:38 +0200, Yannick Duchêne (Hibou57)  
<yannick_duchene@yahoo.fr> a écrit:

> Le Thu, 26 Aug 2010 18:29:07 +0200, <anon@att.net> a écrit:
>> The reason is that first
>> Adacore is the ONLY Ada vendor that has a current standard compiler
> [...]
> The reason which make GNAT more visible than others, is the dual license  
> : there is GNAT Pro and GNAT GPL (in short). Others has only commercial  
> licenses.

This drive to another topic: if GNAT is so much more visible than others,  
this is *also mainly due to users and users choices*. Some can't or don't  
want (depends on people) get a commercial license. AdaCore cannot be  
stated responsible of that. A few others has other requirements and just  
want to be able to rely on a second compiler for safety, comparison, or  
any other concern. This is well is not under control of AdaCore. The main  
reason is: Users and users choices (whatever the reasons are).

Any way, I do not feel the overall comment was constructive, that is  
mainly what make me feel to at ease with it. If at least you were to  
release your own Ada compiler and were hurt by some difficulties while  
trying to make your place there, I would have understood your complaints  
about AdaCore. But this is not, and I really not see any reason why you  
complaint. Because you do not like GNAT ? You feel it does not reach the  
quality you would expected ?

Finally, you exposed complains, but you did not tell anything about why it  
matters and why it troubles you. You did not mention a single reason (may  
be because there is really not a single one).

For other: yes, I know, the previous post was plenty of grammatical and  
spelling mistakes, but it is to late to fix it now. Just apologize.

-- 
* 3 lines of concise statements is readable, 10 pages of concise  
statements is unreadable ;
* 3 lines of verbose statements may looks unuseful, 10 pages of verbose  
statements will never looks too much pedantic



^ permalink raw reply	[relevance 4%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-26 16:29  3%         ` anon
@ 2010-08-26 20:34  3%           ` Yannick Duchêne (Hibou57)
  2010-08-27  4:40  4%             ` Yannick Duchêne (Hibou57)
  2010-08-27 12:10  6%           ` J-P. Rosen
  1 sibling, 1 reply; 200+ results
From: Yannick Duchêne (Hibou57) @ 2010-08-26 20:34 UTC (permalink / raw)


Le Thu, 26 Aug 2010 18:29:07 +0200, <anon@att.net> a écrit:
> The reason is that first
> Adacore is the ONLY Ada vendor that has a current standard compiler
No, there are many other. This is just there do not choose to re-run the  
validation process (I suppose for financial reasons, I do not know the  
price at all).

The validation process requires that passed an amount of time, a compiler  
must be validated again. These other providers still own the exact version  
of their compiler which successfully passed the validation process. Above  
that, users of these compilers can them self run a particular ACAT test as  
they want, as this set of testes if publicly available.

The compiler vendor may do the same as well : running CAT testes on its  
product, without formally running a real validation (I still suppose for  
economical or timing reason).

The reason which make GNAT more visible than others, is the dual license :  
there is GNAT Pro and GNAT GPL (in short). Others has only commercial  
licenses. The other reason is that GNAT was originally funded by an  
university program. Others was not (and this helped GNAT a lot).

GNAT is more visible, but not a monopoly and does not seems to me to have  
any attempt to this way.

And some vendors, like SoftCheck, are unlikely to let this kind of thing  
occurs without shouting a bit I feel.


> Second, all other Ada vendors have decided not to upgrade their Ada
> compilers to the current standard.
Client matters. Although the latest version of the standard is Ada 2005,  
and the nearly born one is Ada 2012, big projects still ask for Ada 95,  
which is the most widely used Ada standard. Think of others using Ada 2005  
or 2012, as hider testers, pioneers, little companies with more  
flexibility, standalone users, students, and so on.

Other areas has other requirements, and many Ada providers just have these  
companies as clients.

> Some may start the upgrade but they
> are not fully Ada 2007 complaint!
Ada 207 ?

> So, the only active Ada vendor is
> Adacore, its just like IBM, is the only active vendor for PL/1.
No. Have a look at this:
http://www.adaic.org/compilers/comp-tool.html
and this:
http://www.adaic.org/links/tools.html

> Also,
> if you visit SGI, SUN, or others hardware/software companies who had
> there own Ada compiler back in the 1980 .. 1990s and look for a current
> version of the Ada compiler they will redirect you to Adacore's GNAT.
Lnks to some pages please ?

> So, Adacore has become a Monopoly legally, because others have chosen
> not to taken an active role in the Ada language any more by maintaining a
> current standard that is usable by the current systems. Yes, Randy  
> Brukardt
> from RRSoftware is a member of ARG but Janus Ada is Ada 95 only for Win
> 95/98. It might work under Windows 7 but how many people are going to buy
> the compiler just to find out because as we all know once open installed
> there's a no returns policy.
Randy may reply you better, but I would like to say that if RRSoftware do  
not provide an Ada compiler for other platform, this is not due to a  
supposed monopoly, this is simply because an Ada compiler is a lot of  
work, and RRSoftware may just have less people working on this.


> So, you either accept Adacore's GNAT "as is" or pay $15K plus to
Janus Ada is far less than $15K. If you want something cheaper, you have a  
choice. If you want to target other platform, like UNIXes, BSDs, embedded  
CPUs, you also have a choice.

> Adacore for support and have the right to talk about accepting your
> package as apart of the next standard.
Silly. Look at Ada issues, these are full of submissions from various  
peoples. Recently Jean-Pierre Rosen suggested I could send a submit a tiny  
proposition for the next standard. I am not at all a member of AdaCore.

> And for others on the list of
> WG9, they may vote but when Adacore, disagree, what are they going
> to do there is no other vendor to chose. So, aka Adacore rules Ada.
Were you present at one of their meeting to state that ?

Once again, look at Ada issues, and you will see:
http://ada-auth.org/ais.html

> And in the US to be a voting member of WG9 a sub of the ISO you must
> be a member of ANSI. Other countries have there own version of the
> standards process that sooner or later you will have to pay a annual
> fee.
You may have to pay fee to be member of some local standard office member.  
That is true, but this does not imply no body else can suggest this and  
that comment about the standard.

> Also, the voting member of WG9 are chosen by the national
> delegations of that country, and in the US that is Robert Dewar of
> AdaCore.
Do not know about that, so will not tell anything.

> All this means is that Adacore has too much control of Ada and the Ada
> Standards, for a language they did not create.
No. AdaCore is not under control of the standard, you did not demonstrated  
this.

Just look at the copyrights on the Ada 2005 standard:
http://www.adaic.org/standards/05rm/html/RM-TTL.html

> Some of the major member of WG9 (as of 2009):
> Note: Spark Ada (Ada vendor) is not on the list.
SPARK, an Ada vendor ? Are serious ?

>   Ada Vendors  -- ( to most the only votes that counts )
>     * Randall Brukardt  -- R.R. Software, Inc., USA
>     * Robert Dewar      -- AdaCore, USA
>     * Greg Gicca        -- AdaCore, USA
>     * Nasser Kettani    -- Rational Software France, France ( IBM )
>
>   Special Ada Interest
>     * Clyde Roby        -- Institute for Defense Analyses, USA (DoD)
>
>   Special Designer Interest
>     * Stephen Michell   -- Maurya Software, Inc. Canada
>                              (Secuity, SRG)
>     * Sally Seitz       -- ANSI, USA
>
>   12 Professors (Worldwide)
>   19 Others interested parties
>      *  Jean-Pierre Rosen   -- Adalog, france
>
You forget the ISO!

And your forget to mention all unknown peoples, [tiny|big] compagnies,  
hobbyst, students, who sent or will send their own comment to ada-auth.


-- 
* 3 lines of concise statements is readable, 10 pages of concise  
statements is unreadable ;
* 3 lines of verbose statements may looks unuseful, 10 pages of verbose  
statements will never looks too much pedantic



^ permalink raw reply	[relevance 3%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-26  8:21  6%       ` J-P. Rosen
@ 2010-08-26 16:29  3%         ` anon
  2010-08-26 20:34  3%           ` Yannick Duchêne (Hibou57)
  2010-08-27 12:10  6%           ` J-P. Rosen
  0 siblings, 2 replies; 200+ results
From: anon @ 2010-08-26 16:29 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 3608 bytes --]

In <i5586l$1q6$1@news.eternal-september.org>, "J-P. Rosen" <rosen@adalog.fr> writes:
>Le 25/08/2010 23:37, anon@att.net a �crit :
>>> ARG:  ISO/IEC JTC 1/SC 22/WG 9 Ada Rapporteur Group (ARG)
>>> AdaCore: Ada vendor, has members in ARG
>>>
>>> There is no monopoly, yet.
>> 
>> Better look at becoming a member, you pay Adacore !!!
>This is 100% PLAIN WRONG (I usually don't like to respond to anon's
>absurdities, but since his messages can be found by newsgroups searches,
>I can't leave it).
>
>I am an ARG member. I never paid anything beyond the travel and meeting
>costs, and certainly not to AdaCore.
>
>-- 
>---------------------------------------------------------
>           J-P. Rosen (rosen@adalog.fr)
>Visit Adalog's web site at http://www.adalog.fr


Monopoly:  Yes, my son Adacore has a monopoly.  The reason is that first 
Adacore is the ONLY Ada vendor that has a current standard compiler and 
is voting.  IBM just upgrades the compiler but they chose not to have a 
direct say in the design of Ada 2007 (2005) or have not made any move 
on the design of Ada 2012, its all Adacore.

Second, all other Ada vendors have decided not to upgrade their Ada 
compilers to the current standard. Some may start the upgrade but they 
are not fully Ada 2007 complaint! So, the only active Ada vendor is 
Adacore, its just like IBM, is the only active vendor for PL/1. Also, 
if you visit SGI, SUN, or others hardware/software companies who had 
there own Ada compiler back in the 1980 .. 1990s and look for a current 
version of the Ada compiler they will redirect you to Adacore's GNAT.

So, Adacore has become a Monopoly legally, because others have chosen 
not to taken an active role in the Ada language any more by maintaining a 
current standard that is usable by the current systems. Yes, Randy Brukardt 
from RRSoftware is a member of ARG but Janus Ada is Ada 95 only for Win 
95/98. It might work under Windows 7 but how many people are going to buy 
the compiler just to find out because as we all know once open installed 
there's a no returns policy.

So, you either accept Adacore's GNAT "as is" or pay $15K plus to 
Adacore for support and have the right to talk about accepting your 
package as apart of the next standard. And for others on the list of 
WG9, they may vote but when Adacore, disagree, what are they going 
to do there is no other vendor to chose. So, aka Adacore rules Ada.

And in the US to be a voting member of WG9 a sub of the ISO you must 
be a member of ANSI. Other countries have there own version of the 
standards process that sooner or later you will have to pay a annual 
fee. Also, the voting member of WG9 are chosen by the national 
delegations of that country, and in the US that is Robert Dewar of 
AdaCore.

All this means is that Adacore has too much control of Ada and the Ada 
Standards, for a language they did not create.


Some of the major member of WG9 (as of 2009):
Note: Spark Ada (Ada vendor) is not on the list.

  Ada Vendors  -- ( to most the only votes that counts )
    * Randall Brukardt  -- R.R. Software, Inc., USA
    * Robert Dewar      -- AdaCore, USA
    * Greg Gicca        -- AdaCore, USA
    * Nasser Kettani    -- Rational Software France, France ( IBM )

  Special Ada Interest
    * Clyde Roby        -- Institute for Defense Analyses, USA (DoD)

  Special Designer Interest
    * Stephen Michell   -- Maurya Software, Inc. Canada
                             (Secuity, SRG)
    * Sally Seitz       -- ANSI, USA

  12 Professors (Worldwide)
  19 Others interested parties
     *  Jean-Pierre Rosen   -- Adalog, france




^ permalink raw reply	[relevance 3%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-26  0:59  3%                                                     ` Georg Bauhaus
@ 2010-08-26  8:49  6%                                                       ` Dmitry A. Kazakov
  2010-09-02 19:25  5%                                                         ` Randy Brukardt
  2010-09-02 19:08  5%                                                       ` Randy Brukardt
  1 sibling, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2010-08-26  8:49 UTC (permalink / raw)


On Thu, 26 Aug 2010 02:59:25 +0200, Georg Bauhaus wrote:

> You said, "You just do not need patterns in directory search."
> Did this refer to the Pattern : String parameter of
> (Start_)Search?

There is no need in either pattern parameter or a filter call back
function. What is needed is a proper abstraction that would define file
name as sequence of code points = in an OS-independent way.

Ada.Directories shall convert OS-specific encoding (actually there are many
per OS, like in the case of Windows), when the directory entities are
enumerated. All operations requiring file name shall convert it back.

There are other self-evident requirements. But since it seems that nobody
actually uses Ada.Directories, there will be no pressure on the ARG to fix
it any soon.

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



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 21:37  6%     ` anon
@ 2010-08-26  8:21  6%       ` J-P. Rosen
  2010-08-26 16:29  3%         ` anon
  0 siblings, 1 reply; 200+ results
From: J-P. Rosen @ 2010-08-26  8:21 UTC (permalink / raw)


Le 25/08/2010 23:37, anon@att.net a �crit :
>> ARG:  ISO/IEC JTC 1/SC 22/WG 9 Ada Rapporteur Group (ARG)
>> AdaCore: Ada vendor, has members in ARG
>>
>> There is no monopoly, yet.
> 
> Better look at becoming a member, you pay Adacore !!!
This is 100% PLAIN WRONG (I usually don't like to respond to anon's
absurdities, but since his messages can be found by newsgroups searches,
I can't leave it).

I am an ARG member. I never paid anything beyond the travel and meeting
costs, and certainly not to AdaCore.

-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 19:39  5%                                                   ` Dmitry A. Kazakov
@ 2010-08-26  0:59  3%                                                     ` Georg Bauhaus
  2010-08-26  8:49  6%                                                       ` Dmitry A. Kazakov
  2010-09-02 19:08  5%                                                       ` Randy Brukardt
  0 siblings, 2 replies; 200+ results
From: Georg Bauhaus @ 2010-08-26  0:59 UTC (permalink / raw)


On 8/25/10 9:39 PM, Dmitry A. Kazakov wrote:

>>    "*" ->  Search ->  Match (file name pattern) ->  ...
>
> What does this have to do with legality of names with spaces?
>
> How could it help to implement search for all files matched by a*¶?

I'm beginning to feel I have once again missed the proper
references for the meaning of words in our discussion.

You said, "You just do not need patterns in directory search."
Did this refer to the Pattern : String parameter of
(Start_)Search?   If so, I fully agree.

Here is what I wanted Matcher : access function (...) to be.

1. get rid of implementation-defined Pattern : String

2. do with the names what I want after they have been read:
   For example, call a function matching a name against some
    RE pattern

3. delegate the calling to (Start_)Search

(Otherwise, everything is pretty much like Search.)

Filenames "as is" means whatever the OS or run-time
passes to (Start_)Search, something that can be passed to
other operations that require a file name.

String is a most flexible data structure for file names
because it can store any kind of file name which I take to be
a sequence of bits. One could use Wide_Wide_String or
Storage_Element_Array for a file name as long as no attempt is
made to attribute meaning to file name other than an ordered
sequence of bits that identifies a file.  Anything more is
wishful thinking. Character strings are just more practical
than bit patterns or number sequences.

IOW, I simply do not care what standard meaning one might
attribute to the sequence of bytes that comes in.  If it
needs to be shown to a user, then "appropriate conversion",
in a best effort sense, is probably best, from bit string to
some other string.

When I said that case insensitivity is handled by RE pattern
matching, I did not mean that issues like moving collections of
files between case-sensitive and case-insensitive file systems
can be handled by RE pattern matching.

I still can't figure out why you have been referring to Name_Error.
The file names considered by my Start_Search variant necessarily
identify existing files.  In this sense, exceptions caused by anything
to do with existing file's names will not seem acceptable.

Here is code looking for a file named "aö" on a number of file
systems.  Source file encoding should be Latin-1.

with Ada.Text_IO;
with Ada.Directories;

procedure Filenames is

    Not_Found_Error : exception;

    procedure Show_String (S: String);
    -- tabular display of Characters in S, with hex codes

    function Find_Odd_Name return String;
    --  Look for a file named "aö" and return the characters of this name.
    --  Raises Not_Found_Error

    function Find_Odd_Name return String is
       use Ada.Directories;
       Search_For_Aö : Search_Type;
       Dir_Entry : Directory_Entry_Type;
       Aö8 : constant String :=  "aö";  -- UTF-8
       AöL : constant String :=  "aö";  -- Latin-1
       AöN : constant String :=  "ao" &
         Character'Val (16#CC#) &
         Character'Val (16#88#);  -- NFD (HFS+)
    begin
       Start_Search (Search => Search_For_Aö,
                     Directory => "News",
                     Pattern => "*");
       loop
          exit when not More_Entries (Search_For_Aö);
          Get_Next_Entry (Search_For_Aö, Dir_Entry);
          declare
             Name : constant String := Simple_Name (Dir_Entry);
          begin
             if
               Name = Aö8
               or Name = AöL
               or Name = AöN
             then
                End_Search(Search_For_Aö);
                return Name;
             end if;
          end;
       end loop;
       raise Not_Found_Error;
    end Find_Odd_Name;

    procedure Show_String (S: String) is
       package Hex_IO is new Ada.Text_IO.Integer_IO (Natural);
    begin
       Hex_IO.Default_Base := 16;
       for K in S'Range loop
          Ada.Text_IO.Put (S(K));
          Hex_IO.Put (Character'Pos(S(K)));
          Ada.Text_IO.New_Line;
       end loop;
    end Show_String;

begin
    declare
       Filename : constant String := Find_Odd_Name ;
    begin
       Show_String(Filename);
    end ;
end Filenames;


-- Georg



^ permalink raw reply	[relevance 3%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 13:13  6%   ` Georg Bauhaus
  2010-08-25 13:28  6%     ` J-P. Rosen
  2010-08-25 14:14  6%     ` Jeffrey Carter
@ 2010-08-25 21:37  6%     ` anon
  2010-08-26  8:21  6%       ` J-P. Rosen
  2 siblings, 1 reply; 200+ results
From: anon @ 2010-08-25 21:37 UTC (permalink / raw)


In <4c7516f7$0$7664$9b4e6d93@newsspool1.arcor-online.net>, Georg Bauhaus <rm.dash-bauhaus@futureapps.de> writes:
>On 25.08.10 15:09, anon@att.net wrote:
>> In <op.vhrt97eexmjfy8@garhos>, =?iso-8859-15?Q?Yannick_Duch=EAne_=28Hibou57=29?= writes:
>>> Hello all,
>>>
>>> What about suggesting for Ada 2012, a Glob method as part of the standard  
>>> Ada.Command_Line package ?
>> 
>> 
>> If you want it, then create the package for your OS and Hardware and 
>> submitted to ARG aka Adacore.
>
>ARG:  ISO/IEC JTC 1/SC 22/WG 9 Ada Rapporteur Group (ARG)
>AdaCore: Ada vendor, has members in ARG
>
>There is no monopoly, yet.

Better look at becoming a member, you pay Adacore !!!



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 21:05  6%                                   ` (see below)
@ 2010-08-25 21:32  5%                                     ` Yannick Duchêne (Hibou57)
  0 siblings, 0 replies; 200+ results
From: Yannick Duchêne (Hibou57) @ 2010-08-25 21:32 UTC (permalink / raw)


Le Wed, 25 Aug 2010 23:05:43 +0200, (see below)  
<yaldnif.w@blueyonder.co.uk> a écrit:
>  <http://developer.apple.com/mac/library/documentation/FileManagement/Concep
> tual/understanding_utis/understand_utis_conc/understand_utis_conc.html#//app
> le_ref/doc/uid/TP40001319-CH202-CHDHIJDE>

I am quoting the above document:

    A key advantage of uniform type identifiers over other type
    identification methods is that they are declared in a conformance
    hierarchy. A conformance hierarchy is analogous to a class hierarchy
    in object-oriented programming. Instead of “type A conforms to
    type B,” you can also think of this as “all instances of type A
    are also instances of type B.”

This is indeed the most logical way to handle file types. Would be nice as  
a public standard, but would require this to be followed, which is another  
affair (what I do not enjoy with the Windows way, is the too much frequent  
clashes with file extensions, and as soon as a clash is there, this make  
the given file extension mostly unusable).

-- 
* 3 lines of concise statements is readable, 10 pages of concise  
statements is unreadable ;
* 3 lines of verbose statements may looks unuseful, 10 pages of verbose  
statements will never looks too much pedantic



^ permalink raw reply	[relevance 5%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 20:39  5%                                 ` Yannick Duchêne (Hibou57)
@ 2010-08-25 21:05  6%                                   ` (see below)
  2010-08-25 21:32  5%                                     ` Yannick Duchêne (Hibou57)
  0 siblings, 1 reply; 200+ results
From: (see below) @ 2010-08-25 21:05 UTC (permalink / raw)


On 25/08/2010 21:39, in article op.vh0gzhj0xmjfy8@garhos, "Yannick Duch�ne
(Hibou57)" <yannick_duchene@yahoo.fr> wrote:

> I do not own a Mac, so may be indeed I was wrong somewhere. But I use to
> read about the Mac system and philosophy to try to figure if there is or
> not a technical solution to compile Mac applications from Windows. So I
> came to this topic, and really I read something about it, stating
> something changed there when switching from the ancient Mac 0S up to 9, to
> the new Mac OS X (completely different system in the core, while mostly
> compatible in many topics). And I am sure I have read complaints about the
> file extension � la Windows vs  the file type tag. May be both are still
> coexisting and there is just less focus on the type tag so fans of the
> original Mac way was disappointed ? (as I said, I do not own a Mac, so
> cannot figure this my self)
> 
> Any way, thanks for the possible error you noticed.
> 
>> See <http://en.wikipedia.org/wiki/Uniform_Type_Identifier>.
> Oh s**t, wikipedia again. Fed-up, sorry, will try to peak another source,
> sure there must be another one.

 <http://developer.apple.com/mac/library/documentation/FileManagement/Concep
tual/understanding_utis/understand_utis_conc/understand_utis_conc.html#//app
le_ref/doc/uid/TP40001319-CH202-CHDHIJDE>

-- 
Bill Findlay
<surname><forename> chez blueyonder.co.uk





^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 20:15  6%                               ` (see below)
@ 2010-08-25 20:39  5%                                 ` Yannick Duchêne (Hibou57)
  2010-08-25 21:05  6%                                   ` (see below)
  0 siblings, 1 reply; 200+ results
From: Yannick Duchêne (Hibou57) @ 2010-08-25 20:39 UTC (permalink / raw)


Le Wed, 25 Aug 2010 22:15:56 +0200, (see below)  
<yaldnif.w@blueyonder.co.uk> a écrit:
>> Mac OS used to have a good technique to tag files types and applications
>> to be used to open it, via meta-data... unfortunately, it drop it with  
>> OS
>> X to follow DOS/Windows convention (many users was disappointed, but  
>> Apple
>> did not care).
>
> This is false (or so misleading as to be false FAPP). The DOS/Windows
> convention is only one of several techniques MacOS X supports for  
> file-type
> association.
I do not own a Mac, so may be indeed I was wrong somewhere. But I use to  
read about the Mac system and philosophy to try to figure if there is or  
not a technical solution to compile Mac applications from Windows. So I  
came to this topic, and really I read something about it, stating  
something changed there when switching from the ancient Mac 0S up to 9, to  
the new Mac OS X (completely different system in the core, while mostly  
compatible in many topics). And I am sure I have read complaints about the  
file extension à la Windows vs  the file type tag. May be both are still  
coexisting and there is just less focus on the type tag so fans of the  
original Mac way was disappointed ? (as I said, I do not own a Mac, so  
cannot figure this my self)

Any way, thanks for the possible error you noticed.

> See <http://en.wikipedia.org/wiki/Uniform_Type_Identifier>.
Oh s**t, wikipedia again. Fed-up, sorry, will try to peak another source,  
sure there must be another one.


-- 
* 3 lines of concise statements is readable, 10 pages of concise  
statements is unreadable ;
* 3 lines of verbose statements may looks unuseful, 10 pages of verbose  
statements will never looks too much pedantic



^ permalink raw reply	[relevance 5%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 13:28  6%     ` J-P. Rosen
@ 2010-08-25 20:29  6%       ` Yannick Duchêne (Hibou57)
  0 siblings, 0 replies; 200+ results
From: Yannick Duchêne (Hibou57) @ 2010-08-25 20:29 UTC (permalink / raw)


Le Wed, 25 Aug 2010 15:28:09 +0200, J-P. Rosen <rosen@adalog.fr> a écrit:
> But maybe anon is confusing the ARG with the ARA? The ARA (Ada Ressource
> Association) is a groupment of vendors, there is a fee to join, but the
> ARA has no power on the evolution of the language.
I remember that name, ARA. I meet it when I was reading documents to  
understand the validation process. Feel to remember the ARA was involved  
in some manner in this (compiler validation).

Found back a page about it:
http://www.adaic.org/compilers/articles/acaa_org.html


-- 
* 3 lines of concise statements is readable, 10 pages of concise  
statements is unreadable ;
* 3 lines of verbose statements may looks unuseful, 10 pages of verbose  
statements will never looks too much pedantic



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25  8:24  6%                             ` Yannick Duchêne (Hibou57)
@ 2010-08-25 20:15  6%                               ` (see below)
  2010-08-25 20:39  5%                                 ` Yannick Duchêne (Hibou57)
  0 siblings, 1 reply; 200+ results
From: (see below) @ 2010-08-25 20:15 UTC (permalink / raw)


On 25/08/2010 09:24, in article op.vhziy8yyxmjfy8@garhos, "Yannick Duch�ne
(Hibou57)" <yannick_duchene@yahoo.fr> wrote:

> Mac OS used to have a good technique to tag files types and applications
> to be used to open it, via meta-data... unfortunately, it drop it with OS
> X to follow DOS/Windows convention (many users was disappointed, but Apple
> did not care).

This is false (or so misleading as to be false FAPP). The DOS/Windows
convention is only one of several techniques MacOS X supports for file-type
association.

See <http://en.wikipedia.org/wiki/Uniform_Type_Identifier>.

-- 
Bill Findlay
<surname><forename> chez blueyonder.co.uk




^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 18:44  4%                                                 ` Georg Bauhaus
@ 2010-08-25 19:39  5%                                                   ` Dmitry A. Kazakov
  2010-08-26  0:59  3%                                                     ` Georg Bauhaus
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2010-08-25 19:39 UTC (permalink / raw)


On Wed, 25 Aug 2010 20:44:17 +0200, Georg Bauhaus wrote:

> On 25.08.10 18:46, Dmitry A. Kazakov wrote:
> 
>>> It is not actually possible to provide a common abstraction
>>> for *new* and *existing* file names.  While "broken", the file
>>> names do exist.  Just a few examples illustrating a variety of file
>>> naming fun:
>>>
>>> - Names created in NTFS that end in a '.'
>>>
>>> - Two names in existing ext2 directories that contain
>>>  "mutually exclusive" characters (via incompatible encoding)
>>>
>>> - Names containing characters that are special in Windows but
>>>  not in POSIX.
>>>
>>> - Names with spaces in them
>> 
>> You don't get the point. See A.13(9)
> 
> procedure Start_Search
>    (Search    : in out Search_Type;
>     Directory : in String;
>     Matcher   : access function (Pattern : Pattern_Type) return Boolean;
>     Filter    : in Filter_Type := (others => True));
> 
> 
> There is no  "string given for the parameter [Matcher]" that "does
> not allow the identification of an external file".
> The situation is reversed: The suggested overloaded procedure
> Directories.Start_Search (or Search) will RECEIVE a name from the file
> system via the run-time system; the name of an existing file; one
> that has been identified already.
> There is no identification attempt performed by the program.
> It acts as if some implementation-defined all-inclusive wildcard
> had been passed to Ada's Directories.Start_Search, as the
> Pattern : String parameter, and then, later, some callback (Matcher
> in the alternative declaration above) checks to see whether the file
> identifying file name that it got from the system is fine.
> 
> 
>   OS -> file name -> Search -> Matcher (sees file name) -> ...
> 
> Not
> 
>   file name pattern -> Search -> !! identification
> 
> But as if
> 
>   "*" -> Search -> Match (file name pattern) -> ...

What does this have to do with legality of names with spaces?

How could it help to implement search for all files matched by a*¶?

>>> If in the real word, I/O of "broken" integer values is a
>>> reality.
>> 
>> What does this have to do with the point?
> 
> I expect file names to be read from the disk, as is, I do not
> construct them.

I don't even know what does it mean to read anything "as-is." It just does
not make any sense. How do you know if ab¶ was read as-is or as something
else? Did you use magnifying glass to inspect the hard drive to tell how is
ab¶ there?

> Whether they are broken WRT some expectation
> or not is like when a program receives a valid or usable representation
> or not from an integer location:
> 
>   V : Integer_Subtype;
>   pramga Import (Ada, V);
>   pragma Volatile (V);

So, V was read as-is?

> As you can see, this is how I consider existing names of existing
> files, too.  But I want to be able to look at the bits of V, not
> just raise an exception.

Why on earth reading file name should raise exceptions except that when the
file system is corrupt? Where did you get it? From Ada.Directories? Well it
probably should if the file is named "это вам не Latin-1". But I bet,
GNAT's implementation does not. Anyway, this is another crack among others
in Ada.Directories.

>>> Almost all WWW documents are broken by your taxonomy.
>>> Google is rich...
>> 
>> I don't understand what you are talking about.
> 
> An analogy.
> If the WWW, that is, the external environment, has valid
> HTML, it is possible to use HTML grammar to describe
> HTML. It isn't valid. But we can still try to extract meaningful
> information even from syntactically broken pages.

This has nothing to do with file names, except that here you again are
confusing encoding and the contents.

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



^ permalink raw reply	[relevance 5%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 16:46  6%                                               ` Dmitry A. Kazakov
@ 2010-08-25 18:44  4%                                                 ` Georg Bauhaus
  2010-08-25 19:39  5%                                                   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2010-08-25 18:44 UTC (permalink / raw)


On 25.08.10 18:46, Dmitry A. Kazakov wrote:

>> It is not actually possible to provide a common abstraction
>> for *new* and *existing* file names.  While "broken", the file
>> names do exist.  Just a few examples illustrating a variety of file
>> naming fun:
>>
>> - Names created in NTFS that end in a '.'
>>
>> - Two names in existing ext2 directories that contain
>>  "mutually exclusive" characters (via incompatible encoding)
>>
>> - Names containing characters that are special in Windows but
>>  not in POSIX.
>>
>> - Names with spaces in them
> 
> You don't get the point. See A.13(9)

procedure Start_Search
   (Search    : in out Search_Type;
    Directory : in String;
    Matcher   : access function (Pattern : Pattern_Type) return Boolean;
    Filter    : in Filter_Type := (others => True));


There is no  "string given for the parameter [Matcher]" that "does
not allow the identification of an external file".
The situation is reversed: The suggested overloaded procedure
Directories.Start_Search (or Search) will RECEIVE a name from the file
system via the run-time system; the name of an existing file; one
that has been identified already.
There is no identification attempt performed by the program.
It acts as if some implementation-defined all-inclusive wildcard
had been passed to Ada's Directories.Start_Search, as the
Pattern : String parameter, and then, later, some callback (Matcher
in the alternative declaration above) checks to see whether the file
identifying file name that it got from the system is fine.


  OS -> file name -> Search -> Matcher (sees file name) -> ...

Not

  file name pattern -> Search -> !! identification

But as if

  "*" -> Search -> Match (file name pattern) -> ...


>> If in the real word, I/O of "broken" integer values is a
>> reality.
> 
> What does this have to do with the point?

I expect file names to be read from the disk, as is, I do not
construct them. Whether they are broken WRT some expectation
or not is like when a program receives a valid or usable representation
or not from an integer location:

  V : Integer_Subtype;
  pramga Import (Ada, V);
  pragma Volatile (V);

As you can see, this is how I consider existing names of existing
files, too.  But I want to be able to look at the bits of V, not
just raise an exception.

> You seem to wish file names checked statically.

No.


>> Almost all WWW documents are broken by your taxonomy.
>> Google is rich...
> 
> I don't understand what you are talking about.

An analogy.
If the WWW, that is, the external environment, has valid
HTML, it is possible to use HTML grammar to describe
HTML. It isn't valid. But we can still try to extract meaningful
information even from syntactically broken pages.
The state of file names may be a little more correct
than an average WWW page.
I want to be able to use both.
How can I do that if the interesting data needs to be
in proper shape to be processed without raising exceptions?
By analogy, how can I process whatever exists in the directory
as file names if these need to be conforming to some scheme?


Georg



^ permalink raw reply	[relevance 4%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 15:51  4%                                             ` Georg Bauhaus
@ 2010-08-25 16:46  6%                                               ` Dmitry A. Kazakov
  2010-08-25 18:44  4%                                                 ` Georg Bauhaus
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2010-08-25 16:46 UTC (permalink / raw)


On Wed, 25 Aug 2010 17:51:39 +0200, Georg Bauhaus wrote:

> On 25.08.10 16:56, Dmitry A. Kazakov wrote:
>> Certainly and without any doubt it is
>> possible to provide an abstraction which would work for Posix, Unix,
>> Windows, VMS, MacOS and name what OS.
> 
> It is not actually possible to provide a common abstraction
> for *new* and *existing* file names.  While "broken", the file
> names do exist.  Just a few examples illustrating a variety of file
> naming fun:
> 
> - Names created in NTFS that end in a '.'
>
> - Two names in existing ext2 directories that contain
>  "mutually exclusive" characters (via incompatible encoding)
> 
> - Names containing characters that are special in Windows but
>  not in POSIX.
> 
> - Names with spaces in them

You don't get the point. See A.13(9)

> Wide_Wide_String can't cure these,

It is, because any file name can be represented by Wide_Wide_String.

>>>  And since there is no single, well defined,
>>> portable οΏ½ for file names,
>> 
>> It is same as to say that there is no portable Integer type.
> 
> If in the real word, I/O of "broken" integer values is a
> reality.

What does this have to do with the point?

You seem to wish file names checked statically. Does Ada.Directories this?
Why then you pose this silly requirement?

> Can't just raise an exception
> because of a faulty name!

See A.13(9)

> Almost all WWW documents are broken by your taxonomy.
> Google is rich...

I don't understand what you are talking about.

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



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 14:56  5%                                           ` Dmitry A. Kazakov
@ 2010-08-25 15:51  4%                                             ` Georg Bauhaus
  2010-08-25 16:46  6%                                               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2010-08-25 15:51 UTC (permalink / raw)


On 25.08.10 16:56, Dmitry A. Kazakov wrote:
> Certainly and without any doubt it is
> possible to provide an abstraction which would work for Posix, Unix,
> Windows, VMS, MacOS and name what OS.

It is not actually possible to provide a common abstraction
for *new* and *existing* file names.  While "broken", the file
names do exist.  Just a few examples illustrating a variety of file
naming fun:

- Names created in NTFS that end in a '.'

- Two names in existing ext2 directories that contain
 "mutually exclusive" characters (via incompatible encoding)

- Names containing characters that are special in Windows but
 not in POSIX.

- Names with spaces in them

To work with these, the abstraction would have to be super
fault tolerant and employ AI, or just tell the user they should
forget about working with their files because the file names
are broken. I consider this disrespectful. Raising an exception
is out of the question; it is the file contents that matter, not
their just their names, no matter how the names have arrived
in the state they are in.

Wide_Wide_String can't cure these, String can, and you
can transform from String to Wide_Wide_String after successful
file name deciphering.


>>  And since there is no single, well defined,
>> portable οΏ½ for file names,
> 
> It is same as to say that there is no portable Integer type.

If in the real word, I/O of "broken" integer values is a
reality.  I/O of integer cannot rely on a perfect
external representation.  Neither can I/O of file names.
The statistics of broken integers are just so much better.
Possibly because no one even remembers that integers
have a representation.  There are less many encodings
for them than for character sets, so there is less risk
that we run into integers of unknown encoding,
or sets of integers of different encodings.

> Unicode code
> points are portable because they are defined so.

Before the fact.  And then the facts are different,
because someone managed to inject some invalid
octet sequence... Nevertheless, this file's content
is darn important. Can't just raise an exception
because of a faulty name!

Almost all WWW documents are broken by your taxonomy.
Google is rich...

Georg



^ permalink raw reply	[relevance 4%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 14:20  4%                                         ` Georg Bauhaus
@ 2010-08-25 14:56  5%                                           ` Dmitry A. Kazakov
  2010-08-25 15:51  4%                                             ` Georg Bauhaus
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2010-08-25 14:56 UTC (permalink / raw)


On Wed, 25 Aug 2010 16:20:03 +0200, Georg Bauhaus wrote:

> On 25.08.10 15:30, Dmitry A. Kazakov wrote:
> 
>> If code points have nothing to do with String why do you propose to do it
>> with String?
> 
> Because file names as entities external to Ada have got nothing
> to do with code points, from an Ada point of view: file names
> have to do with Strings, though. This is in part a consequence
> of how subprogram parameters in Directories.Start_Search were
> chosen.

Yes, that is the point: Ada.Directories is broken.

> Conclusion: there cannot be a good, portable Ada type
> representing file names.

From false premises follows anything. Certainly and without any doubt it is
possible to provide an abstraction which would work for Posix, Unix,
Windows, VMS, MacOS and name what OS.

> Start_Search is based on String; file names do not obey
> the rules of ISO 10646; no hope.

As I said it is broken. Broken things to be repaired or disposed. Since the
ARG cannot change OS they should look forward to change the RM.

> From here, one can go on to a different type from the
> collection that covers Unicode.

I am one who uses "Ada String means UTF-8 encoded string". Surely this
works. Since Ada.Directories is unusable, I deploy Glib bindings instead.
At least they cared to define file paths UTF-8. But the approach is wrong
because it mangles encoding and the contents. If I were to redesign
Ada.Directories, I would use a clone type of Wide_Wide_String for file
names. If Ada had array interfaces I would do it otherwise. But in any case
file name would not be string, file path would not be a file name etc.

>> It could
>> represent some encoding of οΏ½*, which is the point.
> 
> Exactly.  And since there is no single, well defined,
> portable οΏ½ for file names,

It is same as to say that there is no portable Integer type. Unicode code
points are portable because they are defined so.

If some name is not a valid file name you get Name_Error, likewise you get
Constraint_Error if some integer is not valid number for the given machine.

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



^ permalink raw reply	[relevance 5%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 13:30  6%                                       ` Dmitry A. Kazakov
@ 2010-08-25 14:20  4%                                         ` Georg Bauhaus
  2010-08-25 14:56  5%                                           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2010-08-25 14:20 UTC (permalink / raw)


On 25.08.10 15:30, Dmitry A. Kazakov wrote:

> If code points have nothing to do with String why do you propose to do it
> with String?

Because file names as entities external to Ada have got nothing
to do with code points, from an Ada point of view: file names
have to do with Strings, though. This is in part a consequence
of how subprogram parameters in Directories.Start_Search were
chosen.

> And how is this related to the point anyway?

Directories.Start_Search exposes a programmatic interface to
names of files. String has might-work-best name components:
Standard.Character, because the outside world is under the
(full) control of the conflicting real world requirements
of users, other programs, legacy buggy programs, assumptions...
There is no completely working standard for file names.

Conclusion: there cannot be a good, portable Ada type
representing file names. No encoding will help,
no abstraction will help. But what we have, and what does
help, is a programming interface to the bare components of
file names: String.

(For me, not even file name Pattern is needed; but since
Start_Search operates on String, and since scanning a
directory
(a) with OS pattern
(b) without OS pattern
might result in the same computer operations,
I thought we might as well add another Start_Search that
makes Pattern passive: just fetch filenames one by one
as in (b) and let the programmer select based on RE
matching after the fact.)


>> The important question is what constitues Σ,
> 
>    http://en.wikipedia.org/wiki/Code_point

Start_Search is based on String; file names do not obey
the rules of ISO 10646; no hope. Practically, the Σs
established by external file names are not free of contradictions
or ambiguities.  But String can potentially remove
the contradictions, because it does not care about the meaning
of a sequence of (let's say) octets.  This is the big plus of
String: power to the programmer who assigns meaning to sequences
of octets.

And this is the big plus of String based REs: they do not
care about the meaning of a sequence of octets either, but
they can be employed to *find* meaningful sequences when
tackling real world file names.

From here, one can go on to a different type from the
collection that covers Unicode.

> It could
> represent some encoding of Σ*, which is the point.

Exactly.  And since there is no single, well defined,
portable Σ for file names, the best we can do is inspect
their encoded representations (String) and have our programs
draw their own conclusions.

Georg



^ permalink raw reply	[relevance 4%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 13:13  6%   ` Georg Bauhaus
  2010-08-25 13:28  6%     ` J-P. Rosen
@ 2010-08-25 14:14  6%     ` Jeffrey Carter
  2010-08-25 21:37  6%     ` anon
  2 siblings, 0 replies; 200+ results
From: Jeffrey Carter @ 2010-08-25 14:14 UTC (permalink / raw)


On 08/25/2010 06:13 AM, Georg Bauhaus wrote:
> On 25.08.10 15:09, anon@att.net wrote:
>>
>> If you want it, then create the package for your OS and Hardware and
>> submitted to ARG aka Adacore.
>
> ARG:  ISO/IEC JTC 1/SC 22/WG 9 Ada Rapporteur Group (ARG)
> AdaCore: Ada vendor, has members in ARG

Yet more FUD from the "anon" FUD machine.

-- 
Jeff Carter
"What I wouldn't give for a large sock with horse manure in it."
Annie Hall
42

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 13:09  6%                                     ` Georg Bauhaus
@ 2010-08-25 13:30  6%                                       ` Dmitry A. Kazakov
  2010-08-25 14:20  4%                                         ` Georg Bauhaus
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2010-08-25 13:30 UTC (permalink / raw)


On Wed, 25 Aug 2010 15:09:16 +0200, Georg Bauhaus wrote:

> On 25.08.10 14:01, Dmitry A. Kazakov wrote:
>> On Wed, 25 Aug 2010 13:09:41 +0200, Georg Bauhaus wrote:
>> 
>>> If you now want R* to decide the encoding of:
>> 
>> No, I want match this:
>> 
>>    a*¶
> 
> Fine, just do it using String; every component of a String
> is well defined. Code points have nothing to do with Strings.

If code points have nothing to do with String why do you propose to do it
with String? And how is this related to the point anyway?

>> This pattern precisely defines a language L:
> 
> It does no such thing absent a definition of *.

You have commented out the definition:

   L = aΣ*¶

Or in BNF

   L ::= a <star> ¶
   <star> ::= <empty> | <code-point> [<star>]

> The important question is what constitues Σ,

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

> If we use String, used in Directories.Start_Search,
> then everything, including Σ, is well defined in Ada,
> as is.

String as defined by RM 3.5.2 (2/2) does not represent Σ*. It could
represent some encoding of Σ*, which is the point.

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



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 13:13  6%   ` Georg Bauhaus
@ 2010-08-25 13:28  6%     ` J-P. Rosen
  2010-08-25 20:29  6%       ` Yannick Duchêne (Hibou57)
  2010-08-25 14:14  6%     ` Jeffrey Carter
  2010-08-25 21:37  6%     ` anon
  2 siblings, 1 reply; 200+ results
From: J-P. Rosen @ 2010-08-25 13:28 UTC (permalink / raw)


Le 25/08/2010 15:13, Georg Bauhaus a écrit :
> On 25.08.10 15:09, anon@att.net wrote:
>> If you want it, then create the package for your OS and Hardware and 
>> submitted to ARG aka Adacore.
> 
> ARG:  ISO/IEC JTC 1/SC 22/WG 9 Ada Rapporteur Group (ARG)
> AdaCore: Ada vendor, has members in ARG
> 
> There is no monopoly, yet.

>>  or pay the ARG member fee and submit the concept.
There is no fee for being an ARG member (although ARG member pay a lot
by doing the work on their spare time and by financing travels etc.).
And suggestions from anybody are welcome.

But maybe anon is confusing the ARG with the ARA? The ARA (Ada Ressource
Association) is a groupment of vendors, there is a fee to join, but the
ARA has no power on the evolution of the language.
-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 13:09  6% ` anon
@ 2010-08-25 13:13  6%   ` Georg Bauhaus
  2010-08-25 13:28  6%     ` J-P. Rosen
                       ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Georg Bauhaus @ 2010-08-25 13:13 UTC (permalink / raw)


On 25.08.10 15:09, anon@att.net wrote:
> In <op.vhrt97eexmjfy8@garhos>, =?iso-8859-15?Q?Yannick_Duch=EAne_=28Hibou57=29?= writes:
>> Hello all,
>>
>> What about suggesting for Ada 2012, a Glob method as part of the standard  
>> Ada.Command_Line package ?
> 
> 
> If you want it, then create the package for your OS and Hardware and 
> submitted to ARG aka Adacore.

ARG:  ISO/IEC JTC 1/SC 22/WG 9 Ada Rapporteur Group (ARG)
AdaCore: Ada vendor, has members in ARG

There is no monopoly, yet.



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-21  4:47 12% What about a glob standard method in Ada.Command_Line ? Yannick Duchêne (Hibou57)
  2010-08-21  6:41  6% ` J-P. Rosen
@ 2010-08-25 13:09  6% ` anon
  2010-08-25 13:13  6%   ` Georg Bauhaus
  1 sibling, 1 reply; 200+ results
From: anon @ 2010-08-25 13:09 UTC (permalink / raw)


In <op.vhrt97eexmjfy8@garhos>, =?iso-8859-15?Q?Yannick_Duch=EAne_=28Hibou57=29?= writes:
>Hello all,
>
>What about suggesting for Ada 2012, a Glob method as part of the standard  
>Ada.Command_Line package ?


If you want it, then create the package for your OS and Hardware and 
submitted to ARG aka Adacore.  Submit documentation and source code. 

Anyone can suggest a package for Ada but those who truly want it will 
design it and submit it for the board to vote on. Else it must be a prefect 
answer to a number of problems before the board will allocate time to 
design a package that a non paying ARG member suggest.

So, either design the package and submit it to the Adacore aka ARG or pay 
the ARG member fee and submit the concept. 





^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 12:01  6%                                   ` Dmitry A. Kazakov
@ 2010-08-25 13:09  6%                                     ` Georg Bauhaus
  2010-08-25 13:30  6%                                       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2010-08-25 13:09 UTC (permalink / raw)


On 25.08.10 14:01, Dmitry A. Kazakov wrote:
> On Wed, 25 Aug 2010 13:09:41 +0200, Georg Bauhaus wrote:
> 
>> If you now want R* to decide the encoding of:
> 
> No, I want match this:
> 
>    a*¶

Fine, just do it using String; every component of a String
is well defined. Code points have nothing to do with Strings.
Let me try this in Kleene terms, with hypothetical wildcard
meaning (which I think you still have not specified explicitly):

Start with the (terminal) symbol a.
Continue with any number of (terminal) symbols
 drawn from Σ (which includes a and ¶, but not *).
End with the terminal symbol ¶.

> This pattern precisely defines a language L:

It does no such thing absent a definition of *.

The important question is what constitues Σ, not L.
If we use String, used in Directories.Start_Search,
then everything, including Σ, is well defined in Ada,
as is.


Georg



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25 11:09  4%                                 ` Georg Bauhaus
@ 2010-08-25 12:01  6%                                   ` Dmitry A. Kazakov
  2010-08-25 13:09  6%                                     ` Georg Bauhaus
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2010-08-25 12:01 UTC (permalink / raw)


On Wed, 25 Aug 2010 13:09:41 +0200, Georg Bauhaus wrote:

> If you now want R* to decide the encoding of:

No, I want match this:

   a*¶

This pattern precisely defines a language L:

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

The alphabet Σ of L is the set of code points:

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

L = aΣ*¶

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



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25  9:28  6%                               ` Dmitry A. Kazakov
@ 2010-08-25 11:09  4%                                 ` Georg Bauhaus
  2010-08-25 12:01  6%                                   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2010-08-25 11:09 UTC (permalink / raw)


On 25.08.10 11:28, Dmitry A. Kazakov wrote:
> On Wed, 25 Aug 2010 10:57:45 +0200, Georg Bauhaus wrote:
> 
>> Does "wildcard" include both Latin-xyz character ü and UTF-8 ü?
> 
> Wildcard * matches ANY SEQUENCE OF CODE POINTS.

Wildcard has no universal definition, I keep asking
for one.  ISO/IEC 8652 certainly deserves one.

Is * greedy, does it respect locale, ... But more importantly,
is a particular wildcard the crucial part at all?  No.  Again,
when the Pattern_Type is properly defined, there are no questions.

>> Yes.  Many Wildcards do. And it can be handled.
> 
> Wrong, it cannot be implemented to work on both Latin-1 and UTF-8.

Not wrong, insofar as R* typically matches anything that starts
with R which is what you asked for.  Define sets of strings:

- s ∈ S1 where s has a unique representation in any possible
 encoding (based on octets, e.g.)

- s ∈ S2 where s has a unique representation in some encoding
 to be determined by context

S1 is typically empty only if one mentions EBCDI or silly
"GIF text". (When once I had to extract numbers and names from
raw videotext, a simple RE has still been the tool of choice...)

If you now want R* to decide the encoding of:

>    61 C3 B6 = aö    (in Latin-1)
>    61 C3 B6 = aö      (in UTF-8)

then use programming, use context information with S2, or else approach
your customers with the suggestion that you can't solve the problem
because the external environment is not as ideal as it should be...
I don't think a computing device can establish an oracle?
But none is needed!

If the external environment does not specify encoding, and
your algorithm cannot work without encoding then only
normative ontology can add one. So try, add an encoding.

You can write an RE that matches in the following order:

   61 F6	-- aö in Latin-1
   61 C3 B6	-- aö in UTF-8

This is what is needed, not deciding the encoding of 61 C3 B6
without encoding.  Suppose I know the file name has a substring "Rücken".
Therefore I look for strings that have in them one string from
the set of substrings all of which can establish "Rücken" in
some expected encoding. Then I inspect the findings to see whether
one is good.
Done.

Georg



^ permalink raw reply	[relevance 4%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25  8:57  5%                             ` Georg Bauhaus
@ 2010-08-25  9:28  6%                               ` Dmitry A. Kazakov
  2010-08-25 11:09  4%                                 ` Georg Bauhaus
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2010-08-25  9:28 UTC (permalink / raw)


On Wed, 25 Aug 2010 10:57:45 +0200, Georg Bauhaus wrote:

> Does "wildcard" include both Latin-xyz character � and UTF-8 �?

Wildcard * matches ANY SEQUENCE OF CODE POINTS.

> Yes.  Many Wildcards do. And it can be handled.

Wrong, it cannot be implemented to work on both Latin-1 and UTF-8.

As a simple example consider the pattern

   a*�

and the string of octets

   61 C3 B6

Does the pattern match this string?

Hint:

   61 C3 B6 = aö    (in Latin-1)
   61 C3 B6 = a�      (in UTF-8)

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



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25  7:55  5%                           ` Dmitry A. Kazakov
  2010-08-25  8:24  6%                             ` Yannick Duchêne (Hibou57)
@ 2010-08-25  8:57  5%                             ` Georg Bauhaus
  2010-08-25  9:28  6%                               ` Dmitry A. Kazakov
  1 sibling, 1 reply; 200+ results
From: Georg Bauhaus @ 2010-08-25  8:57 UTC (permalink / raw)


On 8/25/10 9:55 AM, Dmitry A. Kazakov wrote:

>>> Does the wildcard pattern "R*"
>>
>> In what RE syntax?
>
> It is a wildcard pattern. Wildcards is the most frequently used pattern
> language.

Does "wildcard" include both Latin-xyz character � and UTF-8 �?
Yes.  Many Wildcards do. And it can be handled.

See whether or not encoding matters in the following program.



with GNAT.SPITBOL.Patterns;  use GNAT.SPITBOL.Patterns;
with Ada.Characters.Latin_1;  use Ada.Characters.Latin_1;

procedure Find_Ruecken (Text : String; Result : VString_Var) is
    In_UTF_8 : constant String := (Character'Val(16#c3#),
                                   Character'Val(16#bc#));
    Ue : Pattern;
begin
    Ue :=  (Any("Rr") & (In_UTF_8 or LC_U_Diaeresis) & "cken") ** Result;

    if not Match (Text, Ue) then
       raise Constraint_Error;
    end if;
end Find_Ruecken;

with GNAT.SPITBOL;  use GNAT.SPITBOL;
with Ada.Text_IO;
with Find_Ruecken;

procedure Test_Find_Ruecken is
    Found : VString;
begin
    Find_Ruecken(Text => "Recken, die R�cken ohne R�ckgrat dr�cken",
                 Result => Found);
    Ada.Text_IO.Put_Line ("Found """ & S(Found) & '"');
end Test_Find_Ruecken;


>>   >  match "readme"? Does it match "R�cken", when
>>> � is (16#c3#, 16#bc#) (UTF-8)?
>>
>> When the Pattern_Type is properly defined, there are no questions.
>
> How do define it properly? Does it match Latin-1's �, UTF-8's �, UTF-16's
> �, UTF-32's �? Don't you get that it cannot be done without abstracting
> *encoding* away?

When the Pattern_Type is properly defined, there are no questions.

Since I have to process a lot of text file and text streams
of unknown encoding, I'm used to REs that just find "R�cken"
in whatever encoding.  That's called programming.  Think of Google
or Yahoo or Bing searching the WWW and tons of email ...

There is no such thing as clean external data.
That  including file names.


Georg



^ permalink raw reply	[relevance 5%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-25  7:55  5%                           ` Dmitry A. Kazakov
@ 2010-08-25  8:24  6%                             ` Yannick Duchêne (Hibou57)
  2010-08-25 20:15  6%                               ` (see below)
  2010-08-25  8:57  5%                             ` Georg Bauhaus
  1 sibling, 1 reply; 200+ results
From: Yannick Duchêne (Hibou57) @ 2010-08-25  8:24 UTC (permalink / raw)


Le Wed, 25 Aug 2010 09:55:14 +0200, Dmitry A. Kazakov  
<mailbox@dmitry-kazakov.de> a écrit:
> They are not obsolete, in fact they won against Unix's flabby and
> disordered attempts to offer anything useful instead.
Mac OS used to have a good technique to tag files types and applications  
to be used to open it, via meta-data... unfortunately, it drop it with OS  
X to follow DOS/Windows convention (many users was disappointed, but Apple  
did not care).


-- 
* 3 lines of concise statements is readable, 10 pages of concise  
statements is unreadable ;
* 3 lines of verbose statements may looks unuseful, 10 pages of verbose  
statements will never looks too much pedantic



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-24 21:32  4%                         ` Georg Bauhaus
@ 2010-08-25  7:55  5%                           ` Dmitry A. Kazakov
  2010-08-25  8:24  6%                             ` Yannick Duchêne (Hibou57)
  2010-08-25  8:57  5%                             ` Georg Bauhaus
  0 siblings, 2 replies; 200+ results
From: Dmitry A. Kazakov @ 2010-08-25  7:55 UTC (permalink / raw)


On Tue, 24 Aug 2010 23:32:15 +0200, Georg Bauhaus wrote:

> Dmitry A. Kazakov wrote:
> 
>>> Is there an OS that reflects a file's content in its path?
>> 
>> MS-DOS, Windows, VMS, RSX-11
> 
> (These purport to reflect the file's content in the file name
> (which by habitual formalism is also a path...),
> but they don't.  Just open a file named README.DOC and be
> surprised that it is plain text.

Weakly typed is what this means. Nevertheless it is the path which is
supposed to identify the content type.

> Open a file ending in .AVI
> and see if this gets you anywhere.  File name extensions as
> file content descriptors are technically obsolete but they are
> still sold as important because some MS heads think
> it gives them best returns, people are used to them, everyone
> can profit from what programmers find useful, they are simple,
> etc.)

They are not obsolete, in fact they won against Unix's flabby and
disordered attempts to offer anything useful instead. The problem is that
they are not enforced, so weak typing: you think it is a document?
Surprise, surprise! Another problem is that there should be no files at all
and how should look like the naming scheme in an OO OS, nobody cares. 

>> Does the wildcard pattern "R*"
> 
> In what RE syntax?

It is a wildcard pattern. Wildcards is the most frequently used pattern
language.

* matches any, maybe empty, sequence of characters. Sometimes ? or % is
introduced, to mach exactly one character. 

>  > match "readme"? Does it match "R�cken", when
>> � is (16#c3#, 16#bc#) (UTF-8)?
> 
> When the Pattern_Type is properly defined, there are no questions.

How do define it properly? Does it match Latin-1's �, UTF-8's �, UTF-16's
�, UTF-32's �? Don't you get that it cannot be done without abstracting
*encoding* away?

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



^ permalink raw reply	[relevance 5%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-24 17:41  6%                       ` Dmitry A. Kazakov
@ 2010-08-24 21:32  4%                         ` Georg Bauhaus
  2010-08-25  7:55  5%                           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2010-08-24 21:32 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

>> Is there an OS that reflects a file's content in its path?
> 
> MS-DOS, Windows, VMS, RSX-11

(These purport to reflect the file's content in the file name
(which by habitual formalism is also a path...),
but they don't.  Just open a file named README.DOC and be
surprised that it is plain text.  Open a file ending in .AVI
and see if this gets you anywhere.  File name extensions as
file content descriptors are technically obsolete but they are
still sold as important because some MS heads think
it gives them best returns, people are used to them, everyone
can profit from what programmers find useful, they are simple,
etc.)

This is getting OT...

When you have a GNAT installation with default naming
scheme for compilation units, finding child units is
as simple as matching a regular expression---on some
systems.  When RE matching supports grouping, the possibilities
further exceed those of "content type" indicating filename
extensions.  When your log files include an ISO calendar
date in filenames, find all log files of last week without
looking at one single line in it...

This name based processing is useful in real cases,
is isn't fully portable to 8.3 filesystems, still useful,
and most flexibly handled with REs matching filenames.



> Does the wildcard pattern "R*"

In what RE syntax?  Does it have to be another syntax
embedded in String or can we do better?  GNAT's SPITBOL
demonstrates: Integrate Strings.Maps etc. with the type
system and establish a well defined pattern type.


 > match "readme"? Does it match "R�cken", when
> � is (16#c3#, 16#bc#) (UTF-8)?

When the Pattern_Type is properly defined, there are no questions.


> Naive string patterns will never work.

Simple filename patterns do work, now, unless you want them to
replace operating systems, application configuration, program
porting, adapting a program to a given environment, etc...



Georg



^ permalink raw reply	[relevance 4%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-24 18:42 11%                         ` Yannick Duchêne (Hibou57)
@ 2010-08-24 18:51  6%                           ` Simon Wright
  0 siblings, 0 replies; 200+ results
From: Simon Wright @ 2010-08-24 18:51 UTC (permalink / raw)


"Yannick Duchêne (Hibou57)" <yannick_duchene@yahoo.fr> writes:

> Le Tue, 24 Aug 2010 19:24:41 +0200, Georg Bauhaus
> <rm.dash-bauhaus@futureapps.de> a écrit:
>> I meant (forgetting the footnote, sorry):
>>
>> ls *.foo
>>
>> may just not work, since glob may hit a memory limit when building the
>> list of filenames.  On the other hand,
>>
>> ls | while read filename
>>   do
>>     case $filename in
>>       *.foo)
>>         ...;;
>>
>> does not have this problem.
> I understand that point, theoretically, not practically. Reaching
> memory limit would typically requires millions of match. This may
> occur in  theory, less in practice (where you will have at most a
> thousand... and  this would be not so common).

I'm pretty sure that bash has a limit on the length of a command line
which is different between Linux & Windows; I had a tool that was quite
happy with *.ad? on Linux but to make it portable I had to use a 'find'
approach, because the Windows (Cygwin) limit was considerably
smaller. This was actually a better solution anyway ...



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-24 17:24  6%                       ` Georg Bauhaus
@ 2010-08-24 18:42 11%                         ` Yannick Duchêne (Hibou57)
  2010-08-24 18:51  6%                           ` Simon Wright
  0 siblings, 1 reply; 200+ results
From: Yannick Duchêne (Hibou57) @ 2010-08-24 18:42 UTC (permalink / raw)


Le Tue, 24 Aug 2010 19:24:41 +0200, Georg Bauhaus  
<rm.dash-bauhaus@futureapps.de> a écrit:
> I meant (forgetting the footnote, sorry):
>
> ls *.foo
>
> may just not work, since glob may hit a memory limit when building the
> list of filenames.  On the other hand,
>
> ls | while read filename
>   do
>     case $filename in
>       *.foo)
>         ...;;
>
> does not have this problem.
I understand that point, theoretically, not practically. Reaching memory  
limit would typically requires millions of match. This may occur in  
theory, less in practice (where you will have at most a thousand... and  
this would be not so common).

I though this was a good idea, but do not feel it is worth the reactions  
it produced, so I suggest to just forget it (unless someone feel the  
layout of Ada.Command_Line may be part of the good first feeling some new  
comers may have about Ada).


-- 
* 3 lines of concise statements is readable, 10 pages of concise  
statements is unreadable ;
* 3 lines of verbose statements may looks unuseful, 10 pages of verbose  
statements will never looks too much pedantic



^ permalink raw reply	[relevance 11%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-24 17:10  5%                     ` Georg Bauhaus
  2010-08-24 17:24  6%                       ` Georg Bauhaus
@ 2010-08-24 17:41  6%                       ` Dmitry A. Kazakov
  2010-08-24 21:32  4%                         ` Georg Bauhaus
  1 sibling, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2010-08-24 17:41 UTC (permalink / raw)


On Tue, 24 Aug 2010 19:10:14 +0200, Georg Bauhaus wrote:

> On 24.08.10 18:04, Dmitry A. Kazakov wrote:
>> On Tue, 24 Aug 2010 17:42:17 +0200, Georg Bauhaus wrote:
>> 
>>> To me, directory search based on file content ("second order search")
>>> seems rather unusual as a first step.
>> 
>> Surely it is. Don't you look for text files, ada source files etc? 
> 
> No. I look at file names when I scan a directory.

Really? What for anybody would scan directories? I would say that almost
any file search is content-type based, e.g. "ls *.ads". Specific names and
time stamps are not so frequent and almost always intermixed with a content
type constraint.

>> Those
>> are called *content type*. Whether the content type is reflected by the
>> file path and in which form is OS-dependent.
> 
> Is there an OS that reflects a file's content in its path?

MS-DOS, Windows, VMS, RSX-11

>>> Case-(in)sensitivity is easily handled by text pattern matching,
>>> with existing Ada.
>> 
>> It cannot be handled.
> 
> Sure can, for file names.
> But whether the names "Readme" and "README" refer to two different
> files in a directory is another matter, just like the file
> "Frodo.txt" may refer to the same file as "README" and "Readme",
> in Unix file systems, NTFS, and others that support inodes with
> multiple links.

Does the wildcard pattern "R*" match "readme"? Does it match "R�cken", when
� is (16#c3#, 16#bc#) (UTF-8)?

To make patterns work you have to abstract file paths in an OS-independent
way and then define patterns over that abstraction. Naive string patterns
will never work.

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



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-24 17:10  5%                     ` Georg Bauhaus
@ 2010-08-24 17:24  6%                       ` Georg Bauhaus
  2010-08-24 18:42 11%                         ` Yannick Duchêne (Hibou57)
  2010-08-24 17:41  6%                       ` Dmitry A. Kazakov
  1 sibling, 1 reply; 200+ results
From: Georg Bauhaus @ 2010-08-24 17:24 UTC (permalink / raw)


On 24.08.10 19:10, Georg Bauhaus wrote:

> Efficiency of glob is unpredictable.  Linear scans of a directory
> are slightly different in this regard [*].

I meant (forgetting the footnote, sorry):

ls *.foo

may just not work, since glob may hit a memory limit when building the
list of filenames.  On the other hand,

ls | while read filename
  do
    case $filename in
      *.foo)
        ...;;

does not have this problem.




^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-24 16:04  5%                   ` Dmitry A. Kazakov
@ 2010-08-24 17:10  5%                     ` Georg Bauhaus
  2010-08-24 17:24  6%                       ` Georg Bauhaus
  2010-08-24 17:41  6%                       ` Dmitry A. Kazakov
  0 siblings, 2 replies; 200+ results
From: Georg Bauhaus @ 2010-08-24 17:10 UTC (permalink / raw)


On 24.08.10 18:04, Dmitry A. Kazakov wrote:
> On Tue, 24 Aug 2010 17:42:17 +0200, Georg Bauhaus wrote:
> 
>> On 24.08.10 16:24, Dmitry A. Kazakov wrote:
>>> On Tue, 24 Aug 2010 12:27:01 +0200, Georg Bauhaus wrote:
>>>>
>>>> procedure Start_Search
>>>>   (Search    : in out Search_Type;
>>>>    Directory : in String;
>>>>    Matcher   : access function (Pattern : Pattern_Type) return Boolean;
>>>>    Filter    : in Filter_Type := (others => True));
>>>>
>>> You just do not need patterns in directory search. The first reason is that
>>> the underlying  OS does not support that arbitrary stuff anyway.
>>
>> It is my program that matches file names against a pattern, not the OS.
> 
> Right, this is why an argument to efficiency would be invalid.

Efficiency of glob is unpredictable.  Linear scans of a directory
are slightly different in this regard [*].
And yes, both the Pattern parameter in current Directories.Start_Search,
or Matcher above could really be dropped. Not much will be lost, if
selecting file names can be performed later.


>> To me, directory search based on file content ("second order search")
>> seems rather unusual as a first step.
> 
> Surely it is. Don't you look for text files, ada source files etc? 

No. I look at file names when I scan a directory.


> Those
> are called *content type*. Whether the content type is reflected by the
> file path and in which form is OS-dependent.

Is there an OS that reflects a file's content in its path?


> Patterns cannot work here.

Patterns are intended for names, not content.

(It is odd that most contemporary file systems and archive formats
support extended attributes, but still everyone will keep using files
as if fopen() is the only means of finding information about a file...)


>> Case-(in)sensitivity is easily handled by text pattern matching,
>> with existing Ada.
> 
> It cannot be handled.

Sure can, for file names.
But whether the names "Readme" and "README" refer to two different
files in a directory is another matter, just like the file
"Frodo.txt" may refer to the same file as "README" and "Readme",
in Unix file systems, NTFS, and others that support inodes with
multiple links.

Directories.Start_Search is not about files, I think.
It is about file names (of certain directory entries).


Georg



^ permalink raw reply	[relevance 5%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-24 15:42  6%                 ` Georg Bauhaus
@ 2010-08-24 16:04  5%                   ` Dmitry A. Kazakov
  2010-08-24 17:10  5%                     ` Georg Bauhaus
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2010-08-24 16:04 UTC (permalink / raw)


On Tue, 24 Aug 2010 17:42:17 +0200, Georg Bauhaus wrote:

> On 24.08.10 16:24, Dmitry A. Kazakov wrote:
>> On Tue, 24 Aug 2010 12:27:01 +0200, Georg Bauhaus wrote:
>>>
>>> procedure Start_Search
>>>   (Search    : in out Search_Type;
>>>    Directory : in String;
>>>    Matcher   : access function (Pattern : Pattern_Type) return Boolean;
>>>    Filter    : in Filter_Type := (others => True));
>>>
>> You just do not need patterns in directory search. The first reason is that
>> the underlying  OS does not support that arbitrary stuff anyway.
> 
> It is my program that matches file names against a pattern, not the OS.

Right, this is why an argument to efficiency would be invalid. You filter
entries as you wish, no pattern or filter is needed as you get all entries
anyway. Do with them what you want.

>> Another,
>> more important reason is that real-life search would use filters based many
>> criteria, e.g. content, and patterns beyond the scope of RE, especially
>> when neither the name encoding nor case-sensitivity specified.
> 
> To me, directory search based on file content ("second order search")
> seems rather unusual as a first step.

Surely it is. Don't you look for text files, ada source files etc? Those
are called *content type*. Whether the content type is reflected by the
file path and in which form is OS-dependent. Patterns cannot work here.

> Case-(in)sensitivity is easily handled by text pattern matching,
> with existing Ada.

It cannot be handled. You don't even know if two file names are equivalent
using Ada.Directories, how then do you want to do this with pattern
matching? That is OS-dependent.

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



^ permalink raw reply	[relevance 5%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-24 14:24  6%               ` Dmitry A. Kazakov
@ 2010-08-24 15:42  6%                 ` Georg Bauhaus
  2010-08-24 16:04  5%                   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2010-08-24 15:42 UTC (permalink / raw)


On 24.08.10 16:24, Dmitry A. Kazakov wrote:
> On Tue, 24 Aug 2010 12:27:01 +0200, Georg Bauhaus wrote:
>>
>> procedure Start_Search
>>   (Search    : in out Search_Type;
>>    Directory : in String;
>>    Matcher   : access function (Pattern : Pattern_Type) return Boolean;
>>    Filter    : in Filter_Type := (others => True));
>>
> You just do not need patterns in directory search. The first reason is that
> the underlying  OS does not support that arbitrary stuff anyway.

It is my program that matches file names against a pattern, not the OS.

The alternative Directories.Start_Search above does not need to known about
pattern matching.  The Boolean result of Matcher is all that
matters. It matters only after the OS has supplied a String and after
Matcher has run with that string (the file name) and Pattern as input.

> Another,
> more important reason is that real-life search would use filters based many
> criteria, e.g. content, and patterns beyond the scope of RE, especially
> when neither the name encoding nor case-sensitivity specified.

To me, directory search based on file content ("second order search")
seems rather unusual as a first step.  At least in my real world.
Do we have usage data?

Case-(in)sensitivity is easily handled by text pattern matching,
with existing Ada.


Georg



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-24 10:27  6%             ` Georg Bauhaus
@ 2010-08-24 14:24  6%               ` Dmitry A. Kazakov
  2010-08-24 15:42  6%                 ` Georg Bauhaus
  0 siblings, 1 reply; 200+ results
From: Dmitry A. Kazakov @ 2010-08-24 14:24 UTC (permalink / raw)


On Tue, 24 Aug 2010 12:27:01 +0200, Georg Bauhaus wrote:

> Maybe the following change can lift Directories.Start_Search
> from implementation defined to standard?  Assuming a simplified
> Ada style RE package based on Strings.Maps etc., and a Pattern_Type:
> 
> procedure Start_Search
>   (Search    : in out Search_Type;
>    Directory : in String;
>    Matcher   : access function (Pattern : Pattern_Type) return Boolean;
>    Filter    : in Filter_Type := (others => True));

You just do not need patterns in directory search. The first reason is that
the underlying  OS does not support that arbitrary stuff anyway. Another,
more important reason is that real-life search would use filters based many
criteria, e.g. content, and patterns beyond the scope of RE, especially
when neither the name encoding nor case-sensitivity specified.

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



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-24  0:24 11%           ` Adam Beneschan
@ 2010-08-24 10:27  6%             ` Georg Bauhaus
  2010-08-24 14:24  6%               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2010-08-24 10:27 UTC (permalink / raw)


On 24.08.10 02:24, Adam Beneschan wrote:

> By the way, I was just as befuddled as Randy about the meaning of
> "glob" even though I've done lots of work with Unix and C.  The shell
> expands stuff on the command line, so I've never had any desire to use
> the program or library function that does this. 

"Globbing" can turn out to be wishful thinking, anyway, when
for example, directories are prohibitively large; a generally
usable program will have sequential directory scanning.

Maybe the following change can lift Directories.Start_Search
from implementation defined to standard?  Assuming a simplified
Ada style RE package based on Strings.Maps etc., and a Pattern_Type:

procedure Start_Search
  (Search    : in out Search_Type;
   Directory : in String;
   Matcher   : access function (Pattern : Pattern_Type) return Boolean;
   Filter    : in Filter_Type := (others => True));


Georg



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-24  0:02  5%         ` Yannick Duchêne (Hibou57)
@ 2010-08-24  0:24 11%           ` Adam Beneschan
  2010-08-24 10:27  6%             ` Georg Bauhaus
  0 siblings, 1 reply; 200+ results
From: Adam Beneschan @ 2010-08-24  0:24 UTC (permalink / raw)


On Aug 23, 5:02 pm, Yannick Duchêne (Hibou57)
<yannick_duch...@yahoo.fr> wrote:
> Le Tue, 24 Aug 2010 01:06:37 +0200, Randy Brukardt <ra...@rrsoftware.com>  
> a écrit:> It would surely help to have some idea of what a "glob" is! And  
> > explained in
> > some way which is not specific to any particular OS.
>
> The old one inherited from first UNIX and which while old is still part of  
> many core libraries (C, Python, Eiffel, Pascal, etc) and one of the most  
> commonly used to handle command-line parameters, the one which as an  
> example, from a "/directory/*.adb" returns an array of strings for all the  
> files matching the pattern.

Although a function like that would perhaps be useful, it would
definitely not belong in Ada.Command_Line or a child.  Some child of
Ada.Directories would be a much better place.

By the way, I was just as befuddled as Randy about the meaning of
"glob" even though I've done lots of work with Unix and C.  The shell
expands stuff on the command line, so I've never had any desire to use
the program or library function that does this.  I thought "glob"
meant a typical C program that is so impenetrable that it looks more
like a glob of random characters than like actual instructions for a
computer...... :)

                            -- Adam



^ permalink raw reply	[relevance 11%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-23 23:06  6%       ` Randy Brukardt
@ 2010-08-24  0:02  5%         ` Yannick Duchêne (Hibou57)
  2010-08-24  0:24 11%           ` Adam Beneschan
  0 siblings, 1 reply; 200+ results
From: Yannick Duchêne (Hibou57) @ 2010-08-24  0:02 UTC (permalink / raw)


Le Tue, 24 Aug 2010 01:06:37 +0200, Randy Brukardt <randy@rrsoftware.com>  
a écrit:
> It would surely help to have some idea of what a "glob" is! And  
> explained in
> some way which is not specific to any particular OS.
The old one inherited from first UNIX and which while old is still part of  
many core libraries (C, Python, Eiffel, Pascal, etc) and one of the most  
commonly used to handle command-line parameters, the one which as an  
example, from a "/directory/*.adb" returns an array of strings for all the  
files matching the pattern.

This could be implemented based on the directories package, so provided  
for platforms where this package is available. If there is no trouble to  
keep Ada.Directories, there should be no matter to have a glob method. It  
is at least as much platform independent as Ada.Directories is, as it can  
be based on it.

I though about it while I was reading something about its little variants,  
and in the while though “this is so commonly used, and this is not in Ada  
standard methods, this may make Ada look a bit more friendly to people who  
do not know it if it was there”.

Here is the story. Not a critical item, just a possibly appealing item.

-- 
* 3 lines of concise statements is readable, 10 pages of concise  
statements is unreadable ;
* 3 lines of verbose statements may looks unuseful, 10 pages of verbose  
statements will never looks too much pedantic



^ permalink raw reply	[relevance 5%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-22 19:00  6%     ` J-P. Rosen
  2010-08-22 19:29  6%       ` Yannick Duchêne (Hibou57)
@ 2010-08-23 23:06  6%       ` Randy Brukardt
  2010-08-24  0:02  5%         ` Yannick Duchêne (Hibou57)
  1 sibling, 1 reply; 200+ results
From: Randy Brukardt @ 2010-08-23 23:06 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 482 bytes --]

"J-P. Rosen" <rosen@adalog.fr> wrote in message 
news:i4rs3k$t6v$1@news.eternal-september.org...
> Le 21/08/2010 11:11, Pascal Obry a �crit :
...
> However, it IS too late for Ada 2012, and I'm serious when I say please
> propose it; a good proposal is never lost, but it may be harder than you
> think.

It would surely help to have some idea of what a "glob" is! And explained in 
some way which is not specific to any particular OS.

                                Randy.





^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-22 19:30  6%     ` Yannick Duchêne (Hibou57)
@ 2010-08-22 19:46  6%       ` Dmitry A. Kazakov
  0 siblings, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2010-08-22 19:46 UTC (permalink / raw)


On Sun, 22 Aug 2010 21:30:35 +0200, Yannick Duch�ne (Hibou57) wrote:

> Le Sat, 21 Aug 2010 11:11:39 +0200, Pascal Obry <pascal@obry.net> a �crit:
>> I see the argument but there is already some APIs that cannot be
>> implemented in some OS (like Ada.Execution_Time.Timers on Win32 for
>> example).
> Will have to check about what Ada.Execution_Time.Timers is exactly,  
> because I know there is a timer provided in the Windows API, and for long.

Under Windows there is no way to reliable determine the time a thread owned
CPU. Using existing APIs you can count quants, not the time. The problem is
that when the thread releases processor before it consumed the whole quant,
e.g. by entering non-busy waiting, the pending quant is not counted.
Theoretically you could have 99% CPU usage with 0% indicated in the task
manager.

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



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-21  9:11  6%   ` Pascal Obry
  2010-08-22 19:00  6%     ` J-P. Rosen
@ 2010-08-22 19:30  6%     ` Yannick Duchêne (Hibou57)
  2010-08-22 19:46  6%       ` Dmitry A. Kazakov
  1 sibling, 1 reply; 200+ results
From: Yannick Duchêne (Hibou57) @ 2010-08-22 19:30 UTC (permalink / raw)


Le Sat, 21 Aug 2010 11:11:39 +0200, Pascal Obry <pascal@obry.net> a écrit:
> I see the argument but there is already some APIs that cannot be
> implemented in some OS (like Ada.Execution_Time.Timers on Win32 for
> example).
Will have to check about what Ada.Execution_Time.Timers is exactly,  
because I know there is a timer provided in the Windows API, and for long.



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-22 19:00  6%     ` J-P. Rosen
@ 2010-08-22 19:29  6%       ` Yannick Duchêne (Hibou57)
  2010-08-23 23:06  6%       ` Randy Brukardt
  1 sibling, 0 replies; 200+ results
From: Yannick Duchêne (Hibou57) @ 2010-08-22 19:29 UTC (permalink / raw)


Le Sun, 22 Aug 2010 21:00:02 +0200, J-P. Rosen <rosen@adalog.fr> a écrit:
> However, it IS too late for Ada 2012, and I'm serious when I say please
> propose it; a good proposal is never lost, but it may be harder than you
> think.
OK, and sorry to have missunderstand



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-21  9:11  6%   ` Pascal Obry
@ 2010-08-22 19:00  6%     ` J-P. Rosen
  2010-08-22 19:29  6%       ` Yannick Duchêne (Hibou57)
  2010-08-23 23:06  6%       ` Randy Brukardt
  2010-08-22 19:30  6%     ` Yannick Duchêne (Hibou57)
  1 sibling, 2 replies; 200+ results
From: J-P. Rosen @ 2010-08-22 19:00 UTC (permalink / raw)


Le 21/08/2010 11:11, Pascal Obry a ï¿œcrit :
> 
> Jean-Pierre,
> 
>> 2) Make a good proposal, and make sure it is compiler independent,
>> system independent, powerful and easy to use. Then propose it to the
>> ARG, and the ARG will tell you why it doesn't work ;-)
> 
> I see the argument but there is already some APIs that cannot be
> implemented in some OS (like Ada.Execution_Time.Timers on Win32 for
> example). That's not a reason to dismiss it. A glob support for
> Command_Line (in a child package) would be most welcomed even if not
> supported (or supported but with some slight differences) on some OS I
> would say.
> 
Sure. And the whole history of Ada is full of stuff where we first said
it was not possible to define in a system independent manner, and later
we changed our mind on the name of usability. Command_Line was dismissed
for Ada 83 and provided in Ada 95. Directory_Operations was dismissed in
Ada 95 and introduced in Ada 2005.

However, it IS too late for Ada 2012, and I'm serious when I say please
propose it; a good proposal is never lost, but it may be harder than you
think.
-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-21  6:41  6% ` J-P. Rosen
  2010-08-21  7:21  6%   ` Yannick Duchêne (Hibou57)
@ 2010-08-21  9:11  6%   ` Pascal Obry
  2010-08-22 19:00  6%     ` J-P. Rosen
  2010-08-22 19:30  6%     ` Yannick Duchêne (Hibou57)
  1 sibling, 2 replies; 200+ results
From: Pascal Obry @ 2010-08-21  9:11 UTC (permalink / raw)



Jean-Pierre,

> 2) Make a good proposal, and make sure it is compiler independent,
> system independent, powerful and easy to use. Then propose it to the
> ARG, and the ARG will tell you why it doesn't work ;-)

I see the argument but there is already some APIs that cannot be
implemented in some OS (like Ada.Execution_Time.Timers on Win32 for
example). That's not a reason to dismiss it. A glob support for
Command_Line (in a child package) would be most welcomed even if not
supported (or supported but with some slight differences) on some OS I
would say.

-- 

--|------------------------------------------------------
--| 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 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-21  6:41  6% ` J-P. Rosen
@ 2010-08-21  7:21  6%   ` Yannick Duchêne (Hibou57)
  2010-08-21  9:11  6%   ` Pascal Obry
  1 sibling, 0 replies; 200+ results
From: Yannick Duchêne (Hibou57) @ 2010-08-21  7:21 UTC (permalink / raw)


Le Sat, 21 Aug 2010 08:41:54 +0200, J-P. Rosen <rosen@adalog.fr> a écrit:
> 2) Make a good proposal, and make sure it is compiler independent,
> system independent, powerful and easy to use. Then propose it to the
> ARG, and the ARG will tell you why it doesn't work ;-)
OK, I see, this would not be enough system independent, you are right.
I had some kind of typical usage in mind when I wrote this (though this  
may help Ada to look more attractive), and I forget about other targets  
(just at that time).



^ permalink raw reply	[relevance 6%]

* Re: What about a glob standard method in Ada.Command_Line ?
  2010-08-21  4:47 12% What about a glob standard method in Ada.Command_Line ? Yannick Duchêne (Hibou57)
@ 2010-08-21  6:41  6% ` J-P. Rosen
  2010-08-21  7:21  6%   ` Yannick Duchêne (Hibou57)
  2010-08-21  9:11  6%   ` Pascal Obry
  2010-08-25 13:09  6% ` anon
  1 sibling, 2 replies; 200+ results
From: J-P. Rosen @ 2010-08-21  6:41 UTC (permalink / raw)


Le 21/08/2010 06:47, Yannick Duchï¿œne (Hibou57) a ï¿œcrit :
> Hello all,
> 
> What about suggesting for Ada 2012, a Glob method as part of the
> standard Ada.Command_Line package ?
1) It's far too late. You can propose anything you want for Ada 2022.

2) Make a good proposal, and make sure it is compiler independent,
system independent, powerful and easy to use. Then propose it to the
ARG, and the ARG will tell you why it doesn't work ;-)

-- 
---------------------------------------------------------
           J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[relevance 6%]

* What about a glob standard method in Ada.Command_Line ?
@ 2010-08-21  4:47 12% Yannick Duchêne (Hibou57)
  2010-08-21  6:41  6% ` J-P. Rosen
  2010-08-25 13:09  6% ` anon
  0 siblings, 2 replies; 200+ results
From: Yannick Duchêne (Hibou57) @ 2010-08-21  4:47 UTC (permalink / raw)


Hello all,

What about suggesting for Ada 2012, a Glob method as part of the standard  
Ada.Command_Line package ?



^ permalink raw reply	[relevance 12%]

* Example GNAT Ada program for openGl
@ 2010-07-11  4:22  4% 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 4%]

* Re: Disabling string evaluation in a logging system
  @ 2010-05-18 11:27  8%   ` Gautier write-only
  0 siblings, 0 replies; 200+ results
From: Gautier write-only @ 2010-05-18 11:27 UTC (permalink / raw)


OK, I missed the point about "&", To_String etc., as the example below
shows.
If you combine Stefan's solution and the Inline pragma, it should be
fine...
Gautier
_____________
with Log;
-- Try preventing compiler from optimizing parameters out...
-- -> Dynamic data.
with Ada.Command_Line, Ada.Strings.Unbounded;
--
procedure Test_Opti_inline is
  use Ada.Strings.Unbounded;
  --
  procedure Tricky(Param_Name: Unbounded_String; X: Integer) is
  pragma Inline(Tricky);
  begin
    Log.Write (Text => "Parameter " & To_String (Param_Name) & " Value
= " & Integer'Image (X), Level => 0);
  end Tricky;
  --
  Param_Name: Unbounded_String:=
To_Unbounded_String(Ada.Command_Line.Command_Name);
  X: Integer:= Ada.Command_Line.Argument_Count;

begin
  Log.Write (Text => "Blabla...", Level => 5);
  Log.Write (Text => "No no no!", Level => 0);
  Tricky (Param_Name => Param_Name, X => X); -- Hope: this is
optimized out.
end;



^ permalink raw reply	[relevance 8%]

* Re: gdb hijacks my argument list
@ 2010-01-05  1:06  3% Leslie
  0 siblings, 0 replies; 200+ results
From: Leslie @ 2010-01-05  1:06 UTC (permalink / raw)


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

Hi,
        Has anyone else seen this problem with gdb?  I had originally
posted it to bug-gdb@gnu.org, but got no useful response. 
Original post:

     I'm writing a package that accepts arbitrary character
strings from the command line, and I'm trying to debug it with
gdb.

    When run without gdb the command line string is passed
directly to my program, but when I tell gdb to pass it, gdb
insists on interpreting it as a filename, and won't pass it
through.

Example without gdb:
=================================================
./testtoken ' (name testtoken endchar \) < testtoken.adb |
(trace) count lines|cons '

Input string is:
....+....1....+....2....+....3....+....4....+....5....+....6
(name testtoken endchar \) < testtoken.adb | (trace) count lines
cons

    Before: TokenFrom =   1
            TextLeft  =  71
    After:  TokenFrom =   1
            TextLeft  =  71
Token  1 is: ' (name testtoken endchar \) < testtoken.adb |
(trace) count lines|cons '

End of tokens reached.

=================================================

Example with gdb:
=================================================
gdb testtoken --args ' (name testtoken endchar \) <
testtoken.adb | (trace) count lines|cons '
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html> This is free software: you are
free to change and redistribute it. There is NO WARRANTY, to the
extent permitted by law.  Type "show copying" and "show
warranty" for details.
This GDB was configured as "i586-suse-linux"...
(name testtoken endchar \) < testtoken.adb | (trace) count lines
cons : No such file or directory.
(gdb)
=================================================

        I have tried using the 'run PROGNAME ARGUMENTS...' method, but
it gives 
me the same results.  I have attached the source code and a
terminal session showing exactly what I have tried, so that you
can (presumably) duplicate my results.  Perhaps I am
misunderstanding somehow the proper gdb syntax to be used, or
have wrong versions of tools?

Leslie

[-- Attachment #2: gdbSession.txt --]
[-- Type: text/plain, Size: 6463 bytes --]

15:48:37 turriff@pinto
~/Documents/SourceCode$
uname -a
Linux pinto 2.6.25.20-0.5-pae #1 SMP 2009-08-14 01:48:11 +0200 i686 i686 i386 GNU/Linux

15:48:39 turriff@pinto
~/Documents/SourceCode$
cat /etc/SuSE-release
openSUSE 11.0 (i586)
VERSION = 11.0

15:48:46 turriff@pinto
~/Documents/SourceCode$
gcc -v
Using built-in specs.
Target: i586-suse-linux
Configured with: ../configure --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --libexecdir=/usr/lib --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.3 --enable-ssp --disable-libssp --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --with-slibdir=/lib --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --program-suffix=-4.3 --enable-version-specific-runtime-libs --enable-linux-futex --without-system-libunwind --with-cpu=generic --build=i586-suse-linux
Thread model: posix
gcc version 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036] (SUSE Linux)

15:48:50 turriff@pinto
~/Documents/SourceCode$
gnat
GNAT 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036]
Copyright 1996-2007, Free Software Foundation, Inc.

List of available commands

gnat bind               gnatbind
gnat chop               gnatchop
gnat clean              gnatclean
gnat compile            gnatmake -f -u -c
gnat check              gnatcheck
gnat elim               gnatelim
gnat find               gnatfind
gnat krunch             gnatkr
gnat link               gnatlink
gnat list               gnatls
gnat make               gnatmake
gnat metric             gnatmetric
gnat name               gnatname
gnat preprocess         gnatprep
gnat pretty             gnatpp
gnat stack              gnatstack
gnat stub               gnatstub
gnat xref               gnatxref

Commands find, list, metric, pretty, stack, stub and xref accept project file switches -vPx, -Pprj and -Xnam=val

15:48:54 turriff@pinto
~/Documents/SourceCode$
ll testcmdline*
-rw-r--r-- 1 turriff users 379 2009-12-19 14:27 testcmdline.adb

15:49:00 turriff@pinto
~/Documents/SourceCode$
gcc -c -g testcmdline.adb && gnatmake -g testcmdline
gnatbind -x testcmdline.ali
gnatlink testcmdline.ali -g

15:49:19 turriff@pinto
~/Documents/SourceCode$
./testcmdline with an arbitrary command string
with

15:49:35 turriff@pinto
~/Documents/SourceCode$
./testcmdline 'with an arbitrary command string'
with an arbitrary command string

15:49:44 turriff@pinto
~/Documents/SourceCode$
gdb -v
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i586-suse-linux".

15:49:55 turriff@pinto
~/Documents/SourceCode$
gdb --quiet testcmdline
(gdb) break testcmdline
Breakpoint 1 at 0x8049bdb: file testcmdline.adb, line 5.
(gdb) set args 'with an arbitrary command string'
(gdb) run
Starting program: /home/turriff/Documents/SourceCode/testcmdline 'with an arbitrary command string'
unable to open script file 'exec /home/turriff/Documents/SourceCode/testcmdline 'with an arbitrary command string'' : file not found

Program exited with code 01.
You can't do that without a process to debug.
(gdb) quit

15:50:36 turriff@pinto
~/Documents/SourceCode$
gdb --quiet --args testcmdline 'with an arbitrary command string'
(gdb) break testcmdline
Breakpoint 1 at 0x8049bdb: file testcmdline.adb, line 5.
(gdb) show args
Argument list to give program being debugged when it is started is "".
(gdb) run
Starting program: /home/turriff/Documents/SourceCode/testcmdline with\ an\ arbitrary\ command\ string
unable to open script file 'exec /home/turriff/Documents/SourceCode/testcmdline with\ an\ arbitrary\ command\ string' : file not found

Program exited with code 01.
You can't do that without a process to debug.
(gdb) quit

15:51:40 turriff@pinto
~/Documents/SourceCode$
gdb --help
This is the GNU debugger.  Usage:

    gdb [options] [executable-file [core-file or process-id]]
    gdb [options] --args executable-file [inferior-arguments ...]

Options:

  --args             Arguments after executable-file are passed to inferior
  -b BAUDRATE        Set serial port baud rate used for remote debugging.
  --batch            Exit after processing options.
  --batch-silent     As for --batch, but suppress all gdb stdout output.
  --return-child-result
                     GDB exit code will be the child's exit code.
  --cd=DIR           Change current directory to DIR.
  --command=FILE, -x Execute GDB commands from FILE.
  --eval-command=COMMAND, -ex
                     Execute a single GDB command.
                     May be used multiple times and in conjunction
                     with --command.
  --core=COREFILE    Analyze the core dump COREFILE.
  --pid=PID          Attach to running process PID.
  --dbx              DBX compatibility mode.
  --directory=DIR    Search for source files in DIR.
  --epoch            Output information used by epoch emacs-GDB interface.
  --exec=EXECFILE    Use EXECFILE as the executable.
  --fullname         Output information used by emacs-GDB interface.
  --help             Print this message.
  --interpreter=INTERP
                     Select a specific interpreter / user interface
  -l TIMEOUT         Set timeout in seconds for remote debugging.
  --nw               Do not use a window interface.
  --nx               Do not read .gdbinit file.
  --quiet            Do not print version number on startup.
  --readnow          Fully read symbol files on first access.
  --se=FILE          Use FILE as symbol file and executable file.
  --symbols=SYMFILE  Read symbols from SYMFILE.
  --tty=TTY          Use TTY for input/output by the program being debugged.
  --tui              Use a terminal user interface.
  --version          Print version information and then exit.
  -w                 Use a window interface.
  --write            Set writing into executable and core files.
  --xdb              XDB compatibility mode.

For more information, type "help" from within GDB, or consult the
GDB manual (available as on-line info or a printed manual).
Report bugs to "bug-gdb@gnu.org".

[-- Attachment #3: testcmdline.adb --]
[-- Type: text/plain, Size: 380 bytes --]

with Ada.Command_Line;       use Ada.Command_Line;
with Ada.Strings.Unbounded;  use Ada.Strings.Unbounded;
with Ada.Strings;            use Ada.Strings;
with Ada.Text_IO;            use Ada.Text_IO;
  procedure testcmdline is
    TextLine : unbounded_string;
    begin
      TextLine := to_unbounded_string(argument(1));
      put_line(to_string(TextLine));
    end testcmdline;


^ permalink raw reply	[relevance 3%]

* Re: Performance of the Streams 'Read and 'Write
  2009-10-30 13:40  5% ` Gautier write-only
@ 2009-11-02 22:19  5%   ` Gautier write-only
  0 siblings, 0 replies; 200+ results
From: Gautier write-only @ 2009-11-02 22:19 UTC (permalink / raw)


Here is the ultimate test ;-), with Jeff's overlay idea and the
unchecked_conversion as well.
G.

-- Usage: test_stream_performance <big_file>
-- Produces .tmp files that are copies of <big_file>.
--
-- Example of output with GNAT GPL 2008 / Win32:
--
--  xxx'Write / xxx'Read (Stream attributes)......... 9.282530042
seconds
--  Workarounds with Stream_Element_Array buffer:
--    copy........................................... 0.444120412
seconds
--    overlay (read), unchecked_conversion (write)... 0.156874407
seconds
--    overlay........................................ 0.150155676
seconds
--  Factor (Copy)    20.900930898
--  Factor (Overlay) 61.819374993

--  Buffer size in bits..... 8192
--  SE Buffer size in bits.. 8192

--  File size in megabytes..... 2.46367E+01

with Ada.Calendar;                      use Ada.Calendar;
with Ada.Text_IO;
with Ada.Streams.Stream_IO;             use Ada.Streams.Stream_IO;
with Ada.Command_Line;                  use Ada.Command_Line;
with Ada.Unchecked_Conversion;
with Interfaces;                        use Interfaces;

procedure Test_Stream_Performance is

  f_in, f_out: Ada.Streams.Stream_IO.File_Type;

  buffer_size, SE_buffer_size: Natural:= 0;
  -- To check if buffers are binary compatible (same packing)

  type Buffer is array(Natural range <>) of Unsigned_8;

  ------------------------------------------------
  -- 1) Stream attributes - xxx'Read, xxx'Write --
  ------------------------------------------------

  -- NB: usually we would just have: Buffer'Read(Stream(f_in), b);
  -- Here we care about end of file.
  --
  procedure Read_Attribute( b: out Buffer; last_read: out Natural ) is
    idx: constant Positive_Count:= Index(f_in);
    siz: constant Positive_Count:= Size(f_in);
  begin
    if End_Of_File(f_in) then
      last_read:= b'First-1;
    else
      last_read:= Natural'Min(b'First+Natural(siz-idx),b'Last);
      Buffer'Read(Stream(f_in), b(b'First .. last_read));
    end if;
  end Read_Attribute;

  procedure Write_Attribute( b: in Buffer ) is
  begin
    if buffer_size = 0 then
      buffer_size:= b'size; -- just for stats
    end if;
    Buffer'Write(Stream(f_out), b);
  end Write_Attribute;

  ---------------------------------------------
  -- 2) The Stream_Element_Array workarounds --
  ---------------------------------------------

  procedure Read_SE_Copy( b: out Buffer; last_read: out Natural ) is
    use Ada.Streams;
    First     : constant Stream_Element_Offset:= Stream_Element_Offset
(b'First);
    Last      :          Stream_Element_Offset:= Stream_Element_Offset
(b'Last);
    SE_Buffer : Stream_Element_Array (First..Last);
  begin
    Read(Stream(f_in).all, SE_Buffer, Last);
    for i in First..Last loop
      b(Natural(i)):= Unsigned_8(SE_Buffer(i));
    end loop;
    last_read:= Natural(last);
  end Read_SE_Copy;

  procedure Write_SE_Copy( b: in Buffer ) is
    use Ada.Streams;
    First     : constant Stream_Element_Offset:= Stream_Element_Offset
(b'First);
    Last      : constant Stream_Element_Offset:= Stream_Element_Offset
(b'Last);
    SE_Buffer : Stream_Element_Array (First..Last);
  begin
    if SE_buffer_size = 0 then
      SE_buffer_size:= SE_Buffer'size; -- just for stats
    end if;
    for i in SE_Buffer'Range loop
      SE_Buffer(i):= Stream_Element(b(Natural(i)));
    end loop;
    Write(Stream(f_out).all, SE_Buffer);
  end Write_SE_Copy;

  -- Overlay idea by Jeff Carter

  procedure Read_SE_Overlay( b: out Buffer; last_read: out Natural )
is
    use Ada.Streams;
    Last: Stream_Element_Offset;
    SE_Buffer : Stream_Element_Array (1..b'Length);
    for SE_Buffer'Address use b'Address;
  begin
    Read(Stream(f_in).all, SE_Buffer, Last);
    last_read:= b'First + Natural(Last) - 1;
  end Read_SE_Overlay;

  procedure Write_SE_Overlay( b: in Buffer ) is
    use Ada.Streams;
    SE_Buffer : Stream_Element_Array (1..b'Length);
    for SE_Buffer'Address use b'Address;
  begin
    Write(Stream(f_out).all, SE_Buffer);
  end Write_SE_Overlay;

  -- Using Unchecked_Conversion

  procedure Write_SE_UC( b: in Buffer ) is
    subtype My_SEA is Ada.Streams.Stream_Element_Array(1..b'Length);
    function To_SEA is new Ada.Unchecked_Conversion(Buffer, My_SEA);
    use Ada.Streams;
  begin
    Write(Stream(f_out).all, To_SEA(b));
  end Write_SE_UC;

  ----------
  -- Test --
  ----------

  function name return String is
  begin
    return Argument(1);
  end;

  generic
    label: String;
    with procedure Read( b: out Buffer; last_read: out Natural  );
    with procedure Write( b: in Buffer  );
  procedure Test;

  procedure Test is
    b: Buffer(1..1024);
    l: Natural;
  begin
    Open(f_in, In_File, name);
    Create(f_out, Out_File, name & "_$$$_" & label & ".tmp");
    while not End_of_File(f_in) loop
      Read(b,l);
      Write(b(1..l));
    end loop;
    Close(f_out);
    Close(f_in);
  end;

  procedure Test_Attribute is new Test("Attribute", Read_Attribute,
Write_Attribute);
  procedure Test_SE_Copy is new Test("SE_Copy", Read_SE_Copy,
Write_SE_Copy);
  procedure Test_SE_Overlay is new Test("SE_Overlay", Read_SE_Overlay,
Write_SE_Overlay);
  procedure Test_SE_UC is new Test("SE_UC", Read_SE_Overlay,
Write_SE_UC);

  T0, T1, T2, T3, T4: Time;

  use Ada.Text_IO;

begin
  if Argument_Count=0 then
    Put_Line(" Usage: test_stream_performance <big_file>");
    Put_Line(" Produces .tmp files that are copies of <big_file>.");
    return;
  end if;
  T0:= Clock;
  Test_Attribute;
  T1:= Clock;
  Test_SE_Copy;
  T2:= Clock;
  Test_SE_Overlay;
  T3:= Clock;
  Test_SE_UC;
  T4:= Clock;
  Put_Line("xxx'Write / xxx'Read (Stream attributes)........." &
Duration'Image(T1-T0) & " seconds");
  Put_Line("Workarounds with Stream_Element_Array buffer:");
  Put_Line("  copy..........................................." &
Duration'Image(T2-T1) & " seconds");
  Put_Line("  overlay (read), unchecked_conversion (write)..." &
Duration'Image(T4-T3) & " seconds");
  Put_Line("  overlay........................................" &
Duration'Image(T3-T2) & " seconds");
  Put_Line("Factor (Copy)   " & Duration'Image((T1-T0)/(T2-T1)));
  Put_Line("Factor (Overlay)" & Duration'Image((T1-T0)/(T3-T2)));
  New_Line;
  Put_Line("Buffer size in bits....." & Integer'Image(buffer_size));
  Put_Line("SE Buffer size in bits.." & Integer'Image
(SE_buffer_size));
  New_Line;
  Open(f_in, In_File, name);
  Put_Line("File size in megabytes....." & Float'Image(Float(Size
(f_in))/(1024.0*1024.0)));
  Close(f_in);
end;




^ permalink raw reply	[relevance 5%]

* Re: Performance of the Streams 'Read and 'Write
  @ 2009-10-30 13:40  5% ` Gautier write-only
  2009-11-02 22:19  5%   ` Gautier write-only
  0 siblings, 1 reply; 200+ results
From: Gautier write-only @ 2009-10-30 13:40 UTC (permalink / raw)


Here is a test program. I am curious about other results

-- Usage: test_stream_performance <file>
-- Produces two .tmp files that are copies of <file>.
--
-- Example of output with file m.wmv, 2.59 MB, GNAT GPL 2008 / Win32:
--
--  xxx'Write / xxx'Read (Attribute).. 1.925210886 seconds
--  Workaround with SE buffer......... 0.049318559 seconds
--  Factor 39.036235547

--  Buffer size in bits..... 8192
--  SE Buffer size in bits.. 8192

with Ada.Calendar;                      use Ada.Calendar;
with Ada.Text_IO;
with Ada.Streams.Stream_IO;             use Ada.Streams.Stream_IO;
with Ada.Command_Line;                  use Ada.Command_Line;
with Interfaces;                        use Interfaces;

procedure Test_Stream_Performance is

  f_in, f_out: Ada.Streams.Stream_IO.File_Type;

  buffer_size, SE_buffer_size: Natural:= 0;
  -- To check if buffers could be overlapped (packing)

  type Buffer is array(Natural range <>) of Unsigned_8;

  ------------------------------------------------
  -- 1) Stream attributes - xxx'Read, xxx'Write --
  ------------------------------------------------

  -- Usually we would just have: Buffer'Read(Stream(f_in), b);
  -- Here we care about end of file.

  procedure Read_Attribute( b: out Buffer; last_read: out Natural ) is
    idx: constant Positive_Count:= Index(f_in);
    siz: constant Positive_Count:= Size(f_in);
  begin
    if End_Of_File(f_in) then
      last_read:= b'First-1;
    else
      last_read:= Natural'Min(b'First+Natural(siz-idx),b'Last);
      Buffer'Read(Stream(f_in), b(b'First .. last_read));
    end if;
  end Read_Attribute;

  procedure Write_Attribute( b: in Buffer ) is
  begin
    if buffer_size = 0 then
      buffer_size:= b'size;
    end if;
    Buffer'Write(Stream(f_out), b);
  end Write_Attribute;

  --------------------------------------------
  -- 2) The Stream_Element_Array workaround --
  --------------------------------------------

  procedure Read_SE( b: out Buffer; last_read: out Natural ) is
    use Ada.Streams;
    First     : constant Stream_Element_Offset:= Stream_Element_Offset
(b'First);
    Last      :          Stream_Element_Offset:= Stream_Element_Offset
(b'Last);
    SE_Buffer : Stream_Element_Array (First..Last);
  begin
    Read(Stream(f_in).all, SE_Buffer, Last);
    for i in First..Last loop
      b(Natural(i)):= Unsigned_8(SE_Buffer(i));
    end loop;
    last_read:= Natural(last);
  end Read_SE;

  procedure Write_SE( b: in Buffer ) is
    use Ada.Streams;
    First     : constant Stream_Element_Offset:= Stream_Element_Offset
(b'First);
    Last      : constant Stream_Element_Offset:= Stream_Element_Offset
(b'Last);
    SE_Buffer : Stream_Element_Array (First..Last);
  begin
    if SE_buffer_size = 0 then
      SE_buffer_size:= SE_Buffer'size;
    end if;
    for i in SE_Buffer'Range loop
      SE_Buffer(i):= Stream_Element(b(Natural(i)));
    end loop;
    Write(Stream(f_out).all, SE_Buffer);
  end Write_SE;

  name : constant String:= Argument(1);

  generic
    label: String;
    with procedure Read( b: out Buffer; last_read: out Natural  );
    with procedure Write( b: in Buffer  );
  procedure Test;

  procedure Test is
    b: Buffer(1..1024);
    l: Natural;
  begin
    Open(f_in, In_File, name);
    Create(f_out, Out_File, name & "_$$$_" & label & ".tmp");
    while not End_of_File(f_in) loop
      Read(b,l);
      Write(b(1..l));
    end loop;
    Close(f_out);
    Close(f_in);
  end;

  procedure Test_Attribute is new Test("Attribute", Read_Attribute,
Write_Attribute);
  procedure Test_SE is new Test("SE", Read_SE, Write_SE);

  T0, T1, T2: Time;

  use Ada.Text_IO;

begin
  T0:= Clock;
  Test_Attribute;
  T1:= Clock;
  Test_SE;
  T2:= Clock;
  Put_Line("xxx'Write / xxx'Read (Attribute).." & Duration'Image(T1-
T0) & " seconds");
  Put_Line("Workaround with SE buffer........." & Duration'Image(T2-
T1) & " seconds");
  Put_Line("Factor" & Duration'Image((T1-T0)/(T2-T1)));
  New_Line;
  Put_Line("Buffer size in bits....." & Integer'Image(buffer_size));
  Put_Line("SE Buffer size in bits.." & Integer'Image
(SE_buffer_size));
end;



^ permalink raw reply	[relevance 5%]

* Re: Tasking for Mandelbrot program
  @ 2009-10-13 12:57  6%             ` Georg Bauhaus
  0 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2009-10-13 12:57 UTC (permalink / raw)


Gautier write-only schrieb:
> On 13 Okt., 11:11, Mark Lorenzen <mark.loren...@gmail.com> wrote:
> 
>> Please note that the "bit-wise or" operation in the following line has
>> no effect:
>>      Byte_Acc := Shift_Left (Byte_Acc, 1) or 16#00#
>>
>> When shifting left, you are guaranteed that zeroes are shifted in.
> 
> Well "or 0" has no effect anyway (shift or not shift). If you wanted
> to filter something, you would write "and 16#FFFFFF00# :-)

I'm stating the obvious when saying that the compiler
knows that "or 16#00#" has no effect... ;-)  FWIW, the
simple symmetric if/else around the above line seems
to give the fastest program with this distinction,
at least when produced by the Shootout compiler;
with GNATs such as GPL GNAT we might be able to reduce source
size by using Boolean'Pos instead of if/else or even anonymous
conditional expressions as are proposed for Ada 1Y.

Compile  with -gnatX if using GNAT, to see timing differences,
if any:


with Interfaces; use Interfaces;
with Ada.Command_Line ; use Ada.Command_Line;
with Ada.Calendar;  use Ada.Calendar;
with Ada.Text_IO;  use Ada.Text_IO;

procedure Bittest is

   Byte_Acc : Unsigned_8;
   Ntests : constant := 100;

   procedure Work (This_Way: Boolean) is
      pragma Inline (Work);
   begin
      for K in 1 .. Ntests loop
	 Byte_Acc := Shift_Left (Byte_Acc, 1)
                       or
                     Boolean'Pos(not This_Way);
      end loop;
   end work;

   procedure Work2 (This_Way: Boolean) is  -- original
      pragma Inline (Work2);
   begin
      for K in 1 .. Ntests loop
	 if This_Way then
	    Byte_Acc := Shift_Left (Byte_Acc, 1) or 16#00#;
	 else
	    Byte_Acc := Shift_Left (Byte_Acc, 1) or 16#01#;
	 end if;
      end loop;
   end Work2;

   procedure WorkX (This_Way: Boolean) is
      pragma Inline (WorkX);
   begin
      for K in 1 .. Ntests loop
	 Byte_Acc := Shift_Left (Byte_Acc, 1) or (if This_Way
						    then 16#00#
						    else 16#01#);
      end loop;
   end WorkX;

   Start, Finish: Time;
begin
   Byte_Acc := Boolean'Pos(Argument_Count > 1);

   Start := Clock;
   for K in 1 .. 5_000_000 loop
      Work (Argument(1) = "yes");
   end loop;
   Finish := Clock;
   Put_Line ("Work: Byte_Acc = " & Unsigned_8'Image (Byte_Acc) &
	       " in " & Duration'Image (Finish - Start) & " seconds");

   Byte_Acc := Boolean'Pos(Argument_Count > 1);

   Start := Clock;
   for K in 1 .. 5_000_000 loop
      Work2 (Argument(1) = "yes");
   end loop;
   Finish := Clock;
   Put_Line ("Work2: Byte_Acc = " & Unsigned_8'Image (Byte_Acc) &
	       " in " & Duration'Image (Finish - Start) & " seconds");

   Byte_Acc := Boolean'Pos(Argument_Count > 1);

   Start := Clock;
   for K in 1 .. 5_000_000 loop
      WorkX (Argument(1) = "yes");
   end loop;
   Finish := Clock;
   Put_Line ("WorkX: Byte_Acc = " & Unsigned_8'Image (Byte_Acc) &
	       " in " & Duration'Image (Finish - Start) & " seconds");

end Bittest;



^ permalink raw reply	[relevance 6%]

* Re: Get the path and namefile in run time
  @ 2009-10-03 17:09  6%   ` sjw
  0 siblings, 0 replies; 200+ results
From: sjw @ 2009-10-03 17:09 UTC (permalink / raw)


On Oct 2, 9:13 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Fri, 2 Oct 2009 12:54:40 -0700 (PDT), Pablo wrote:
> > How can I set a string in run-time with the name of the file and other
> > with the path?
> > Say us, If the exec file is in c:\myexecutable\main.exe, I want a way
> > to set a String in such a way that String1="main.exe" "and c:
> > \myexecutable\".
>
> See Ada.Directories, functions:
>
> Simple_Name
> Containing_Directory

And Ada.Command_Line.Command_Name (actually .. does this include the
".exe" if that wasn't part of what was actually typed at the command
line?)



^ permalink raw reply	[relevance 6%]

* Tasking for Mandelbrot program
@ 2009-09-27  1:08  5% Georg Bauhaus
    0 siblings, 1 reply; 200+ results
From: Georg Bauhaus @ 2009-09-27  1:08 UTC (permalink / raw)


A Mandelbrot program has been submitted to the language
Shootout by Jim Rogers, Pascal Obry, and
Gautier de Montmollin.  Given the no tricks approach
that it shares with other entries, it is performing
well, I'd think.  But, it is sequential.

The patch below adds tasking.

A few notes on patch:
The computation is split into parts, one per task;
many entries seem to use a similar approach.
The number of tasks is set high, task switching does
not seem to matter much in this program.
The alternative of making the environment task perform
the same subprogram as the tasks concurrently
and matching the number of tasks to the number of cores
was not significantly faster.  The alternative
spoils the simplicity of the main block, so I set
a higher number of tasks and got basically the same
performance.

Maybe these are possible improvements:

- Ada.Streams.Stream_IO? (In total absence of Text_IO,
  GNAT.IO performs well.)

- adjust compilation options to match the FPT hardware
  (type Real is now digits 16 because of this, cf.
  the spectral-norm entry at the Shootout)

Comments?  Can I ask what the authors think?


pragma Restrictions (No_Abort_Statements);
pragma Restrictions (Max_Asynchronous_Select_Nesting => 0);

with Ada.Command_Line; use Ada.Command_Line;
with Ada.Numerics.Generic_Complex_Types;

with Interfaces;       use Interfaces;
with GNAT.IO;          use GNAT.IO;


procedure Mandelbrot is
   type Real is digits 16;
   package R_Complex is new Ada.Numerics.Generic_Complex_Types (Real);
   use R_Complex;
   Iter           : constant := 50;
   Limit          : constant := 4.0;
   Size           : Positive;
   Zero           : constant Complex := (0.0, 0.0);
   Two_on_Size    : Real;

   subtype Output_Queue is String;
   type Output is access Output_Queue;

   task type X_Step is
      entry Compute_Z (Y1, Y2 : Natural);
      entry Get_Output (Result : out Output; Last : out Natural);
   end X_Step;

   procedure Allocate_Output_Queue (Y1, Y2 : Natural; Result : out Output);

   procedure Compute
     (Y1, Y2 : Natural; Result : Output; Last : out Natural)
   is
      Bit_Num     : Natural    := 0;
      Byte_Acc    : Unsigned_8 := 0;
      Z, C        : Complex;
   begin
      Last := 0;
      for Y in Y1 .. Y2 - 1 loop
         for X in 0 .. Size - 1 loop
            Z := Zero;
            C := Two_on_Size * (Real (X), Real (Y)) - (1.5, 1.0);

            declare
               Z2 : Complex;
            begin
               for I in 1 .. Iter + 1 loop
                  Z2 := (Z.re ** 2, Z.im ** 2);
                  Z  := (Z2.re - Z2.im, 2.0 * Z.re * Z.im) + C;
                  exit when Z2.re + Z2.im > Limit;
               end loop;

               if Z2.re + Z2.im > Limit then
                  Byte_Acc := Shift_Left (Byte_Acc, 1) or 16#00#;
               else
                  Byte_Acc := Shift_Left (Byte_Acc, 1) or 16#01#;
               end if;
            end;

            Bit_Num := Bit_Num + 1;

            if Bit_Num = 8 then
               Last := Last + 1;
               Result (Last) := Character'Val (Byte_Acc);
               Byte_Acc := 0;
               Bit_Num  := 0;
            elsif X = Size - 1 then
               Byte_Acc := Shift_Left (Byte_Acc, 8 - (Size mod 8));
               Last := Last + 1;
               Result (Last) := Character'Val (Byte_Acc);
               Byte_Acc := 0;
               Bit_Num  := 0;
            end if;
         end loop;
      end loop;
   end Compute;

   task body X_Step is
      Data        : Output;
      Pos         : Natural;
      Y1, Y2      : Natural;
   begin
      accept Compute_Z (Y1, Y2 : Natural) do
         X_Step.Y1 := Y1;
         X_Step.Y2 := Y2;
      end Compute_Z;

      Allocate_Output_Queue (Y1, Y2, Data);
      Compute (Y1, Y2, Data, Pos);

      accept Get_Output (Result : out Output; Last : out Natural) do
         Result := Data;
         Last := Pos;
      end Get_Output;
   end X_Step;

   procedure Allocate_Output_Queue (Y1, Y2 : Natural; Result : out
Output) is
   begin
      Result := new Output_Queue (1 .. (Y2 - Y1 + 8) * Size / 8);
   end Allocate_Output_Queue;


begin
   Size := Positive'Value (Argument (1));
   Two_on_Size := 2.0 / Real (Size);

   Put_Line ("P4");
   Put_Line (Argument (1) & " " & Argument (1));

   declare
      No_Of_Workers : constant := 16;
      Chunk_Size    : constant Positive :=
        (Size + No_Of_Workers) / No_Of_Workers;
      Pool          : array (0 .. No_Of_Workers) of X_Step;
      pragma          Assert (Pool'Length * Chunk_Size >= Size);
      Buffer        : Output;
      Last          : Natural;
   begin
      pragma Assert (Pool'First = 0);

      for P in Pool'Range loop
         Pool (P).Compute_Z
           (Y1 => P * Chunk_Size,
            Y2 => Positive'Min ((P + 1) * Chunk_Size, Size));
      end loop;

      for P in Pool'Range loop
         Pool (P).Get_Output (Buffer, Last);
         Put (Buffer (Buffer'First .. Last));
      end loop;
   end;

end Mandelbrot;



^ permalink raw reply	[relevance 5%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-24  1:11  6%                 ` Adam Beneschan
@ 2009-09-25 12:25  6%                   ` Stephen Leake
  0 siblings, 0 replies; 200+ results
From: Stephen Leake @ 2009-09-25 12:25 UTC (permalink / raw)


Adam Beneschan <adam@irvine.com> writes:

> On Sep 23, 5:31�pm, Bj�rn Persson <bj...@xn--rombobjrn-67a.se> wrote:
>
>> You might argue that programs that have their own pattern matching features
>> should use a different set of special characters to distinguish the patterns
>> from those that the shell expands, but that's a bad idea in my opinion.
>> Having multiple different syntaxes makes it hard to remember when to use
>> which syntax.
>
> Multiple syntaxes is a bad idea, but I've always wanted a way to add a
> flag to certain executables to tell the shell "don't expand wildcards
> when running this executable".  

That flag exists, but it's a shell feature, of course, since you are
telling the shell to not do something. It's called "quotes".

> Then you could actually write a command of the sort that exists on
> other OS's:
>
>    rename *.ada *.adb

rename "*.ada *.adb"

or 

rename "*.ada" "*.adb"

-- 
-- Stephe



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-24  0:31  6%               ` Björn Persson
@ 2009-09-24  1:11  6%                 ` Adam Beneschan
  2009-09-25 12:25  6%                   ` Stephen Leake
  0 siblings, 1 reply; 200+ results
From: Adam Beneschan @ 2009-09-24  1:11 UTC (permalink / raw)


On Sep 23, 5:31 pm, Björn Persson <bj...@xn--rombobjrn-67a.se> wrote:

> You might argue that programs that have their own pattern matching features
> should use a different set of special characters to distinguish the patterns
> from those that the shell expands, but that's a bad idea in my opinion.
> Having multiple different syntaxes makes it hard to remember when to use
> which syntax.

Multiple syntaxes is a bad idea, but I've always wanted a way to add a
flag to certain executables to tell the shell "don't expand wildcards
when running this executable".  Then you could actually write a
command of the sort that exists on other OS's:

   rename *.ada *.adb

(The shell wouldn't expand either parameter.  The "rename" program
would be responsible for searching for files that matched the first
parameter.  Ideally, this would be accomplished by a library routine
that the shell also uses when it does expand.)

                                    -- Adam



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-23 16:06  6%             ` Gautier write-only
@ 2009-09-24  0:31  6%               ` Björn Persson
  2009-09-24  1:11  6%                 ` Adam Beneschan
  0 siblings, 1 reply; 200+ results
From: Björn Persson @ 2009-09-24  0:31 UTC (permalink / raw)


Gautier write-only wrote:
> I was disturbed that unzip (maybe other tools ?) won't give a warning
> (maybe can't, because they can't know ?) when receiving the unexpanded
> '*.adb' and expands its way, using the zip archive's name list.

I don't understand what you think unzip should warn about. Warning about a 
strange looking filename with an asterisk in it makes no sense, as wildcards 
are a feature that has been added to unzip because it's useful.

You might argue that programs that have their own pattern matching features 
should use a different set of special characters to distinguish the patterns 
from those that the shell expands, but that's a bad idea in my opinion. 
Having multiple different syntaxes makes it hard to remember when to use 
which syntax.

-- 
Bj�rn Persson
PGP key A88682FD



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-23  1:07  6%           ` Adam Beneschan
  2009-09-23 13:03  5%             ` Hyman Rosen
@ 2009-09-23 16:06  6%             ` Gautier write-only
  2009-09-24  0:31  6%               ` Björn Persson
  1 sibling, 1 reply; 200+ results
From: Gautier write-only @ 2009-09-23 16:06 UTC (permalink / raw)


On 23 sep, 03:07, Adam Beneschan <a...@irvine.com> wrote:

> But did you read the rest of Hyman's sentence?  I just tested it too,
> and "unzip archive *.adb" WILL expand *.adb, if there any *.adb files
> existing in the current directory.

I was wrong, you are right. Just forgot to test *with* an .adb file
around...
I was disturbed that unzip (maybe other tools ?) won't give a warning
(maybe can't, because they can't know ?) when receiving the unexpanded
'*.adb' and expands its way, using the zip archive's name list.

Gautier



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-23  1:07  6%           ` Adam Beneschan
@ 2009-09-23 13:03  5%             ` Hyman Rosen
  2009-09-23 16:06  6%             ` Gautier write-only
  1 sibling, 0 replies; 200+ results
From: Hyman Rosen @ 2009-09-23 13:03 UTC (permalink / raw)


Adam Beneschan wrote:
> "Unix" is not a synonym for "Bourne shell".

Just to make things clear, all "normal" UNIX (and Linux)
shells will expand '*.adb' into a list of files if there
are files in the current directory which match the pattern.
They differ in what they do if there are no such files.
Bourne shell and its variants (ksh, bash, etc.) will pass
'*.adb' literally as an argument to the command. Csh and
its variants (tcsh, zsh, etc.) will issue an error message
and not execute the command at all. Some shells also allow
you to configure this behavior to taste.

For formalists who wonder why such a pattern shouldn't
"expand" to nothing when no files match, it's because UNIX
commands tend to be written to either process a list of files
or else standard input when no files are supplied.



^ permalink raw reply	[relevance 5%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-23  0:20  6%         ` Gautier write-only
@ 2009-09-23  1:07  6%           ` Adam Beneschan
  2009-09-23 13:03  5%             ` Hyman Rosen
  2009-09-23 16:06  6%             ` Gautier write-only
  0 siblings, 2 replies; 200+ results
From: Adam Beneschan @ 2009-09-23  1:07 UTC (permalink / raw)


On Sep 22, 5:20 pm, Gautier write-only <gautier_niou...@hotmail.com>
wrote:
> On 22 sep, 22:00, Hyman Rosen <hyro...@mail.com> wrote:
>
> > Gautier write-only wrote:
> > > There are exceptions to that. If you type:
> > > unzip archive.zip *.adb
> > > the "*.adb" will, even on Unix, fortunately *not* be expanded...
>
> > Why do you believe this to be true?
>
> Because I've tested it just before posting: Linux (Fedora 8), GNU bash
> 3.2.25.

But did you read the rest of Hyman's sentence?  I just tested it too,
and "unzip archive *.adb" WILL expand *.adb, if there any *.adb files
existing in the current directory.  And csh won't work whether or not
there are *.adb files.  So it's definitely not correct to say that
*.adb won't be expanded on Unix, because "Unix" is not a synonym for
"Bourne shell".


> But maybe there is a subtle difference between Linux and UNIX on that
> point ?

I don't think so.

                                -- Adam



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-22 20:00  6%       ` Hyman Rosen
@ 2009-09-23  0:20  6%         ` Gautier write-only
  2009-09-23  1:07  6%           ` Adam Beneschan
  0 siblings, 1 reply; 200+ results
From: Gautier write-only @ 2009-09-23  0:20 UTC (permalink / raw)


On 22 sep, 22:00, Hyman Rosen <hyro...@mail.com> wrote:
> Gautier write-only wrote:
> > There are exceptions to that. If you type:
> > unzip archive.zip *.adb
> > the "*.adb" will, even on Unix, fortunately *not* be expanded...
>
> Why do you believe this to be true?

Because I've tested it just before posting: Linux (Fedora 8), GNU bash
3.2.25.
But maybe there is a subtle difference between Linux and UNIX on that
point ?

Gautier



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-22 19:52  6%     ` Gautier write-only
@ 2009-09-22 20:00  6%       ` Hyman Rosen
  2009-09-23  0:20  6%         ` Gautier write-only
  0 siblings, 1 reply; 200+ results
From: Hyman Rosen @ 2009-09-22 20:00 UTC (permalink / raw)


Gautier write-only wrote:
> There are exceptions to that. If you type:
> unzip archive.zip *.adb
> the "*.adb" will, even on Unix, fortunately *not* be expanded...

Why do you believe this to be true? I believe that the *.adb will
only not be expanded if there happen to be no files in the current
directory which match that pattern, and even then, only in certain
kinds of shells. Those based on the c-shell can give you an error
and not execute the program at all.

If you don't want filename expansion in UNIX, just quote:
     unzip archive.zip "*.adb"



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-16 18:43 11%   ` Keith Thompson
@ 2009-09-22 19:52  6%     ` Gautier write-only
  2009-09-22 20:00  6%       ` Hyman Rosen
  0 siblings, 1 reply; 200+ results
From: Gautier write-only @ 2009-09-22 19:52 UTC (permalink / raw)


On 16 Sep., 20:43, Keith Thompson <ks...@mib.org> wrote:

[about names with wildcards expanded or not into separate arguments]

> The behavior you describe has nothing to do with the compiler, at
> least not on Unix-like systems.  If you type
>     ./my_program *.adb
> in a Unix shell, my_program will see a list of file names; it will
> have no way to know that the list is the result of expanding a
> wildcard expression.  All the processing happens in the shell.  And of
> course programs can be invoked by other programs, not just by the
> shell.

There are exceptions to that. If you type:
unzip archive.zip *.adb
the "*.adb" will, even on Unix, fortunately *not* be expanded...

> On other systems, though, the Ada.Command_Line implementation might
> (optionally?) do some additional processing.

On Windows, the shell doesn't seem to do the expansion, but on the run-
time library side, GNAT does it and Aonix doesn't...
_________________________________________________________
Gautier's Ada programming -- http://sf.net/users/gdemont/
NB: For a direct answer, e-mail address on the Web site!



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-21 19:44  6%           ` sjw
@ 2009-09-22 11:01  6%             ` John McCabe
  0 siblings, 0 replies; 200+ results
From: John McCabe @ 2009-09-22 11:01 UTC (permalink / raw)


On Mon, 21 Sep 2009 12:44:15 -0700 (PDT), sjw <simon.j.wright@mac.com>
wrote:

>On Sep 21, 4:09�pm, John McCabe <j...@nospam.assen.demon.co.uk> wrote:
>
>> Really? Surely the language here is providing a layer of abstraction
>> from the operating system so it should be able to be definitive about
>> whether the program name should be included in the argument count or
>> the list of arguments in Ada.Command_Line?
>
>There's a very strong hint at the end of this page ...
>http://www.adaic.com/standards/05aarm/html/AA-A-15.html

While you're right of course, I just don't get a great feeling from
that chapter. Perhaps it would have been nice to have an explanation
at the point where it says 'the "number of arguments" is
implementation defined'.

Still, never mind.




^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-21 15:09 12%         ` John McCabe
  2009-09-21 15:17  6%           ` Dmitry A. Kazakov
@ 2009-09-21 19:44  6%           ` sjw
  2009-09-22 11:01  6%             ` John McCabe
  1 sibling, 1 reply; 200+ results
From: sjw @ 2009-09-21 19:44 UTC (permalink / raw)


On Sep 21, 4:09 pm, John McCabe <j...@nospam.assen.demon.co.uk> wrote:

> Really? Surely the language here is providing a layer of abstraction
> from the operating system so it should be able to be definitive about
> whether the program name should be included in the argument count or
> the list of arguments in Ada.Command_Line?

There's a very strong hint at the end of this page ...
http://www.adaic.com/standards/05aarm/html/AA-A-15.html



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-21 15:09 12%         ` John McCabe
@ 2009-09-21 15:17  6%           ` Dmitry A. Kazakov
  2009-09-21 19:44  6%           ` sjw
  1 sibling, 0 replies; 200+ results
From: Dmitry A. Kazakov @ 2009-09-21 15:17 UTC (permalink / raw)


On Mon, 21 Sep 2009 16:09:21 +0100, John McCabe wrote:

> On Fri, 18 Sep 2009 18:16:15 -0400, Robert A Duff
> <bobduff@shell01.TheWorld.com> wrote:
> 
>>>>> Does Argument_Count() return 3 or 4? I haven't looked at this
>>>>> paragraph in detail, or what surrounds it, but "the number of
>>>>> arguments passed to the program invoking the function" sounds a bit
>>>>> vague. Is the "program invoking the function" the shell, or the
>>>>> program you're running?
> 
>>>>3.
> 
>>>>The program you're running.
> 
>>> For all implementations?
> 
>>For all reasonable implementations.  It is possible to create a
>>conforming Ada implementation that does something weird, because
>>the RM leaves all this implementation-defined.  It has to, because
>>we can't know about all operating systems.
> 
> Really? Surely the language here is providing a layer of abstraction
> from the operating system so it should be able to be definitive about
> whether the program name should be included in the argument count or
> the list of arguments in Ada.Command_Line?

Yes, but it certainly not as an argument of. If this functionality has to
be supported then as a set of separate functions, like:

Get_Image_Name (the file containing the program image),
Get_Install_Name (the name used to invoke the program),
Get_Command_Line (the user input caused execution of this instance),
Get_Instance_Count (number of instances running)

etc.

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



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-18 22:16  6%       ` Robert A Duff
@ 2009-09-21 15:09 12%         ` John McCabe
  2009-09-21 15:17  6%           ` Dmitry A. Kazakov
  2009-09-21 19:44  6%           ` sjw
  0 siblings, 2 replies; 200+ results
From: John McCabe @ 2009-09-21 15:09 UTC (permalink / raw)


On Fri, 18 Sep 2009 18:16:15 -0400, Robert A Duff
<bobduff@shell01.TheWorld.com> wrote:

>>>> Does Argument_Count() return 3 or 4? I haven't looked at this
>>>> paragraph in detail, or what surrounds it, but "the number of
>>>> arguments passed to the program invoking the function" sounds a bit
>>>> vague. Is the "program invoking the function" the shell, or the
>>>> program you're running?

>>>3.

>>>The program you're running.

>> For all implementations?

>For all reasonable implementations.  It is possible to create a
>conforming Ada implementation that does something weird, because
>the RM leaves all this implementation-defined.  It has to, because
>we can't know about all operating systems.

Really? Surely the language here is providing a layer of abstraction
from the operating system so it should be able to be definitive about
whether the program name should be included in the argument count or
the list of arguments in Ada.Command_Line?




^ permalink raw reply	[relevance 12%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-18 15:03 12%     ` John McCabe
@ 2009-09-18 22:16  6%       ` Robert A Duff
  2009-09-21 15:09 12%         ` John McCabe
  0 siblings, 1 reply; 200+ results
From: Robert A Duff @ 2009-09-18 22:16 UTC (permalink / raw)


John McCabe <john@nospam.assen.demon.co.uk> writes:

> On Thu, 17 Sep 2009 22:12:17 -0700 (PDT), sjw <simon.j.wright@mac.com>
> wrote:
>
>>On Sep 17, 2:50�pm, John McCabe <j...@nospam.assen.demon.co.uk> wrote:
>>
>>> For example if, on the command line, I type:
>>>
>>> prog1.exe a b c
>>>
>>> Does Argument_Count() return 3 or 4? I haven't looked at this
>>> paragraph in detail, or what surrounds it, but "the number of
>>> arguments passed to the program invoking the function" sounds a bit
>>> vague. Is the "program invoking the function" the shell, or the
>>> program you're running?
>>
>>3.
>
>>The program you're running.
>
> For all implementations?

For all reasonable implementations.  It is possible to create a
conforming Ada implementation that does something weird, because
the RM leaves all this implementation-defined.  It has to, because
we can't know about all operating systems.  But for any operating
system that supports command-line arguments, you can count on the
Ada implementation NOT including the command name itself as one
of the arguments.

> I see that Ada.Command_Line.Command_Name returns the name of the
> program that's been run. On Gnat at least it all makes sense. Compared
> to C++ (MSVC) on Win32 for:
>
> printargs.exe 1 2 3
>
> I get..
>                Ada            C++
> Argument Count 3              4
> command name   printargs.exe  equiv. to argv[0]
> argument 1     1              1
> argument 2     2              2
> argument 3     3              3
>
> I guess, from the Annotated ARM, section A.15(22) & A.15(22a).

Right.

- Bob



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-18  5:12  6%   ` sjw
@ 2009-09-18 15:03 12%     ` John McCabe
  2009-09-18 22:16  6%       ` Robert A Duff
  0 siblings, 1 reply; 200+ results
From: John McCabe @ 2009-09-18 15:03 UTC (permalink / raw)


On Thu, 17 Sep 2009 22:12:17 -0700 (PDT), sjw <simon.j.wright@mac.com>
wrote:

>On Sep 17, 2:50�pm, John McCabe <j...@nospam.assen.demon.co.uk> wrote:
>
>> For example if, on the command line, I type:
>>
>> prog1.exe a b c
>>
>> Does Argument_Count() return 3 or 4? I haven't looked at this
>> paragraph in detail, or what surrounds it, but "the number of
>> arguments passed to the program invoking the function" sounds a bit
>> vague. Is the "program invoking the function" the shell, or the
>> program you're running?
>
>3.

>The program you're running.

For all implementations?

I see that Ada.Command_Line.Command_Name returns the name of the
program that's been run. On Gnat at least it all makes sense. Compared
to C++ (MSVC) on Win32 for:

printargs.exe 1 2 3

I get..
               Ada            C++
Argument Count 3              4
command name   printargs.exe  equiv. to argv[0]
argument 1     1              1
argument 2     2              2
argument 3     3              3

I guess, from the Annotated ARM, section A.15(22) & A.15(22a).






^ permalink raw reply	[relevance 12%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-17 13:50  6% ` John McCabe
@ 2009-09-18  5:12  6%   ` sjw
  2009-09-18 15:03 12%     ` John McCabe
  0 siblings, 1 reply; 200+ results
From: sjw @ 2009-09-18  5:12 UTC (permalink / raw)


On Sep 17, 2:50 pm, John McCabe <j...@nospam.assen.demon.co.uk> wrote:

> For example if, on the command line, I type:
>
> prog1.exe a b c
>
> Does Argument_Count() return 3 or 4? I haven't looked at this
> paragraph in detail, or what surrounds it, but "the number of
> arguments passed to the program invoking the function" sounds a bit
> vague. Is the "program invoking the function" the shell, or the
> program you're running?

3.

The program you're running.



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-15 20:58  6% Ada.Command_Line.Argument_Count question 
                   ` (2 preceding siblings ...)
  2009-09-16 10:41  6% ` Jeffrey R. Carter
@ 2009-09-17 13:50  6% ` John McCabe
  2009-09-18  5:12  6%   ` sjw
  3 siblings, 1 reply; 200+ results
From: John McCabe @ 2009-09-17 13:50 UTC (permalink / raw)


On Tue, 15 Sep 2009 22:58:49 +0200, Thomas L�cke <"tl at ada-dk.org">
wrote:

>The RM has this to say about Argument_Count:
>
>"If the external execution environment supports passing arguments to a 
>program, then Argument_Count returns the number of arguments passed to 
>the program invoking the function. Otherwise it returns 0. The meaning 
>of �number of arguments� is implementation defined."
>
>I'm wondering what that last sentence mean? Is the RM trying to tell me 
>that Argument_Count cannot be trusted to yield the same result on 
>different systems (Unix, BSD, Windows, Linux and so on)?
>
>Or am I missing the point?

Are you also thinking of whether the program itself counts as an
argument?

For example if, on the command line, I type:

prog1.exe a b c

Does Argument_Count() return 3 or 4? I haven't looked at this
paragraph in detail, or what surrounds it, but "the number of
arguments passed to the program invoking the function" sounds a bit
vague. Is the "program invoking the function" the shell, or the
program you're running?

John



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-15 21:37 13% ` Gautier write-only
  2009-09-16  6:21  6%   ` 
@ 2009-09-16 18:43 11%   ` Keith Thompson
  2009-09-22 19:52  6%     ` Gautier write-only
  1 sibling, 1 reply; 200+ results
From: Keith Thompson @ 2009-09-16 18:43 UTC (permalink / raw)


Gautier write-only <gautier_niouzes@hotmail.com> writes:
> On 15 sep, 22:58, Thomas Løcke wrote:
>> The RM has this to say about Argument_Count:
>> "If the external execution environment supports passing arguments to a
>> program, then Argument_Count returns the number of arguments passed to
>> the program invoking the function. Otherwise it returns 0. The meaning
>> of “number of arguments” is implementation defined."
>>
>> I'm wondering what that last sentence mean? Is the RM trying to tell me
>> that Argument_Count cannot be trusted to yield the same result on
>> different systems (Unix, BSD, Windows, Linux and so on)?
>
> Perhaps... And it the behaviour is compiler-dependent too!
> Some systems will give 2 for ["a b" c]; others, 3 (maybe only DOS on
> that!).
> Some compilers will always return [*.adb] as is, others (GNAT) will
> return one argument for each file corresponding to that pattern, or
> still "*.adb" if there is no such file!
[...]

The behavior you describe has nothing to do with the compiler, at
least not on Unix-like systems.  If you type
    ./my_program *.adb
in a Unix shell, my_program will see a list of file names; it will
have no way to know that the list is the result of expanding a
wildcard expression.  All the processing happens in the shell.  And of
course programs can be invoked by other programs, not just by the
shell.

On other systems, though, the Ada.Command_Line implementation might
(optionally?) do some additional processing.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"



^ permalink raw reply	[relevance 11%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-15 20:58  6% Ada.Command_Line.Argument_Count question 
  2009-09-15 21:37 13% ` Gautier write-only
  2009-09-15 21:55  4% ` Adam Beneschan
@ 2009-09-16 10:41  6% ` Jeffrey R. Carter
  2009-09-17 13:50  6% ` John McCabe
  3 siblings, 0 replies; 200+ results
From: Jeffrey R. Carter @ 2009-09-16 10:41 UTC (permalink / raw)


Thomas L�cke wrote:
> 
> I'm wondering what that last sentence mean? Is the RM trying to tell me 
> that Argument_Count cannot be trusted to yield the same result on 
> different systems (Unix, BSD, Windows, Linux and so on)?

Consider the argument list

/a/b/c

On some systems, this is 3 arguments: "a", "b", and "c". '/' is used to 
introduce an argument.

On other systems, this is a single argument representing an absolute file path. 
'/' is the directory separator.

On yet other systems, this might be interpreted in a completely different way.

-- 
Jeff Carter
"My dear Mrs. Hemoglobin, when I first saw you, I
was so enamored with your beauty I ran to the basket,
jumped in, went down to the city, and bought myself a
wedding outfit."
Never Give a Sucker an Even Break
111



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-15 21:37 13% ` Gautier write-only
@ 2009-09-16  6:21  6%   ` 
  2009-09-16 18:43 11%   ` Keith Thompson
  1 sibling, 0 replies; 200+ results
From:  @ 2009-09-16  6:21 UTC (permalink / raw)


Gautier write-only wrote:
> Perhaps... And it the behaviour is compiler-dependent too!
> Some systems will give 2 for ["a b" c]; others, 3 (maybe only DOS on
> that!).
> Some compilers will always return [*.adb] as is, others (GNAT) will
> return one argument for each file corresponding to that pattern, or
> still "*.adb" if there is no such file!

Just as I thought, and feared.   :D

Thank you very much for the help Gautier.

-- 
Regards,
Thomas L�cke

Email: tl at ada-dk.org
Web: http:ada-dk.org
IRC nick: ThomasLocke



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-15 21:55  4% ` Adam Beneschan
@ 2009-09-16  6:20  6%   ` 
  0 siblings, 0 replies; 200+ results
From:  @ 2009-09-16  6:20 UTC (permalink / raw)


Adam Beneschan wrote:
> You can probably trust that Argument_Count will give the same result
> on any Unix, BSD, Linux, or other Unix-like OS (Solaris, HP-UX, IRIX,
> etc.), since the mechanisms that the shell uses for passing arguments
> to programs is the same for all of them.  This is assuming the shells
> handle the argument lines the same way.  Obviously, different shells
> don't parse things the same way.  In fact, you have to be careful
> about how you define "yield the same result"---yield the same result
> under what conditions??  If you type the command
> 
>    application {file1,file2,file3}.dat
> 
> the argument count should be 3 if the shell interprets the curly
> braces to convert the line to "file1.dat file2.dat file3.dat", but 1
> if it doesn't (older Bourne shells don't).  So you could get a
> different Argument_Count even on the *same* system, if you use the
> same command line in a different shell.
> 
> Windows uses a totally different "shell" (Command Prompt) so you can't
> expect it to work the same.  In practice, I don't believe Windows
> breaks down the command line at all (maybe later versions do, I'm not
> sure); it just makes the whole argument string available to the
> program as one string (via GetCommandLine).  It's up to the
> implementation to determine what to do with this string.
> 
> 
>> Or am I missing the point?
> 
> Possibly.  The reason the meaning of "number of arguments" is
> implementation-defined is that the language says nothing at all about
> what an "argument" is or how it gets into the program.  The language
> can't even assume that "arguments" will be passed in from a "command
> line"; they could be passed in from separate boxes in a GUI window, or
> created in an array by another program that executes the application,
> or set up by rotating dials manually on a control panel for all we
> know.

Adam, thank you for this very thorough explanation.

I guess this means that program arguments should be treated as slippery 
litlle buggers, who cannot be trusted.  :o)

-- 
Regards,
Thomas L�cke

Email: tl at ada-dk.org
Web: http:ada-dk.org
IRC nick: ThomasLocke



^ permalink raw reply	[relevance 6%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-15 20:58  6% Ada.Command_Line.Argument_Count question 
  2009-09-15 21:37 13% ` Gautier write-only
@ 2009-09-15 21:55  4% ` Adam Beneschan
  2009-09-16  6:20  6%   ` 
  2009-09-16 10:41  6% ` Jeffrey R. Carter
  2009-09-17 13:50  6% ` John McCabe
  3 siblings, 1 reply; 200+ results
From: Adam Beneschan @ 2009-09-15 21:55 UTC (permalink / raw)


On Sep 15, 1:58 pm, Thomas Løcke <"tl at ada-dk.org"> wrote:
> The RM has this to say about Argument_Count:
>
> "If the external execution environment supports passing arguments to a
> program, then Argument_Count returns the number of arguments passed to
> the program invoking the function. Otherwise it returns 0. The meaning
> of “number of arguments” is implementation defined."
>
> I'm wondering what that last sentence mean? Is the RM trying to tell me
> that Argument_Count cannot be trusted to yield the same result on
> different systems (Unix, BSD, Windows, Linux and so on)?

You can probably trust that Argument_Count will give the same result
on any Unix, BSD, Linux, or other Unix-like OS (Solaris, HP-UX, IRIX,
etc.), since the mechanisms that the shell uses for passing arguments
to programs is the same for all of them.  This is assuming the shells
handle the argument lines the same way.  Obviously, different shells
don't parse things the same way.  In fact, you have to be careful
about how you define "yield the same result"---yield the same result
under what conditions??  If you type the command

   application {file1,file2,file3}.dat

the argument count should be 3 if the shell interprets the curly
braces to convert the line to "file1.dat file2.dat file3.dat", but 1
if it doesn't (older Bourne shells don't).  So you could get a
different Argument_Count even on the *same* system, if you use the
same command line in a different shell.

Windows uses a totally different "shell" (Command Prompt) so you can't
expect it to work the same.  In practice, I don't believe Windows
breaks down the command line at all (maybe later versions do, I'm not
sure); it just makes the whole argument string available to the
program as one string (via GetCommandLine).  It's up to the
implementation to determine what to do with this string.


> Or am I missing the point?

Possibly.  The reason the meaning of "number of arguments" is
implementation-defined is that the language says nothing at all about
what an "argument" is or how it gets into the program.  The language
can't even assume that "arguments" will be passed in from a "command
line"; they could be passed in from separate boxes in a GUI window, or
created in an array by another program that executes the application,
or set up by rotating dials manually on a control panel for all we
know.

                               -- Adam




^ permalink raw reply	[relevance 4%]

* Re: Ada.Command_Line.Argument_Count question
  2009-09-15 20:58  6% Ada.Command_Line.Argument_Count question 
@ 2009-09-15 21:37 13% ` Gautier write-only
  2009-09-16  6:21  6%   ` 
  2009-09-16 18:43 11%   ` Keith Thompson
  2009-09-15 21:55  4% ` Adam Beneschan
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 200+ results
From: Gautier write-only @ 2009-09-15 21:37 UTC (permalink / raw)


On 15 sep, 22:58, Thomas Løcke wrote:
> The RM has this to say about Argument_Count:
>
> "If the external execution environment supports passing arguments to a
> program, then Argument_Count returns the number of arguments passed to
> the program invoking the function. Otherwise it returns 0. The meaning
> of “number of arguments” is implementation defined."
>
> I'm wondering what that last sentence mean? Is the RM trying to tell me
> that Argument_Count cannot be trusted to yield the same result on
> different systems (Unix, BSD, Windows, Linux and so on)?

Perhaps... And it the behaviour is compiler-dependent too!
Some systems will give 2 for ["a b" c]; others, 3 (maybe only DOS on
that!).
Some compilers will always return [*.adb] as is, others (GNAT) will
return one argument for each file corresponding to that pattern, or
still "*.adb" if there is no such file!
Always interesting to test a bit with that:

-- Displays the arguments given

with Ada.Command_Line;                  use Ada.Command_Line;
with Ada.Text_IO;                       use Ada.Text_IO;

procedure Args is
begin
  for I in 1..Argument_Count loop
    Put_Line(Integer'Image(I) & " [" & Argument(I) & ']');
  end loop;
  Put("Press Enter"); Skip_Line;
end;

Cheers
_________________________________________________________
Gautier's Ada programming -- http://sf.net/users/gdemont/
NB: For a direct answer, e-mail address on the Web site!



^ permalink raw reply	[relevance 13%]

* Ada.Command_Line.Argument_Count question
@ 2009-09-15 20:58  6% 
  2009-09-15 21:37 13% ` Gautier write-only
                   ` (3 more replies)
  0 siblings, 4 replies; 200+ results
From:  @ 2009-09-15 20:58 UTC (permalink / raw)


The RM has this to say about Argument_Count:

"If the external execution environment supports passing arguments to a 
program, then Argument_Count returns the number of arguments passed to 
the program invoking the function. Otherwise it returns 0. The meaning 
of �number of arguments� is implementation defined."

I'm wondering what that last sentence mean? Is the RM trying to tell me 
that Argument_Count cannot be trusted to yield the same result on 
different systems (Unix, BSD, Windows, Linux and so on)?

Or am I missing the point?

-- 
Regards,
Thomas L�cke

Email: tl at ada-dk.org
Web: http:ada-dk.org
IRC nick: ThomasLocke



^ permalink raw reply	[relevance 6%]

* C++ threads vs. Ada tasks - surprised
@ 2009-08-16 21:34  4% Maciej Sobczak
  0 siblings, 0 replies; 200+ results
From: Maciej Sobczak @ 2009-08-16 21:34 UTC (permalink / raw)


In another thread (pun intended) the discussion on language design
with regard to threads/tasks got obstructed, so I'm starting a new
one.

An important point that was discussed there was the potential gain
from having tasking built-in the language. I have argued that there is
none *functional* gain (there is an obvious gain in readability,
though), or rather that all compiler tricks can be performed with
standard API as well.

As I'm a pragmatist and had a couple of free minutes to spend, I have
written a very simple "benchmark" that uses a shared buffer with
capacity 1 (a unit buffer) and two tasks, one putting values into the
buffer and one consuming them. The idea was to test the performance of
synchronization and condition checks.
A special value in the buffer is used to finish the whole program (the
"poison pill" concept from another thread) and since only two
different values are needed, a Boolean type was used.
The number of iterations is given as an argument to the program (no
error checking is made as it is not the point here).

I have also written an equivalent program in C++ with the direct use
of POSIX threads API (again, no checks, etc.).

To be frank: I have expected to see the C++ version being a hell lot
of faster, as the Ada tasking model is conceptually much more complex
and therefore I have expected tons of overhead there.
My expectations were wrong, as the Ada version proved to be ~2x faster
on my machine (with GNAT 4.4.0 and g++ 4.4.0, taken from the same
package, both versions compiled with -O2).

I have no idea how to explain this other than with the "task morph"
that is allowed by standard to happen when calling protected entries,
so that the entry call is actually executed not by the task that is
calling and waiting, but rather by the task that happened to open the
relevant barrier. This could, in principle, reduce the number of
thread switches.
I would very much welcome an insight from some GNAT implementers to
confirm if that was actually possible here.

After this exercise I have no choice (frankly) than to admit that
built-in threading support is better *also* in terms of performance.
Damned benchmarks... ;-)

For the sake of completeness, here are the complete sources for both
versions. I welcome any suggestions for improving them, there is
always some possibility that I got something totally wrong...
(note: error checking was omitted by intention and both programs
*must* be called with a single positive parameter as the number of
iterations)

-- Ada version:
with Ada.Command_Line;
with Ada.Text_IO;

procedure Test is

   Iterations : Positive := Positive'Value
     (Ada.Command_Line.Argument (1));

   protected Buffer is
      entry Put (X : in Boolean);
      entry Get (X : out Boolean);
   private
      Value : Boolean;
      Full : Boolean := False;
   end Buffer;

   protected body Buffer is
      entry Put (X : in Boolean) when not Full is
      begin
         Value := X;
         Full := True;
      end Put;
      entry Get (X : out Boolean) when Full is
      begin
         X := Value;
         Full := False;
      end Get;
   end Buffer;

   task Producer;
   task body Producer is
   begin
      for I in 1 .. Iterations - 1 loop
         Buffer.Put (False);
      end loop;
      Buffer.Put (True);
   end Producer;

   task Consumer;
   task body Consumer is
      X : Boolean;
      Count : Natural := 0;
   begin
      loop
         Buffer.Get (X);
         Count := Count + 1;
         exit when X;
      end loop;
      Ada.Text_IO.Put_Line
        ("Executed " & Natural'Image (Count) & " iterations");
   end Consumer;

begin
   null;
end Test;

// C++ version (for POSIX systems):
#include <iostream>
#include <sstream>
#include <pthread.h>

class Buffer
{
public:
    Buffer()
    {
        pthread_mutex_init(&mtx_, NULL);
        pthread_cond_init(&full_, NULL);
        pthread_cond_init(&empty_, NULL);

        is_full_ = false;
    }

    ~Buffer()
    {
        pthread_mutex_destroy(&mtx_);
        pthread_cond_destroy(&full_);
        pthread_cond_destroy(&empty_);
    }

    void put(bool x)
    {
        pthread_mutex_lock(&mtx_);
        while (is_full_)
        {
            pthread_cond_wait(&empty_, &mtx_);
        }

        value_ = x;
        is_full_ = true;

        pthread_cond_signal(&full_);
        pthread_mutex_unlock(&mtx_);
    }

    void get(bool & x)
    {
        pthread_mutex_lock(&mtx_);
        while (not is_full_)
        {
            pthread_cond_wait(&full_, &mtx_);
        }

        x = value_;
        is_full_ = false;

        pthread_cond_signal(&empty_);
        pthread_mutex_unlock(&mtx_);
    }

private:
    bool value_;
    bool is_full_;

    pthread_mutex_t mtx_;
    pthread_cond_t full_;
    pthread_cond_t empty_;
};

Buffer buf;

int iterations;

void * producer(void *)
{
    for (int i = 0; i != iterations - 1; ++i)
    {
        buf.put(false);
    }
    buf.put(true);

    return NULL;
}

void * consumer(void *)
{
    int count = 0;
    bool x;
    while (true) {
        buf.get(x);
        ++count;
        if (x)
        {
            break;
        }
    }

    std::cout << "Executed " << count
        << " iterations" << std::endl;

    return NULL;
}

int main(int argc, char * argv[])
{
    std::istringstream ss(argv[1]);
    ss >> iterations;

    pthread_t producer_th;
    pthread_t consumer_th;

    pthread_create(&producer_th, NULL, producer, NULL);
    pthread_create(&consumer_th, NULL, consumer, NULL);

    pthread_join(producer_th, NULL);
    pthread_join(consumer_th, NULL);
}

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



^ permalink raw reply	[relevance 4%]

* Wilcards in Linux (was: Interpretation of extensions different from Unix/Linux?)
  @ 2009-08-14  6:13  7%       ` stefan-lucks
  0 siblings, 0 replies; 200+ results
From: stefan-lucks @ 2009-08-14  6:13 UTC (permalink / raw)


On Fri, 14 Aug 2009, Randy Brukardt wrote:

> "vlc" <just.another.spam.account@googlemail.com> wrote in message 
> news:8a5f3b98-1c5a-4d47-aca7-e106d1223fa9@a26g2000yqn.googlegroups.com...
> ...
> >If the specifications are different, the utilities in Ada.Directories
> >are quite unusable for UNIX/Linux.
> 
> I think you are seriously confused about how this stuff works in Unix. 
> (Either that, or I'm getting senile... ;-)

I wouldn't suggest that. I am working on a linux computer, and I thought 
you where right. But when trying out (Suse Linux 11.0), I was cought by 
suprise. 

First, the behaviour of "rm *.c":

--> start

stef@linux-3fdp:~/Post/TEST> ls -a
.  ..
stef@linux-3fdp:~/Post/TEST> touch x.c
stef@linux-3fdp:~/Post/TEST> touch y.c
stef@linux-3fdp:~/Post/TEST> touch .c
stef@linux-3fdp:~/Post/TEST> ls
x.c  y.c
stef@linux-3fdp:~/Post/TEST> ls -a
.  ..  .c  x.c  y.c
stef@linux-3fdp:~/Post/TEST> rm *.c
stef@linux-3fdp:~/Post/TEST> ls -a
.  ..  .c

<-- stop

Oops, ".c" hasn't been removed! 

Is there something special with predefined or builtin commands, such as 
"rm"? Just write a little command yourself:

--> start

with Ada.Command_Line; with Ada.Text_IO; 
use Ada;

procedure Repeat_Command is
begin
   Text_IO.Put_Line(Natural'Image(Command_Line.Argument_Count));
   for I in 1 .. Command_Line.Argument_Count loop
      Text_IO.Put_Line(Command_Line.Argument(I));
   end loop;
   Text_IO.Put_Line("----------");
end Repeat_Command;
 
<-- stop

Now, call this program with "*.c":

--> start

stef@linux-3fdp:~/Post/TEST> touch x.c
stef@linux-3fdp:~/Post/TEST> touch y.c
linux-3fdp:~/Post/TEST> ./repeat_command
 0
----------
linux-3fdp:~/Post/TEST> ./repeat_command *.c
 2
x.c
y.c
----------

<--stop

The file ".c" was still there, but the shell just called 
"repeat_command x.c y.c", ignoring the file ".c". 

I tried with different shells, including csh and sh. It was the same, 
everywhere. Apparently, "vlc" is right. 

On the other hand, I wonder where this feature has been documented -- the 
docs I found clearly defined the "*" wildcard to represent a string of any 
length, including zero. 

There appears to be a special rule if the zero-string is followed by a 
".", but where is it documented?

Just to verify that "*" _can_ represent a zero-length string:

--> start

linux-3fdp:~/Post/TEST> ./repeat_command repeat_command*
 5
repeat_command
repeat_command.adb
repeat_command.adb~
repeat_command.ali
repeat_command.o
----------

<--stop

-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[relevance 7%]

* Re: unsigned type
  @ 2009-06-29 20:19  5%       ` anon
  0 siblings, 0 replies; 200+ results
From: anon @ 2009-06-29 20:19 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 2388 bytes --]


        Wrong re-read RM 3.5 (8) An Empty string may be a "Null range" string 
but zero ( 0 ) is not within the subtype of the Positive type. The second 
sentence of RM 3.5 ( 8 ) forces the index to be valid for all references 
including a null range statement.  Also, as I pointed out to Adam, about 
"Ada.Command_line" there may be other sections that may strengthen or may 
redefine RM 3.5 ( 8 ). 

        A : String ;
        ...
        A ( 1..1 ) -- is a valid string with a null range also equal 
                   -- to character reference of A ( 1 )  

        A ( 0..0 ) -- is not valid because the index range is not within 
                   -- the valid range of the subtype Postive. 
                   -- And at least the compiler should of trap the error.
                   -- Or is this a Compiler Bug!
  
RM 3.5
8   A range is compatible with a scalar subtype if and only if it is either a
null range or each bound of the range belongs to the range of the subtype.  A
range_constraint is compatible with a scalar subtype if and only if its range
is compatible with the subtype.


        And name calling show just how childless you are.



In <t43a2h.upd.ln@hunter.axlog.fr>, Jean-Pierre Rosen <rosen@adalog.fr> writes:
>anon a �crit :
>> For Strings:
>>                           --  'A' is a zero length string, A'Last = 0, and
>>                           --  put_line  ( A ( A'First .. A'Last ) ) ;
>>                           --  does not raise an Constraint_Error even though in  
>>                           --  this case it translate to:
>>                           --  put_line  ( A ( 0 .. 0 ) ) ; 
>>   A : String := ""        ; 
>> 
>> Since you can have zero length string , the index is Natual instead of Positive, 
>> because zero is in Natural but is not define in Positive. Even though the 
>> Standard package define String index as a Positive type. (GNAT)
>> 
>I usually refrain from responding to "anon", but this is so wrong that I
>have to... (Note: in French, "anon" is a young donkey; maybe that's
>where he got his name from...)
>
>The index of String is Positive, full stop. A'Last is 0 because null
>ranges are treated specially to avoid spurious Constraint_Error. See 3.5(8)
>-- 
>---------------------------------------------------------
>           J-P. Rosen (rosen@adalog.fr)
>Visit Adalog's web site at http://www.adalog.fr




^ permalink raw reply	[relevance 5%]

* Re: How to exit an Ada program with (unix shell) error code?
  @ 2009-05-15 10:20  5%   ` anon
  0 siblings, 0 replies; 200+ results
From: anon @ 2009-05-15 10:20 UTC (permalink / raw)


Well, Adam.  


   You did not take account that when the OS calls a program, it has the 
following format, and is the only way any program or an Ada RTS will have 
access to the command line arguments and environment list.  

( written in Ada type code, but normally written in C )

     --  OS uses:   
                Exit_Status := Application.all ( Argument_Count,
                                                 Argument_List,
                                                 Environment_List ) ;

     -- Calls an application ( any language: Ada, Cobol, Fortran, etc ).

     Now, if the language is Ada. The call is to the Ada RTS (normally created 
in the binding process) for the application , which in turn calls the user's 
"main subprogram". Then normally waits until user's "main subprogram" 
returns then the RTS returns a exit_status or return code to the OS.

     RM 10.2 (21) Since, the "implementation defined" requires a return code 
and uses this value as an exit_status. Ada must comply and return a 
exit_code. 


     But an Ada programmer can create their own RTS. And this partition can 
be called directly by the OS.  Just, compile and then link, and it will be ready 
to execute.
     
     In is Ada outline ( this type of Ada main subprogram can and is called 
directly by the OS ).  This is the basic outline produced by "GNATBIND" with 
the results in b~<file>.adb|s which are directly link to the OS.

        with System ;
        function Application ( Argument_Count   : Integer ;
                               Argument_List    : System.Address ;
                               Environment_List : System.Address )
                 return Integer is


             -- Should use "with Ada.Command_Line" instead of 
             -- using "pragma Import" but that's GNAT design

             gnat_argc : Integer;
             gnat_argv : System.Address;
             gnat_envp : System.Address;
             gnat_exit_status : Integer;
             pragma Import (C, gnat_argc);
             pragma Import (C, gnat_argv);
             pragma Import (C, gnat_envp);
             pragma Import (C, gnat_exit_status);


             procedure Adainit is 
              ...
             procedure Adafinal is
              ...

          begin
            -- set up Ada.Command_Line, if package is available
            gnat_argc := Argument_Count ;
            gnat_argv := Argument_List ;
            gnat_envp := Environment_List ;

            Adainit ;  -- preform elaboration

              --  statement for the core of the user's program
              --
              --  The binder in GNAT just calls the user subroutine
              --  by pragma Import.
              --  If the call is to a function, then it returns the
              --  exit status from that function. And some of 
              --  Ada_Command_Line links are not available.

            Adafinal ; -- preform finalization
            return gnat_exit_status ;
          end Application ;


     This information is also demonstrated in Xavier Gave's toy lovelace 
series in 2004.


Note: OS_Exit and OS_Abort requires the OS to shutdown the Ada RTS and 
other application's subtasks. And the finalization will not be preformed. 

Note: In the RM implementation is define as vendor or OS and OS 
      environments.


Martin.

The RM 10.2 (29) is also, under the "Implementation Permissions" which 
means that the vendor does not have to obey the RM 10.2 (29) rule. Its  
just a strong suggestion.

Binding process is referred to a process of creating an interface from Ada 
"main subprogram" to the "implementation execution environment" aka OS 
which normally done in two phases.  The first, is using a Binder program to 
build the interface routine. And the second is to link and edit the routines 
and required packages together to build the partition. And In the simplest 
form a "Binding Process" is just another name for the linking process.  








In <d30a0294-f9a2-43ec-9cae-777995001e6c@f1g2000prb.googlegroups.com>, Adam Beneschan <adam@irvine.com> writes:
>On May 13, 7:55 pm, a...@anon.org (anon) wrote:
>
>> Now, all OS's (AT&T OS port, Linux, and Windows) shell or application
>> loaders, calls a program using the following format:
>>
>>  Exit_Status := Application.all ( Augment_Count,
>>                                   Argument_List,
>>                                   Environment_List ) ;
>
>I'll have to bow out of this argument, because you're making arguments
>that I've already refuted multiple times, and you seem not to notice.
>In particular, you still seem to assume that the OS is going to call
>the Ada main subprogram directly, and I've dealt with this mistaken
>assumption at least twice already.  I don't feel like taking time
>repeating myself any more.  But I did want to point out a few places
>where you're reading something in the RM that isn't there:
>
>
>> This is defined from the "implementation's execution environment" which
>> RM 1.1.3 (6) states that if it is "impossible or impractical" then Ada
>> variations are permitted. Which states that all Ada partitions that are
>> executed under this type of OS which calls a program as a function shall
>> return a value aka Exit_Status.
>
>This is a huge stretch of interpretation.  This paragraph is saying,
>basically, that variations from the language are permitted if it's
>impossible to implement things the way the standard says in a
>particular execution environment; and you're interpreting this as a
>*requirement* that the result of a function used as a main subprogram
>must be an exit status.
>
>
>> Then you have RM 10.2 (21) which states that Ada must conform to the
>> "implementation's execution environment". By return an exit status
>> unless it terminates abnormally since it was called as a function.
>>
>> 10.2  (21) A call to the main subprogram, if the partition has one. If
>>            the main subprogram has parameters, they are passed; where
>>            the actuals come from is implementation defined. What
>>            happens to the result of a main function is also
>>            implementation defined.
>
>How does this state that "Ada must conform to the implementation's
>execution environment", as you say?  This paragraph doesn't even
>mention the execution environment.  All it says is that "what happens
>to the result of a main function is implementation defined", and the
>phrase "implementation defined" means pretty much "whatever the
>compiler writer chooses it to mean".  If you believe "implementation
>defined" means "determined in some way by the implementation's
>execution environment", or "required to conform to it", well then---
>sorry, you are just not familiar with commonly used computer
>terminology.
>
>
>> 1.1.3 (12) Any result returned or exception propagated from a main
>>            subprogram (see 10.2) or an exported subprogram (see
>>            Annex B) to an external caller;
>
>The effect of this paragraph is to define the result of a main
>subprogram as an "external interaction".  That's all it does.  The
>section of the RM is giving a definition of the term "external
>interaction".  It makes no statement about what the result should be.
>
>                                  -- Adam




^ permalink raw reply	[relevance 5%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-12 22:55  7%         ` Adam Beneschan
@ 2009-05-14  2:55  0%           ` anon
  0 siblings, 0 replies; 200+ results
From: anon @ 2009-05-14  2:55 UTC (permalink / raw)


Well, lets see. I did answer the original poster, Adam. It just that 
Martin suggest that functions are not portable and that where you 
came in.

Now, all OS's (AT&T OS port, Linux, and Windows) shell or application 
loaders, calls a program using the following format:

 Exit_Status := Application.all ( Augment_Count, 
                                  Argument_List, 
                                  Environment_List ) ;

This is defined from the "implementation's execution environment" which 
RM 1.1.3 (6) states that if it is "impossible or impractical" then Ada
variations are permitted. Which states that all Ada partitions that are 
executed under this type of OS which calls a program as a function shall 
return a value aka Exit_Status. 

The exception is where the program exits abnormally, such as an 
"unhanded exception" or using the two exit routines 
"System.OS_LIB.OS_Exit" and "System.OS_LIB.OS_Abort".

Also RM 1.1.3 (12), strengths these calling conversion and the normal 
function type of return value. 

Then you have RM 10.2 (21) which states that Ada must conform to the 
"implementation's execution environment". By return an exit status 
unless it terminates abnormally since it was called as a function. 

10.2  (21) A call to the main subprogram, if the partition has one. If 
           the main subprogram has parameters, they are passed; where 
           the actuals come from is implementation defined. What 
           happens to the result of a main function is also 
           implementation defined.

1.1.3 (12) Any result returned or exception propagated from a main 
           subprogram (see 10.2) or an exported subprogram (see 
           Annex B) to an external caller;

1.1.3 (6)  Contain no variations except those explicitly permitted by 
           this International Standard, or those that are impossible or 
           impractical to avoid given the implementation's execution 
           environment;


Note: Hope you had a fun holiday!!!


Also for Martin.

Can a user-created procedure (main subprogram) be concerned as a "public 
parameterless library procedures.  No! The reason is that the procedure 
is not public, it first must be bound by the binding process.

10.2  (29) An implementation may restrict the kinds of subprograms it 
           supports as main subprograms. However, an implementation is
           required to support all main subprograms that are public 
           parameterless library procedures.




In <d73c38a7-8d9b-447f-a462-2aac8630c45f@v23g2000pro.googlegroups.com>, Adam Beneschan <adam@irvine.com> writes:
>On May 8, 3:17 am, a...@anon.org (anon) wrote:
>
>[Note: I was out of town for a long weekend, for Mother's Day, and saw
>this post just today.]
>
>> Now, in the case of, Ada.Command_Line, RM A.15 (21) states:
>>
>> 21  An alternative declaration is allowed for package Command_Line if
>> different functionality is appropriate for the external execution
>> environment.
>
>OK, I wasn't aware of this.  But it doesn't help your case any.  In
>the post to which I was responding, you said:
>
>"And since there are times where the Ada.Command_Line package is
>not available, there has to be a way to send a 'exit status' to the OS
>in those case."
>
>If the OS is such that it expects programs to return an exit status,
>then certainly an alternative (or omitted) declaration of
>Ada.Command_Line that did not support Set_Exit_Status would not be
>"appropriate for the external execution environment".  (It would only
>be appropriate in cases where there is no real OS, or if there's a
>bare-bones OS that does not care about exit statuses.)  I think the
>point you're trying to make is that the language should *require*
>support for parameterless functions as main programs, but you still
>haven't demonstrated your point; ignoring cases where the vendor just
>plain screws up by providing an inappropriate version of Command_Line,
>you have not shown that there is ever a need to support main programs
>of this form.
>
>                              -- Adam




^ permalink raw reply	[relevance 0%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-08 10:17  7%       ` anon
@ 2009-05-12 22:55  7%         ` Adam Beneschan
  2009-05-14  2:55  0%           ` anon
  0 siblings, 1 reply; 200+ results
From: Adam Beneschan @ 2009-05-12 22:55 UTC (permalink / raw)


On May 8, 3:17 am, a...@anon.org (anon) wrote:

[Note: I was out of town for a long weekend, for Mother's Day, and saw
this post just today.]

> Now, in the case of, Ada.Command_Line, RM A.15 (21) states:
>
> 21  An alternative declaration is allowed for package Command_Line if
> different functionality is appropriate for the external execution
> environment.

OK, I wasn't aware of this.  But it doesn't help your case any.  In
the post to which I was responding, you said:

"And since there are times where the Ada.Command_Line package is
not available, there has to be a way to send a 'exit status' to the OS
in those case."

If the OS is such that it expects programs to return an exit status,
then certainly an alternative (or omitted) declaration of
Ada.Command_Line that did not support Set_Exit_Status would not be
"appropriate for the external execution environment".  (It would only
be appropriate in cases where there is no real OS, or if there's a
bare-bones OS that does not care about exit statuses.)  I think the
point you're trying to make is that the language should *require*
support for parameterless functions as main programs, but you still
haven't demonstrated your point; ignoring cases where the vendor just
plain screws up by providing an inappropriate version of Command_Line,
you have not shown that there is ever a need to support main programs
of this form.

                              -- Adam



^ permalink raw reply	[relevance 7%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-07 16:26  8%     ` Adam Beneschan
@ 2009-05-08 10:17  7%       ` anon
  2009-05-12 22:55  7%         ` Adam Beneschan
  0 siblings, 1 reply; 200+ results
From: anon @ 2009-05-08 10:17 UTC (permalink / raw)


First, the RM (Ada 2005).  There are places that allow a vendor to replace or 
alter and in some case even remove packages from the core Ada system. 
Note: Most packages allow a vendor to add to a package aka altering the 
package.

RM 1.1.2 ( 3, 17 ) states that section 13 is apart of the core that shall be 
include, but RM 13.8 (8) states that System.Machine_Code is not required 
aka it can be removed.

8  An implementation may place restrictions on code_statements. An
implementation is not required to provide package System.Machine_Code.


Now, in the case of, Ada.Command_Line, RM A.15 (21) states:

21  An alternative declaration is allowed for package Command_Line if
different functionality is appropriate for the external execution 
environment.

Now a program that is an OS or boot loader or Kernel/System module can be 
classified as having appropriate "external execution environment" that allows 
for an "alternative declaration" of the Ada.Command_Line package. Which 
allows the vendor to dis-allow the Ada.Command_Line as defined in 
RM A.15 (2-15) because in this package the Argument_Count, Argument, and 
Command_Name are not defined and they would not have a valid routine 
address for an OS or System Module type of "external execution environment" 
(illegal in Ada). 
Plus, using the returned value of a function (main subprogram) as the 
"exit_status" complies with the "alternative declaration" stated in the 
RM A.15 (21), which replaces the Ada.Command_Line.Set_Exit_Status 
routine with a function return.

So, a vendor can alter or even remove this package. Especially for those 
compiler that are use to write modules or OS type of programs.

But does this comply with RM 1.1.2 (17).  The answer is Yes, because  
RM A.15 (21) allows an "alternative declaration".



Now, If the main subprogram is a function the binder creates the binding 
routine like:

  function main

    -- temp storage for exit status returned from main subprogram
    Status : integer ;  

    begin
      Adainit ;
      Status := <User Main function> ; -- main subprogram 
      Adafinal ; 
      return Status ;  -- returns aka "exit status" from main subprogram  
    end ;

So if the main subprogram is a function the returned value is the "exit_status" 
is passed to the OS after Adafinal has preform finalization. 

And in some cases, elaboration is not needed which means AdaInit is not 
needed and in a few rare cases finalization is not necessary, which means 
the Status can be passed directly to the OS or program loading routine. In 
these types of programs the binder could create a optimization binder file 
as:

  function main

    begin
      return <User Main function> ; -- main subprogram 
    end ;


In <be920df0-fd82-481f-9899-e70d5a968b29@v35g2000pro.googlegroups.com>, Adam Beneschan <adam@irvine.com> writes:
>On May 7, 2:08 am, a...@anon.org (anon) wrote:
>> There are basic three types of programs for computers.
>>
>>         The first, are the "Stand-Alone" programs aka OS types, which do not
>>         return and have no needs for Ada.Command_Line routines.  In order
>>         words, there are no links for the Ada.Command_Line package and the
>>         Set_Exit_Status routine.
>>
>>         The second type are "Device Drivers" or "System/Kernel" installable
>>         "Modules".  And the Ada.Command_Line package is not legal. But the
>>         Kernel requires the "Module" to notify the kernel by using the
>>         "exit status" so that the kernel can know if it should reclaim the
>>         memory, etc, on errors. Using a "function" type of module install
>>         program is the only way a "Module" can be written and have an
>>         "exit status".
>>
>>         Note: Ada as a computer language should be allowed to create
>>               these type of programs which means that Ada needs to
>>               support main subprogram that are functions.
>
>But you're ignoring a point I already made.  Since library-level
>finalizations need to be done after the main subprogram is completed,
>the Ada main subprogram cannot exit directly to the OS.  Therefore it
>really doesn't matter whether Ada main subprograms can be functions or
>not.  For an OS that expects its program to return a status in its
>"function result" register, the requirement is that the code generated
>by the compiler, that *does* exit back to the OS, has to put a status
>in that register.  And there's no reason the compiler can't generate
>code that generates this status based on the parameter to the last
>Ada.Command_Line.Set_Exit_Status call (if any), whether or not the
>main subprogram is a function.  If you still think that
>Ada.Command_Line might not be available, read on.
>
>
>>         And since there are times where the Ada.Command_Line package is
>> not available
>
>Ada.Command_Line is defined in Annex A.  Please read RM 1.1.2(2-6) and
>1.1.2(17).  I'm surprised you'd say the above, since you're fond of
>saying there are only a couple of Ada compilers out there since a
>compiler that doesn't support all of the new Ada 2005 features is not
>an Ada compiler---well, a compiler that doesn't support all of Annex A
>(including Ada.Command_Line) is not an Ada compiler either, so why
>would you be concerned about that?
>
>                                 -- Adam




^ permalink raw reply	[relevance 7%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-07  9:08  8%   ` anon
@ 2009-05-07 16:26  8%     ` Adam Beneschan
  2009-05-08 10:17  7%       ` anon
  0 siblings, 1 reply; 200+ results
From: Adam Beneschan @ 2009-05-07 16:26 UTC (permalink / raw)


On May 7, 2:08 am, a...@anon.org (anon) wrote:
> There are basic three types of programs for computers.
>
>         The first, are the "Stand-Alone" programs aka OS types, which do not
>         return and have no needs for Ada.Command_Line routines.  In order
>         words, there are no links for the Ada.Command_Line package and the
>         Set_Exit_Status routine.
>
>         The second type are "Device Drivers" or "System/Kernel" installable
>         "Modules".  And the Ada.Command_Line package is not legal. But the
>         Kernel requires the "Module" to notify the kernel by using the
>         "exit status" so that the kernel can know if it should reclaim the
>         memory, etc, on errors. Using a "function" type of module install
>         program is the only way a "Module" can be written and have an
>         "exit status".
>
>         Note: Ada as a computer language should be allowed to create
>               these type of programs which means that Ada needs to
>               support main subprogram that are functions.

But you're ignoring a point I already made.  Since library-level
finalizations need to be done after the main subprogram is completed,
the Ada main subprogram cannot exit directly to the OS.  Therefore it
really doesn't matter whether Ada main subprograms can be functions or
not.  For an OS that expects its program to return a status in its
"function result" register, the requirement is that the code generated
by the compiler, that *does* exit back to the OS, has to put a status
in that register.  And there's no reason the compiler can't generate
code that generates this status based on the parameter to the last
Ada.Command_Line.Set_Exit_Status call (if any), whether or not the
main subprogram is a function.  If you still think that
Ada.Command_Line might not be available, read on.


>         And since there are times where the Ada.Command_Line package is
> not available

Ada.Command_Line is defined in Annex A.  Please read RM 1.1.2(2-6) and
1.1.2(17).  I'm surprised you'd say the above, since you're fond of
saying there are only a couple of Ada compilers out there since a
compiler that doesn't support all of the new Ada 2005 features is not
an Ada compiler---well, a compiler that doesn't support all of Annex A
(including Ada.Command_Line) is not an Ada compiler either, so why
would you be concerned about that?

                                 -- Adam



^ permalink raw reply	[relevance 8%]

* Re: How to exit an Ada program with (unix shell) error code?
  @ 2009-05-07  9:08  8%   ` anon
  2009-05-07 16:26  8%     ` Adam Beneschan
  0 siblings, 1 reply; 200+ results
From: anon @ 2009-05-07  9:08 UTC (permalink / raw)


There are basic three types of programs for computers.  

        The first, are the "Stand-Alone" programs aka OS types, which do not 
        return and have no needs for Ada.Command_Line routines.  In order 
        words, there are no links for the Ada.Command_Line package and the 
        Set_Exit_Status routine.

        The second type are "Device Drivers" or "System/Kernel" installable 
        "Modules".  And the Ada.Command_Line package is not legal. But the 
        Kernel requires the "Module" to notify the kernel by using the 
        "exit status" so that the kernel can know if it should reclaim the 
        memory, etc, on errors. Using a "function" type of module install 
        program is the only way a "Module" can be written and have an 
        "exit status".
 
        Note: Ada as a computer language should be allowed to create 
              these type of programs which means that Ada needs to 
              support main subprogram that are functions.

        The third is "Applications" programs but runs under a command shell, 
        which contains the links for the Ada.Command_Line package. Which 
        allow a program to use Ada.Command_Line.Set_Exit_Status routine. 
        But the RM does not force a programmer to use the Set_Exit_Status 
        in Ada.Command_Line package to return the "exit status"


Note: In GNAT, using a function for the main subprogram, the return value 
      of this function will be the "exit status". And if the program 
      uses the Ada.Command_Line.Set_Exit_Status routine the value is 
      discarded.


Then you have one of the "High Priority" concepts within the Ada language 
that is the "Safety and Security" concerns which make it illegal and against 
the RM for any Ada program to cause the OS or an external environment to 
become unstable. This includes, the execution of the Ada programs, or the 
result of its exiting. Now returning a "exit status" help keep the OS 
stable. Because the "exit status" can informs the OS if it needs to perform 
any error recovery processes on the resources used by the Ada program before 
reclaiming that resource, such as closing files that Ada can not close or 
reset devices that Ada has no knowledge of how to do.

        And since there are times where the Ada.Command_Line package is 
not available, there has to be a way to send a "exit status" to the OS 
in those case. The easiest is to use function type of "main subprograms" 
which returns the program "exit status".  One reason is if the Ada 
programmer, is using a "close source" Ada RTL there is no way of knowing 
how to perform a Set_Exit_Status for that version of Ada. 

Note: Is Ada becoming like C!!!! 

        Ada does allow some tricks that makes it more like C's nasty little 
tricks. Like using "pragma Import" and "pragma Export" within Ada to Ada 
packages which bypasses Ada package design structure is one. GNAT loves 
this one in the GNAT RTL. This also, can cause errors in the elaboration 
order which may result in other problems.

        Also, another one is in all of the GNAT programs (like gnatmake, 
gnatbind, gnatlink to name three) in the GNAT package are using a 
File_Descriptor type and direct to C type of IO routines which are defined 
in the System.OS_LIB or the older GNAT.OS_LIB package. These are not apart
of the RM.   Why did they not just use "File_Type" from either Ada.Text_IO, 
Ada.Direct_IO, or Ada.Sequential_IO standard Ada packages. All source files 
and the assembly translated output files can be handled by the Ada.Text_IO 
package. While the ALI files could use either Ada.Text_IO or 
Ada.Sequential_IO package. And as for the objects files, well in the 
GNAT design, all object files are created by the gcc "as", and are linked 
with either the gcc's "collect2" or "ld" be default. 

Note: There are options for other version of linkers, but GNATLINK 
defaufts to gcc's "collect2" or "ld". 

        Actually it seams that every year more and more trashy C routines 
and data types are inserted in the packages that GNAT wants programmers to 
use. Like the C file structure and routines in the System.OS_LIB package. 
Yes, some of those have been around for years, but by now Adacore should be
rewritting then to use pure RM Ada. And provide only a limited standard 
C and OS library routines, such as may be System.Sockets.  Plus, every year 
there are always additional C files, to be interfaces C libraries and OS to Ada. 
And I notice last year the GNAT GPL 2008 had one C file that replaced a 
couple of Ada routines that were in the GNAT GPL 2007. That's going away 
from Ada back to C, that's just WRONG!


In <356247f9-4a83-44aa-a412-4500e6af19cf@f1g2000prb.googlegroups.com>, Adam Beneschan <adam@irvine.com> writes:
>On May 5, 8:34 am, Jean-Pierre Rosen <ro...@adalog.fr> wrote:
>> Adam Beneschan a =E9crit :> Right; and even if your Ada compiler *does* s=
>upport functions that
>> > return integers as main programs, and you're compiling for some
>> > operating system with an "x" in its name (or Solaris), this does *not*
>> > mean that the Ada compiler will treat the function result as the
>> > status code.  The compiler could decide that the function result is
>> > something to be formatted and spit out onto standard output.  If an
>> > Ada implementation supports parameters and/or function results on main
>> > programs, the language leaves it up to the implementation how those
>> > are interpreted.  There's no rule that says that the interpretation
>> > has to mimic the behavior of the C language (thank God).  So anon's
>> > solution may work on GNAT, but it can't be assumed to work anywhere
>> > else.
>>
>> That's right from a legalistic point of view, but don't forget that
>> compiler writers are not masochists.
>
>That last statement might be tautologically false.  :) :) :)
>
>In any case, if you're implying that writing the extra code needed to
>get the program to display the function result on the standard output
>is an act of self-inflicted pain---trust me, it's nowhere near as
>painful as trying to understand and implement 3.10.2.
>
>
>> If an implementation supports
>> functions returning integers as main programs, I would be very surprised
>> if it was not interpreted as the return code, since this is what the
>> consumer would expect...
>
>Irvine Compiler's Ada compiler (the one I masochistically work on
>maintaining) does behave in the way I described.  Main subprograms can
>be procedures or functions; they can take parameters that are scalars
>or String (which are parsed from the command line); and they can be
>functions that return scalars or String, with the result being
>formatted and displayed on the standard output.  The compiler was
>originally written to run on Unix and VMS---and, by the way, I'm not
>sure that VMS supports the convention that a main program's function
>result becomes the return status (which is not a simple zero or non-
>zero as it is on Unix, if I recall correctly).  The compiler also runs
>on a variety of other targets, although the parameters and function
>result aren't supported in most cases.
>
>Surprised?  Well, the compiler is consistent across platforms and with
>respect to allowing various types to be used as function results.  It
>wouldn't make any sense to break consistency and make integer-
>returning functions on Unix-type platforms behave differently.  And
>nobody has ever complained about it.  As for whether it's what I'd
>expect if I were a consumer...  I'm not much of a C hack, but when I
>do use C I use exit() to set the status code, not "return", which
>seems to me to pervert the meaning of what a "function" and a function
>result should be; or as Georg said it, it's "playing tricks" with the
>language.  I don't feel any particular need to expect Ada compilers to
>support the same sort of trickery C programmers are used to.
>
>But that's just my opinion.
>
>                              -- Adam
>
>
>




^ permalink raw reply	[relevance 8%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-06  8:41  0%         ` anon
@ 2009-05-06  9:14  0%           ` Martin
  0 siblings, 0 replies; 200+ results
From: Martin @ 2009-05-06  9:14 UTC (permalink / raw)


On May 6, 9:41 am, a...@anon.org (anon) wrote:
> By your logic, who said procedures are portable!

Perhaps you could rephrase that into a meaning sentence?


>  Using RM 10.2 (29), a
> vendor could easily restrict the "main subprograms" to functions only.

No they can't - read the sentence begining "However". In fact, here it
is:

  "However, an implementation is required to support all main
   subprograms that are public parameterless library procedures."

Read it slowly. Read it repeatedly.

Here's a link to it:

http://www.adaic.org/standards/1zrm/html/RM-10-2.html


> And there is no definition in the RM that states a "main subprograms"
> subroutine must be a parameterless library procedure, either.

See above. Especially the link.


> So, its better to have and state that both subprogram types are portable. Then
> one can point out that the "main subprograms" that are procedures are more
> widely used in Ada.

That's would be lying, so probably better not to state this at all.



> In <948d6a6b-d603-4e38-add2-50016c2dc...@s20g2000vbp.googlegroups.com>, Martin <martin.do...@btopenworld.com> writes:
>
> >On May 5, 9:31=A0pm, a...@anon.org (anon) wrote:
> >> Martin.
>
> >> =A0 You misread RM 10.2 (29), its quoted below.
>
> >> Both of the subprograms types are valid and portable and even though
> >> RM 10.2 (29) allows a vendor to restrict the main subprogram. Adacore
> >> (GNAT) and IBM which follow the RM to the letter have decided to allow
> >> and support both main subprograms types in Ada 83/95/2005 specs.
>
> >> Note: At this time Adacore and IBM are the only ones supporting Ada 2005.
>
> >> Now, in the GNAT design the "GNATBIND" process actually wraps the main
> >> subprogram ( "procedure main" or a "function main return integer" ) withi=
> >n
> >> a function called "main" within a package called "ada_main". =A0And if th=
> >e
> >> "main" subprogram is a procedure, the binder function "main" calls this
> >> procedure and returns the exit status which is normally set to zero unles=
> >s it
> >> is altered by "Ada.Command_Line.Set_Exit_Status". But if main subprogram
> >> is a function type of partition, then the binder function "main" returns =
> >the
> >> value returned from the partition "function main" to the OS as the exit
> >> status. To see this, just compile any program and then bind it. Check the
> >> resulting output files "b~<name>.adb" and its spec file before linking.
>
> >> Note: normally during linking the linker "GNATLINK" deletes the
> >> binder source/object files.
>
> >> So both of these are valid in the RM. =A0It just that most programmers pr=
> >efer
> >> the "Procedure" type of partitions design.
>
> >> --
> >> -- main subprograms as a procedure
> >> --
> >> procedure main is
> >> =A0 begin -- main
> >> =A0 =A0 =A0null ;
> >> =A0 end main ;
> >> --
> >> -- or main subprograms as a public parameterless function
> >> --
> >> function main return integer is
> >> =A0 begin -- main
> >> =A0 =A0 =A0return ( 0 ) ; -- 0 :=3D normal exit status.
> >> =A0 end main ;
>
> >> Ada RM -- quoted
>
> >> =A0 RM 10.2 Program Execution
> >> =A0 =A0...
>
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Implementation Permiss=
> >ions
> >> =A0 =A0...
>
> >> 29 =A0 =A0An implementation may restrict the kinds of subprograms it supp=
> >orts as
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ------------
> >> main subprograms. However, an implementation is required to support all m=
> >ain
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
> >=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ----------------
> >> subprograms that are public parameterless library procedures.
> >> -----------
>
> >> =A0 RM 10.1 Separate Compilation
>
> >> 1 =A0 =A0 A program unit is either a package, a task unit, a protected un=
> >it, a
> >> protected entry, a generic unit, or an explicitly declared subprogram oth=
> >er
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
> >=A0 =A0------------------------------
> >> than an enumeration literal. Certain kinds of program units can be separa=
> >tely
> >> compiled. Alternatively, they can appear physically nested within other
> >> program units.
>
> >You forgot to underline the important bit - "procedures". Not
> >"subprograms", not "functions or procedures" - just "procedures". The
> >_only_ subprogram that _must_ be supported is:
>
> >   procedure <Main_Subprogram_Name> is
> >   ...
>
> >Yes an implementation is free to support other forms (including
> >functions) but they are not portable.
>
> >Lord only know why your quoting 10.1 - it's nothing to do with main
> >procedures.




^ permalink raw reply	[relevance 0%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-05 21:27  0%       ` Martin
@ 2009-05-06  8:41  0%         ` anon
  2009-05-06  9:14  0%           ` Martin
  0 siblings, 1 reply; 200+ results
From: anon @ 2009-05-06  8:41 UTC (permalink / raw)


By your logic, who said procedures are portable!  Using RM 10.2 (29), a 
vendor could easily restrict the "main subprograms" to functions only. 
And there is no definition in the RM that states a "main subprograms" 
subroutine must be a parameterless library procedure, either.

So, its better to have and state that both subprogram types are portable. Then 
one can point out that the "main subprograms" that are procedures are more 
widely used in Ada. 


In <948d6a6b-d603-4e38-add2-50016c2dcc9d@s20g2000vbp.googlegroups.com>, Martin <martin.dowie@btopenworld.com> writes:
>On May 5, 9:31=A0pm, a...@anon.org (anon) wrote:
>> Martin.
>>
>> =A0 You misread RM 10.2 (29), its quoted below.
>>
>> Both of the subprograms types are valid and portable and even though
>> RM 10.2 (29) allows a vendor to restrict the main subprogram. Adacore
>> (GNAT) and IBM which follow the RM to the letter have decided to allow
>> and support both main subprograms types in Ada 83/95/2005 specs.
>>
>> Note: At this time Adacore and IBM are the only ones supporting Ada 2005.
>>
>> Now, in the GNAT design the "GNATBIND" process actually wraps the main
>> subprogram ( "procedure main" or a "function main return integer" ) withi=
>n
>> a function called "main" within a package called "ada_main". =A0And if th=
>e
>> "main" subprogram is a procedure, the binder function "main" calls this
>> procedure and returns the exit status which is normally set to zero unles=
>s it
>> is altered by "Ada.Command_Line.Set_Exit_Status". But if main subprogram
>> is a function type of partition, then the binder function "main" returns =
>the
>> value returned from the partition "function main" to the OS as the exit
>> status. To see this, just compile any program and then bind it. Check the
>> resulting output files "b~<name>.adb" and its spec file before linking.
>>
>> Note: normally during linking the linker "GNATLINK" deletes the
>> binder source/object files.
>>
>> So both of these are valid in the RM. =A0It just that most programmers pr=
>efer
>> the "Procedure" type of partitions design.
>>
>> --
>> -- main subprograms as a procedure
>> --
>> procedure main is
>> =A0 begin -- main
>> =A0 =A0 =A0null ;
>> =A0 end main ;
>> --
>> -- or main subprograms as a public parameterless function
>> --
>> function main return integer is
>> =A0 begin -- main
>> =A0 =A0 =A0return ( 0 ) ; -- 0 :=3D normal exit status.
>> =A0 end main ;
>>
>> Ada RM -- quoted
>>
>> =A0 RM 10.2 Program Execution
>> =A0 =A0...
>>
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Implementation Permiss=
>ions
>> =A0 =A0...
>>
>> 29 =A0 =A0An implementation may restrict the kinds of subprograms it supp=
>orts as
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ------------
>> main subprograms. However, an implementation is required to support all m=
>ain
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
>=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ----------------
>> subprograms that are public parameterless library procedures.
>> -----------
>>
>> =A0 RM 10.1 Separate Compilation
>>
>> 1 =A0 =A0 A program unit is either a package, a task unit, a protected un=
>it, a
>> protected entry, a generic unit, or an explicitly declared subprogram oth=
>er
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
>=A0 =A0------------------------------
>> than an enumeration literal. Certain kinds of program units can be separa=
>tely
>> compiled. Alternatively, they can appear physically nested within other
>> program units.
>
>
>You forgot to underline the important bit - "procedures". Not
>"subprograms", not "functions or procedures" - just "procedures". The
>_only_ subprogram that _must_ be supported is:
>
>   procedure <Main_Subprogram_Name> is
>   ...
>
>Yes an implementation is free to support other forms (including
>functions) but they are not portable.
>
>Lord only know why your quoting 10.1 - it's nothing to do with main
>procedures.
>
>Cheers
>-- Martin




^ permalink raw reply	[relevance 0%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-05 20:31  4%     ` anon
@ 2009-05-05 21:27  0%       ` Martin
  2009-05-06  8:41  0%         ` anon
  0 siblings, 1 reply; 200+ results
From: Martin @ 2009-05-05 21:27 UTC (permalink / raw)


On May 5, 9:31 pm, a...@anon.org (anon) wrote:
> Martin.
>
>   You misread RM 10.2 (29), its quoted below.
>
> Both of the subprograms types are valid and portable and even though
> RM 10.2 (29) allows a vendor to restrict the main subprogram. Adacore
> (GNAT) and IBM which follow the RM to the letter have decided to allow
> and support both main subprograms types in Ada 83/95/2005 specs.
>
> Note: At this time Adacore and IBM are the only ones supporting Ada 2005.
>
> Now, in the GNAT design the "GNATBIND" process actually wraps the main
> subprogram ( "procedure main" or a "function main return integer" ) within
> a function called "main" within a package called "ada_main".  And if the
> "main" subprogram is a procedure, the binder function "main" calls this
> procedure and returns the exit status which is normally set to zero unless it
> is altered by "Ada.Command_Line.Set_Exit_Status". But if main subprogram
> is a function type of partition, then the binder function "main" returns the
> value returned from the partition "function main" to the OS as the exit
> status. To see this, just compile any program and then bind it. Check the
> resulting output files "b~<name>.adb" and its spec file before linking.
>
> Note: normally during linking the linker "GNATLINK" deletes the
> binder source/object files.
>
> So both of these are valid in the RM.  It just that most programmers prefer
> the "Procedure" type of partitions design.
>
> --
> -- main subprograms as a procedure
> --
> procedure main is
>   begin -- main
>      null ;
>   end main ;
> --
> -- or main subprograms as a public parameterless function
> --
> function main return integer is
>   begin -- main
>      return ( 0 ) ; -- 0 := normal exit status.
>   end main ;
>
> Ada RM -- quoted
>
>   RM 10.2 Program Execution
>    ...
>
>                          Implementation Permissions
>    ...
>
> 29    An implementation may restrict the kinds of subprograms it supports as
>                         ------------
> main subprograms. However, an implementation is required to support all main
>                                                             ----------------
> subprograms that are public parameterless library procedures.
> -----------
>
>   RM 10.1 Separate Compilation
>
> 1     A program unit is either a package, a task unit, a protected unit, a
> protected entry, a generic unit, or an explicitly declared subprogram other
>                                        ------------------------------
> than an enumeration literal. Certain kinds of program units can be separately
> compiled. Alternatively, they can appear physically nested within other
> program units.


You forgot to underline the important bit - "procedures". Not
"subprograms", not "functions or procedures" - just "procedures". The
_only_ subprogram that _must_ be supported is:

   procedure <Main_Subprogram_Name> is
   ...

Yes an implementation is free to support other forms (including
functions) but they are not portable.

Lord only know why your quoting 10.1 - it's nothing to do with main
procedures.

Cheers
-- Martin



^ permalink raw reply	[relevance 0%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-05 14:57  0%     ` Adam Beneschan
@ 2009-05-05 20:48  0%       ` anon
  0 siblings, 0 replies; 200+ results
From: anon @ 2009-05-05 20:48 UTC (permalink / raw)


Actually, Adam the design for all OS currectly use today states that if the 
program returns the "Accumulator Register" will contain the program exit 
code. Been a standard for at least 40 years.


In <62b174a9-c9c5-479c-9dd6-71916c102eb0@z16g2000prd.googlegroups.com>, Adam Beneschan <adam@irvine.com> writes:
>On May 5, 4:43 am, Martin <martin.do...@btopenworld.com> wrote:
>> On May 4, 5:09 pm, a...@anon.org (anon) wrote:
>>
>> > --
>> > --  Besides the Ada.Command_Line you can just use functions for
>> > --  the instead of procedures for your nain program. This design is
>> > --  great for application where Command_Line is not used.
>> > --
>>
>> > function work return Integer is
>>
>> >   begin
>> >     return ( 0 ) ; -- no error status code
>> >   end work ;
>>
>> Be aware that this is not portable. The only main subprogram that all
>> compilers must support (if they support a main subprogram) is "public
>> parameterless library procedures" (RM2005 10.2, 29 - previous RMs have
>> similar requirements), i.e.
>>
>>    procedure Main is
>>    ...
>>
>> Cheers
>> -- Martin
>
>
>Right; and even if your Ada compiler *does* support functions that
>return integers as main programs, and you're compiling for some
>operating system with an "x" in its name (or Solaris), this does *not*
>mean that the Ada compiler will treat the function result as the
>status code.  The compiler could decide that the function result is
>something to be formatted and spit out onto standard output.  If an
>Ada implementation supports parameters and/or function results on main
>programs, the language leaves it up to the implementation how those
>are interpreted.  There's no rule that says that the interpretation
>has to mimic the behavior of the C language (thank God).  So anon's
>solution may work on GNAT, but it can't be assumed to work anywhere
>else.
>
>                                -- Adam




^ permalink raw reply	[relevance 0%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-05 11:43  0%   ` Martin
  2009-05-05 14:57  0%     ` Adam Beneschan
@ 2009-05-05 20:31  4%     ` anon
  2009-05-05 21:27  0%       ` Martin
  1 sibling, 1 reply; 200+ results
From: anon @ 2009-05-05 20:31 UTC (permalink / raw)


Martin.

  You misread RM 10.2 (29), its quoted below.

Both of the subprograms types are valid and portable and even though 
RM 10.2 (29) allows a vendor to restrict the main subprogram. Adacore 
(GNAT) and IBM which follow the RM to the letter have decided to allow 
and support both main subprograms types in Ada 83/95/2005 specs.

Note: At this time Adacore and IBM are the only ones supporting Ada 2005.

Now, in the GNAT design the "GNATBIND" process actually wraps the main 
subprogram ( "procedure main" or a "function main return integer" ) within 
a function called "main" within a package called "ada_main".  And if the 
"main" subprogram is a procedure, the binder function "main" calls this 
procedure and returns the exit status which is normally set to zero unless it 
is altered by "Ada.Command_Line.Set_Exit_Status". But if main subprogram 
is a function type of partition, then the binder function "main" returns the 
value returned from the partition "function main" to the OS as the exit 
status. To see this, just compile any program and then bind it. Check the 
resulting output files "b~<name>.adb" and its spec file before linking. 

Note: normally during linking the linker "GNATLINK" deletes the 
binder source/object files.


So both of these are valid in the RM.  It just that most programmers prefer 
the "Procedure" type of partitions design.

--
-- main subprograms as a procedure 
--
procedure main is
  begin -- main
     null ;
  end main ;
--
-- or main subprograms as a public parameterless function
--
function main return integer is
  begin -- main
     return ( 0 ) ; -- 0 := normal exit status.
  end main ;



Ada RM -- quoted 


  RM 10.2 Program Execution
   ...

                         Implementation Permissions
   ...

29    An implementation may restrict the kinds of subprograms it supports as
                        ------------
main subprograms. However, an implementation is required to support all main
                                                            ----------------
subprograms that are public parameterless library procedures.
-----------


  RM 10.1 Separate Compilation


1     A program unit is either a package, a task unit, a protected unit, a
protected entry, a generic unit, or an explicitly declared subprogram other
                                       ------------------------------
than an enumeration literal. Certain kinds of program units can be separately
compiled. Alternatively, they can appear physically nested within other
program units.



In <8ef6052e-4f51-416b-bae7-ff83d7024267@t11g2000vbc.googlegroups.com>, Martin <martin.dowie@btopenworld.com> writes:
>On May 4, 5:09=A0pm, a...@anon.org (anon) wrote:
>> --
>> -- =A0Besides the Ada.Command_Line you can just use functions for
>> -- =A0the instead of procedures for your nain program. This design is
>> -- =A0great for application where Command_Line is not used.
>> --
>>
>> function work return Integer is
>>
>> =A0 begin
>> =A0 =A0 return ( 0 ) ; -- no error status code
>> =A0 end work ;
>
>Be aware that this is not portable. The only main subprogram that all
>compilers must support (if they support a main subprogram) is "public
>parameterless library procedures" (RM2005 10.2, 29 - previous RMs have
>similar requirements), i.e.
>
>   procedure Main is
>   ...
>
>Cheers
>-- Martin




^ permalink raw reply	[relevance 4%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-05 11:43  0%   ` Martin
@ 2009-05-05 14:57  0%     ` Adam Beneschan
  2009-05-05 20:48  0%       ` anon
  2009-05-05 20:31  4%     ` anon
  1 sibling, 1 reply; 200+ results
From: Adam Beneschan @ 2009-05-05 14:57 UTC (permalink / raw)


On May 5, 4:43 am, Martin <martin.do...@btopenworld.com> wrote:
> On May 4, 5:09 pm, a...@anon.org (anon) wrote:
>
> > --
> > --  Besides the Ada.Command_Line you can just use functions for
> > --  the instead of procedures for your nain program. This design is
> > --  great for application where Command_Line is not used.
> > --
>
> > function work return Integer is
>
> >   begin
> >     return ( 0 ) ; -- no error status code
> >   end work ;
>
> Be aware that this is not portable. The only main subprogram that all
> compilers must support (if they support a main subprogram) is "public
> parameterless library procedures" (RM2005 10.2, 29 - previous RMs have
> similar requirements), i.e.
>
>    procedure Main is
>    ...
>
> Cheers
> -- Martin


Right; and even if your Ada compiler *does* support functions that
return integers as main programs, and you're compiling for some
operating system with an "x" in its name (or Solaris), this does *not*
mean that the Ada compiler will treat the function result as the
status code.  The compiler could decide that the function result is
something to be formatted and spit out onto standard output.  If an
Ada implementation supports parameters and/or function results on main
programs, the language leaves it up to the implementation how those
are interpreted.  There's no rule that says that the interpretation
has to mimic the behavior of the C language (thank God).  So anon's
solution may work on GNAT, but it can't be assumed to work anywhere
else.

                                -- Adam



^ permalink raw reply	[relevance 0%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-04 16:09  7% ` anon
  2009-05-05 10:49  0%   ` Rob Norris
@ 2009-05-05 11:43  0%   ` Martin
  2009-05-05 14:57  0%     ` Adam Beneschan
  2009-05-05 20:31  4%     ` anon
  1 sibling, 2 replies; 200+ results
From: Martin @ 2009-05-05 11:43 UTC (permalink / raw)


On May 4, 5:09 pm, a...@anon.org (anon) wrote:
> --
> --  Besides the Ada.Command_Line you can just use functions for
> --  the instead of procedures for your nain program. This design is
> --  great for application where Command_Line is not used.
> --
>
> function work return Integer is
>
>   begin
>     return ( 0 ) ; -- no error status code
>   end work ;

Be aware that this is not portable. The only main subprogram that all
compilers must support (if they support a main subprogram) is "public
parameterless library procedures" (RM2005 10.2, 29 - previous RMs have
similar requirements), i.e.

   procedure Main is
   ...

Cheers
-- Martin



^ permalink raw reply	[relevance 0%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-05 10:49  0%   ` Rob Norris
@ 2009-05-05 11:15  0%     ` Georg Bauhaus
  0 siblings, 0 replies; 200+ results
From: Georg Bauhaus @ 2009-05-05 11:15 UTC (permalink / raw)


Rob Norris schrieb:
> On Mon, 04 May 2009 16:09:01 GMT, anon@anon.org (anon) wrote:
> 
>> --
>> --  Besides the Ada.Command_Line you can just use functions for 
>> --  the instead of procedures for your nain program. This design is 
>> --  great for application where Command_Line is not used.
>> --
>>
>> function work return Integer is
>>
>>  begin
>>    return ( 0 ) ; -- no error status code
>>  end work ;
>>
>>
>>
>> In <49ba30c9-a1e6-4346-8618-d256f87ac301@s31g2000vbp.googlegroups.com>, reinkor <reinkor@gmail.com> writes:
>>> I want to use Ada programs within unix/linux makefiles and shell
>>> scripts.
>>> Then these programs must sometimes exit with an exit code (error
>>> status)
>>> so execution of the Makefile/scripts halts.
>>>
>>> How I do this ?
>>>
>>> reinert
> 
> Further to anon's reply, when your main program is a function, you can obviously return various
> other values. I think in UNIX world anything other than 0 means an error, but one can encode
> different error states of your own choosing eg:

When choosing an OS specific return code mechanism
also be sure to choose the proper return type for OS's
return code values.



^ permalink raw reply	[relevance 0%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-04 16:09  7% ` anon
@ 2009-05-05 10:49  0%   ` Rob Norris
  2009-05-05 11:15  0%     ` Georg Bauhaus
  2009-05-05 11:43  0%   ` Martin
  1 sibling, 1 reply; 200+ results
From: Rob Norris @ 2009-05-05 10:49 UTC (permalink / raw)


On Mon, 04 May 2009 16:09:01 GMT, anon@anon.org (anon) wrote:

>
>--
>--  Besides the Ada.Command_Line you can just use functions for 
>--  the instead of procedures for your nain program. This design is 
>--  great for application where Command_Line is not used.
>--
>
>function work return Integer is
>
>  begin
>    return ( 0 ) ; -- no error status code
>  end work ;
>
>
>
>In <49ba30c9-a1e6-4346-8618-d256f87ac301@s31g2000vbp.googlegroups.com>, reinkor <reinkor@gmail.com> writes:
>>I want to use Ada programs within unix/linux makefiles and shell
>>scripts.
>>Then these programs must sometimes exit with an exit code (error
>>status)
>>so execution of the Makefile/scripts halts.
>>
>>How I do this ?
>>
>>reinert

Further to anon's reply, when your main program is a function, you can obviously return various
other values. I think in UNIX world anything other than 0 means an error, but one can encode
different error states of your own choosing eg:

if (not File_Exists (file)) then
	return (3); -- File not found
end if;

if (not In_Correct_Format (file)) then
	return (15); -- Dodgy file
end if;

etc...

Also see: http://www.faqs.org/docs/abs/HTML/exitcodes.html

I have a few programs that do this, that are called from scripts that use the exit code to determine
what to do next.



^ permalink raw reply	[relevance 0%]

* Re: How to exit an Ada program with (unix shell) error code?
    2009-05-04  9:17  6% ` Samuel Tardieu
@ 2009-05-04 16:09  7% ` anon
  2009-05-05 10:49  0%   ` Rob Norris
  2009-05-05 11:43  0%   ` Martin
      3 siblings, 2 replies; 200+ results
From: anon @ 2009-05-04 16:09 UTC (permalink / raw)



--
--  Besides the Ada.Command_Line you can just use functions for 
--  the instead of procedures for your nain program. This design is 
--  great for application where Command_Line is not used.
--

function work return Integer is

  begin
    return ( 0 ) ; -- no error status code
  end work ;



In <49ba30c9-a1e6-4346-8618-d256f87ac301@s31g2000vbp.googlegroups.com>, reinkor <reinkor@gmail.com> writes:
>I want to use Ada programs within unix/linux makefiles and shell
>scripts.
>Then these programs must sometimes exit with an exit code (error
>status)
>so execution of the Makefile/scripts halts.
>
>How I do this ?
>
>reinert




^ permalink raw reply	[relevance 7%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-04  9:31  7%     ` Ludovic Brenta
  2009-05-04  9:47  0%       ` reinkor
@ 2009-05-04 10:07  8%       ` stefan-lucks
  1 sibling, 0 replies; 200+ results
From: stefan-lucks @ 2009-05-04 10:07 UTC (permalink / raw)


On Mon, 4 May 2009, Ludovic Brenta wrote:

> reinkor wrote on comp.lang.ada:
> > Thanks, but how I terminate the program in a "natural" way
> > (without using goto or "raise exception") ?
> 
> Simply allow the execution to reach the "end;" of the main subprogram.
> 
> with Ada.Command_Line;
> procedure Exit_With_False is
> begin
>    Ada.Command_Line.Set_Exit_Status (1); -- False, in shell terms

     Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);

> end Exit_With_False; -- nothing else required

I believe, it is preferable to use the predefined constants "Success" and 
"Failure" in Ada.Command line:

  1. If you port your program to another (i.e. non-unix) system, 
     it is not clear that "1" maintains the logical value "False". 
     (Perhaps the RM is clear about that -- I didn't check ...) 

  2. Without the comment "-- False, in shell terms", many readers 
     (except for unix-shell experts, of course) would rather expect 

       Ada.Command_Line.Set_Exit_Status (1);

     to indicate a positive result ("True"), rather then "False". 

Here is a slightly larger example:

with Ada.Command_Line;
procedure False_If_No_Arguments is
   package ACL renames Ada.Command_Line;
begin
   if ACL.Argument_Count > 0 then
      ACL.Set_Exit_Status (ACL.Success);
   else
      ACL.Set_Exit_Status (ACL.Failure);
   end if;
end False_If_No_Arguments;

P.S.: (As you see, you can indicate either a positive or a negative 
outcome without ever having to raise an exception ...)



-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




^ permalink raw reply	[relevance 8%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-04  9:47  0%       ` reinkor
@ 2009-05-04  9:54  0%         ` Martin
  0 siblings, 0 replies; 200+ results
From: Martin @ 2009-05-04  9:54 UTC (permalink / raw)


On May 4, 10:47 am, reinkor <rein...@gmail.com> wrote:
> On 4 Mai, 11:31, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote:
>
> > reinkor wrote on comp.lang.ada:
>
> > > Thanks, but how I terminate the program in a "natural" way
> > > (without using goto or "raise exception") ?
>
> > Simply allow the execution to reach the "end;" of the main subprogram.
>
> > with Ada.Command_Line;
> > procedure Exit_With_False is
> > begin
> >    Ada.Command_Line.Set_Exit_Status (1); -- False, in shell terms
> > end Exit_With_False; -- nothing else required
>
> > --
> > Ludovic Brenta.
>
> OK, using "return" ?
>
> reinert

No need for a return. But remember to ensure any tasks have completed
too.

Cheers
-- Martin



^ permalink raw reply	[relevance 0%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-04  9:31  7%     ` Ludovic Brenta
@ 2009-05-04  9:47  0%       ` reinkor
  2009-05-04  9:54  0%         ` Martin
  2009-05-04 10:07  8%       ` stefan-lucks
  1 sibling, 1 reply; 200+ results
From: reinkor @ 2009-05-04  9:47 UTC (permalink / raw)


On 4 Mai, 11:31, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote:
> reinkor wrote on comp.lang.ada:
>
> > Thanks, but how I terminate the program in a "natural" way
> > (without using goto or "raise exception") ?
>
> Simply allow the execution to reach the "end;" of the main subprogram.
>
> with Ada.Command_Line;
> procedure Exit_With_False is
> begin
>    Ada.Command_Line.Set_Exit_Status (1); -- False, in shell terms
> end Exit_With_False; -- nothing else required
>
> --
> Ludovic Brenta.

OK, using "return" ?

reinert



^ permalink raw reply	[relevance 0%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-04  9:26  0%   ` reinkor
@ 2009-05-04  9:31  7%     ` Ludovic Brenta
  2009-05-04  9:47  0%       ` reinkor
  2009-05-04 10:07  8%       ` stefan-lucks
  0 siblings, 2 replies; 200+ results
From: Ludovic Brenta @ 2009-05-04  9:31 UTC (permalink / raw)


reinkor wrote on comp.lang.ada:
> Thanks, but how I terminate the program in a "natural" way
> (without using goto or "raise exception") ?

Simply allow the execution to reach the "end;" of the main subprogram.

with Ada.Command_Line;
procedure Exit_With_False is
begin
   Ada.Command_Line.Set_Exit_Status (1); -- False, in shell terms
end Exit_With_False; -- nothing else required

--
Ludovic Brenta.



^ permalink raw reply	[relevance 7%]

* Re: How to exit an Ada program with (unix shell) error code?
  2009-05-04  9:17  6% ` Samuel Tardieu
@ 2009-05-04  9:26  0%   ` reinkor
  2009-05-04  9:31  7%     ` Ludovic Brenta
  0 siblings, 1 reply; 200+ results
From: reinkor @ 2009-05-04  9:26 UTC (permalink / raw)


On 4 Mai, 11:17, Samuel Tardieu <s...@rfc1149.net> wrote:
> >>>>> "Reinert" == reinkor  <rein...@gmail.com> writes:
>
> Reinert> I want to use Ada programs within unix/linux makefiles and
> Reinert> shell scripts.  Then these programs must sometimes exit with an
> Reinert> exit code (error status) so execution of the Makefile/scripts
> Reinert> halts.
>
> Reinert> How I do this ?
>
> Ada.Command_Line.Set_Exit_Status(your_integer);
>
>   Sam
> --
> Samuel Tardieu -- s...@rfc1149.net --http://www.rfc1149.net/

Thanks, but how I terminate the program in a "natural" way
(without using goto or "raise exception") ?



^ permalink raw reply	[relevance 0%]

* Re: How to exit an Ada program with (unix shell) error code?
  @ 2009-05-04  9:17  6% ` Samuel Tardieu
  2009-05-04  9:26  0%   ` reinkor
  2009-05-04 16:09  7% ` anon
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 200+ results
From: Samuel Tardieu @ 2009-05-04  9:17 UTC (permalink / raw)


>>>>> "Reinert" == reinkor  <reinkor@gmail.com> writes:

Reinert> I want to use Ada programs within unix/linux makefiles and
Reinert> shell scripts.  Then these programs must sometimes exit with an
Reinert> exit code (error status) so execution of the Makefile/scripts
Reinert> halts.

Reinert> How I do this ?

Ada.Command_Line.Set_Exit_Status(your_integer);

  Sam
-- 
Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/



^ permalink raw reply	[relevance 6%]

* Re: Example of Spawn call
  2009-05-02 15:50  0%   ` Hang
@ 2009-05-02 18:28  0%     ` anon
  0 siblings, 0 replies; 200+ results
From: anon @ 2009-05-02 18:28 UTC (permalink / raw)


I am not the guy that ask for help. My example worked for the simple version 
of spawn.

I think the first guy "Daniel" who ask for help forgot to use the 
"Argument_String_To_List" routine to build the agument list.  Even if 
there is no arguments he should call "Argument_String_To_List"
and give it a null string ( "" ) to insure that the parameter is correct 
for the "spawn" call.



In <7cc6117d-689f-41ef-be05-882a7b5453a7@y34g2000prb.googlegroups.com>, Hang <xiehang@gmail.com> writes:
>On 5=D4=C21=C8=D5, =CF=C2=CE=E711=CA=B128=B7=D6, a...@anon.org (anon) wrote=
>:
>> with Ada.Text_IO ;
>> use  Ada.Text_IO ;
>>
>> with GNAT.OS_Lib ;  -- Could be System.OS_Lib
>> use GNAT.OS_Lib ;
>>
>> procedure test is
>>
>>   Program_Name : String :=3D "temp.exe" ;
>>   Args         : Argument_List_Access ;
>>   Success      : Boolean ;
>>
>> begin -- test
>>
>>   -- Create argument list.
>>
>>   Args :=3D Argument_String_To_List ( " First -second 3" ) ;
>>
>>   Spawn ( Program_Name, Args.all, Success ) ;
>>   if Success then
>>     Put_Line ( "Temp was Spawned Correctly" ) ;
>>   else
>>     Put_Line ( "ERROR: Spawn" ) ;
>>   end if ;
>> end test ;
>>
>> --
>> -- Spawned program.  May require open/close calls for checking output
>> --
>> with Ada.Command_Line ;
>> use  Ada.Command_Line ;
>> with Ada.Text_IO ;
>> use  Ada.Text_IO ;
>>
>> procedure temp is
>>
>> begin
>>   for Index in 1 .. Argument_Count loop
>>     Put ( Index'img ) ;
>>     Put ( "  =3D> " ) ;
>>     Put_Line ( Argument ( Index ) ) ;
>>   end loop ;
>> end temp ;
>>
>> In <50d832b4-140d-4029-8d7c-939711516...@u8g2000yqn.googlegroups.com>, da=
>niel.wenge...@home.se writes:
>>
>> >Though not an Ada issue, really, someone here might have had the same
>> >problem as I have had: I tried to make a small program start another
>> >program using System.OS_Lib.Spawn. However, it raised Program_Error
>> >and stated Exception_Access_Violation.
>>
>> >Any ideas why, and what to do about it?
>>
>> >/D
>>
>>
>
>I'm not seeing any problem:
>
>C:\GNAT\Projects\test>test
> 1  =3D> First
> 2  =3D> -second
> 3  =3D> 3
>Temp was Spawned Correctly
>




^ permalink raw reply	[relevance 0%]

* Re: Example of Spawn call
  2009-05-02  6:28  7% ` Example of Spawn call anon
@ 2009-05-02 15:50  0%   ` Hang
  2009-05-02 18:28  0%     ` anon
  0 siblings, 1 reply; 200+ results
From: Hang @ 2009-05-02 15:50 UTC (permalink / raw)


On 5月1日, 下午11时28分, a...@anon.org (anon) wrote:
> with Ada.Text_IO ;
> use  Ada.Text_IO ;
>
> with GNAT.OS_Lib ;  -- Could be System.OS_Lib
> use GNAT.OS_Lib ;
>
> procedure test is
>
>   Program_Name : String := "temp.exe" ;
>   Args         : Argument_List_Access ;
>   Success      : Boolean ;
>
> begin -- test
>
>   -- Create argument list.
>
>   Args := Argument_String_To_List ( " First -second 3" ) ;
>
>   Spawn ( Program_Name, Args.all, Success ) ;
>   if Success then
>     Put_Line ( "Temp was Spawned Correctly" ) ;
>   else
>     Put_Line ( "ERROR: Spawn" ) ;
>   end if ;
> end test ;
>
> --
> -- Spawned program.  May require open/close calls for checking output
> --
> with Ada.Command_Line ;
> use  Ada.Command_Line ;
> with Ada.Text_IO ;
> use  Ada.Text_IO ;
>
> procedure temp is
>
> begin
>   for Index in 1 .. Argument_Count loop
>     Put ( Index'img ) ;
>     Put ( "  => " ) ;
>     Put_Line ( Argument ( Index ) ) ;
>   end loop ;
> end temp ;
>
> In <50d832b4-140d-4029-8d7c-939711516...@u8g2000yqn.googlegroups.com>, daniel.wenge...@home.se writes:
>
> >Though not an Ada issue, really, someone here might have had the same
> >problem as I have had: I tried to make a small program start another
> >program using System.OS_Lib.Spawn. However, it raised Program_Error
> >and stated Exception_Access_Violation.
>
> >Any ideas why, and what to do about it?
>
> >/D
>
>

I'm not seeing any problem:

C:\GNAT\Projects\test>test
 1  => First
 2  => -second
 3  => 3
Temp was Spawned Correctly




^ permalink raw reply	[relevance 0%]

* Example of Spawn call
  @ 2009-05-02  6:28  7% ` anon
  2009-05-02 15:50  0%   ` Hang
  0 siblings, 1 reply; 200+ results
From: anon @ 2009-05-02  6:28 UTC (permalink / raw)


with Ada.Text_IO ;
use  Ada.Text_IO ;

with GNAT.OS_Lib ;  -- Could be System.OS_Lib
use GNAT.OS_Lib ;

procedure test is

  Program_Name : String := "temp.exe" ;
  Args         : Argument_List_Access ;
  Success      : Boolean ;

begin -- test 

  -- Create argument list.

  Args := Argument_String_To_List ( " First -second 3" ) ;

  Spawn ( Program_Name, Args.all, Success ) ;
  if Success then
    Put_Line ( "Temp was Spawned Correctly" ) ;
  else
    Put_Line ( "ERROR: Spawn" ) ;
  end if ;
end test ;


--
-- Spawned program.  May require open/close calls for checking output
--
with Ada.Command_Line ;
use  Ada.Command_Line ;
with Ada.Text_IO ;
use  Ada.Text_IO ;

procedure temp is

begin
  for Index in 1 .. Argument_Count loop
    Put ( Index'img ) ;
    Put ( "  => " ) ;
    Put_Line ( Argument ( Index ) ) ;
  end loop ;
end temp ;



In <50d832b4-140d-4029-8d7c-9397115160ba@u8g2000yqn.googlegroups.com>, daniel.wengelin@home.se writes:
>
>Though not an Ada issue, really, someone here might have had the same
>problem as I have had: I tried to make a small program start another
>program using System.OS_Lib.Spawn. However, it raised Program_Error
>and stated Exception_Access_Violation.
>
>Any ideas why, and what to do about it?
>
>/D




^ permalink raw reply	[relevance 7%]

* Re: Structure of the multitasking server
  @ 2008-09-23  9:25  4%   ` anon
  0 siblings, 0 replies; 200+ results
From: anon @ 2008-09-23  9:25 UTC (permalink / raw)


--
--  A Server and a Client that shows how to use 
--  GNAT.Sockets.Check_Selection as a controller for
--  multiple port server. And can be alter to allow multiple 
--  services type of server.
--
--  In C,  they call this type of server a Super-Server Class 
--  of servers.
--

-- ------------------------------------------------------------ --
-- Multi-Tasking Server that allows Multi-Service to be handled --
-- ------------------------------------------------------------ --

with Ada.Text_IO ;
with GNAT.Sockets ;
with System ;

use  Ada.Text_IO ;
use  GNAT.Sockets ;

procedure testserver is 


  -- ------------------- --
  --  Server Task Types  --
  -- ------------------- --

    -- 
    --  TCP Task
    -- 

    task tcp_hello is
        entry Initialize ;
        entry Acknowledge ;
      end tcp_hello ;


    -- 
    --  UDP Task
    -- 

    task udp_hello is
        entry Initialize ;
        entry Acknowledge ;
      end udp_hello ;


    Server_Error  : exception ;

    tcp_Socket    : Socket_Type       ;
    udp_Socket    : Socket_Type       ;


-- ------------------------------------------------------------------------ --
----                        TCP/IP Controller Task                        ----
----                                                                      ----
----  dispatches server task to handle tcp/ip services.                   ----
----                                                                      ----
-- ------------------------------------------------------------------------ --

    task Controller is
        entry Initialize_Controller ;
      end Controller  ;


    task body Controller is

        Selector      : Selector_Type   ;
        Server_Status : Selector_Status ;

        --  Exception_Fds is not use in Ada 95
        --  and is optional Ada 2005 GNAT.Sockets

        Read_Fds      : Socket_Set_Type ;
        Write_Fds     : Socket_Set_Type ;


      begin -- Controller 
          --
          -- Set up controller variables
          --
          Create_Selector ( Selector ) ;
          Empty ( Read_Fds ) ;
          Empty ( Write_Fds ) ;


          Accept Initialize_Controller ;

          --
          -- Set up and active Server
          --
          Put_Line ( "Controller: Server Dispatching Loop" ) ;
          loop
            -- Insure Fds value, 
            Empty ( Read_Fds ) ;
            Empty ( Write_Fds ) ;

            Set ( Read_Fds, tcp_Socket ) ;
            Set ( Read_Fds, udp_Socket ) ;

            --
            --  Excute the TCP/IP "Select" routine.  This routine is blocked
            --  until a connecion is made. In this part it is identical to 
            --  TCP/IP "Accept".
            --
            --  Also, Exception_Fds is not use in Ada 95 and is optional 
            --  Ada 2005 GNAT.Sockets
            --
            Check_Selector ( Selector, 
                             Read_Fds, 
                             Write_Fds, 
                             Server_Status ) ;

            -- call a server to handle job using Signalling Fds

            if Is_Set ( Read_Fds, tcp_Socket ) then
                tcp_hello.Acknowledge ;
            elsif Is_Set ( Read_Fds, udp_Socket ) then
                udp_hello.Acknowledge ;
            else
              raise Socket_Error ;
            end if ;
          end loop ;
       exception
         when Socket_Error => 
             -- need to signal servers to shutdown because 
             -- dispatcher has stopped
             raise ;            
      end Controller  ;




-- ------------------------------------------------------------------------ --
----                         TCP/IP Server Tasks                          ----
----                                                                      ----
----  Both tasks are similar.  They both send a message to a client       ----
----  Differences:                                                        ----
----        1) Transport protocols: One uses TCP, the other uses UDP      ----
----        2) Message and message length                                 ----
----                                                                      ----
----  Excution of these two servers will cause the "netstat" program      ----
----  to add the following info to the "netstat" socket report            ----
----                                                                      ----
----      IP Address        protocol    port                              ----
----      127.0.0.1         tcp         54321                             ----
----      127.0.0.1         udp         54321                             ----
----                                                                      ----
-- ------------------------------------------------------------------------ --



    task body tcp_hello is

        Port         : constant Port_Type := 54321 ;

        Address      : Sock_Addr_Type    ;
        Channel      : Stream_Access     ;
        Client       : Socket_Type       ; 

        hello_string : String ( 1..25 ) := "TCP Server: Hello, World!" ; 

      begin -- Tcp_hello

        Create_Socket ( tcp_Socket, Family_Inet, Socket_Stream ) ;
        --
--        Address.Addr := Any_Inet_Addr ;
        Address.Addr := Inet_Addr ( "127.0.0.1" ) ; -- Limited access
        Address.Port := Port ;
        --
        Bind_Socket ( tcp_Socket, Address ) ;

        --
        Listen_Socket ( tcp_Socket, 4 ) ;  

        Accept Initialize ;
        --
        --  Main Server processing routine 
        --
        Put_Line ( "TCP: Active the Server loop" ) ;
        loop 
          accept Acknowledge ;

          -- ------------------------ --
          --  Do server services job  --
          -- ------------------------ --

          --
          --  Because of Check_Selector, no wait for Accept_Socket
          --  used to obtain connected socket ( Client ) address 
          --  for the tcp protocol.
          --
          Accept_Socket ( tcp_Socket, Client, Address ) ;

          Channel := Stream ( Client ) ;

          String'Write ( Channel, hello_string ) ;

          Close_Socket ( Client ) ;

        end loop ;

        --
        -- for security, close socket if exception occured
        --
        exception
          when others =>
              Put_Line ( "TCP: Exception" ) ;
              Close_Socket ( tcp_Socket ) ;
              raise ;
      end tcp_hello ;



    -- 
    --  UDP Task
    -- 

    task body udp_hello is

        Port           : constant Port_Type := 54321 ;

        Address        : Sock_Addr_Type    ;
        Channel_Input  : Stream_Access     ;
        Channel_Output : Stream_Access     ;

        Temp           : Character         ;
        hello_string : String := "UDP Server: Repeat Hello, World!" ; 

      begin -- udp_hello

        Create_Socket ( udp_Socket, Family_Inet, Socket_Datagram ) ;
        --
--        Address.Addr := Any_Inet_Addr ;
        Address.Addr := Inet_Addr ( "127.0.0.1" ) ;
        Address.Port := Port ;
        --
        Bind_Socket ( udp_Socket, Address ) ;


        Accept Initialize ;
        --
        --  Main Server processing routine 
        --
        Put_Line ( "UDP: Active the Server loop" ) ;
        loop 
          accept Acknowledge ;

          -- ------------------------ --
          --  Do server services job  --
          -- ------------------------ --
                                           -- Accept from any Address and Port
          Address.Addr := Any_Inet_Addr ;
          Address.Port := Any_Port ;

          Channel_Input := Stream ( udp_Socket, Address ) ;  
      
          Character'Read ( Channel_Input, Temp ) ;

                                           -- Open an output channel
          Address := Get_Address ( Channel_Input ) ;
          Channel_Output := Stream ( udp_Socket, Address ) ;

          String'Write ( Channel_Output, hello_string ) ;
        end loop ;

        --
        -- for security, close socket if exception occured
        --
        exception
          when others =>
              Put_Line ( "UDP: Exception" ) ;
              Close_Socket ( udp_Socket ) ;
              raise ;
      end udp_hello ;



                      -- ------------------------ --
                      ----   Server Initiaizer  ----
                      -- ------------------------ --



  begin

    -- Initialize each server service task

    tcp_hello.Initialize ;
    udp_hello.Initialize ;

    --  Startup network controller

    Controller.Initialize_Controller ;

  --
  -- Handle all exceptions
  --
  exception 
    when Socket_Error =>
      raise ;
    when others =>
      raise ;
  end testserver ;





-- ----------------------------------------------------- --
-- Non-Tasking Client that test the Multi-Service Server --
-- ----------------------------------------------------- --

with Ada.Command_Line ;
with Ada.Text_IO ;
with Ada.Unchecked_Conversion ;
with GNAT.Sockets ;

use  Ada.Command_Line ;
use  Ada.Text_IO ;
use  GNAT.Sockets ;

procedure testclient is 

    localhost : constant Inet_Addr_Type := Inet_Addr ( "127.0.0.1" ) ;
    localport : constant Port_Type := 54321 ;
    --
    Address : Sock_Addr_Type    ;
    Channel : Stream_Access     ;
    Socket  : Socket_Type       ;
    --
    tcp_Buffer  : String ( 1..25 )  ;
    udp_Buffer  : String ( 1..32 )  ;

  begin -- Daytime0

    --
    Address.Addr := localhost ;
    Address.Port := localport ;

    --
    if Argument ( 1 ) = "-T" then
      Put_Line ( "Protocol: TCP" ) ;
      --
      Create_Socket ( Socket, Family_Inet, Socket_Stream ) ;
      Connect_Socket ( Socket, Address ) ;
      --
      Channel := Stream ( Socket ) ;
      String'Read ( Channel, tcp_Buffer ) ;
      --
      Close_Socket ( Socket ) ;
      --
      Put ( "Server Data => " ) ;
      Put ( tcp_Buffer ) ;
      Put ( " <= " ) ;
      New_Line ;

    elsif Argument ( 1 ) = "-U" then
      Put_Line ( "Protocol: UDP" ) ;
      --
      Create_Socket ( Socket, Family_Inet, Socket_Datagram ) ;
      Channel := Stream ( Socket, Address ) ;

      -- Allows server to obtain client address by send a dummy character 

      Character'Write ( Channel, Ascii.nul ) ; 
      --
      Channel := Stream ( Socket, Address ) ;
      String'Read ( Channel, udp_Buffer ) ;
      --
      Close_Socket ( Socket ) ;
      --
      Put ( "Server Data => " ) ;
      Put ( udp_Buffer ) ;
      Put ( " <= " ) ;
      New_Line ;

     else
      Put_Line ( Standard_Error, "usage: testclient [-DT]" ) ;
      Put_Line ( Standard_Error, "-T: tcp" ) ;
      Put_Line ( Standard_Error, "-U: udp" ) ;
      New_Line ;
    end if ;
  end testclient ;



^ permalink raw reply	[relevance 4%]

* Re: Structure of the multitasking server
  @ 2008-09-19 23:01  3% ` anon
    1 sibling, 0 replies; 200+ results
From: anon @ 2008-09-19 23:01 UTC (permalink / raw)


Since you are using Channels, I am assuming that your talking about TCP/IP 
servers. In this case you should look into using the Check_Selector with 
the use of Signalling_Fds and Socket_Sets instead of using arrays.

Now the way GNAT has written the Selector function and the way the C_Select
is written the maximum number of server per Check_Selector is 27.  That is, 
each C_Select function can only monitor 32 sockets, but 
GNAT.Sockets.Create_Selector uses two socket and the TCP/IP sub-system 
uses or predefines 3, so you are left with 27 user define servers.

Found this clent/server on the net.  The following client/server shows how to 
use the Check_Selector routine. They were both were written in all caps and 
use Ada-95 spec so,  you may need to adjust the Signalling_Fds routine 
calls for Ada-2005 (GNAT-2008), but they do compile and excute under 
GNAT GPL 2007 using Linux. 

Note: 1) I alter for spacing and cap format. To make them more readable.
      2) The procedure "Set_Socket_Option" may need to be commented 
          out.  Some TCP/IP system do not like GNAT version of that 
          routine.
      3) As for Windows, I did not test!


--------------------------------------------------------------
--
--  Pool_Server
--
with GNAT.Sockets ; 
use GNAT.Sockets ;
with Ada.Text_IO ;

procedure Pool_Server is

    MaxTasks : constant Positive := 5 ;  -- buffer size
    type Index is mod MaxTasks ;

    function Rev ( S : String ) return String is
        Res : String ( S'Range ) ;
        J : Integer := S'First ;
      begin
        for I in reverse S'Range loop
         Res ( J ) := S ( I ) ;
         J := J + 1 ;
        end loop ;
        return Res ;
      end Rev ;

    protected Aborted is
      procedure Set ;
      function Check return Boolean ;
    private
      Done : Boolean := False ;
    end Aborted ;

    protected body Aborted is
      procedure Set is
        begin
          Done := True ;
        end Set ;

      function Check return Boolean is
        begin
          return Done ;
        end Check ;
    end Aborted ;


   type Echo ;
   type Echo_Access is access Echo ;

    task type Echo is
      entry Start ( N_Sock : IN Socket_Type ;
                    Self : IN Echo_Access   ) ;
      entry ReStart ( N_Sock : IN Socket_Type ) ;
    end Echo ;

    type Task_Array is array ( Index ) of Echo_Access ;

    protected Buffer is
      entry Deposit ( X : in Echo_Access ) ;
      entry Extract ( X : out Echo_Access ) ;
      function NumWaiting return Natural ;
    private
      Buf : Task_Array ;
      I, J : Index := 0 ;
      Count : Natural range 0 .. MaxTasks := 0 ;
    end Buffer ;


    task body Echo is
        Sock : Socket_Type ;
        S : Stream_Access ;
        Me : Echo_Access ;
        Input_Selector : Selector_Type ;
        Input_Set : Socket_Set_Type ;
        WSet : Socket_Set_Type ;
        Input_Status : Selector_Status ;
      begin
      --set up selector
      Create_Selector ( Input_Selector ) ;

      --Initialise socket sets
      --WSet is always empty as we are not interested in output events
      -- RSet only ever contains one socket namely Sock
      Empty ( Input_Set ) ;
      Empty ( WSet ) ;

      ACCEPT Start ( N_Sock : IN Socket_Type ;
                     Self : IN Echo_Access   ) DO
        Sock := N_Sock ;
        Me := Self ;
      end Start ;

      loop
        begin   -- block for exception handling
          S := Stream ( Sock ) ;    -- set up stream on socket
          Boolean'Write ( S, True ) ;  -- acknowledge connection

          loop
            -- check for input on Sock socket
            Set ( Input_Set, Sock ) ;

            -- time-out on check if no input within 0.5 second
            Check_Selector ( Input_Selector,
                             Input_Set,
                             WSet,
                             Input_Status,
                             0.5 ) ;
            if Input_Status = Completed then
              -- we have input, so process it
              declare
                  Str : String := String'Input ( S ) ;
              begin
                exit when Str = "quit" ;
                String'Output ( S, Rev ( Str ) ) ;
              end ;
            end if ;
            if Aborted.Check then
              String'Output ( S, "Server aborted" ) ;
              exit ;
            end if ;
          end loop ;

          Ada.Text_IO.New_Line ;
          Ada.Text_IO.Put_Line ( "Slave Closing Connection" ) ;
          ShutDown_Socket ( Sock, Shut_Read_Write ) ;
          Buffer.Deposit ( Me ) ;

          exception
            -- The mostly likely exception is if client quits unexpectedly
            -- close the socket and deposit ourselves in the buffer
          when others =>
               Ada.Text_IO.New_Line ;
               Ada.Text_IO.Put_Line ( "Connection closed unexpectedly" ) ;
               Close_Socket ( Sock ) ;
               Buffer.Deposit ( Me ) ;
        end ;

        select
          ACCEPT ReStart ( N_Sock : IN Socket_Type ) DO
            Sock := N_Sock ;
          end ReStart ;
        or
          -- terminate if all slaves are queued here and
          -- if the main server task has finished
          terminate ;
        end select ;

      end loop ;
    end Echo ;

    protected body Buffer is
      entry Deposit ( X : IN Echo_Access ) when Count < MaxTasks is
        begin
          Buf ( I ) := X ;
          I := I + 1 ;
          Count := Count + 1 ;
        end Deposit ;

      entry Extract ( X : OUT Echo_Access ) when Count > 0 is
        begin
          X := Buf ( J ) ;
          J := J + 1 ;
          Count := Count - 1 ;
        end Extract ;

      function NumWaiting return Natural is
      begin
         return Count ;
      end NumWaiting ;
   end Buffer ;

    Server          : Socket_Type ;
    New_Sock        : Socket_Type ;
    Slave           : Echo_Access ;
    Addr            : Sock_Addr_Type ( Family_Inet ) ;
    Peer_Addr       : Sock_Addr_Type ( Family_Inet ) ;
    Avail           : Boolean := False ;
    Ch              : Character ;
    TotalTasks      : Natural := 0 ;
    Accept_Selector : Selector_Type ;
    Accept_Set      : Socket_Set_Type ;
    WSet            : Socket_Set_Type ;
    Accept_Status   : Selector_Status ;

  begin  --  main server task
    Ada.Text_IO.Put_Line ( "WARNING server loops for ever." ) ;
    Ada.Text_IO.Put ( "Press A to terminate server and all " ) ;
    Ada.Text_IO.Put_Line ( "tasks immediately or press Q to ") ;
    Ada.Text_IO.Put ( "accept no further connections and " ) ;
    Ada.Text_IO.Put ( "terminate gracefully when all clients " ) ;
    Ada.Text_IO.Put ( "are fully when all clients are through." ) ;
    Ada.Text_IO.New_Line ;
    Initialize ;
    Create_Socket ( Server) ;
    Addr := ( Family_Inet,
              Addresses ( Get_Host_By_Name ( Host_Name ), 1 ),
              50000 ) ;
    --  allow server address to be reused for multiple connections
    Set_Socket_Option ( Server, 
                        Socket_Level,
                        ( Reuse_Address, True ) ) ;

    Bind_Socket ( Server, Addr ) ;
    Listen_Socket ( Server, 4 ) ;

    --  set up selector
    Create_Selector ( Accept_Selector ) ;

    --  Initialise socket sets
    --  WSet is always empty as we are not interested in output 
    --  events Accept_Set only ever contains one socket namely 
    --  Server
    Empty ( Accept_Set ) ;
    Empty ( WSet ) ;
    loop
      Ada.Text_IO.Get_Immediate ( Ch, Avail ) ;
      if Avail and then
         ( Ch = 'q' or Ch = 'Q' or Ch = 'a' or Ch = 'A' ) then
        exit ;
      end if ;

      --  check for input (connection requests) on Server socket
      Set ( Accept_Set, Server ) ;
      --  time-out on check if no request within 1 second
      Check_Selector ( Accept_Selector, 
                       Accept_Set,
                       WSet, 
                       Accept_Status, 
                       1.0 ) ;

      if Accept_Status = Completed then
        --  must be an event on Server socket as it is the only 
        --  one that we are checking.
        --  Hence the Accept_Socket call should not block.

        Accept_Socket ( Server, New_Sock, Peer_Addr ) ;
        Ada.Text_IO.New_Line ;
        Ada.Text_IO.Put_Line 
                        ( "Connection accepted -- allocating slave" ) ;


      if Buffer.NumWaiting = 0  and TotalTasks < MaxTasks then
          Slave := NEW Echo ;              -- start new task
          TotalTasks := TotalTasks + 1 ;
          Ada.Text_IO.Put_Line ( "New slave task started" ) ;
          --  call entry Start to activate task
          Slave.Start ( New_Sock, Slave ) ;
        else
          Ada.Text_IO.Put_Line ( "Waiting for an idle slave task" ) ;
          Buffer.Extract ( Slave ) ;
          --  call entry Start to re-activate task
          Slave.ReStart ( New_Sock ) ;
          Ada.Text_IO.Put_Line ( " Idle slave task reactivated" ) ;
        end if ;
      end if ;
    end loop ;

    if Ch = 'a' or Ch = 'A' then
      --  signal slave tasks to terminate
      Aborted.Set ;
    end if ;

   --  tidy up
    Close_Selector ( Accept_Selector ) ;
    Empty ( Accept_Set ) ;

    Close_Socket ( Server ) ;
    Ada.Text_IO.New_Line ;
    Ada.Text_IO.Put_Line ( "Main server task exiting ..." ) ;
    Finalize ;
end Pool_Server ;


--------------------------------------------------------------
--
--  Pool_Client
--
with Gnat.Sockets ;
use  Gnat.Sockets ;
with Ada.Command_Line ; 
use  Ada.Command_Line ;
with Ada.Text_IO ;
use  Ada.Text_IO ;

procedure Pool_Client is
    Sock : Socket_Type ;
    S : Stream_Access ;
    Addr : Sock_Addr_Type ( Family_Inet ) ;
    Msg : String ( 1 .. 80 ) ;
    Last : Natural ;
    B : Boolean ;
    Read_Selector : Selector_Type ;
    Read_Set, WSet : Socket_Set_Type ;
    Read_Status : Selector_Status ;
  begin
    Initialize ;
    Create_Socket ( Sock ) ;
    Addr := ( Family_Inet,
              Addresses ( Get_Host_By_Name ( Argument ( 1 ) ), 1 ),
              50000 ) ;
    Create_Selector ( Read_Selector ) ;
    Empty ( Read_Set ) ;
    Empty ( WSet ) ;


    Connect_Socket ( Sock, Addr ) ;
    S := Stream ( Sock ) ;
    Boolean'Read ( S, B ) ;
    -- wait for connection to be accepted

    loop
      Set ( Read_Set, Sock ) ;

      -- check for input on socket  (server may be aborting)
      -- time-out immediately if no input pending
      -- We seem to need a small delay here (using zero seems to block
      -- forever)
      -- Is this a GNAT bug or AB misreading Check_Selector docs?

      Check_Selector ( Read_Selector, 
                       Read_Set,
                       WSet, 
                       Read_Status,
                       0.005 ) ;
      if Read_Status = Expired then
        Ada.Text_IO.Put ( "Message> " ) ;  -- prompt user for message
        Ada.Text_IO.Get_Line ( Msg, Last ) ;

        -- send message to socket unless server is aborting
        String'Output ( S, Msg ( 1 .. Last ) ) ;
        exit when Msg ( 1 .. Last ) = "quit" ;
      end if ;

      declare 
          -- receive message
          Str : String := String'Input ( S ) ;
      begin      Ada.Text_IO.Put_Line ( Str ) ;
        exit when Str = "Server aborted" ;
      end ;
    end loop ;

    Ada.Text_IO.Put_Line ( "Client quitting ..." ) ;
    ShutDown_Socket ( Sock ) ;
    Close_Selector ( Read_Selector ) ;
    Finalize ;
  exception 
    when others =>
        Ada.Text_IO.Put_Line ("Exception: Client quitting ..." ) ;
        Close_Socket ( Sock ) ;
        Close_Selector( Read_Selector ) ;
        Finalize ;
  end Pool_Client ;


In <8b4d1170-22e6-40d3-8ed1-096dc0163491@m36g2000hse.googlegroups.com>, Maciej Sobczak <see.my.homepage@gmail.com> writes:
>Hi all,
>
>Imagine a server with fixed number of worker tasks. There is no queue
>of jobs and jobs are immediately passed to one of the tasks that is
>currently idle. There is a separate task (or just the main one) that
>provides jobs for worker tasks.
>
>I am concerned with the proper structure of objects - I mean in the
>sense of recommended Ada practice.
>Obviously there is a need for some shared resource where the
>requesting task will put the job and from where the worker task will
>pick it up.
>
>This is more or less what I came up with, where the "channel" is a
>single processing pipeline:
>
>   type Worker_State is (Idle, Ready, Working);
>
>   protected type Channel_State is
>      procedure Post (J : in Job_Type);
>      entry Get_Job (J : out Job_Type);
>      function Busy return Boolean;
>   private
>      State : Worker_State := Idle;
>      Job_To_Do : Job_Type;
>   end Channel_State;
>
>   protected body Channel_State is
>
>      procedure Post (J : in Job_Type) is
>      begin
>         if State /= Idle then
>            raise Program_Error;
>         end if;
>
>         Job_To_Do := J;
>         State := Ready;
>      end Post;
>
>      entry Get_Job (J : out Job_Type) when State = Ready is
>      begin
>         J := Job_To_Do;
>         State := Working;
>      end Get_Job;
>
>      function Busy return Boolean is
>      begin
>         return State /= Idle;
>      end Busy;
>
>   end Channel_State;
>
>   type Channel;
>   task type Worker_Task (Ch : access Channel);
>
>   type Channel is record
>      State : Channel_State;
>      Worker : Worker_Task (Channel'Access);
>   end record;
>
>   task body Worker_Task is
>      Job : Job_Type;
>   begin
>      loop
>         Ch.all.Get_Job (Job);
>
>         --  do the job ...
>
>      end loop;
>   end Worker_Task;
>
>   Max_Channels : constant := 5;
>
>   Channels : array (1 .. Max_Channels) of Channel;
>
>My question is whether this is what a seasoned Ada programmer would
>do.
>Initially I tried to have two separate arrays, one for jobs and one
>for worker tasks, but I found it difficult to link workers with their
>respective jobs. After bundling them together in a single record that
>is referenced from the task it worked and I actually find it
>structured better.
>
>The main task after constructing a job object finds some channel where
>the worker task is not busy and posts the job to its shared state
>component:
>
>   loop
>      Job := ...
>
>      Found_Worker := False;
>      for I in Channels'Range loop
>         if not Channels (I).State.Busy then
>            Channels (I).State.Post (Job);
>            Found_Worker := True;
>            exit;
>         end if;
>      end loop;
>
>      if not Found_Worker then
>         --  all pipelines are busy,
>         --  but the overflow handling is not shown...
>      end if;
>   end loop;
>
>All this works fine, but my question considers the choice of language
>constructs and idioms.
>
>--
>Maciej Sobczak * www.msobczak.com * www.inspirel.com
>
>Database Access Library for Ada: www.inspirel.com/soci-ada




^ permalink raw reply	[relevance 3%]

* Re: Command Line on windows
  2008-09-12 12:25  6% ` Gautier
@ 2008-09-12 14:36  8%   ` RasikaSrinivasan
  0 siblings, 0 replies; 200+ results
From: RasikaSrinivasan @ 2008-09-12 14:36 UTC (permalink / raw)


On Sep 12, 8:25 am, Gautier <gaut...@fakeaddress.nil> wrote:
> Not solving your problem, but you'd prefer to use Ada.Command_Line which
> is standard and with Ada strings instead of C strings.
> _________________________________________________________
> Gautier's Ada programming --http://sf.net/users/gdemont/
>
> NB: For a direct answer, e-mail address on the Web site!

unfortunately ada.command_line says the behaviour is implementation
defined.

in fact the following is a test of my original attempt :

with Text_Io; use Text_Io;
with Ada.Command_Line;

procedure Test_Cli is
begin
   Put_Line(Ada.Command_Line.Argument(1));
end Test_Cli ;

this when compiled with gnat - produced results similar to
gnat.command_line. That is why I thought gnat.command_line might work
better.

   function Get_Argument (Do_Expansion : Boolean := False) return
String;
   --  Returns the next element on the command line which is not a
switch.
   --  This function should not be called before Getopt has returned
   --  ASCII.NUL.

the do_expansion led me to believe i could turn it off.

any other ideas?

of course specifying for example "*.adb" (within quotations) does
disable it but i guess that is the unix behaviour expected.

thanks, srini



^ permalink raw reply	[relevance 8%]

* Re: Command Line on windows
  @ 2008-09-12 12:25  6% ` Gautier
  2008-09-12 14:36  8%   ` RasikaSrinivasan
  0 siblings, 1 reply; 200+ results
From: Gautier @ 2008-09-12 12:25 UTC (permalink / raw)


Not solving your problem, but you'd prefer to use Ada.Command_Line which 
is standard and with Ada strings instead of C strings.
_________________________________________________________
Gautier's Ada programming -- http://sf.net/users/gdemont/

NB: For a direct answer, e-mail address on the Web site!



^ permalink raw reply	[relevance 6%]

* Gnade/ODBC example - please help
@ 2008-08-01 12:18  3% azdakiel
  0 siblings, 0 replies; 200+ results
From: azdakiel @ 2008-08-01 12:18 UTC (permalink / raw)


Hi,
    I'm new here. I also just started my advanture with ADA.
    I'm building a portal using AWS (my project for university) and i
need to connect to a MySQL database. I using Gnade/ODBC interface.
    There is simple example, in the Gnade User's Guide, how to connect
and get some data from databese. And it works.

And now my problem: This example shows how to pass integer parameter
to the query and get string and float from the database.
I trying to pass to the query string and the boolean (...WHERE NAME =
name AND IsVisible = visible...) and I can't. I have no idea how to
rewrite this example.

Is there anyone who can tell me how to change this example?


---------------=========The Example========------------
with Ada.Characters.Handling;
with Ada.Command_Line;
with Ada.Strings.Fixed;        use Ada.Strings.Fixed;
with Ada.Text_IO;              use Ada.Text_IO;
with Ada.Exceptions;           use Ada.Exceptions;
with GNU.DB.SQLCLI;            use GNU.DB.SQLCLI;
with GNU.DB.SQLCLI.Bind;

with GNU.DB.SQLCLI.Info;       use GNU.DB.SQLCLI.Info;
with GNU.DB.SQLCLI.Info.Debug;

with GNU.DB.SQLCLI.Environment_Attribute;
use GNU.DB.SQLCLI.Environment_Attribute;
with GNU.DB.SQLCLI.Environment_Attribute.Debug;

with GNU.DB.SQLCLI.Connection_Attribute;
use  GNU.DB.SQLCLI.Connection_Attribute;
with GNU.DB.SQLCLI.Connection_Attribute.Debug;

use GNU.DB.SQLCLI;

with GNAT.Traceback.Symbolic;

procedure odbc_mysql is


      package RIO is new Ada.Text_IO.Float_IO (SQLDOUBLE);

      EnvironmentHandle : SQLHENV;
      ConnectionHandle  : SQLHDBC;

      ServerName     : constant String := String'("test");
      UserName       : constant String := String'("test");
      Authentication : constant String := String'("test");

      Quoting_Character : Character := Character'Val (34);

      function  QuoteIdentifier (ID : String) return String;
      procedure Get_Identifier_Info;

      function QuoteIdentifier (ID : String) return String is
      begin
         return Quoting_Character & ID & Quoting_Character;
      end QuoteIdentifier;

      pragma Inline (QuoteIdentifier);
      procedure Get_Identifier_Info is
         QC : constant Driver_Info_String :=
           Driver_Info_String (SQLGetInfo
                               (ConnectionHandle,
SQL_IDENTIFIER_QUOTE_CHAR));

      begin
         if QC.Value'Length /= 1 then
            null;
         else
            Quoting_Character := QC.Value (QC.Value'First);
         end if;
      end Get_Identifier_Info;

   begin
      SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE,
EnvironmentHandle);
      SQLSetEnvAttr  (EnvironmentHandle,
Environment_Attribute_ODBC_Version'
          (Attribute => SQL_ATTR_ODBC_VERSION,
           Value     => SQL_OV_ODBC3));

      SQLAllocHandle (SQL_HANDLE_DBC, EnvironmentHandle,
ConnectionHandle);
      SQLConnect (ConnectionHandle => ConnectionHandle,
                  ServerName       => ServerName,
                  UserName         => UserName,
                  Authentication   => Authentication);

      Get_Identifier_Info;

      declare
         package Double_Binding is new
           GNU.DB.SQLCLI.FloatBinding (SQLDOUBLE);
         package DB renames Double_Binding;

         type ManagerID is new SQLINTEGER;
         type ManagerID_Ptr is access all ManagerID;
         package ManagerID_Binding is new
           GNU.DB.SQLCLI.Bind (ManagerID, ManagerID_Ptr);
         package MB renames ManagerID_Binding;

         StatementHandle : SQLHSTMT;
         Search_Manager  : aliased ManagerID := 2;
         Len             : aliased SQLINTEGER := 0;
         Name            : aliased String := 20 * '.';
         Firstname       : aliased String := 20 * '.';
         Len_Firstname   : aliased SQLINTEGER;
         Len_Name        : aliased SQLINTEGER;
         Len_Salary      : aliased SQLINTEGER;
         Salary          : aliased SQLDOUBLE;

      begin
         SQLAllocHandle (SQL_HANDLE_STMT, ConnectionHandle,
StatementHandle);
         SQLPrepare (StatementHandle,
                     "SELECT " & QuoteIdentifier ("NAME") & ", " &
                     QuoteIdentifier ("FIRSTNAME") & ", " &
                     QuoteIdentifier ("SALARY") &
                     " FROM " & QuoteIdentifier ("EMPLOYEES") & " " &
                     "WHERE " & QuoteIdentifier ("MANAGER") & " = ? "
&
                     "ORDER BY " & QuoteIdentifier ("NAME") & "," &
                     QuoteIdentifier ("FIRSTNAME"));
         MB.SQLBindParameter
           (StatementHandle  => StatementHandle,
            ParameterNumber  => 1,
            InputOutputType  => SQL_PARAM_INPUT,
            ValueType        => SQL_C_SLONG,
            ParameterType    => SQL_INTEGER,
            ColumnSize       => 0,
            DecimalDigits    => 0,
            Value            => Search_Manager'Access,
            BufferLength     => 0,
            StrLen_Or_IndPtr => Len'Access);

         SQLBindCol
           (StatementHandle, 1, Name'Access, Len_Name'Access);
         SQLBindCol (StatementHandle, 2, Firstname'Access,
Len_Firstname'Access);
         DB.SQLBindCol (StatementHandle, 3, Salary'Access,
Len_Salary'Access);
         SQLExecute (StatementHandle);

      begin
         loop
            SQLFetch (StatementHandle);
            SQLFixNTS (Name, Len_Name);
            SQLFixNTS (Firstname, Len_Firstname);
            Put (Name);
            Put (", ");
            Put (Firstname);
            Put (", ");
            RIO.Put (Item => Salary, Fore => 5, Aft => 2, Exp => 0);
            New_Line;
         end loop;
      exception
         when No_Data =>
            null;
      end;
   end;

   SQLCommit (ConnectionHandle);
   SQLDisconnect (ConnectionHandle);
   SQLFreeHandle (SQL_HANDLE_DBC, ConnectionHandle);
   SQLFreeHandle (SQL_HANDLE_ENV, EnvironmentHandle);

end odbc_mysql;
======================================================


Thanks,
Hubert Walter



^ permalink raw reply	[relevance 3%]

* Re: DOS Options
  2007-12-21  0:39  0%       ` Jeffrey R. Carter
@ 2007-12-22  0:45  0%         ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2007-12-22  0:45 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@acm.nospam.org> wrote in message
news:eXDaj.259984$Fc.65173@attbi_s21...
> Randy Brukardt wrote:
...
> > Ada.Command_Line is a thinly-veiled wrapper on the normal C "argv/argc"
> > mechanism. I think most Ada compilers simply copy that mechanism (that's
> > pretty much a requirement on Unix, and it is better for portability on
all
> > platforms). The fact that that mechanism isn't very useful is not
considered
> > relevant. (And yes, for the record, Janus/Ada does exactly that for
> > Ada.Command_Line. We don't even bother to use Ada.Command_Line for the
> > command line processing of our compiler and tools; it is just as easy to
> > process starting from the original string.)
> >
> >                        Randy.
> >
> >
>
> This got posted 5 times. That's a record, even for you.

I didn't notice that each time I wrote a message (and I wrote a bunch that
day), it tried again to post that message and failed (well, failed on this
end, obviously it didn't *actually* fail). Normally, it would just try when
I close the newsreader and then again when I reopen it (leading to a double
posting at most). That behavior hasn't repeated (that goodness), but I'm not
at all sure what is going on in any case. Hopefully it will go away and stay
that way...

                       Randy.





^ permalink raw reply	[relevance 0%]

* Re: DOS Options
  @ 2007-12-21  0:39  0%       ` Jeffrey R. Carter
  2007-12-22  0:45  0%         ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: Jeffrey R. Carter @ 2007-12-21  0:39 UTC (permalink / raw)


Randy Brukardt wrote:
> "Charles H. Sampson" <csampson@inetworld.net> wrote in message
> news:1i9d4ab.twgszk4zp5evN%csampson@inetworld.net...
> ...
>>      This has the effect that it's still necessary to write a parser for
>> Argument (1), something I thought Ada.Command_Line might be taking care
>> of.  I'm talking about the case of multiple slash-headed options jammed
>> against the command:
>>
>>         command/x/y/z
>>
>> I was hoping that Ada.Command_Line would return "/x" as Argument (1),
>> "/y" as Argument (2), etc.
>>
>>      Is the GNAT implementation a reasonable one?  Knowing some of the
>> people at ACT, I suspect that they researched it fully and are doing
>> exactly what is expected for a DOS program.
> 
> Ada.Command_Line is a thinly-veiled wrapper on the normal C "argv/argc"
> mechanism. I think most Ada compilers simply copy that mechanism (that's
> pretty much a requirement on Unix, and it is better for portability on all
> platforms). The fact that that mechanism isn't very useful is not considered
> relevant. (And yes, for the record, Janus/Ada does exactly that for
> Ada.Command_Line. We don't even bother to use Ada.Command_Line for the
> command line processing of our compiler and tools; it is just as easy to
> process starting from the original string.)
> 
>                        Randy.
> 
> 

This got posted 5 times. That's a record, even for you.

-- 
Jeff Carter
"We use a large, vibrating egg."
Annie Hall
44



^ permalink raw reply	[relevance 0%]

* Re: DOS Options
  2007-12-19 23:36  0%         ` Adam Beneschan
@ 2007-12-20 22:15  0%           ` Randy Brukardt
  0 siblings, 0 replies; 200+ results
From: Randy Brukardt @ 2007-12-20 22:15 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message
news:4c374a25-562c-4b8e-9770-07868bd88f15@e23g2000prf.googlegroups.com...
> On Dec 19, 2:59 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
> > "Gautier" <gaut...@fakeaddress.nil> wrote in message
> >
> > news:476973a3$1_5@news.bluewin.ch...
> > ...
> >
> > > Your 3.15p is certainly the Windows version, and what you are seeing
is a
> > Win32
> > > console output. Indeed, you need to congratulate Microsoft which
decided
> > to
> > > parse and separate the arguments in Win32 in a fashion consistent with
> > DOS -
> > > adding the parsing of filenames containing spaces, enclosed by "".
> > > Ada.Command_Line.Argument(i) just gives the "ith" argument from the
> > system, as
> > > the system wants to give it, that's it.
> >
> > I have no idea what you are talking about. Both MS-DOS and Win32 only
> > provide a single string as the result of the command line -- the system
> > provides no parsing whatsoever. For Win32, the function is
GetCommandLine.
> > In DOS, you had to grab the string from the memory of your executable
> > process -- there isn't even a function to get it.
>
> Windows does appear to have a CommandLineToArgvW function that parses
> the command line (or whatever string you give it).  I don't know
> whether GNAT uses it.  I'm pretty sure that not all C compilers use
> it---the MINGW32 version, I believe, does its own parsing, in whatever
> startup routine is linked into the program before main() is called.

Fascinating; never noticed that one. I doubt anything much uses it, though,
because it isn't supported on Windows 95/98/ME, so any compiler runtime that
used it would have to be almost brand-new. (It would have been nasty to make
programs that don't run on older Windows systems just to use a function that
is easy to write yourself. Not as big of an issue today, but I doubt
compiler vendors are rewriting their runtime to purposely break something
that previously worked!)

                              Randy.





^ permalink raw reply	[relevance 0%]

* Re: DOS Options
  @ 2007-12-19 23:36  0%         ` Adam Beneschan
  2007-12-20 22:15  0%           ` Randy Brukardt
  0 siblings, 1 reply; 200+ results
From: Adam Beneschan @ 2007-12-19 23:36 UTC (permalink / raw)


On Dec 19, 2:59 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
> "Gautier" <gaut...@fakeaddress.nil> wrote in message
>
> news:476973a3$1_5@news.bluewin.ch...
> ...
>
> > Your 3.15p is certainly the Windows version, and what you are seeing is a
> Win32
> > console output. Indeed, you need to congratulate Microsoft which decided
> to
> > parse and separate the arguments in Win32 in a fashion consistent with
> DOS -
> > adding the parsing of filenames containing spaces, enclosed by "".
> > Ada.Command_Line.Argument(i) just gives the "ith" argument from the
> system, as
> > the system wants to give it, that's it.
>
> I have no idea what you are talking about. Both MS-DOS and Win32 only
> provide a single string as the result of the command line -- the system
> provides no parsing whatsoever. For Win32, the function is GetCommandLine.
> In DOS, you had to grab the string from the memory of your executable
> process -- there isn't even a function to get it.

Windows does appear to have a CommandLineToArgvW function that parses
the command line (or whatever string you give it).  I don't know
whether GNAT uses it.  I'm pretty sure that not all C compilers use
it---the MINGW32 version, I believe, does its own parsing, in whatever
startup routine is linked into the program before main() is called.

                                -- Adam



^ permalink raw reply	[relevance 0%]

Results 1-200 of ~700   | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2007-12-05  3:34     DOS Options Charles H. Sampson
2007-12-05  5:15     ` Jeffrey Creem
2007-12-19 18:00       ` Charles H. Sampson
2007-12-19 19:40         ` Gautier
2007-12-19 22:59           ` Randy Brukardt
2007-12-19 23:36  0%         ` Adam Beneschan
2007-12-20 22:15  0%           ` Randy Brukardt
2007-12-19 22:47         ` Randy Brukardt
2007-12-21  0:39  0%       ` Jeffrey R. Carter
2007-12-22  0:45  0%         ` Randy Brukardt
2008-08-01 12:18  3% Gnade/ODBC example - please help azdakiel
2008-09-12 12:05     Command Line on windows RasikaSrinivasan
2008-09-12 12:25  6% ` Gautier
2008-09-12 14:36  8%   ` RasikaSrinivasan
2008-09-19 12:21     Structure of the multitasking server Maciej Sobczak
2008-09-19 23:01  3% ` anon
2008-09-22 13:05     ` Maciej Sobczak
2008-09-23  9:25  4%   ` anon
2009-05-01 21:39     GNAT on WinXP: System.OS_Lib.Spawn raises Program_Error daniel.wengelin
2009-05-02  6:28  7% ` Example of Spawn call anon
2009-05-02 15:50  0%   ` Hang
2009-05-02 18:28  0%     ` anon
2009-05-04  9:08     How to exit an Ada program with (unix shell) error code? reinkor
2009-05-04  9:17  6% ` Samuel Tardieu
2009-05-04  9:26  0%   ` reinkor
2009-05-04  9:31  7%     ` Ludovic Brenta
2009-05-04  9:47  0%       ` reinkor
2009-05-04  9:54  0%         ` Martin
2009-05-04 10:07  8%       ` stefan-lucks
2009-05-04 16:09  7% ` anon
2009-05-05 10:49  0%   ` Rob Norris
2009-05-05 11:15  0%     ` Georg Bauhaus
2009-05-05 11:43  0%   ` Martin
2009-05-05 14:57  0%     ` Adam Beneschan
2009-05-05 20:48  0%       ` anon
2009-05-05 20:31  4%     ` anon
2009-05-05 21:27  0%       ` Martin
2009-05-06  8:41  0%         ` anon
2009-05-06  9:14  0%           ` Martin
2009-05-06 15:28     ` Adam Beneschan
2009-05-07  9:08  8%   ` anon
2009-05-07 16:26  8%     ` Adam Beneschan
2009-05-08 10:17  7%       ` anon
2009-05-12 22:55  7%         ` Adam Beneschan
2009-05-14  2:55  0%           ` anon
2009-05-14 15:34     ` Adam Beneschan
2009-05-15 10:20  5%   ` anon
2009-06-28 23:08     unsigned type anon
2009-06-29  0:19     ` tmoran
2009-06-29  8:00       ` anon
2009-06-29  9:56         ` Jean-Pierre Rosen
2009-06-29 20:19  5%       ` anon
2009-08-01 17:53     Interpretation of extensions different from Unix/Linux? vlc
2009-08-02 17:13     ` Jacob Sparre Andersen
2009-08-04 11:31       ` vlc
2009-08-14  5:19         ` Randy Brukardt
2009-08-14  6:13  7%       ` Wilcards in Linux (was: Interpretation of extensions different from Unix/Linux?) stefan-lucks
2009-08-16 21:34  4% C++ threads vs. Ada tasks - surprised Maciej Sobczak
2009-09-15 20:58  6% Ada.Command_Line.Argument_Count question 
2009-09-15 21:37 13% ` Gautier write-only
2009-09-16  6:21  6%   ` 
2009-09-16 18:43 11%   ` Keith Thompson
2009-09-22 19:52  6%     ` Gautier write-only
2009-09-22 20:00  6%       ` Hyman Rosen
2009-09-23  0:20  6%         ` Gautier write-only
2009-09-23  1:07  6%           ` Adam Beneschan
2009-09-23 13:03  5%             ` Hyman Rosen
2009-09-23 16:06  6%             ` Gautier write-only
2009-09-24  0:31  6%               ` Björn Persson
2009-09-24  1:11  6%                 ` Adam Beneschan
2009-09-25 12:25  6%                   ` Stephen Leake
2009-09-15 21:55  4% ` Adam Beneschan
2009-09-16  6:20  6%   ` 
2009-09-16 10:41  6% ` Jeffrey R. Carter
2009-09-17 13:50  6% ` John McCabe
2009-09-18  5:12  6%   ` sjw
2009-09-18 15:03 12%     ` John McCabe
2009-09-18 22:16  6%       ` Robert A Duff
2009-09-21 15:09 12%         ` John McCabe
2009-09-21 15:17  6%           ` Dmitry A. Kazakov
2009-09-21 19:44  6%           ` sjw
2009-09-22 11:01  6%             ` John McCabe
2009-09-27  1:08  5% Tasking for Mandelbrot program Georg Bauhaus
2009-09-27 11:24     ` Martin
2009-09-27 21:27       ` Georg Bauhaus
2009-09-28 19:52         ` jonathan
2009-10-12 16:58           ` Georg Bauhaus
2009-10-13  9:11             ` Mark Lorenzen
2009-10-13  9:39               ` Gautier write-only
2009-10-13 12:57  6%             ` Georg Bauhaus
2009-10-02 19:54     Get the path and namefile in run time Pablo
2009-10-02 20:13     ` Dmitry A. Kazakov
2009-10-03 17:09  6%   ` sjw
2009-10-29 23:29     Performance of the Streams 'Read and 'Write Gautier write-only
2009-10-30 13:40  5% ` Gautier write-only
2009-11-02 22:19  5%   ` Gautier write-only
2010-01-05  1:06  3% gdb hijacks my argument list Leslie
2010-05-18  7:48     Disabling string evaluation in a logging system dhenry
2010-05-18  9:32     ` Gautier write-only
2010-05-18 11:27  8%   ` Gautier write-only
2010-07-11  4:22  4% Example GNAT Ada program for openGl anon
2010-08-21  4:47 12% What about a glob standard method in Ada.Command_Line ? Yannick Duchêne (Hibou57)
2010-08-21  6:41  6% ` J-P. Rosen
2010-08-21  7:21  6%   ` Yannick Duchêne (Hibou57)
2010-08-21  9:11  6%   ` Pascal Obry
2010-08-22 19:00  6%     ` J-P. Rosen
2010-08-22 19:29  6%       ` Yannick Duchêne (Hibou57)
2010-08-23 23:06  6%       ` Randy Brukardt
2010-08-24  0:02  5%         ` Yannick Duchêne (Hibou57)
2010-08-24  0:24 11%           ` Adam Beneschan
2010-08-24 10:27  6%             ` Georg Bauhaus
2010-08-24 14:24  6%               ` Dmitry A. Kazakov
2010-08-24 15:42  6%                 ` Georg Bauhaus
2010-08-24 16:04  5%                   ` Dmitry A. Kazakov
2010-08-24 17:10  5%                     ` Georg Bauhaus
2010-08-24 17:24  6%                       ` Georg Bauhaus
2010-08-24 18:42 11%                         ` Yannick Duchêne (Hibou57)
2010-08-24 18:51  6%                           ` Simon Wright
2010-08-24 17:41  6%                       ` Dmitry A. Kazakov
2010-08-24 21:32  4%                         ` Georg Bauhaus
2010-08-25  7:55  5%                           ` Dmitry A. Kazakov
2010-08-25  8:24  6%                             ` Yannick Duchêne (Hibou57)
2010-08-25 20:15  6%                               ` (see below)
2010-08-25 20:39  5%                                 ` Yannick Duchêne (Hibou57)
2010-08-25 21:05  6%                                   ` (see below)
2010-08-25 21:32  5%                                     ` Yannick Duchêne (Hibou57)
2010-08-25  8:57  5%                             ` Georg Bauhaus
2010-08-25  9:28  6%                               ` Dmitry A. Kazakov
2010-08-25 11:09  4%                                 ` Georg Bauhaus
2010-08-25 12:01  6%                                   ` Dmitry A. Kazakov
2010-08-25 13:09  6%                                     ` Georg Bauhaus
2010-08-25 13:30  6%                                       ` Dmitry A. Kazakov
2010-08-25 14:20  4%                                         ` Georg Bauhaus
2010-08-25 14:56  5%                                           ` Dmitry A. Kazakov
2010-08-25 15:51  4%                                             ` Georg Bauhaus
2010-08-25 16:46  6%                                               ` Dmitry A. Kazakov
2010-08-25 18:44  4%                                                 ` Georg Bauhaus
2010-08-25 19:39  5%                                                   ` Dmitry A. Kazakov
2010-08-26  0:59  3%                                                     ` Georg Bauhaus
2010-08-26  8:49  6%                                                       ` Dmitry A. Kazakov
2010-09-02 19:25  5%                                                         ` Randy Brukardt
2010-09-02 20:47  5%                                                           ` Dmitry A. Kazakov
2010-09-02 19:08  5%                                                       ` Randy Brukardt
2010-09-02 20:48  5%                                                         ` Georg Bauhaus
2010-08-22 19:30  6%     ` Yannick Duchêne (Hibou57)
2010-08-22 19:46  6%       ` Dmitry A. Kazakov
2010-08-25 13:09  6% ` anon
2010-08-25 13:13  6%   ` Georg Bauhaus
2010-08-25 13:28  6%     ` J-P. Rosen
2010-08-25 20:29  6%       ` Yannick Duchêne (Hibou57)
2010-08-25 14:14  6%     ` Jeffrey Carter
2010-08-25 21:37  6%     ` anon
2010-08-26  8:21  6%       ` J-P. Rosen
2010-08-26 16:29  3%         ` anon
2010-08-26 20:34  3%           ` Yannick Duchêne (Hibou57)
2010-08-27  4:40  4%             ` Yannick Duchêne (Hibou57)
2010-08-27 12:10  6%           ` J-P. Rosen
2010-09-01  8:08  6%             ` Ada compilers and Ada 2005 (was: What about a glob standard method in Ada.Command_Line ?) Georg Bauhaus
2010-10-23 20:16  9% Problems with String processing George
2010-10-23 20:24  6% ` Niklas Holsti
2010-10-23 20:25  6% ` Dmitry A. Kazakov
2010-10-23 23:59  0% ` Jeffrey Carter
2010-10-23 21:08  9% Wrong program structure George
2010-10-23 21:16  0% ` Vinzent Hoefler
2011-02-18 22:52     Need some light on using Ada or not Luis P. Mendes
2011-02-19 13:07     ` Brian Drummond
2011-02-19 14:36       ` Georg Bauhaus
2011-02-19 18:25         ` Brian Drummond
2011-02-20 14:34  5%       ` Brian Drummond
2011-02-20 15:45             ` jonathan
2011-02-20 19:49               ` Pascal Obry
2011-02-20 19:57                 ` Brian Drummond
2011-02-20 22:47                   ` Simon Wright
2011-02-21 12:52  5%                 ` Brian Drummond
2011-02-21 13:44  5%                   ` Simon Wright
2011-02-22  2:15  3%                   ` Shark8
2011-07-02 14:47     Passing shell arguments to Ada programs the Linux way A famous IT technical writer
2011-07-02 15:40     ` Simon Wright
2011-07-03  5:44  7%   ` anon
2011-07-04 16:59  0%     ` Oliver Kleinke
2011-07-25 17:36  7% Eigenvalues to find roots of polynomials marius63
2011-07-26  6:21     ` John B. Matthews
2011-07-26 15:40  7%   ` marius63
2011-10-14  6:58     Why no Ada.Wide_Directories? Michael Rohan
2011-10-15  1:06     ` ytomino
2011-10-17 21:33       ` Randy Brukardt
2011-10-17 23:47  5%     ` ytomino
2011-10-18  1:10  0%       ` Adam Beneschan
2011-10-18  2:32  4%         ` ytomino
2011-10-18  2:59         ` Yannick Duchêne (Hibou57)
2011-10-18  4:07  5%       ` Michael Rohan
2011-12-21 15:14     Debugging Ada awdorrin
2011-12-21 16:45     ` Ludovic Brenta
2011-12-21 16:51       ` awdorrin
2011-12-21 17:18  6%     ` Ludovic Brenta
2012-06-29  9:17     GNAT (GCC) Profile Guided Compilation Keean Schupke
2012-06-29 12:39     ` gautier_niouzes
2012-06-29 12:52       ` Keean Schupke
2012-06-29 14:14         ` gautier_niouzes
2012-06-29 15:05           ` gautier_niouzes
2012-06-29 17:03             ` Keean Schupke
2012-07-01 17:45  4%           ` Georg Bauhaus
2012-07-01 22:57  0%             ` Keean Schupke
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  5%     ` Niklas Holsti
2012-07-21 17:47  3%       ` Patrick
2012-10-23 19:42     Ada.Storage_IO: applied example? Yannick Duchêne (Hibou57)
2012-10-23 20:28     ` Dmitry A. Kazakov
2012-10-24  5:03       ` J-P. Rosen
2012-10-24  7:34         ` Dmitry A. Kazakov
2012-10-24  9:49           ` AdaMagica
2012-10-24 10:28             ` Dmitry A. Kazakov
2012-10-24 11:51               ` Yannick Duchêne (Hibou57)
2012-10-24 14:03  5%             ` Georg Bauhaus
2012-12-07 18:14     platform specific question Hans Vlems
2012-12-07 18:29  7% ` Jeffrey Carter
2012-12-09 13:50  0%   ` Hans Vlems
2012-12-09 15:11  0%     ` Bill Findlay
2012-12-10 11:36  0%       ` Hans Vlems
2013-03-07 18:04     Ada and OpenMP Rego, P.
2013-03-07 22:52     ` Simon Wright
2013-03-08 21:37  8%   ` Brad Moore
2013-04-23 20:30  5% Gnat Version 4.5.4 v protected objects v tasking stvcook53
2013-06-27 13:53     Where would you start debugging? Peter Brooks
2013-06-27 14:33  5% ` G.B.
2013-06-28 10:35  0%   ` Peter Brooks
2013-08-09 16:50     4 beginner's questions on the PL Ada Emanuel Berg
2013-08-09 17:09  4% ` Adam Beneschan
2013-08-10 12:31  7% ` Emanuel Berg
2013-08-10 12:37  0%   ` Emanuel Berg
2014-01-28  1:06     need help learning Ada for a modula-2 programmer agent
2014-01-28 12:18     ` Brian Drummond
2014-02-02  2:47       ` agent
2014-02-02  6:09  9%     ` Jeffrey Carter
2014-02-02 15:02  0%       ` agent
2014-02-02 19:48  9%         ` Jeffrey Carter
2014-03-20 17:00     Generating an XML DOM tree from scratch withXML/Ada 2013 Marc C
2014-03-21 16:12  7% ` J Kimball
2014-05-02  8:42     Safety of unprotected concurrent operations on constant objects Natasha Kerensikova
2014-05-03 13:43     ` sbelmont700
2014-05-03 20:54       ` Natasha Kerensikova
2014-05-03 21:40         ` Simon Wright
2014-05-04  0:28           ` Jeffrey Carter
2014-05-04  7:46             ` Natasha Kerensikova
2014-05-04 15:18               ` sbelmont700
2014-05-04 15:57                 ` Natasha Kerensikova
2014-05-05 19:04                   ` Brad Moore
2014-05-05 21:23                     ` Brad Moore
2014-05-04 21:44                       ` Shark8
2014-05-05  8:39                         ` Simon Wright
2014-05-05 15:11                           ` Brad Moore
2014-05-05 16:36                             ` Dmitry A. Kazakov
2014-05-06  6:00                               ` Brad Moore
2014-05-06  8:11                                 ` Dmitry A. Kazakov
2014-05-08  4:12                                   ` Brad Moore
2014-05-08  8:20                                     ` Dmitry A. Kazakov
2014-05-09 13:14                                       ` Brad Moore
2014-05-09 19:00                                         ` Dmitry A. Kazakov
2014-05-10 12:30                                           ` Brad Moore
2014-05-10 20:27                                             ` Dmitry A. Kazakov
2014-05-11  6:56  5%                                           ` Brad Moore
2014-06-15 17:07     Lotto simulation montgrimpulo
2014-06-15 18:54     ` Stefan.Lucks
2014-06-15 19:53       ` J-P. Rosen
2014-06-16  5:25         ` Stefan.Lucks
2014-06-16  7:49           ` J-P. Rosen
2014-06-16 11:15  6%         ` Stefan.Lucks
2014-08-09 15:35     Preconditions which anyway would be caught? Victor Porton
2014-08-09 16:08  6% ` Jeffrey Carter
2014-10-05 15:39  5% specification file ads problem Stribor40
2014-11-21 11:41     How to get nice with GNAT? Natasha Kerensikova
2014-11-21 12:42  4% ` Björn Lundin
2015-07-27 14:28     Running a preprocessor from GPS? EGarrulo
2015-07-27 20:26     ` Randy Brukardt
2015-07-28 11:36       ` EGarrulo
2015-07-28 21:12         ` Randy Brukardt
2015-07-28 22:11           ` EGarrulo
2015-07-29 20:32             ` Randy Brukardt
2015-07-29 22:32               ` EGarrulo
2015-07-29 23:51                 ` Jeffrey R. Carter
2015-07-30  0:10                   ` EGarrulo
2015-07-30  6:01                     ` Niklas Holsti
2015-07-30  7:33                       ` Björn Lundin
2015-07-30  8:03                         ` EGarrulo
2015-07-30  8:08                           ` Jacob Sparre Andersen
2015-07-30  8:37                             ` EGarrulo
2015-07-30 19:29                               ` Jeffrey R. Carter
2015-07-30 20:53                                 ` EGarrulo
2015-07-30 22:52  4%                               ` Jeffrey R. Carter
2015-08-27 13:52  6% Exclusive file access ahlan
2015-08-28  5:41  0% ` ahlan
2015-08-28  7:10  0%   ` Georg Bauhaus
2015-08-28 17:40  0% ` ahlan
2015-09-01 12:37  0% ` brbarkstrom
2015-09-01 14:05  0% ` ahlan
2015-09-01 20:02  0%   ` brbarkstrom
2015-09-01 15:31  0% ` ahlan
2015-10-26 10:21     HELP | function Is_Open (File : File_Type) return Boolean; package ada.text_io comicfanzine
2015-10-26 20:40  7% ` Niklas Holsti
2016-01-06 15:55     Re-write a file in Ada comicfanzine
2016-01-10 16:54     ` comicfanzine
2016-01-11 17:16       ` Brian Drummond
2016-01-18 15:05         ` gautier_niouzes
2016-01-19 12:24  5%       ` Brian Drummond
2016-04-21 12:59  7% Building an encapsulated library that uses GNAT sockets under Windows Dmitry A. Kazakov
2016-04-22  7:58  0% ` ahlan.marriott
2016-04-22  8:23  0%   ` Dmitry A. Kazakov
2016-04-23  9:20  0%     ` Ahlan
2016-04-30 20:49  8% GNAT.Command_Line and -? rrr.eee.27
2016-05-12 11:36     Ada.Strings.Fixed.Count raises Storage_Error Xavier Petit
2016-05-12 22:05     ` Georg Bauhaus
2016-06-26 21:18       ` Victor Porton
2016-06-26 23:23         ` rieachus
2016-06-27  0:51           ` Xavier Petit
2016-06-27  4:48             ` rieachus
2016-06-28 18:25  5%           ` Xavier Petit
2016-06-05 23:26  7% An extra CR character when writing to file (in addition to CR LF) John Smith
2016-09-21 22:05     New to Ada need help implementing Warshall's algorithm James Brewer
2016-09-23  4:31     ` Shark8
2016-09-23  6:26       ` Simon Wright
2016-09-23 15:07         ` James Brewer
2016-09-25 16:06  7%       ` Stephen Leake
2016-09-26 20:40  6%         ` Simon Wright
2016-09-30 22:27     Passing a 2d array into a package and returning the same processed 2d back to main diane74
2016-10-03 18:36     ` James Brewer
2016-10-03 19:43       ` Björn Lundin
2016-10-03 21:59         ` James Brewer
2016-10-04 11:29           ` Brian Drummond
2016-10-05 16:16             ` James Brewer
2016-10-05 17:19  3%           ` James Brewer
2017-10-28 20:02  1% Read-write mutex sometimes fails on deadlock pascal.malaise
2019-11-07 22:05     hello world ada-ncurses new_window Alain De Vos
2019-11-08  6:50  6% ` J-P. Rosen
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  6%         ` Dmitry A. Kazakov
2020-06-06 23:40  4% CONSTRAINT ERROR: erroneous memory access jcupak
2020-06-07 15:53  0% ` Anh Vo
2023-02-28 21:10     Build order with gprbuild Gautier write-only address
2023-02-28 22:07     ` Dmitry A. Kazakov
2023-03-01 20:08  5%   ` Gautier write-only address
2023-07-27  5:26     When using the Ada Big_Numbers.Big_Integers package, can the To_String function output be sliced? Kenneth Wolcott
2023-07-27  8:53     ` Jeffrey R.Carter
2023-07-27 22:47  6%   ` Kenneth Wolcott
2023-07-28 18:21         ` Simon Wright
2023-07-29 11:07           ` AdaMagica
2023-07-29 23:49             ` Kenneth Wolcott
2023-07-29 23:53  7%           ` Kenneth Wolcott
2023-07-30  4:43  6%             ` Randy Brukardt

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