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: XMLAda & unicode symbols
  2021-06-20 18:16  0%         ` Dmitry A. Kazakov
@ 2021-06-21 19:40  0%           ` 196...@googlemail.com
  0 siblings, 0 replies; 162+ results
From: 196...@googlemail.com @ 2021-06-21 19:40 UTC (permalink / raw)


On Sunday, 20 June 2021 at 19:16:57 UTC+1, Dmitry A. Kazakov wrote:
> On 2021-06-20 19:58, 196...@googlemail.com wrote: 
> > On Sunday, 20 June 2021 at 18:23:35 UTC+1, Dmitry A. Kazakov wrote: 
> >> On 2021-06-20 19:02, 196...@googlemail.com wrote: 
> >>> On Saturday, 19 June 2021 at 20:53:49 UTC+1, Jeffrey R. Carter wrote: 
> >>>> On 6/19/21 8:28 PM, 196...@googlemail.com wrote: 
> >>>>> I'm creating SVG files with XMLAda and I need to have a degree symbol within some text. 
> >>>>> 
> >>>>> I have: 
> >>>>> procedure Add_Min_Max (Min_Max_Str : String; X_Pos : String; Y_Pos : String) is 
> >>>> The degree symbol is part of Latin-1, so why not include it directly in your string? 
> >>>> 
> >>>> S : constant String := "50" & Ada.Characters.Handling.Latin_1.Degree_Sign; 
> >>> 
> >>> Unfortunately, when XMLAda comes to exporting the DOM tree, it crashed with: 
> >>> raised UNICODE.CES.INVALID_ENCODING : unicode-ces-utf8.adb:258 
> >> Maybe it expects UTF-8, as most third party Ada libraries do. In that 
> >> case use: 
> >> 
> >> Character'Val (16#C2#) & Character'Val (16#B0#) 
> > 
> > That's the degree symbol, what I really need is the degree centigrade symbol which is U+2103. 
> > 
> > Having Character'Val (16#21#) & Character'Val (16#03#) fails at runtime. 
> > 
> > I'm sure it's easy enough, and when I get it, I'll be banging my head against the desk.
> Why do you use XMLAda? SVG is a text file, I would write directly. It is 
> the reverse, rendering SVG image, that is difficult to write from scratch. 
> 
> And why do you want to create SVG files?
> -- 
> Regards, 
> Dmitry A. Kazakov 
> http://www.dmitry-kazakov.de

I am using XML/Ada as I wish to do it "properly", it's the way you learn.

As for SVG, I am graphing temps, humidity & pressure, and when you zoom in, it still looks sharp. The previous system I coded in C, used png's which were screwed up when Google screwed up and forced HDPI settings on chrome users. THE svg's will also contain code to highlight etc points.

^ permalink raw reply	[relevance 0%]

* Re: XMLAda & unicode symbols
  2021-06-20 17:02  0%   ` 196...@googlemail.com
  2021-06-20 17:23  0%     ` Dmitry A. Kazakov
@ 2021-06-20 18:21  0%     ` Jeffrey R. Carter
  1 sibling, 0 replies; 162+ results
From: Jeffrey R. Carter @ 2021-06-20 18:21 UTC (permalink / raw)


On 6/20/21 7:02 PM, 196...@googlemail.com wrote:
> On Saturday, 19 June 2021 at 20:53:49 UTC+1, Jeffrey R. Carter wrote:
>> On 6/19/21 8:28 PM, 196...@googlemail.com wrote:
>>> I'm creating SVG files with XMLAda and I need to have a degree symbol within some text.
>>>
>>> I have:
>>> procedure Add_Min_Max (Min_Max_Str : String; X_Pos : String; Y_Pos : String) is
>> The degree symbol is part of Latin-1, so why not include it directly in your string?
>>
>> S : constant String := "50" & Ada.Characters.Handling.Latin_1.Degree_Sign;
>>
>> -- 
>> Jeff Carter
>> "I would never want to belong to any club that
>> would have someone like me for a member."
>> Annie Hall
>> 41
> 
> Unfortunately, when XMLAda comes to exporting the DOM tree, it crashed with:
> raised UNICODE.CES.INVALID_ENCODING : unicode-ces-utf8.adb:258

I would call that an error in XMLAda. Anything that uses String should accept 
any String.

The exception name indicates that XMLAda is probably misusing String to hold 
encoded Unicode text, probably with UTF-8 encoding. Any use of String as 
anything other than its intended use, as a sequence of Latin-1 characters, is a 
mistake.

-- 
Jeff Carter
"Help! Help! I'm being repressed!"
Monty Python & the Holy Grail
67

^ permalink raw reply	[relevance 0%]

* Re: XMLAda & unicode symbols
  2021-06-20 17:58  0%       ` 196...@googlemail.com
@ 2021-06-20 18:16  0%         ` Dmitry A. Kazakov
  2021-06-21 19:40  0%           ` 196...@googlemail.com
  0 siblings, 1 reply; 162+ results
From: Dmitry A. Kazakov @ 2021-06-20 18:16 UTC (permalink / raw)


On 2021-06-20 19:58, 196...@googlemail.com wrote:
> On Sunday, 20 June 2021 at 18:23:35 UTC+1, Dmitry A. Kazakov wrote:
>> On 2021-06-20 19:02, 196...@googlemail.com wrote:
>>> On Saturday, 19 June 2021 at 20:53:49 UTC+1, Jeffrey R. Carter wrote:
>>>> On 6/19/21 8:28 PM, 196...@googlemail.com wrote:
>>>>> I'm creating SVG files with XMLAda and I need to have a degree symbol within some text.
>>>>>
>>>>> I have:
>>>>> procedure Add_Min_Max (Min_Max_Str : String; X_Pos : String; Y_Pos : String) is
>>>> The degree symbol is part of Latin-1, so why not include it directly in your string?
>>>>
>>>> S : constant String := "50" & Ada.Characters.Handling.Latin_1.Degree_Sign;
>>>
>>> Unfortunately, when XMLAda comes to exporting the DOM tree, it crashed with:
>>> raised UNICODE.CES.INVALID_ENCODING : unicode-ces-utf8.adb:258
>> Maybe it expects UTF-8, as most third party Ada libraries do. In that
>> case use:
>>
>> Character'Val (16#C2#) & Character'Val (16#B0#)
> 
> That's the degree symbol, what I really need is the degree centigrade symbol which is U+2103.
> 
> Having Character'Val (16#21#) & Character'Val (16#03#) fails at runtime.
> 
> I'm sure it's easy enough, and when I get it, I'll be banging my head against the desk.

Why do you use XMLAda? SVG is a text file, I would write directly. It is 
the reverse, rendering SVG image, that is difficult to write from scratch.

And why do you want to create SVG files?

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

^ permalink raw reply	[relevance 0%]

* Re: XMLAda & unicode symbols
  2021-06-20 17:23  0%     ` Dmitry A. Kazakov
@ 2021-06-20 17:58  0%       ` 196...@googlemail.com
  2021-06-20 18:16  0%         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 162+ results
From: 196...@googlemail.com @ 2021-06-20 17:58 UTC (permalink / raw)


On Sunday, 20 June 2021 at 18:23:35 UTC+1, Dmitry A. Kazakov wrote:
> On 2021-06-20 19:02, 196...@googlemail.com wrote: 
> > On Saturday, 19 June 2021 at 20:53:49 UTC+1, Jeffrey R. Carter wrote: 
> >> On 6/19/21 8:28 PM, 196...@googlemail.com wrote: 
> >>> I'm creating SVG files with XMLAda and I need to have a degree symbol within some text. 
> >>> 
> >>> I have: 
> >>> procedure Add_Min_Max (Min_Max_Str : String; X_Pos : String; Y_Pos : String) is 
> >> The degree symbol is part of Latin-1, so why not include it directly in your string? 
> >> 
> >> S : constant String := "50" & Ada.Characters.Handling.Latin_1.Degree_Sign; 
> >
> > Unfortunately, when XMLAda comes to exporting the DOM tree, it crashed with: 
> > raised UNICODE.CES.INVALID_ENCODING : unicode-ces-utf8.adb:258
> Maybe it expects UTF-8, as most third party Ada libraries do. In that 
> case use: 
> 
> Character'Val (16#C2#) & Character'Val (16#B0#) 

That's the degree symbol, what I really need is the degree centigrade symbol which is U+2103.

Having Character'Val (16#21#) & Character'Val (16#03#) fails at runtime.

I'm sure it's easy enough, and when I get it, I'll be banging my head against the desk.

^ permalink raw reply	[relevance 0%]

* Re: XMLAda & unicode symbols
  2021-06-20 17:02  0%   ` 196...@googlemail.com
@ 2021-06-20 17:23  0%     ` Dmitry A. Kazakov
  2021-06-20 17:58  0%       ` 196...@googlemail.com
  2021-06-20 18:21  0%     ` Jeffrey R. Carter
  1 sibling, 1 reply; 162+ results
From: Dmitry A. Kazakov @ 2021-06-20 17:23 UTC (permalink / raw)


On 2021-06-20 19:02, 196...@googlemail.com wrote:
> On Saturday, 19 June 2021 at 20:53:49 UTC+1, Jeffrey R. Carter wrote:
>> On 6/19/21 8:28 PM, 196...@googlemail.com wrote:
>>> I'm creating SVG files with XMLAda and I need to have a degree symbol within some text.
>>>
>>> I have:
>>> procedure Add_Min_Max (Min_Max_Str : String; X_Pos : String; Y_Pos : String) is
>> The degree symbol is part of Latin-1, so why not include it directly in your string?
>>
>> S : constant String := "50" & Ada.Characters.Handling.Latin_1.Degree_Sign;
> 
> Unfortunately, when XMLAda comes to exporting the DOM tree, it crashed with:
> raised UNICODE.CES.INVALID_ENCODING : unicode-ces-utf8.adb:258

Maybe it expects UTF-8, as most third party Ada libraries do. In that 
case use:

    Character'Val (16#C2#) & Character'Val (16#B0#)

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

^ permalink raw reply	[relevance 0%]

* Re: XMLAda & unicode symbols
  2021-06-19 19:53  9% ` Jeffrey R. Carter
@ 2021-06-20 17:02  0%   ` 196...@googlemail.com
  2021-06-20 17:23  0%     ` Dmitry A. Kazakov
  2021-06-20 18:21  0%     ` Jeffrey R. Carter
  0 siblings, 2 replies; 162+ results
From: 196...@googlemail.com @ 2021-06-20 17:02 UTC (permalink / raw)


On Saturday, 19 June 2021 at 20:53:49 UTC+1, Jeffrey R. Carter wrote:
> On 6/19/21 8:28 PM, 196...@googlemail.com wrote: 
> > I'm creating SVG files with XMLAda and I need to have a degree symbol within some text. 
> > 
> > I have: 
> > procedure Add_Min_Max (Min_Max_Str : String; X_Pos : String; Y_Pos : String) is
> The degree symbol is part of Latin-1, so why not include it directly in your string? 
> 
> S : constant String := "50" & Ada.Characters.Handling.Latin_1.Degree_Sign; 
> 
> -- 
> Jeff Carter 
> "I would never want to belong to any club that 
> would have someone like me for a member." 
> Annie Hall 
> 41

Unfortunately, when XMLAda comes to exporting the DOM tree, it crashed with:
raised UNICODE.CES.INVALID_ENCODING : unicode-ces-utf8.adb:258

^ permalink raw reply	[relevance 0%]

* Re: XMLAda & unicode symbols
  @ 2021-06-19 19:53  9% ` Jeffrey R. Carter
  2021-06-20 17:02  0%   ` 196...@googlemail.com
  0 siblings, 1 reply; 162+ results
From: Jeffrey R. Carter @ 2021-06-19 19:53 UTC (permalink / raw)


On 6/19/21 8:28 PM, 196...@googlemail.com wrote:
> I'm creating SVG files with XMLAda and I need to have a degree symbol within some text.
> 
> I have:
> procedure Add_Min_Max (Min_Max_Str : String; X_Pos : String; Y_Pos : String) is

The degree symbol is part of Latin-1, so why not include it directly in your string?

S : constant String := "50" & Ada.Characters.Handling.Latin_1.Degree_Sign;

-- 
Jeff Carter
"I would never want to belong to any club that
would have someone like me for a member."
Annie Hall
41

^ permalink raw reply	[relevance 9%]

* Re: gnat_regpat and unexpected handling of alnum and unicode needed
  @ 2019-02-17 12:50 10% ` Simon Wright
  0 siblings, 0 replies; 162+ results
From: Simon Wright @ 2019-02-17 12:50 UTC (permalink / raw)


19.krause.70@googlemail.com writes:

> The expression [[:alnum:]] matches the underscore in gnat_regpat but
> not in egrep. It feels much more natural to don't match the underscore
> like egrep does. And I think it is more posix compliant.
>
> Question is why?

Because, at s-regpat.adb:2325, we find

   function Is_Alnum (C : Character) return Boolean is
   begin
      return Is_Alphanumeric (C) or else C = '_';
   end Is_Alnum;

(Is_Alphanumeric is in Ada.Characters.Handling), presumably because the
author liked using underscores in identifiers.

> How do I handle unicode strings with gnat_regpat, because [[:alpha:]]
> seems to match only ascii a-zA-Z.

What GNAT does with -gnatW8 is to read UTF-8 from the source file and,
in the case of characters, convert then to the internal Latin-1
(approximately) character. So your 'ö' is converted to the single
character with value 246, LC_O_Diaeresis.

I tried just letters, and got

   fööbär Matched regexp3 ^[[:alpha:]]+$!

No idea what's going on here!


^ permalink raw reply	[relevance 10%]

* Re: The extension of Is_Basic to unicode (about AI12-0260-1)
  2018-04-11 22:20  9%     ` Randy Brukardt
@ 2018-04-11 23:57  0%       ` ytomino
  0 siblings, 0 replies; 162+ results
From: ytomino @ 2018-04-11 23:57 UTC (permalink / raw)


On Thursday, April 12, 2018 at 7:20:28 AM UTC+9, Randy Brukardt wrote:
> "J-P. Rosen" <rosen@adalog.fr> wrote in message 
> news:palsmv$g18$1@gioia.aioe.org...
> > Le 11/04/2018 à 16:32, Dan'l Miller a écrit :
> >>> True if Item is a basic letter. A basic letter is a character that
> >>> is in one of the ranges 'A'..'Z' and 'a'..'z', or that is one of
> >>> the following: 'Æ', 'æ', 'Ğ', 'ğ', 'Ş', 'ş', or 'ß'.
> >> If this Ada-specific definition of this is-basic/base-Latin-letter
> >> property is the official normative list, then it seems rather
> >> arbitrary and capricious, not conforming to Unicode or to linguistic
> >> reality.
> >>
> >> In Unicode-speak's terminology/jargon, the definition of base
> >> character at https://definedterm.com/a/definition/160575 would admit
> >> quite a few more, [...]
> > The above Is_Basic is about Character, and is defined only when using
> > Latin-1. Unicode is a different standard.
> 
> Moreover, its definition is historical -- it was defined this way for Ada 
> 95, and whether or not that would be the correct definition had it been 
> defined in 2018 is irrelevant. Changing the definition would potentially 
> silently break programs that use it. There are a number of things in 
> Ada.Characters.Handling that aren't correct for Unicode purposes, one of 
> them is even called out by the third note in A.3.2.
> 
>                       Randy.

Thanks for your detailed description.

If Character.Handling.Is_Basic can not be changed because compatibility, still more, this *overloading* will create new problem for the future.

For example, on rewriting some applications from Character to Wide_Character, it may be imagined that two meanings of Is_Basic will confuse.
Or, they makes hard to use "use clause", or use as a generic formal subprogram.

Excuse me for repeating, should new function name be used for new definition?

  function Is_Base (Item : Wide_Character) return Boolean; -- according with Unicode
  function Is_Basic (Item : Wide_Character) return Boolean is (Is_Base (Item) and Is_Letter (Item)); -- for compatibility

^ permalink raw reply	[relevance 0%]

* Re: The extension of Is_Basic to unicode (about AI12-0260-1)
  @ 2018-04-11 22:20  9%     ` Randy Brukardt
  2018-04-11 23:57  0%       ` ytomino
  0 siblings, 1 reply; 162+ results
From: Randy Brukardt @ 2018-04-11 22:20 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1284 bytes --]

"J-P. Rosen" <rosen@adalog.fr> wrote in message 
news:palsmv$g18$1@gioia.aioe.org...
> Le 11/04/2018 à 16:32, Dan'l Miller a écrit :
>>> True if Item is a basic letter. A basic letter is a character that
>>> is in one of the ranges 'A'..'Z' and 'a'..'z', or that is one of
>>> the following: 'Æ', 'æ', 'Ð', 'ð', 'Þ', 'þ', or 'ß'.
>> If this Ada-specific definition of this is-basic/base-Latin-letter
>> property is the official normative list, then it seems rather
>> arbitrary and capricious, not conforming to Unicode or to linguistic
>> reality.
>>
>> In Unicode-speak's terminology/jargon, the definition of base
>> character at https://definedterm.com/a/definition/160575 would admit
>> quite a few more, [...]
> The above Is_Basic is about Character, and is defined only when using
> Latin-1. Unicode is a different standard.

Moreover, its definition is historical -- it was defined this way for Ada 
95, and whether or not that would be the correct definition had it been 
defined in 2018 is irrelevant. Changing the definition would potentially 
silently break programs that use it. There are a number of things in 
Ada.Characters.Handling that aren't correct for Unicode purposes, one of 
them is even called out by the third note in A.3.2.

                      Randy.




^ permalink raw reply	[relevance 9%]

* Re: CONSTRAINT ERROR? access check failed
  @ 2018-03-01 13:45 11%     ` Björn Lundin
  0 siblings, 0 replies; 162+ results
From: Björn Lundin @ 2018-03-01 13:45 UTC (permalink / raw)


On 2018-03-01 13:44, Mehdi Saada wrote:
> Those are the two last things I would like you people to review. First, I can't get out of that loop, even with the exit INNER; after "Rentrez vos commandes". It starts it again.
> 

seems strange, since you do exit INNNER.
Are you sure that not something else is happening,
like all this is in a procedure that you call again?


> INNER : loop
...
> 	Put_Line ("Rentrer maintenant vos commandes"); exit INNER;
>     exception when others => Put_Line ("ERREUR");
>     end;
> end loop INNER;
> 
> Then, could you tell what you think of that subprogram that is meant to purge a STRING from non graphic characters (those that make the program crash) ?


 I'm likely gettting bashed for using unbounded string like this,
 but I'd do like this

function Let_Only_Graphic_Characters (Input_String : in String) return
String is
  use Ada.Strings.Unbounded;
  use Ada.Characters.Handling;
  Tmp : Unbounded_String;
begin
  for i in Input_String'range loop
    if Is_Graphic(Input_String(i)) then
      Append(Tmp, Input_String(i));
    end if;
  end loop;
  return To_String(Tmp);
end Let_Only_Graphic_Characters;

or with 'for of' loop

function Let_Only_Graphic_Characters (Input_String : in String) return
String is
  use Ada.Strings.Unbounded;
  use Ada.Characters.Handling;
  Tmp : Unbounded_String;
begin
  for C of Input_String loop
    if Is_Graphic(C) then
      Append(Tmp, C);
    end if;
  end loop;
  return To_String(Tmp);
end Let_Only_Graphic_Characters;



-- 
--
Björn

^ permalink raw reply	[relevance 11%]

* Re: Question on bounded / unbounded strings
  2016-09-14 19:39  6%   ` Jeffrey R. Carter
@ 2016-09-17 16:35  6%     ` Arie van Wingerden
  0 siblings, 0 replies; 162+ results
From: Arie van Wingerden @ 2016-09-17 16:35 UTC (permalink / raw)


Thx for the extensive review!   I'll look into it.

"Jeffrey R. Carter"  schreef in bericht news:nrc923$nth$1@dont-email.me...

On 09/14/2016 05:57 AM, Arie van Wingerden wrote:
>
>    Path   : string := ASF.Translate(AEV.Value("Path"), 
> ASMC.Lower_Case_Map);
>    Match : string := ASF.Translate(ATIO.Get_Line, ASMC.Lower_Case_Map);

You might want to look at pkg Ada.Characters.Handling, particularly the
functions To_Lower.

Ada is case insensitive, and many of us will run your code through a 
formatter
to make it look like the code we're familiar with, converting identifiers to
Initial_Caps, and changing CamelCase into difficult to read things like
Findmatch. The recommended practice for Ada is to

>    procedure FindMatch (Match : in string; Path : in string; StartPos : in
> positive; Len : in natural) is
>        EndPos : positive;
>    begin
>        if Len > 0 then  -- Ignore case of an unnecessary semi colon

This test is unnecessary. If Len = 0, Endpos = Startpos - 1, and Startpos ..
Endpos is a null range. Any array sliced with a null range yields a 
zero-length
slice; in the case of String, the null string (""). Index will always return 
0
if Source is null and Pattern is not.

>            EndPos := StartPos + Len - 1;
>            if ASF.Index(Source => Path(StartPos .. EndPos), Pattern => 
> Match) >
> 0 then
>                ATIO.Put_Line(Path(StartPos .. EndPos));
>            end if;
>        end if;
>    end FindMatch;
>
>    procedure Match_Path (Match : in string; Path : in string) is
>        StartPos : positive := 1;
>        Len   : natural  := 0;
>    begin
>        for I in Path'Range loop
>            if Path(I) = ';' then

You can use index to find semi-colons in Path

   Index (Path, ";")

>                FindMatch(Match, Path, StartPos, Len);

Note that you're passing Path and Startpos to Findmatch, which uses Startpos 
as
an index into Path. The first time you do this, Startpos = 1. In other 
words,
you're assuming that 1 is a valid index for Path. While this may always be 
true
for this program, if you need to do something similar in another situation, 
you
might reuse this code, but pass a value for Path for which it is not true. 
It
would be better to initialize Startpos to Path'First.

Rather than calculate Endpos and slice Path in Findmatch, why not pass the 
slice
of Path

   procedure Findmatch (Match : in String; Path : in String);

   Findmatch (Match => Match, Path => Path (Startpos .. Startpos + Len - 
1) );

? As noted above, passing a null string for Path will not be a problem.

If Path doesn't contain ';', your program does nothing. If Path doesn't end 
with
';', the part of Path from the last semi-colon to the end won't be checked. 
What
should it do if Match is null?

I suspect this could be implemented more simply and clearly (and correctly)
using Index for the ';' as well as for Match.

-- 
Jeff Carter
"Since I strongly believe that overpopulation is by
far the greatest problem in the world, this [Soylent
Green] would be my only message movie."
Charleton Heston
123 


^ permalink raw reply	[relevance 6%]

* Re: Question on bounded / unbounded strings
  @ 2016-09-14 19:39  6%   ` Jeffrey R. Carter
  2016-09-17 16:35  6%     ` Arie van Wingerden
  0 siblings, 1 reply; 162+ results
From: Jeffrey R. Carter @ 2016-09-14 19:39 UTC (permalink / raw)


On 09/14/2016 05:57 AM, Arie van Wingerden wrote:
> 
>    Path   : string := ASF.Translate(AEV.Value("Path"), ASMC.Lower_Case_Map);
>    Match : string := ASF.Translate(ATIO.Get_Line, ASMC.Lower_Case_Map);

You might want to look at pkg Ada.Characters.Handling, particularly the
functions To_Lower.

Ada is case insensitive, and many of us will run your code through a formatter
to make it look like the code we're familiar with, converting identifiers to
Initial_Caps, and changing CamelCase into difficult to read things like
Findmatch. The recommended practice for Ada is to

>    procedure FindMatch (Match : in string; Path : in string; StartPos : in
> positive; Len : in natural) is
>        EndPos : positive;
>    begin
>        if Len > 0 then  -- Ignore case of an unnecessary semi colon

This test is unnecessary. If Len = 0, Endpos = Startpos - 1, and Startpos ..
Endpos is a null range. Any array sliced with a null range yields a zero-length
slice; in the case of String, the null string (""). Index will always return 0
if Source is null and Pattern is not.

>            EndPos := StartPos + Len - 1;
>            if ASF.Index(Source => Path(StartPos .. EndPos), Pattern => Match) >
> 0 then
>                ATIO.Put_Line(Path(StartPos .. EndPos));
>            end if;
>        end if;
>    end FindMatch;
> 
>    procedure Match_Path (Match : in string; Path : in string) is
>        StartPos : positive := 1;
>        Len   : natural  := 0;
>    begin
>        for I in Path'Range loop
>            if Path(I) = ';' then

You can use index to find semi-colons in Path

   Index (Path, ";")

>                FindMatch(Match, Path, StartPos, Len);

Note that you're passing Path and Startpos to Findmatch, which uses Startpos as
an index into Path. The first time you do this, Startpos = 1. In other words,
you're assuming that 1 is a valid index for Path. While this may always be true
for this program, if you need to do something similar in another situation, you
might reuse this code, but pass a value for Path for which it is not true. It
would be better to initialize Startpos to Path'First.

Rather than calculate Endpos and slice Path in Findmatch, why not pass the slice
of Path

   procedure Findmatch (Match : in String; Path : in String);

   Findmatch (Match => Match, Path => Path (Startpos .. Startpos + Len - 1) );

? As noted above, passing a null string for Path will not be a problem.

If Path doesn't contain ';', your program does nothing. If Path doesn't end with
';', the part of Path from the last semi-colon to the end won't be checked. What
should it do if Match is null?

I suspect this could be implemented more simply and clearly (and correctly)
using Index for the ';' as well as for Match.

-- 
Jeff Carter
"Since I strongly believe that overpopulation is by
far the greatest problem in the world, this [Soylent
Green] would be my only message movie."
Charleton Heston
123


^ permalink raw reply	[relevance 6%]

* How to check if letters are in a string?
@ 2015-07-18  9:00 11% Trish Cayetano
  0 siblings, 0 replies; 162+ results
From: Trish Cayetano @ 2015-07-18  9:00 UTC (permalink / raw)


Hi, 

How do you check if (exact number of) letters are in a string? 

1. This example should PASS because every letter is found in the string
LETTERS: HID
STRING:  HIDDEN

2. This example should FAIL because the letters contain 2 N's but the string only has 1 N. 
LETTERS: NINE
STRING:  HIDDEN


Pangram doesn't seem to be a solution... because it considers #2 above as PASS.
This is because pangrams check for AT LEAST one letter (this means, it considers a pangram even if the letter is a duplicate)


Is there another way how to check if (exact number of) letters are in a string? 
Thank you very much!


====
Here is the sample code: 

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Maps; use Ada.Strings.Maps;
with Ada.Characters.Handling; use Ada.Characters.Handling;
procedure main is
 
	function ispangram(txt: String) return Boolean is
		lowtxt : String := To_Lower(txt);
		letset,txtset : Character_Set;
		begin
		letset := To_Set("nine");
		txtset := To_Set(lowtxt);
		return (letset-txtset)=Null_Set;
	end ispangram;
 
begin
put_line(Boolean'Image(ispangram("hidden")));

end main;

============================================
OUTPUT: 

C:\Users\a0284014\Desktop\ada\pangram\obj\main
TRUE

[2015-07-18 16:52:42] process terminated successfully, elapsed time: 00.37s

^ permalink raw reply	[relevance 11%]

* Re: Parsing Ada?
  @ 2015-06-03 11:04 11%   ` Simon Wright
  0 siblings, 0 replies; 162+ results
From: Simon Wright @ 2015-06-03 11:04 UTC (permalink / raw)


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

> Note that ASIS does not produce a parse tree either; it just gives you
> structured access to the source. ASIS code tends to feel like a
> recursive descent parser (at least, for the tools I've written in
> ASIS).

You might find ASIS2XML[1] helpful (it doesn't attempt to retain
comments, and really only retains textual information (that is, it
retains the name in an entity reference but not the links to the
referenced entity). Also, could do some cleanup of compound identifiers
- it retains the ASIS structure; so "with Ada.Characters.Handling;"
becomes

      <with_clause>
        <selected_component>
          <selected_component>
            <identifier>Ada</identifier>
            <identifier>Characters</identifier>
          </selected_component>
          <identifier>Handling</identifier>
        </selected_component>
      </with_clause>

Also Avatox[2].

The ASIS GPL 2014 source distribution contains a tool gnat2xml which
doesn't appear to be installed automatically. I didn't like the schema
very much, can't remember why now!

You'd probably use xslt to work with the generated XML.

[1] https://sourceforge.net/projects/asis2xml/
[2] Original site unavailable. See the ASIS GPL 2014 distro,
    tools/gnat2xml for READMEs; I have a copy of avatox-1.8.tgz if you
    want.

^ permalink raw reply	[relevance 11%]

* Interesting containers problem.
@ 2015-04-17 13:42  7% Shark8
  0 siblings, 0 replies; 162+ results
From: Shark8 @ 2015-04-17 13:42 UTC (permalink / raw)


Ok, so let's say we have a type for Identifiers:

   SubType Identifier is String
   with Dynamic_Predicate => Is_Valid( Identifier )
     or else raise Parse_Error with "Invalid identifier: """ & Identifier & '"';
--...
   -- ACH is a rename for Ada.Characters.Handling.
   Function Is_Valid( Input: String ) return Boolean is
     ( Input'Length in Positive and then
       ACH.Is_Letter(Input(Input'First)) and then
       ACH.Is_Alphanumeric(Input(Input'Last)) and then
       (for all Ch of Input => Ch = '_' or ACH.Is_Alphanumeric(Ch)) and then
       (for all Index in Input'First..Positive'Pred(Input'Last) =>
          (if Input(Index) = '_' then Input(Index+1) /= '_')
       )
     );

And a few types for types:
   Type Data_Type is ( Integer, Float, Fixed );
   Type Variable_Data( Type_Value : Data_Type ) is
    case Type_Value is
     when Integer => Integer_Value : Standard.Integer;
     when Float   => Float_Value   : Standard.Float;
     when Fixed   => Fixed_Value   : Fixed_Type; -- Defined elsewhere.
    end case;
   end record;

Now we can define a Symbol-table using the standard containers simply with this:

  Package Symbol_Table is
    new Ada.Containers.Indefinite_Ordered_Maps(
        Key_Type     => Identifier,
        Element_Type => Variable_Data,
        "<"          => Ada.Strings.Less_Case_Insensitive,
        "="          => "="
    );

And that's all well and good; however, there is one limitation here that is revealed when you need nesting scopes -- there is, apparently, no way to define an Element_Type to feed to Indefinite_Ordered_Maps which is an instance of Indefinite_Ordered_Maps.Maps or an instance of Variable_Data (by way of a variant record; even one which is forward declared).

What would be the proper way to handle this sort of situation?

^ permalink raw reply	[relevance 7%]

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


Dear All,

I tried out GID (Generic Image Decoder) from

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

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

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

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

I did something very very stupid ?

reinert

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

Here is the actual code:

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

with Ada.Characters.Latin_1;

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

with system;
with Ada.Unchecked_Conversion;
with Interfaces;

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

with Text_IO; use Text_IO;




package body file_handling3 is

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

  use Interfaces;

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


  img_buf: p_Byte_Array := null;

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

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

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

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

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



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

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

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

      return img1;
    end;
 end read_jpg;

end file_handling3;

^ permalink raw reply	[relevance 9%]

* Re: A bad counterintuitive behaviour of Ada about OO
  @ 2014-08-08 19:34  7%                               ` Shark8
  0 siblings, 0 replies; 162+ results
From: Shark8 @ 2014-08-08 19:34 UTC (permalink / raw)


On 08-Aug-14 05:20, Dmitry A. Kazakov wrote:
> And they [subtypes] break in-operations. As an example consider:
>
>     X : Integer := -1;
>
> Now substitute Positive for Integer.

That's going the wrong way.
You're narrowing the set when you move to the subtype, so obviously not 
all values will be present; this is a Good Thing.

For example, we can enforce consistency [and correctness] in a DB with 
subtypes:

     Subtype Digit is Character range '0'..'9';

     -- The following is a string, of length 9, that has ONLY digits.
     Subtype Social_Security_Number is String(1..9)
     with Dynamic_Predicate =>
       (for all C of Social_Security_Number => C in Digit);

     -- The following function cannot have an invalid invalid SSN parameter.
     Procedure Save( SSN : Social_Security_Number; ID: User_ID);
     Function  Load(ID: User_ID) return Social_Security_Number;

And this is good because we *don't* want any string in the DB's SSN 
field, we only want strings which are SSNs.

Likewise, we may want Ada-like identifiers, say in a mapping:

     -- Validation rules:
     -- #1 - Identifier cannot be the empty-string.
     -- #2 - Identifier must contain only alphanumeric characters + 
underscore.
     -- #3 - Identifier cannot begin with a digit.
     -- #4 - Identifier cannot begin or end with an underscore.
     -- #5 - Identifier cannot have two consecutive underscores.
     Function Valid_Identifier(Input : String) return Boolean;

     -- A string containing an identifier.
     Subtype Identifier is String
       with Dynamic_Predicate => Valid_Identifier( Identifier )
                                 or else raise Constraint_Error;

     -- This package defines a mapping of a name to a type; both of these
     -- are instances of Identifier.
     Package Attribute_List is new Ada.Containers.Indefinite_Ordered_Maps(
         Key_Type     => Identifier,
         Element_Type => Identifier
       );

     -- ...in body.

     Function Valid_Identifier(Input : String) return Boolean is
         Subtype Internal_Range is Natural range 
Input'First+1..Input'Last-1;
         First : Character renames Input(Input'First);
         Last  : Character renames Input(Input'Last);

         Use Ada.Characters.Handling;
     Begin
         -- Initialize w/ conformance to rule #1.
         Return Result : Boolean:= Input'Length in Positive do
             -- Rule 2
             Result:= Result and
               (For all C of Input => Is_Alphanumeric(C) OR C = '_');
             -- Rule 3
             Result:= Result and not Is_Decimal_Digit(First);
             -- Rule 4
             Result:= Result and First /= '_' and Last /= '_';
             -- Rule 5
             Result:= Result and
               (for all Index in Internal_Range =>
                  (if Input(Index) = '_' then Input(Index+1) /= '_')
               );
         end return;
     End Valid_Identifier;


And this is good.
We *don't* want to substitute STRING for Social_Security_Number or 
Identifier as the values that STRING can take are outside what we want 
to deal with... and if we had to deal with validation at every 
subprogram-call or function-return then Ada would be little better than PHP.

 > Subsetting means nothing to subtyping and both very little to
substitutability. All three are different things.

Ridiculous; as shown above subtyping *is* the subsetting of the valid 
values: Social_Security_Number in particular has only 10**9 values 
rather than the Σ(n=0..Positive'Last) 256**n values that the STRING type 
would have.

>
> Huh, great mathematical problems are about fighting constraints. E.g.
> solving x**n + y**n = z**n in real numbers vs. in natural ones. No big
> deal? Same applies to programming, it is mostly about working around
> constraints.

...that's the most idiotic thing I've *ever* heard you say.
Constraints are fundamental for mathematical proofs; they are essential 
for making robust programs. (HINT: definitions are often constraints.)

^ permalink raw reply	[relevance 7%]

* Re: trimming strings
  @ 2014-08-03 21:42 13%   ` agent
  0 siblings, 0 replies; 162+ results
From: agent @ 2014-08-03 21:42 UTC (permalink / raw)


On Sat, 2 Aug 2014 10:22:26 -0700 (PDT), mockturtle
<framefritti@gmail.com> wrote:

>On Saturday, August 2, 2014 3:10:16 PM UTC+2, ag...@drrob1.com wrote:
>> I am having a very difficult time understanding something.  I am
>> 
>> trying to do this using gnat on Ubuntu 14.04 system:
>> 
>> with Ada.Strings; use Ada.Strings;
>> with Ada.Strings.Fixed; use Ada.Strings.Fixed;
>> 
>> subtype string255fixedtype is string (1.255);
>> inbuf : string255fixedtype;
>> 
>> BEGIN
>> 
>>   inbuf := Get_Line;
>>   inbuf := trim(inbuf,both);  
>> 
>> --    this does not work, error is both is not visible
>> 
>> No combination of ada.strings.fixed.both, or ada.strings.both got it
>> to be visible.
>
>
>As others said, a complete example would help us to help you.  Anyway,  I am going to do  a wild guessing: did you maybe declared another "both" in your code?  I do not have a compiler at hand and I cannot check, but if I remember correctly in this case you get a "non visible" error because the two symbols hide each other.
>
>Riccardo


I am, after all, a newbie in Ada.  I was wondering what the
non-visible error meant, as I was getting that also.  Now I know it
means that identifiers are clashing in different packages.

I'm guessing that it is the use statements that make the symbols
clash?

I also don't have string processing down.  


> one of these being likely that an array of 255 characters
> is to receive a string object that may not have that many
> due to trimming.

> That's definitely an error (and assigning a string with a known length to Get_Line won't work either).  
> But those won't cause errors at compile time.  They will result in exceptions at run time.
>                                 -- Adam


with Ada.Text_IO; use Ada.Text_IO;
with Ada.Characters; use Ada.Characters;
with Ada.Characters.Conversions;  use Ada.Characters.Conversions;
with Ada.Characters.Handling; use Ada.Characters.Handling;
with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
with Ada.Strings; use Ada.Strings;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
---------------------------

Procedure trimtest is
  Subtype String255FixedType is String(1..255); 

  str    : String255Fixedtype;
  STRLEN : Natural;
 
BEGIN
  Put(" Enter line: ");
  Get_Line(Str,StrLen);
  Str := TRIM(Str,Side => Both);
--  Str := Ada.Strings.Fixed.TRIM(str,side => Ada.Strings.both);
  Put_Line(" Line is: " & Str(1..StrLen) & " with length of " &
Natural'image(StrLen) );
End trimtest;

This simple procedure compiles, but does give me an exception at
run-time after I call trim.  I don't understand how to avoid this.  I
am used to more flexible strings that are null terminated.

How do I avoid a constraint_error exception at run-time?

Thanks

^ permalink raw reply	[relevance 13%]

* Re: Weird error with Dynamic_Predicate
  2014-05-12 19:47  9% Weird error with Dynamic_Predicate mockturtle
  2014-05-12 21:01  0% ` Adam Beneschan
@ 2014-05-13  4:59  9% ` Shark8
  1 sibling, 0 replies; 162+ results
From: Shark8 @ 2014-05-13  4:59 UTC (permalink / raw)


On 12-May-14 13:47, mockturtle wrote:
> Any ideas?

   -- Identifier:
   Type Identifier is new String
   with Dynamic_Predicate =>
         Validate_Identifier_String( String(Identifier) )
      or Validate_Qualified_Identifier_String( String(Identifier) );

-- Typecasting is desired so that the predicate doesn't depend on
-- the input checking the predicate and thereby infinite-looping.

-- ...

     -- Ensures conformance of identifiers.
     --
     -- EBNF:
     -- identifier ::= identifier_letter {[ "_" ] ( identifier_letter | 
digit )}
     -- identifier_letter ::= upper_case_letter | lower_case_letter
     -- digit ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
     Function Validate_Identifier_String	( Input : String ) return Boolean;

-- body

     Function Validate_Identifier_String	( Input : String ) return 
Boolean is
         Use Ada.Characters.Handling;
         Head : Character renames Input(Input'First);

         Function Underscore_Alphanumeric(C : Character) return Boolean is
           ( C = '_' or else Is_Alphanumeric(C) );

         Subtype Tail is Positive Range Input'First+1..Input'Last;

     Begin
         Return Result : Boolean := True do
             -- Ensure that Input's first character is a letter.
             -- (Implicit: that there is a first character.)
             -- (Implicit: that there is a last character.)
             Result:= Result
               and then Input'Length in Positive
               and then Is_Letter(Head);

             -- All subsequent characters must be underscor or alphanumeric;
             -- also, there can be no double underscore.
             For Index in Tail loop
                 Exit when not Result;
                 declare
                     C : Character renames Input(Index);
                 begin
                     Result := Result and Underscore_Alphanumeric( C ) and
                               (if C = '_' then Input(Index-1) /= '_');
                 end;
             end loop;

             -- The last character cannot be an underscore.
             Result:= Result and Input(Input'Last) /= '_';
         End return;
     End Validate_Identifier_String;

--------
     Validate_Qualified_Identifier_String would take its input and, upon 
detection of '.' pass the two substrings to Validate_Identifier_String 
since both would have to be valid identifiers.

^ permalink raw reply	[relevance 9%]

* Re: Weird error with Dynamic_Predicate
  2014-05-12 19:47  9% Weird error with Dynamic_Predicate mockturtle
@ 2014-05-12 21:01  0% ` Adam Beneschan
  2014-05-13  4:59  9% ` Shark8
  1 sibling, 0 replies; 162+ results
From: Adam Beneschan @ 2014-05-12 21:01 UTC (permalink / raw)


For what it's worth, here's the smallest reduced example I can come up with that gives the same error message:

package Prova is
   type Identifier_Name is new String with Dynamic_Predicate => true;
   function Extract_Namespace (Nome : Identifier_Name)
                               return Identifier_Name;
end Prova;

package body Prova is
   function Extract_Namespace (Nome : Identifier_Name)
                               return Identifier_Name
   is
      Idx : Natural := Ada.Strings.Fixed.Index (String (Nome), ".");
   begin
      return "ns";
   end Extract_Namespace;
end Prova;

This is with GCC 4.5.4 (20120510).

                            -- Adam


On Monday, May 12, 2014 12:47:41 PM UTC-7, mockturtle wrote:
> Dear all,
> 
> I am experiencing an error that is making me crazy and I was wondering if someone can help.
> 
> 
> 
> Some background: I want to define a type that represents an "identifier."  The identifier can assume two forms: 
> 
>  - qualified (es. namespace.foo)
> 
>  - not qualified (es. foo)
> 
> 
> 
> The two components (namespace and name) have the usual syntax (letters, digits and underscore).  Note that there are at most two components.  I want to use the aspect Dynamic_Predicate to enforce (and document) the right syntax.
> 
> 
> 
> You can find prova.ads and prova.adb at the end of this message.  I am using GPS 5.2.1 (20130102) and when I try to compile I get the obscure message
> 
> 
> 
>   29:32 error: conversion to incomplete type
> 
>   29:32 confused by earlier errors, bailing out
> 
> 
> 
> on >> prova.ads <<.  If I try to do "check semantic" on prova.ads and prova.adb, everything is fine.  
> 
> 
> 
> 
> 
> Any ideas?  Is it a compiler bug or am I doing something wrong?  Updating the compiler in this moment it would be a little pain for me (for several reasons), so I would like to be sure that I am not doing some subtle error before trying the update path.
> 
> 
> 
> Thank you in advance 
> 
> 
> 
> Riccardo
> 
> 
> 
> 
> 
> 
> 
> --- prova.ads ---
> 
> with Ada.Characters.Handling;     use Ada.Characters.Handling;
> 
> with Ada.Strings.Fixed;
> 
> 
> 
> package Prova is
> 
>    type Identifier_Name is new
> 
>      String
> 
>        with Dynamic_Predicate =>
> 
>          ((for all I in Identifier_Name'Range =>
> 
>              Is_Alphanumeric (Identifier_Name (I))
> 
>            or Identifier_Name (I) = '_'
> 
>            or Identifier_Name (I) = '.')
> 
>           and
> 
>             (not (Identifier_Name (Identifier_Name'First) in '0' .. '9'))
> 
>           and
> 
>             (Identifier_Name (Identifier_Name'First) /= '.')
> 
>           and
> 
>             Ada.Strings.Fixed.Count (String (Identifier_Name), ".") <= 1);
> 
> 
> 
>    function Is_Qualified (Item : Identifier_Name) return Boolean
> 
>      is (Ada.Strings.Fixed.Count (String (Item), ".") = 1);
> 
> 
> 
>    subtype Namespace_Identifier is Identifier_Name
> 
>    with Dynamic_Predicate => not Is_Qualified (Namespace_Identifier);
> 
> 
> 
>    subtype Full_Identifier is Identifier_Name
> 
>    with Dynamic_Predicate => Is_Qualified (Full_Identifier);
> 
> 
> 
> 
> 
>    function Extract_Namespace (Nome : Full_Identifier)
> 
>                                return Namespace_Identifier;
> 
> 
> 
> end Prova;
> 
> 
> 
> --- prova.adb --- 
> 
> 
> 
> package body Prova is
> 
> 
> 
> 
> 
>    -----------------------
> 
>    -- Extract_Namespace --
> 
>    -----------------------
> 
> 
> 
>    function Extract_Namespace (Nome : Full_Identifier)
> 
>                                return Namespace_Identifier
> 
>    is
> 
>       Idx : Natural := Ada.Strings.Fixed.Index (String (Nome), ".");
> 
>    begin
> 
>       return Namespace_Identifier (Nome (Nome'First .. Idx - 1));
> 
>    end Extract_Namespace;
> 
> 
> 
> end Prova;
> 
> ----

^ permalink raw reply	[relevance 0%]

* Weird error with Dynamic_Predicate
@ 2014-05-12 19:47  9% mockturtle
  2014-05-12 21:01  0% ` Adam Beneschan
  2014-05-13  4:59  9% ` Shark8
  0 siblings, 2 replies; 162+ results
From: mockturtle @ 2014-05-12 19:47 UTC (permalink / raw)


Dear all,
I am experiencing an error that is making me crazy and I was wondering if someone can help.

Some background: I want to define a type that represents an "identifier."  The identifier can assume two forms: 
 - qualified (es. namespace.foo)
 - not qualified (es. foo)

The two components (namespace and name) have the usual syntax (letters, digits and underscore).  Note that there are at most two components.  I want to use the aspect Dynamic_Predicate to enforce (and document) the right syntax.

You can find prova.ads and prova.adb at the end of this message.  I am using GPS 5.2.1 (20130102) and when I try to compile I get the obscure message

  29:32 error: conversion to incomplete type
  29:32 confused by earlier errors, bailing out

on >> prova.ads <<.  If I try to do "check semantic" on prova.ads and prova.adb, everything is fine.  


Any ideas?  Is it a compiler bug or am I doing something wrong?  Updating the compiler in this moment it would be a little pain for me (for several reasons), so I would like to be sure that I am not doing some subtle error before trying the update path.

Thank you in advance 

Riccardo



--- prova.ads ---
with Ada.Characters.Handling;     use Ada.Characters.Handling;
with Ada.Strings.Fixed;

package Prova is
   type Identifier_Name is new
     String
       with Dynamic_Predicate =>
         ((for all I in Identifier_Name'Range =>
             Is_Alphanumeric (Identifier_Name (I))
           or Identifier_Name (I) = '_'
           or Identifier_Name (I) = '.')
          and
            (not (Identifier_Name (Identifier_Name'First) in '0' .. '9'))
          and
            (Identifier_Name (Identifier_Name'First) /= '.')
          and
            Ada.Strings.Fixed.Count (String (Identifier_Name), ".") <= 1);

   function Is_Qualified (Item : Identifier_Name) return Boolean
     is (Ada.Strings.Fixed.Count (String (Item), ".") = 1);

   subtype Namespace_Identifier is Identifier_Name
   with Dynamic_Predicate => not Is_Qualified (Namespace_Identifier);

   subtype Full_Identifier is Identifier_Name
   with Dynamic_Predicate => Is_Qualified (Full_Identifier);


   function Extract_Namespace (Nome : Full_Identifier)
                               return Namespace_Identifier;

end Prova;

--- prova.adb --- 

package body Prova is


   -----------------------
   -- Extract_Namespace --
   -----------------------

   function Extract_Namespace (Nome : Full_Identifier)
                               return Namespace_Identifier
   is
      Idx : Natural := Ada.Strings.Fixed.Index (String (Nome), ".");
   begin
      return Namespace_Identifier (Nome (Nome'First .. Idx - 1));
   end Extract_Namespace;

end Prova;
----


^ permalink raw reply	[relevance 9%]

* Re: gnatmake error I don't understand
  @ 2014-04-04  0:44 12% ` agent
  0 siblings, 0 replies; 162+ results
From: agent @ 2014-04-04  0:44 UTC (permalink / raw)


I forgot 1 thing.  My tokenizea.adb routine has this line that I use
stolen from Modula-2:

function CAP(Item : Character) return Character renames
Ada.Characters.Handling.To_Upper;

function CAP(Item : String) return String renames
Ada.Characters.Handling.To_Upper;

So I with and use tokenizea because of the CAP function that I like
from Modula-2.

--rob solomon

^ permalink raw reply	[relevance 12%]

* Re: character literals
  @ 2014-02-12 15:53  8%   ` Robert A Duff
  0 siblings, 0 replies; 162+ results
From: Robert A Duff @ 2014-02-12 15:53 UTC (permalink / raw)


adambeneschan@gmail.com writes:

> On Tuesday, February 11, 2014 2:27:57 PM UTC-8, ag...@drrob1.com wrote:
>> I have been having a difficulty in my code with character literals.
>> 
>> For example
>> 
>>  IF ch in '0' .. '9' THEN

Note to OP:  If you have questions about an error message, it's best to
cut&paste the exact complete compilable code that caused the error,
along with the exact text of the error message.

The above is legal given the right declaration of ch, but you
didn't show that; there are all sorts of reasons the above could
be illegal.

Also look at Ada.Characters.Handling.  You can call the Is_Digit function.

> Finally, the language does have one special rule:
>
>     for I in 0 .. 9 loop
>
> The literals 0 and 9 could be resolved to any integer type, which
> would make this ambiguous since there are normally multiple integer
> types visible in the program (Integer, Long_Integer, Short_Integer,
> maybe types in Interfaces if you "use" that packaged).  But the
> language rules decree that the type will be Integer in that case.
> This is a situation where some programmers might recommend making the
> type Integer explicit.

Like me.  I think the special-case for Integer is a kludge, so I
would write:

    for I in Some_Type range 0 .. 9 loop

One exception:  If I want to say "do this 5 times", I might write:

    for I in 1 .. 5 loop

and there are no references to I in the loop, so its type is irrelevant.

On the other hand, if the type is clear from the bounds, as in

    for I in 1 .. Some_Array'Last - 1 loop

I wouldn't put the type in.

- Bob

^ permalink raw reply	[relevance 8%]

* need help learning Ada for a modula-2 programmer
@ 2014-01-28  1:06 10% agent
  0 siblings, 0 replies; 162+ results
From: agent @ 2014-01-28  1:06 UTC (permalink / raw)


The following code does not compile.  I don't understand why.

The string processing fails to compile, saying "prefix of image must
be a type"

and 

"move is undefined"

I don't yet understand string processing with Ada

--rob

with Ada.Calendar; use Ada.Calendar;
Package timliba is

--  REVISION HISTORY
--  ----------------
--   6 Oct 13 -- Converted to gm2.  And changed its name.
--  19 Jan 14 -- Converted to Ada.

  SubType String10Type is String(1..10);
  TYPE DAYNAMESType is ARRAY (1..7) OF String10Type;
  TYPE MONTHNAMESType is ARRAY (1..12) OF String10Type;
  Type DateTimeType is RECORD
    SystemTime: Time;
    month,day,year,hours,minutes,seconds : Natural;
    ElapsedSec : Duration;
  END Record;

  DateTime: DateTimeType;

  DAYNAMES : Constant DayNamesType  := ("Sunday    ","Monday
","Tuesday   ","Wednesday ", "Thursday  ","Friday    ","Saturday  ");
  MONTHNAMES : Constant MonthNamesType := ("January   ","February
","March     ","April     ","May       ",
      "June      ","July      ","August    ","September ","October
","November  ","December  ");

PROCEDURE TIME2MDY(M,D,Y : Out Natural);
-- System Time To Month, Day, and Year Conversion.

Procedure GetDateTime(DateTime: Out DateTimeType);
-- DateTimeType is my record time type containing everything.

Function JULIAN(M,D,Y : Natural) return Natural;

PROCEDURE GREGORIAN(Juldate : Natural; M,D,Y : OUT Natural);

END timliba;



-- with environa; use environa;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Characters; use Ada.Characters;
with Ada.Characters.Conversions;  use Ada.Characters.Conversions;
with Ada.Characters.Handling; use Ada.Characters.Handling;
with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
with Ada.Calendar; use Ada.Calendar;

Package body timliba is

--  REVISION HISTORY
--  ----------------
--  14 Apr 92 -- Created JULIAN and GREGORIAN procs, which are
accurate beyond 3/1/2100.
--  25 Jul 93 -- Changed GREG2JUL and JUL2GREG limits to those imposed
by the
--                algorithm, ie, only years <2100 are now allowed.
--  25 Jul 94 -- Changed limits of allowed years to 1700 from 1900.
--  10 Nov 02 -- Converted to SBM2 Win v4.
--  17 May 03 -- First Win32 version.
--  26 May 03 -- Adjusted algorithm for Julian fcn so year has a
pivot.
--   6 Oct 13 -- Converted to gm2.
--  19 Jan 14 -- Converted to Ada.

  SubType String255 is String(1..255);
  K,IDX,PTR,c,RETCOD                           : Natural;
  CH                                           : CHARacter;
  FLAG,FLAG2,FLAG3,FLAG4,FLAG5,EOFFLG          : BOOLEAN;
--  PROMPT,NAMDFT,TYPDFT,INFNAM,OUTFNAM,
--  TMPBUF,NUMBUF,DRVPATH,INBUF,TOKEN            : BUFTYP;
--  TKNSTATE                                     : FSATYP;
  I,J                                          : INTEGER;

  TYPE ADIPMType is ARRAY (0..11) OF INTEGER;

--  This is a typed constant that represents the difference btwn the
last day
--  of the previous month and 30, assuming each month was 30 days
long.
--  The variable name is an acronym of Accumulated Days In Previous
Months.

  ADIPM : CONSTant ADIPMType :=  (0,1,-1,0,0,1,1,2,3,3,4,4);
  FUDGEFACTOR : CONSTant LONG_FLOAT := 5.0;
-- These are declared in the spec file
--  Type DateTimeType is RECORD
--    SystemTime: Time;
--    month,day,year,hours,minutes,seconds : Natural;
--    ElapsedSec : Duration;
--  END Record;


PROCEDURE TIME2MDY(M,D,Y : Out Natural) is
-- *********************************** TIME2MDY
*************************
-- System Time To Month, Day, and Year Conversion.

  Systime : Time;

BEGIN
  Systime := Clock;
  M := Month(Systime);
  D := Day(Systime);
  Y := Year(Systime);
END TIME2MDY;

Procedure GetDateTime(DateTime : Out DateTimeType) is
   CardSec : Natural;

BEGIN
  DateTime.SystemTime := Clock;

Split(DateTime.SystemTime,DateTime.year,DateTime.month,DateTime.day,DateTime.ElapsedSec);
  CardSec := Natural(DateTime.ElapsedSec+0.5);
  DateTime.hours := CardSec / 3600;
  CardSec := CardSec - DateTime.hours * 3600;
  DateTime.minutes := CardSec / 60;
  DateTime.seconds := CardSec MOD 60;
END GetDateTime;


PROCEDURE MDY2STR(M,D,Y : Natural; MDYSTR : Out String255) is
-- ***************************** MDY2STR
*********************************
-- Month Day Year Cardinals To String.

  DateSepChar : constant character :=  '/';
  MSTR,DSTR,YSTR : String(1..2);
  IntermedStr    : String(1..10);
  m0,d0,y0       : Natural;

BEGIN
  m0 := M;
  d0 := D;
  y0 := Y;
  IntermedStr := m0'Image & DateSepChar & d0'Image & DateSepChar &
y0'Image;
--  DSTR := D'Image;
--  YSTR := Y'Image;
--  MDYSTR := To255(IntermedStr);
    Move(IntermedStr,MDYstr);
END MDY2STR;



Function JULIAN(M,D,Y : Natural) return Natural is

  M0,D0,Y0   : Natural;
  Juldate    : Natural;

BEGIN
  IF Y < 30 THEN
    Y0 := Y + 2000 - 1;
  ELSIF Y < 100 THEN
    Y0 := Y + 1900 - 1;
  ELSE
    Y0 := Y - 1;
  END IF;
  IF (M < 1) OR (M > 12) OR (D < 1) OR (D > 31) OR (Y < 1700) OR (Y >
2500) THEN
-- Month, Day or Year is out of range
    Juldate := 0;
    RETURN(Juldate);
  END IF;

  M0 := M - 1;

  Juldate :=  Y0 * 365     -- Number of days in previous normal years
            + Y0 / 4   -- Number of possible leap days
            - Y0 / 100 -- Subtract all century years
            + Y0 / 400 -- Add back the true leap century years
            + ADIPM(M0) + M0 * 30 + D;

  IF ((( Y MOD 4 = 0) AND ( Y MOD 100 /= 0)) OR ( Y MOD 400 = 0)) AND
--   123            3     3               32    2              21
                                                                 (M >
2) THEN
    Juldate := Juldate + 1;
  END IF;
  RETURN Juldate;
END JULIAN;

PROCEDURE GREGORIAN(Juldate : Natural; M,D,Y : OUT Natural) is

  Y0,M0,D0,L,JD : Natural;

BEGIN
  Y0 := Juldate / 365;
  M0 := 1;
  D0 := 1;

  WHILE JULIAN(M0,D0,Y0) > Juldate LOOP Y0 := Y0 - 1; END Loop;

  M0 := 12;
  WHILE JULIAN(M0,D0,Y0) > Juldate Loop M0 := M0 - 1; END Loop;

  WHILE JULIAN(M0,D0,Y0) < Juldate Loop D0 := D0 + 1; END Loop;

  M := M0;
  D := D0;
  Y := Y0;
END GREGORIAN;

END timliba;


^ permalink raw reply	[relevance 10%]

* Re: string and wide string usage
  2013-03-07 14:20 11% ` ytomino
  2013-03-07 17:14  0%   ` Dmitry A. Kazakov
@ 2013-03-07 23:53  0%   ` Randy Brukardt
  1 sibling, 0 replies; 162+ results
From: Randy Brukardt @ 2013-03-07 23:53 UTC (permalink / raw)


"ytomino" <aghia05@gmail.com> wrote in message 
news:5e5e7e80-7d69-47e1-9550-19e2e0a211a9@googlegroups.com...
> On Thursday, March 7, 2013 8:12:01 PM UTC+9, Ali Bendriss wrote:
>> I've got some problem with some string in example:
>> a base 64 encoded string
>> V2luZG93c8KgNyBQcm9mZXNzaW9ubmVsIE4=
>> wich decode to 'Windows\xa07 Professionnel N' in utf-8
>> every thing is working if I feed directly the database, but if want to
>> apply Ada.Characters.Handling.To_Lower on the string before feeding the
>> database postgres is not happy
>> 'ERROR:  invalid byte sequence for encoding "UTF8": 0xe2 0xa0 0x37'
>> it's not really a big deal, but I would like to understand where the
>> problem is. Do I have to use wide string ?
>
> Because functions in Ada.Characters.Handling take not UTF-8 but Latin-1.

Right. The proper thing to do (for Ada 2012) is to use 
Ada.Characters.Wide_Handling (or Wide_Wide_Handling) to do the case 
conversion, after converting the UTF-8 into a Wide_String (or 
Wide_Wide_String).

If you're trying to do this in an older version of Ada, you'll have to find 
some library somewhere to do the job.

But I want to caution you that "converting to lower case" is not a great 
idea if you plan to support arbitrary Unicode strings. Such conversions are 
somewhat ambiguous, and tend to make strings appear similar that are 
different (and sometimes the reverse happens as well). Usually, the best 
plan is to store the strings unmodified and use Equal_Case_Insensitive to 
compare them (this uses the most accurate comparison defined by Unicode, and 
has the advantage of being guarenteed not to change in future character set 
standards, which is NOT true of conversion to lower case).

There is a nice example of this problem in the next chapter of the Ada 2012 
Rationale (although you'll have to wait untiil May to see it, unless you get 
the Ada User Journal).

I realize you may have no choice given the design of your database might not 
be in your control, and it might not matter if you don't plan to have Greek 
and Turkish characters in your data (to mention two of the most common where 
convert to lower case and Equal_Case_Insensitive give different answers for 
Wide_Strings).

                                     Randy.





^ permalink raw reply	[relevance 0%]

* Re: string and wide string usage
  2013-03-07 14:20 11% ` ytomino
@ 2013-03-07 17:14  0%   ` Dmitry A. Kazakov
  2013-03-07 23:53  0%   ` Randy Brukardt
  1 sibling, 0 replies; 162+ results
From: Dmitry A. Kazakov @ 2013-03-07 17:14 UTC (permalink / raw)


On Thu, 7 Mar 2013 06:20:05 -0800 (PST), ytomino wrote:

> On Thursday, March 7, 2013 8:12:01 PM UTC+9, Ali Bendriss wrote:
>> I've got some problem with some string in example:
>> a base 64 encoded string
>> V2luZG93c8KgNyBQcm9mZXNzaW9ubmVsIE4=
>> wich decode to 'Windows\xa07 Professionnel N' in utf-8
>> every thing is working if I feed directly the database, but if want to 
>> apply Ada.Characters.Handling.To_Lower on the string before feeding the 
>> database postgres is not happy 
>> 'ERROR:  invalid byte sequence for encoding "UTF8": 0xe2 0xa0 0x37'
>> it's not really a big deal, but I would like to understand where the 
>> problem is. Do I have to use wide string ?
> 
> Because functions in Ada.Characters.Handling take not UTF-8 but Latin-1.
> You have to
> 1. convert UTF-8 String to Wide_Wide_String, process UTF-32 and restore it to UTF-8.
>   (Ada.Characters.Conversion also take Latin-1. You have to use GNAT.Encode_String/Decode_String or Ada.Strings.UTF_Encoding for converting.)
> 2. search a external library to process UTF-8 directly.

Provided the base 64 encodes an UTF-8 string, which you wanted to convert
to lower case UTF-8 string using the Unicode lower case mapping, then you
can use

   function To_Lowercase (Value : String) return String;

from

http://www.dmitry-kazakov.de/ada/strings_edit.htm#7.6

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



^ permalink raw reply	[relevance 0%]

* Re: string and wide string usage
  2013-03-07 11:12  8% string and wide string usage Ali Bendriss
@ 2013-03-07 14:20 11% ` ytomino
  2013-03-07 17:14  0%   ` Dmitry A. Kazakov
  2013-03-07 23:53  0%   ` Randy Brukardt
  0 siblings, 2 replies; 162+ results
From: ytomino @ 2013-03-07 14:20 UTC (permalink / raw)


On Thursday, March 7, 2013 8:12:01 PM UTC+9, Ali Bendriss wrote:
> I've got some problem with some string in example:
> a base 64 encoded string
> V2luZG93c8KgNyBQcm9mZXNzaW9ubmVsIE4=
> wich decode to 'Windows\xa07 Professionnel N' in utf-8
> every thing is working if I feed directly the database, but if want to 
> apply Ada.Characters.Handling.To_Lower on the string before feeding the 
> database postgres is not happy 
> 'ERROR:  invalid byte sequence for encoding "UTF8": 0xe2 0xa0 0x37'
> it's not really a big deal, but I would like to understand where the 
> problem is. Do I have to use wide string ?

Because functions in Ada.Characters.Handling take not UTF-8 but Latin-1.
You have to
1. convert UTF-8 String to Wide_Wide_String, process UTF-32 and restore it to UTF-8.
  (Ada.Characters.Conversion also take Latin-1. You have to use GNAT.Encode_String/Decode_String or Ada.Strings.UTF_Encoding for converting.)
2. search a external library to process UTF-8 directly.



^ permalink raw reply	[relevance 11%]

* string and wide string usage
@ 2013-03-07 11:12  8% Ali Bendriss
  2013-03-07 14:20 11% ` ytomino
  0 siblings, 1 reply; 162+ results
From: Ali Bendriss @ 2013-03-07 11:12 UTC (permalink / raw)


Hello,

I've got a small program that read some value from an ldap server and 
copy them in a posgres database.
the function reading the ldap value return an unbounded_string, then I 
use to_string to feed postgres (using gnatcoll).

I've got some problem with some string in example:
a base 64 encoded string
V2luZG93c8KgNyBQcm9mZXNzaW9ubmVsIE4=
wich decode to 'Windows\xa07 Professionnel N' in utf-8
every thing is working if I feed directly the database, but if want to 
apply Ada.Characters.Handling.To_Lower on the string before feeding the 
database postgres is not happy 
'ERROR:  invalid byte sequence for encoding "UTF8": 0xe2 0xa0 0x37'
it's not really a big deal, but I would like to understand where the 
problem is. Do I have to use wide string ?

thanks,

Ali



^ permalink raw reply	[relevance 8%]

* Re: Child packages named Ada illegal?
  @ 2012-10-31 19:39  0%         ` Shark8
  0 siblings, 0 replies; 162+ results
From: Shark8 @ 2012-10-31 19:39 UTC (permalink / raw)


> package body AA.Languages.Ada is
>    ...
>    function Non_Alphanum_To_Underscore (From : Character) return Character is
>       (if Ada.Characters.Handling.Is_Alphanumeric (From) then From else '_');
>    ...
> end;

One option would be to put package renaming inside the AA or Languages package; thus:

with Ada.Characters;
Package AA.Language is
...
package Internal_Characters Renames Ada.Characters;
End AA.Language;

would allow you to refer to Ada.Characters via the Internal_Characters name.



^ permalink raw reply	[relevance 0%]

* Re: Child packages named Ada illegal?
  2012-10-31 17:59 13%   ` Marius Amado-Alves
@ 2012-10-31 18:16  9%     ` Adam Beneschan
    0 siblings, 1 reply; 162+ results
From: Adam Beneschan @ 2012-10-31 18:16 UTC (permalink / raw)


On Wednesday, October 31, 2012 10:59:26 AM UTC-7, Marius Amado-Alves wrote:
> Thanks. The package is as follows (the entire thing is at sourceforge.net/projects/aalibrary/). GNAT shouts <<missing "with Ada.Characters;">> at line "(if Ada...);". The fix is to rename the package AA.Languages.Ada_Language. The Standard.Ada trick doesn't work.

Hmmm ... interesting, it should work.  I'm using an earlier version of GNAT that doesn't support Ada 2012 syntax, so I had to rewrite the function to try your example.  But it worked fine (inside AA.Languages.Ada) when I referred to Standard.Ada.Characters.Handling.Is_Alphanumeric.  So maybe this is a recently introduced bug?

                           -- Adam


> with Ada.Characters.Handling;
> ...
> package body AA.Languages.Ada is
>    ...
>    function Non_Alphanum_To_Underscore (From : Character) return Character is
>       (if Ada.Characters.Handling.Is_Alphanumeric (From) then From else '_'); 
>    ...
> end;




^ permalink raw reply	[relevance 9%]

* Re: Child packages named Ada illegal?
  @ 2012-10-31 17:59 13%   ` Marius Amado-Alves
  2012-10-31 18:16  9%     ` Adam Beneschan
  0 siblings, 1 reply; 162+ results
From: Marius Amado-Alves @ 2012-10-31 17:59 UTC (permalink / raw)


Thanks. The package is as follows (the entire thing is at sourceforge.net/projects/aalibrary/). GNAT shouts <<missing "with Ada.Characters;">> at line "(if Ada...);". The fix is to rename the package AA.Languages.Ada_Language. The Standard.Ada trick doesn't work.

with Ada.Characters.Handling;
...
package body AA.Languages.Ada is
   ...
   function Non_Alphanum_To_Underscore (From : Character) return Character is
      (if Ada.Characters.Handling.Is_Alphanumeric (From) then From else '_');
   ...
end;



^ permalink raw reply	[relevance 13%]

* Re: Ada  "library only" compiler ?
  @ 2012-07-21 16:47  3%     ` Niklas Holsti
  0 siblings, 0 replies; 162+ 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 3%]

* Re: Checking to see if a string is a letter
  2012-04-05 17:12  0%           ` deuteros
@ 2012-04-05 17:24  0%             ` Martin Dowie
  0 siblings, 0 replies; 162+ results
From: Martin Dowie @ 2012-04-05 17:24 UTC (permalink / raw)


deuteros <deuteros@xrs.net> wrote:
> On Tue 03 Apr 2012 04:26:40a, Simon Wright <simon@pushface.org> wrote in
> news:m2k41xi5kv.fsf@pushface.org: 
> 
>> deuteros <deuteros@xrs.net> writes:
>> 
>>> On Tue 03 Apr 2012 01:15:27a, Jeffrey Carter
>>> <spam.jrcarter.not@spam.not.acm.org> wrote in
>>> news:jle13q$ale$1@tornado.tornevall.net: 
>>> 
>>>> What do you mean by "contains a single letter"?
>>> 
>>> I mean the string contains a single letter and nothing more. For
>>> example:
>>> 
>>> a  - Legal
>>> A  - Legal
>>> aa - Illegal
>>> a1 - Illegal
>> 
>> Then for a start the length of the string needs to be 1.
>> 
>> If it is, the first (and only!) character needs to be a lower- or
>> upper-case letter. There are (at least) three ways of doing this:
>> 
>> * declare an array of Boolean indexed by Character, with the elements
>>   indexed by letters set to True and the others to False, and index by
>>   the character to be tested;
>> 
>> * declare two subtypes of character ("Character range 'a' .. 'z'", for
>>   instance) and check whether the character to be tested is 'in' either
>>   of the subtypes;
>> 
>> * use the standard library, Ada.Characters.Handling.Is_Letter (probably
>>   the easiest for you!)
> 
> Alright, here's my function:
> 
>    function isVariable(token: in String) return Boolean is
>       ParserException : Exception;
>    begin
>       if(token'Length = 1) then
>          return (Is_Letter(token(1)));
>       end if;
> 
>       raise ParserException with ("Not a letter : " & token);
>      
>    end isVariable;
> 
> But I'm getting this warning:
> 
> warning: index for "token" may assume lower bound of 1
> warning: suggested replacement: "token'First + -1"

See http://www.ada-auth.org/standards/12rm/html/RM-3-6-3.html to see how
String is defined.

From this you can see that token may not have a value at "token (1)",
perhaps it is indexed by 10..20.

If you know that all the strings you'll ever pass to this function will
start with an index = 1, then you could add a "pragma Assert (tokenFirst =
1);" at the start of the declarative part. An exception will then be raised
if this isn't true (assuming the correct compiler switches are selected).

NB: ParserException is declared locally, so isn't visible to any subprogram
that could attempt to catch it...you'd need to use "when others =>".

HTH
-- Martin



-- 
-- Sent from my iPad



^ permalink raw reply	[relevance 0%]

* Re: Checking to see if a string is a letter
  2012-04-03  8:26  8%         ` Simon Wright
  2012-04-03 12:56  0%           ` deuteros
  2012-04-03 13:46  0%           ` Dmitry A. Kazakov
@ 2012-04-05 17:12  0%           ` deuteros
  2012-04-05 17:24  0%             ` Martin Dowie
  2 siblings, 1 reply; 162+ results
From: deuteros @ 2012-04-05 17:12 UTC (permalink / raw)


On Tue 03 Apr 2012 04:26:40a, Simon Wright <simon@pushface.org> wrote in
news:m2k41xi5kv.fsf@pushface.org: 

> deuteros <deuteros@xrs.net> writes:
> 
>> On Tue 03 Apr 2012 01:15:27a, Jeffrey Carter
>> <spam.jrcarter.not@spam.not.acm.org> wrote in
>> news:jle13q$ale$1@tornado.tornevall.net: 
>>
>>> What do you mean by "contains a single letter"?
>>
>> I mean the string contains a single letter and nothing more. For
>> example:
>>
>> a  - Legal
>> A  - Legal
>> aa - Illegal
>> a1 - Illegal
> 
> Then for a start the length of the string needs to be 1.
> 
> If it is, the first (and only!) character needs to be a lower- or
> upper-case letter. There are (at least) three ways of doing this:
> 
> * declare an array of Boolean indexed by Character, with the elements
>   indexed by letters set to True and the others to False, and index by
>   the character to be tested;
> 
> * declare two subtypes of character ("Character range 'a' .. 'z'", for
>   instance) and check whether the character to be tested is 'in' either
>   of the subtypes;
> 
> * use the standard library, Ada.Characters.Handling.Is_Letter (probably
>   the easiest for you!)

Alright, here's my function:

   function isVariable(token: in String) return Boolean is
      ParserException : Exception;
   begin
      if(token'Length = 1) then
         return (Is_Letter(token(1)));
      end if;

      raise ParserException with ("Not a letter : " & token);
     
   end isVariable;

But I'm getting this warning:

warning: index for "token" may assume lower bound of 1
warning: suggested replacement: "token'First + -1"



^ permalink raw reply	[relevance 0%]

* Re: Checking to see if a string is a letter
    2012-04-03  8:26  8%         ` Simon Wright
@ 2012-04-03 20:40  9%         ` Jeffrey Carter
  1 sibling, 0 replies; 162+ results
From: Jeffrey Carter @ 2012-04-03 20:40 UTC (permalink / raw)


On 04/02/2012 11:07 PM, deuteros wrote:
>
> I mean the string contains a single letter and nothing more. For example:
>
> a  - Legal
> A  - Legal
> aa - Illegal
> a1 - Illegal

Then you'd probably start by checking 'Length for the String to be sure it's 1. 
Then you'd check that the single Character in the String is a letter, probably 
using an operation in Ada.Characters.Handling.

-- 
Jeff Carter
"I fart in your general direction."
Monty Python & the Holy Grail
05



^ permalink raw reply	[relevance 9%]

* Re: Checking to see if a string is a letter
  2012-04-03  8:26  8%         ` Simon Wright
  2012-04-03 12:56  0%           ` deuteros
@ 2012-04-03 13:46  0%           ` Dmitry A. Kazakov
  2012-04-05 17:12  0%           ` deuteros
  2 siblings, 0 replies; 162+ results
From: Dmitry A. Kazakov @ 2012-04-03 13:46 UTC (permalink / raw)


On Tue, 03 Apr 2012 09:26:40 +0100, Simon Wright wrote:

> * use the standard library, Ada.Characters.Handling.Is_Letter (probably
>   the easiest for you!)

Ada.Wide_Wide_Characters.Handling.Is_Letter for Unicode.

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



^ permalink raw reply	[relevance 0%]

* Re: Checking to see if a string is a letter
  2012-04-03  8:26  8%         ` Simon Wright
@ 2012-04-03 12:56  0%           ` deuteros
  2012-04-03 13:46  0%           ` Dmitry A. Kazakov
  2012-04-05 17:12  0%           ` deuteros
  2 siblings, 0 replies; 162+ results
From: deuteros @ 2012-04-03 12:56 UTC (permalink / raw)


On Tue 03 Apr 2012 04:26:40a, Simon Wright <simon@pushface.org> wrote in
news:m2k41xi5kv.fsf@pushface.org: 

> deuteros <deuteros@xrs.net> writes:
> 
>> On Tue 03 Apr 2012 01:15:27a, Jeffrey Carter
>> <spam.jrcarter.not@spam.not.acm.org> wrote in
>> news:jle13q$ale$1@tornado.tornevall.net: 
>>
>>> What do you mean by "contains a single letter"?
>>
>> I mean the string contains a single letter and nothing more. For
>> example:
>>
>> a  - Legal
>> A  - Legal
>> aa - Illegal
>> a1 - Illegal
> 
> Then for a start the length of the string needs to be 1.
> 
> If it is, the first (and only!) character needs to be a lower- or
> upper-case letter. There are (at least) three ways of doing this:
> 
> * declare an array of Boolean indexed by Character, with the elements
>   indexed by letters set to True and the others to False, and index by
>   the character to be tested;
> 
> * declare two subtypes of character ("Character range 'a' .. 'z'", for
>   instance) and check whether the character to be tested is 'in' either
>   of the subtypes;
> 
> * use the standard library, Ada.Characters.Handling.Is_Letter (probably
>   the easiest for you!)

Thanks. I'll check out that library.



^ permalink raw reply	[relevance 0%]

* Re: Checking to see if a string is a letter
  @ 2012-04-03  8:26  8%         ` Simon Wright
  2012-04-03 12:56  0%           ` deuteros
                             ` (2 more replies)
  2012-04-03 20:40  9%         ` Jeffrey Carter
  1 sibling, 3 replies; 162+ results
From: Simon Wright @ 2012-04-03  8:26 UTC (permalink / raw)


deuteros <deuteros@xrs.net> writes:

> On Tue 03 Apr 2012 01:15:27a, Jeffrey Carter
> <spam.jrcarter.not@spam.not.acm.org> wrote in
> news:jle13q$ale$1@tornado.tornevall.net: 
>
>> What do you mean by "contains a single letter"?
>
> I mean the string contains a single letter and nothing more. For
> example:
>
> a  - Legal
> A  - Legal
> aa - Illegal
> a1 - Illegal

Then for a start the length of the string needs to be 1.

If it is, the first (and only!) character needs to be a lower- or
upper-case letter. There are (at least) three ways of doing this:

* declare an array of Boolean indexed by Character, with the elements
  indexed by letters set to True and the others to False, and index by
  the character to be tested;

* declare two subtypes of character ("Character range 'a' .. 'z'", for
  instance) and check whether the character to be tested is 'in' either
  of the subtypes;

* use the standard library, Ada.Characters.Handling.Is_Letter (probably
  the easiest for you!)



^ permalink raw reply	[relevance 8%]

* Re: Need Help On Ada95 Problem
  @ 2012-02-12 19:40 11%             ` Will
  0 siblings, 0 replies; 162+ results
From: Will @ 2012-02-12 19:40 UTC (permalink / raw)


Here Is The Solution and it does work so all of you can understand.  I
am fairly new to Ada95 so I have not been introduced to Arrays and
Case and all that stuff but I do understand the solutions here. I did
use the ASCII table and if you view it and go through this by hand you
will understand why it works. The solutions are as follows:



with Ada.Text_IO; use Ada.Text_IO;

with Ada.Characters.Handling; use Ada.Characters.Handling;

with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

with Ada.Strings.Fixed; use Ada.Strings.Fixed;



procedure hw4 is



   function Encrypt(PIN : String) return String is

      -- Convert the 4-digit PIN to the corresponding 4-letter code.

      -- Assume PIN'Length is 4 and that all the characters in PIN are
digits.

      -- Example: Encrypt("9537") = "ELVI"



      -- FILL IN FOUR MORE TEST CASES.

		--Test Case 1: Encrypt("6789") = "TINE"

		--Test Case 2: Encrypt("5432") = "LAVO"

		--Test Case 3: Encrypt("0926") = "UEOT"

		--Test Case 4: Encrypt("7359") = "IVLE"

		letterWheel : string := "UROVALTINE";

		password : string := PIN;

		counter : integer := 1;

		number : Character := '0';

		AdaIsHard : integer :=0 ;

begin

while counter <= 4 loop

number:= password(counter);

AdaIsHard := (Character'Pos(number)- 47);

password(counter):= letterWheel(AdaIsHard);

counter := counter + 1;

 end loop;

      return password;

   end Encrypt;



^ permalink raw reply	[relevance 11%]

* Re: Why no Ada.Wide_Directories?
  2011-10-18 15:02 11%           ` Adam Beneschan
@ 2011-10-18 22:54  0%             ` ytomino
  0 siblings, 0 replies; 162+ results
From: ytomino @ 2011-10-18 22:54 UTC (permalink / raw)


On Oct 19, 12:02 am, Adam Beneschan <a...@irvine.com> wrote:
> I think we have a terminology problem.
OK, sorry that my point of the argument was not put in order well.
Do confirming.

> Latin-1 is a set of characters (a subset of the full Unicode character set).
Yes.
And it's also used as name of encoding. (ISO 8859-1, like Yannick
calls)

> So I get
> confused when people talk about Latin-1 versus UTF-8 strings as if
> they were mutually exclusive.  They're not, the way I understand the
> terms.  You can have a string composed of Latin-1 characters that's
> represented using UTF-8 encoding; and the bits in that string would be
> different from a string of the same Latin-1 characters using the
> "regular" encoding, if any character in the string is in the 16#80#..
> 16#FF# range.

Yes.
"Latin-1 as character set" is not exclusive with Unicode (UCS-2 or
UCS-4).
"Latin-1 as encoding" is exclusive with UTF-8.
And then, I (we?) talked about "Latin-1 as encoding".

> On the other hand, I was confused by your statement
> "Ada.Character.Handling.To_Upper breaks UTF-8".  I don't even see a
> way for this to make sense.  Ada.Characters.Handling works on
> character types, and a character type is an enumeration type; but a
> UTF-8 "character" can't be an enumeration type at all, since it's a
> variable-length sequence of 8-bit bytes.  I'm not quite sure what you
> meant here.

Ada.Characters and Ada.Strings are defined to work with "Latin-1 as
encoding" in String type.
Some subprograms (like To_Upper) in these will replace upper half
characters (16#80#..) to meaningless values in String holding UTF-8,
if we invoke these with UTF-8 String. (Equal_Case_Insensitive does not
replace characters, but returns meaningless value if parameters have
upper half characters encoded as UTF-8.)

Of course, Ada.Wide_Wide_Characters.Handling.To_Upper
(UTF_Encoding.Wide_Wide_Strings.Decode (any UTF-8 encoded string))
works fine.

> As to having utilities such as versions of Ada.Strings.Unbounded or
> Ada.Strings.Fixed that work directly on UTF-8-encoded strings (and
> versions of Ada.Characters that operate on single UTF-8-encoded
> characters): it's certainly possible to write a package like that, and
> anyone is free to do so, but I just don't think they'd be widely used
> enough to add to the Standard.  I could be wrong.

I throught the standard library is going to be separated UTF-8 from
Latin-1, when read about UTF-8 mode of Form parameter that Randy says.
Latin-1 is not familiar for me usually, so I has wanted UTF-8 versions
of Ada.Characters. Sorry that my personal wish was mixed.
But it's certain that the standard library has some lacks for handling
non-ASCII file names.

By the way...

I probably will confuse you more :-)
Do you know that single code-point is NOT single letter for display?
Unicode has "composed character". The cases is existing that plural
code-points represent single real letter.
(refer http://www.unicode.org/reports/tr15/tr15-33.html)
In addition, Unicode has "variation selector", This is a decorator for
previous letter (possible to mix with composed character).
(refer http://www.unicode.org/Public/UNIDATA/StandardizedVariants.html)

Therefore, the difficulty of handling Wide_Wide_String is similar to
the difficulty of handling encoded (UTF-8 or other format) string, in
fact.



^ permalink raw reply	[relevance 0%]

* Re: Why no Ada.Wide_Directories?
  @ 2011-10-18 15:02 11%           ` Adam Beneschan
  2011-10-18 22:54  0%             ` ytomino
  0 siblings, 1 reply; 162+ results
From: Adam Beneschan @ 2011-10-18 15:02 UTC (permalink / raw)


On Oct 17, 7:32 pm, ytomino <aghi...@gmail.com> wrote:
>
> I'm not confused. Your misreading.

I think we have a terminology problem.  To me, Latin-1 is a set of
characters (a subset of the full Unicode character set).  So I get
confused when people talk about Latin-1 versus UTF-8 strings as if
they were mutually exclusive.  They're not, the way I understand the
terms.  You can have a string composed of Latin-1 characters that's
represented using UTF-8 encoding; and the bits in that string would be
different from a string of the same Latin-1 characters using the
"regular" encoding, if any character in the string is in the 16#80#..
16#FF# range.

However, everyone else seems to be using "Latin-1" to talk about the
*representation* in addition to the subset of characters that's being
represented---in particular, the representation in which each symbol
is represented as one 8-bit byte.  And I guess we don't really have a
good term to describe that representation.  I think UCS-1 is best, but
it doesn't seem to be commonly used.  So I guess I'll have to learn to
live with the misuse of the term "Latin-1" to refer to a
representation (encoding)---just as we older programmers have learned
to live with the terms "Julian Date" and "Gregorian Date" to mean a
dates in year/day-of-year form and in year/month/day form despite the
fact that this has nothing to do with the Julian or Gregorian
calendar.  OK, then.  I apologize for assuming that this was a sign of
your misunderstanding.

On the other hand, I was confused by your statement
"Ada.Character.Handling.To_Upper breaks UTF-8".  I don't even see a
way for this to make sense.  Ada.Characters.Handling works on
character types, and a character type is an enumeration type; but a
UTF-8 "character" can't be an enumeration type at all, since it's a
variable-length sequence of 8-bit bytes.  I'm not quite sure what you
meant here.

As to having utilities such as versions of Ada.Strings.Unbounded or
Ada.Strings.Fixed that work directly on UTF-8-encoded strings (and
versions of Ada.Characters that operate on single UTF-8-encoded
characters): it's certainly possible to write a package like that, and
anyone is free to do so, but I just don't think they'd be widely used
enough to add to the Standard.  I could be wrong.

                            -- Adam



^ permalink raw reply	[relevance 11%]

* Re: how to i get the type of a parameter specification is ASIS
  @ 2010-10-25 13:32  9%       ` stuart clark
  0 siblings, 0 replies; 162+ results
From: stuart clark @ 2010-10-25 13:32 UTC (permalink / raw)


On Oct 25, 10:24 pm, Julian Leyh <jul...@vgai.de> wrote:
> On 25 Okt., 15:12, stuart clark <clark.stuart...@gmail.com> wrote:
>
>
>
> > On Oct 25, 10:07 pm, Julian Leyh <jul...@vgai.de> wrote:
>
> > > On 25 Okt., 13:55, stuart clark <clark.stuart...@gmail.com> wrote:
>
> > > > 1) i am getting the parameter_specification using
>
> > > >  params : Asis.Parameter_Specification_List :=
> > > >                  asis.Declarations.Parameter_Profile
> > > >                    (element);
>
> > > > 2) from params i am getting the parameter name using
>
> > > >  names: asis.Defining_Name_list :=
> > > >                        asis.declarations.Names(params(i));
>
> > > > 3) i am also getting the parameter mode_kind using
>
> > > > mode_kind : Asis.Mode_Kinds :=
> > > >                        asis.elements.mode_kind
> > > >                          (params(i));
>
> > > > it looks like this
>
> > > > param  =  b : in out float
> > > > name  =   b
> > > > mode kind  = AN_IN_OUT_MODE
>
> > > > but i also want the type of the parameter, eg float.
>
> > > > anybody know how ???
>
> > > from AdaBrowse source:
>
> > >       declare
> > >          Params : constant Parameter_Specification_List :=
> > >            Parameter_Profile (Decl);
> > >       begin
> > >          for I in Params'Range loop
> > >             declare
> > >                T : constant Type_Descriptor :=
> > >                  Type_Of (Declaration_Subtype_Mark (Params (I)));
> > >             begin
> > >                if T.Attrs = No_Attributes and then
> > >                   Is_Equal (T.Decl, The_Type)
> > >                then
> > >                   return True;
> > >                end if;
> > >             end;
> > >          end loop;
> > >       end;
>
> > thanks but which package is type_descriptor from ???
>
> Oh, sorry... Type_Descriptor and Type_Of are from AdaBrowse... You
> could have a look at the body of Type_Of to find out how they did it.
>
> AdaBrowse:http://home.tiscalinet.ch/t_wolf/tw/ada95/adabrowse/

this works...

                  declare
                     x: Asis.Expression :=
                       asis.declarations.Declaration_Subtype_Mark
(Params (I));
                  begin
                     ada.Text_IO.Put_Line("type  = " &
 
ada.characters.Handling.To_String
 
(asis.Text.Element_Image(x)));
                  end;

thanks heaps, i've been doing it the dumb way, ie parsing strings
searching/deleting/using :in out etc.



^ permalink raw reply	[relevance 9%]

* Re: Wrong program structure
  2010-10-23 21:08 10% Wrong program structure George
@ 2010-10-23 21:16  0% ` Vinzent Hoefler
  0 siblings, 0 replies; 162+ 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 10% George
  2010-10-23 21:16  0% ` Vinzent Hoefler
  0 siblings, 1 reply; 162+ 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 10%]

* Re: Problems with String processing
  2010-10-23 20:16 12% Problems with String processing George
  2010-10-23 20:24  9% ` Niklas Holsti
@ 2010-10-23 20:25  9% ` Dmitry A. Kazakov
  1 sibling, 0 replies; 162+ 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 9%]

* Re: Problems with String processing
  2010-10-23 20:16 12% Problems with String processing George
@ 2010-10-23 20:24  9% ` Niklas Holsti
  2010-10-23 20:25  9% ` Dmitry A. Kazakov
  1 sibling, 0 replies; 162+ 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 9%]

* Problems with String processing
@ 2010-10-23 20:16 12% George
  2010-10-23 20:24  9% ` Niklas Holsti
  2010-10-23 20:25  9% ` Dmitry A. Kazakov
  0 siblings, 2 replies; 162+ 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 12%]

* Re: Types, packages & objects : the good old naming conventions question (without religious ware)
  @ 2009-10-30  0:01  9%   ` Robert A Duff
  0 siblings, 0 replies; 162+ results
From: Robert A Duff @ 2009-10-30  0:01 UTC (permalink / raw)


Georg Bauhaus <rm.dash-bauhaus@futureapps.de> writes:

>...  For example, the role
> can be given as "just any object" of the type.  I would not be
> comfortable with such an answer...

In some cases, "just any object" is the right answer.
No need for discomfort.
For example, parameters of general-purpose procedures.

    function To_Upper(X: String) return String;
    --  Convert X to upper case.

There's nothing interesting to say about X, except that
it's a String.  Just any String.  Trying to come up with
a meaningful name for X will just generate noise.

In the standard package Ada.Characters.Handling, it's
called Item, which is no more meaningful than X.

In the GNAT front end, there are huge numbers of parameters
declared as:

    N : Node_Id

- Bob



^ permalink raw reply	[relevance 9%]

* Re: determining input data type
  @ 2008-10-18 18:54 11% ` anon
  0 siblings, 0 replies; 162+ results
From: anon @ 2008-10-18 18:54 UTC (permalink / raw)


--
-- Without knowing what format your data is in it is kind of 
-- hard to decide what way is the best. Some ways are easy 
-- while others are more complex
--
-- But if the data is a packed buffer string then you could use 
-- Ada.Characters.Handling.Is_Digit.
--
-- In this case the best was is to use a loop and search for all 
-- valid data where the search routine would find the integer 
-- value and no error occurs unless the data is float. Also in this 
-- example, only base 10 integers are valid.
--
with Ada.Text_IO ;
use Ada.Text_IO ;

with Ada.Integer_Text_IO ;
use Ada.Integer_Text_IO ;

with Ada.Characters.Handling ;
use  Ada.Characters.Handling ;

procedure b is

  Data_Error : exception ;

  function To_Integer ( Buffer : String ) return Integer is

    Index : Natural ;
    First : Natural ; -- first valid digit
    Last  : Natural ; -- Last valid digit

  begin -- To_Integer
    Index := Buffer'First ;
    while Index <= Buffer'Last and then 
          not is_digit ( Buffer ( Index ) ) loop 
      Index := Index + 1 ;
    end loop ;
    First := Index ; 

    while Index <= Buffer'Last and then
          is_digit ( Buffer ( Index ) ) loop 
      Index := Index + 1 ;
    end loop ;
    Last := Index - 1 ;

    --  check for decimal point aka the number is float

    if Index <= Buffer'Last and then
       Buffer ( Index ) = '.' then  
       raise Data_Error ;
    end if ;
  
    return Integer'Value ( Buffer ( First..Last ) ) ;

  exception
    when Data_Error =>
      Put_Line ( "Data was invalid -- need to check data source" ) ;
      Put_Line ( "Invalid Data element =>" & Buffer ( Index ) ) ;
      raise ;
  end To_Integer ;


  Data   : integer ;

begin -- b

  Data := To_Integer ( " =123;" ) ;

  Put ( "Data => " ) ;
  Put ( Data ) ;
  New_Line ;


  -- Data_Error is raised

  Data := To_Integer ( "asv456" ) ; 

  Put ( "Data => " ) ;
  Put ( Data ) ;
  New_Line ;

  -- Data_Error is raised

  Data := To_Integer ( " =789.;" ) ; 

  Put ( "Data => " ) ;
  Put ( Data ) ;
  New_Line ;

exception
  when Data_Error =>
      null ;
end b ;

In <d39e1918-0c74-40b5-860d-f8d93181afd2@p59g2000hsd.googlegroups.com>, jedivaughn <jedivaughn14@gmail.com> writes:
>Hi, How is the best way to determine the type of input. I have the
>input coming in through a string but if the contents of the string is
>an integer then I want to convert it to such. This seems like it
>should be very easy to do but I can't seem to find out how to do it
>any where.
>
>
>Thanks,
>
>John




^ permalink raw reply	[relevance 11%]

* Gnade/ODBC example - please help
@ 2008-08-01 12:18  5% azdakiel
  0 siblings, 0 replies; 162+ 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 5%]

* Re: Converting Type Characters to type string
  @ 2008-03-31  8:54 10%       ` Ludovic Brenta
  0 siblings, 0 replies; 162+ results
From: Ludovic Brenta @ 2008-03-31  8:54 UTC (permalink / raw)


As a matter of general principle, I always use a for loop when
traversing an array:

procedure Get_Digits (Result : out String; Last : out Natural);
-- Reads at most Result'Length characters from standard input. Stops
-- after the first character that is not a decimal digit.
-- On output, Result (Result'First .. Last) contains the digits from
stdin;
-- Last may be zero, indicating no digits entered (i.e. one character
that
-- is not a digit was read).

procedure Get_Digits (Result : out String; Last : out Natural) is
begin
   Last := Result'Last; -- be optimistic
   for Index in Result'Range loop
      Ada.Text_IO.Get (Result (Index));
      if not Ada.Characters.Handling.Is_Digit (Result (Index)) then
         Last := Index - 1;
         exit;
      end if;
   end loop;
end Get_Digits;

procedure Test_Get is
   Str : String (1 .. 10);
   Last : Natural;
begin
   Get_Digits (Result => Str, Last => Last);
   Ada.Text_IO.Put_Line (Str (1 .. Last));
end Test_Get;

--
Ludovic Brenta.



^ permalink raw reply	[relevance 10%]

* Re: Converting Type Characters to type string
  @ 2008-03-31  3:04  9%   ` george.priv
    0 siblings, 1 reply; 162+ results
From: george.priv @ 2008-03-31  3:04 UTC (permalink / raw)


On Mar 30, 7:52 pm, jedivaughn <jedivaugh...@gmail.com> wrote:
> Thanks for the suggestions but I'm not quite sure how I would apply
> these to my program can you give me an example in code?
>
> Thanks for your patience
> John

procedure Test_Get is

   Str   : String (1 .. 10) := (others => ' ');
   Index : Natural          := 0;
   C     : Character;

begin

   while index < Str'Last loop
      Ada.Text_IO.Get (C);
      -- This check can be different according to your needs:
      exit when not Ada.Characters.Handling.Is_Digit (C);
      Index := Index + 1;
      Str (Index) := C;
   end loop;
   Ada.Text_IO.Put_Line (Str);

end Test_Get;

But I would rather use Get_Line instead of Get to get entire string
and then figure out what to do with it.

George.



^ permalink raw reply	[relevance 9%]

* Re: STORAGE_ERROR : EXCEPTION_STACK_OVERFLOW
  @ 2007-04-02 14:11  3%   ` andrew.carroll
  0 siblings, 0 replies; 162+ results
From: andrew.carroll @ 2007-04-02 14:11 UTC (permalink / raw)


All the files are below.  The last file in the list, called
tables.txt, is the input file.  I've supplied the input file I am
using when I get the errors.





with Ada.Text_IO, Ada.Directories, GNAT.Calendar.Time_IO,
Ada.Characters.Latin_1, Ada.IO_Exceptions,
 Ada.Strings.Maps.Constants, Ada.Strings.Fixed,
Ada.Characters.Handling, Ada.Calendar,
 schema_types, attribute_types, parser, util, index_types;

use parser, GNAT.Calendar.Time_IO, Ada.Characters.Latin_1,
Ada.Strings.Maps.Constants, Ada.Strings.Fixed,
Ada.Characters.Handling, Ada.Calendar, schema_types, attribute_types,
util;

procedure dbprog is

    -- the input file contains the table specifications --
    input : Ada.Text_IO.File_Type;

    ------------------------------------
    --    Variables for Processing    --
    ------------------------------------
    char      : Character;
    line      : string_ptr;
    tablename : string_ptr;
    datacols  : string_array_ptr;
    pkcols    : string_array_ptr;
    schemas   : schema_array_ptr;
    sindex    : Integer := 1;
    tupls     : tuple_ptr;

    procedure showoptionsmenu is
    begin
        cls;
        pl ("---------------------------------------------------",
True);
        pl ("Type one of the following at the prompt:", True);
        pl (" ", True);
        pl ("~  QUIT ", True);
        pl ("1  INSERT DATA", True);
        pl ("2  UPDATE DATA", True);
        pl ("3  DELETE DATA", True);
        pl ("4  SHOW RECORDS", True);
        pl ("For help type 'help'", True);
        pl ("---------------------------------------------------",
True);
        pl (">>", False);

        while Ada.Text_IO.End_Of_Line loop
            Ada.Text_IO.Skip_Line;
        end loop;

        line := new String'(Ada.Text_IO.Get_Line);

    end showoptionsmenu;

    function markschema return Integer is
        idx : Integer := 0;
    begin
        --find the schema in schemas.
        if schemas'length <= 0 then
            return idx;
        end if;

        loop
            idx := idx + 1;
            exit when idx > schemas'length
                     or else Index (To_Upper (schemas
(idx).tablename), tablename.all) > 0;
        end loop;

        return idx;

    end markschema;

    procedure getcolumnnamesandvalues is
        year  : Year_Number;
        month : Month_Number;
        day   : Day_Number;
        line  : string_ptr := new String'("");
        valid : Boolean    := False;
    begin
        --markschema sets sindex to the appropriate index in schemas
        --for the table with tablename.
        sindex := markschema;

        --tables are already loaded and ready to go.
        datacols := new string_array (1 .. schemas
(sindex).attributes'length);

        for x in  1 .. schemas (sindex).attributes'length loop
            if Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) = "DATE" then

                while not valid loop
                    pl
                       ("Enter a YEAR (1901 - 2099) for " &
                        Trim (schemas (sindex).attributes (x).name,
Ada.Strings.Both) &
                        "  >>",
                        False,
                        False);

                    while Ada.Text_IO.End_Of_Line loop
                        Ada.Text_IO.Skip_Line;
                    end loop;

                    line := new String'(Ada.Text_IO.Get_Line);

                    if Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) > 0 then
                        pl ("!! INVALID !!", True, False);
                    elsif Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) <= 0
                       and then Integer'value (line.all) not  in
Ada.Calendar.Year_Number'range
                    then
                        pl ("!! INVALID !!", True, False);
                    else
                        valid := True;
                    end if;
                end loop;

                year  := Year_Number'value (line.all);
                valid := False;

                while not valid loop
                    pl
                       ("Enter a MONTH NUMBER for " &
                        Trim (schemas (sindex).attributes (x).name,
Ada.Strings.Both) &
                        "  >>",
                        False,
                        False);

                    while Ada.Text_IO.End_Of_Line loop
                        Ada.Text_IO.Skip_Line;
                    end loop;

                    line := new String'(Ada.Text_IO.Get_Line);

                    if Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) > 0 then
                        pl ("!! INVALID !!", True, False);
                    elsif Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) <= 0
                       and then Integer'value (line.all) not  in
Ada.Calendar.Month_Number'range
                    then
                        pl ("!! INVALID !!", True, False);
                    else
                        valid := True;
                    end if;
                end loop;

                month := Month_Number'value (line.all);
                valid := False;

                while not valid loop
                    pl
                       ("Enter a DAY NUMBER for " &
                        Trim (schemas (sindex).attributes (x).name,
Ada.Strings.Both) &
                        "  >>",
                        False,
                        False);

                    while Ada.Text_IO.End_Of_Line loop
                        Ada.Text_IO.Skip_Line;
                    end loop;

                    line := new String'(Ada.Text_IO.Get_Line);

                    if Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) > 0 then
                        pl ("!! INVALID !!", True, False);
                    elsif Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) <= 0
                       and then Integer'value (line.all) not  in
Ada.Calendar.Day_Number'range
                    then
                        pl ("!! INVALID !!", True, False);
                    else
                        valid := True;
                    end if;
                end loop;

                day              := Day_Number'value (line.all);
                datacols.all (x) := new String'(Image (Time_Of (year,
month, day), ISO_Date));
                valid            := False;
            else
                while not valid loop
                    pl
                       ("Enter a value for " &
                        Trim (schemas (sindex).attributes (x).name,
Ada.Strings.Both) &
                        "(" &
                        Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) &
                        ")  >>",
                        False,
                        False);

                    while Ada.Text_IO.End_Of_Line loop
                        Ada.Text_IO.Skip_Line;
                    end loop;

                    line := new String'(Ada.Text_IO.Get_Line);

                    if Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) =
                       "BOOLEAN"
                    then
                        if To_Upper (line.all) = "TRUE" then
                            line  := new String'("True");
                            valid := True;
                        elsif To_Upper (line.all) = "FALSE" then
                            line  := new String'("False");
                            valid := True;
                        elsif line.all = "1" then
                            line  := new String'("True");
                            valid := True;
                        elsif line.all = "0" then
                            line  := new String'("False");
                            valid := True;
                        else
                            pl ("!! INVALID !!", True, False);
                        end if;
                    elsif Trim (schemas (sindex).attributes
(x).domain, Ada.Strings.Both) =
                          "INTEGER"
                    then
                        if Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) <= 0 then
                            valid := True;
                        else
                            pl ("!! INVALID !!", True, False);
                        end if;
                    else --"STRING"
                        valid := True;
                    end if;

                end loop;

                valid            := False;
                datacols.all (x) := new String'(line.all);
            end if;

        end loop;

    end getcolumnnamesandvalues;

    procedure getprimarykeynamesandvalues is
        year  : Year_Number;
        month : Month_Number;
        day   : Day_Number;
        line  : string_ptr := new String'("");
        valid : Boolean    := False;
    begin
        --markschema sets sindex to the appropriate index in schemas
        --for the table with tablename.
        sindex := markschema;

        pl ("Provide the primary key values to identify the record to
delete.", False, True);
        pl ("Press Enter to continue...", True, True);
        Ada.Text_IO.Get_Immediate (char);

        --tables are already loaded and ready to go.
        pkcols := new string_array (1 .. schemas
(sindex).primary_key_count);

        for x in  1 .. schemas (sindex).attributes'length loop
            if schemas (sindex).attributes (x).isprimarykey then
                if Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) = "DATE" then

                    while not valid loop
                        pl
                           ("Enter a YEAR (1901 - 2099) for " &
                            Trim (schemas (sindex).attributes
(x).name, Ada.Strings.Both) &
                            "  >>",
                            False,
                            False);

                        while Ada.Text_IO.End_Of_Line loop
                            Ada.Text_IO.Skip_Line;
                        end loop;

                        line := new String'(Ada.Text_IO.Get_Line);

                        if Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) > 0 then
                            pl ("!! INVALID !!", True, False);
                        elsif Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) <= 0
                           and then Integer'value (line.all) not  in
Ada.Calendar.Year_Number'range
                        then
                            pl ("!! INVALID !!", True, False);
                        else
                            valid := True;
                        end if;
                    end loop;

                    year  := Year_Number'value (line.all);
                    valid := False;

                    while not valid loop
                        pl
                           ("Enter a MONTH NUMBER for " &
                            Trim (schemas (sindex).attributes
(x).name, Ada.Strings.Both) &
                            "  >>",
                            False,
                            False);

                        while Ada.Text_IO.End_Of_Line loop
                            Ada.Text_IO.Skip_Line;
                        end loop;

                        line := new String'(Ada.Text_IO.Get_Line);

                        if Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) > 0 then
                            pl ("!! INVALID !!", True, False);
                        elsif Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) <= 0
                           and then Integer'value (line.all) not  in
Ada.Calendar.Month_Number'
                             range
                        then
                            pl ("!! INVALID !!", True, False);
                        else
                            valid := True;
                        end if;
                    end loop;

                    month := Month_Number'value (line.all);
                    valid := False;

                    while not valid loop
                        pl
                           ("Enter a DAY NUMBER for " &
                            Trim (schemas (sindex).attributes
(x).name, Ada.Strings.Both) &
                            "  >>",
                            False,
                            False);

                        while Ada.Text_IO.End_Of_Line loop
                            Ada.Text_IO.Skip_Line;
                        end loop;

                        line := new String'(Ada.Text_IO.Get_Line);

                        if Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) > 0 then
                            pl ("!! INVALID !!", True, False);
                        elsif Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) <= 0
                           and then Integer'value (line.all) not  in
Ada.Calendar.Day_Number'range
                        then
                            pl ("!! INVALID !!", True, False);
                        else
                            valid := True;
                        end if;
                    end loop;

                    day            := Day_Number'value (line.all);
                    pkcols.all (x) := new String'(Image (Time_Of
(year, month, day), ISO_Date));
                    valid          := False;
                else
                    while not valid loop
                        pl
                           ("Enter a value for " &
                            Trim (schemas (sindex).attributes
(x).name, Ada.Strings.Both) &
                            "(" &
                            Trim (schemas (sindex).attributes
(x).domain, Ada.Strings.Both) &
                            ")  >>",
                            False,
                            False);

                        while Ada.Text_IO.End_Of_Line loop
                            Ada.Text_IO.Skip_Line;
                        end loop;

                        line := new String'(Ada.Text_IO.Get_Line);

                        if Trim (schemas (sindex).attributes
(x).domain, Ada.Strings.Both) =
                           "BOOLEAN"
                        then
                            if To_Upper (line.all) = "TRUE" then
                                line  := new String'("True");
                                valid := True;
                            elsif To_Upper (line.all) = "FALSE" then
                                line  := new String'("False");
                                valid := True;
                            elsif line.all = "1" then
                                line  := new String'("True");
                                valid := True;
                            elsif line.all = "0" then
                                line  := new String'("False");
                                valid := True;
                            else
                                pl ("!! INVALID !!", True, False);
                            end if;
                        elsif Trim (schemas (sindex).attributes
(x).domain, Ada.Strings.Both) =
                              "INTEGER"
                        then
                            if Index (line.all, Decimal_Digit_Set,
Ada.Strings.Outside) <=
                               0
                            then
                                valid := True;
                            else
                                pl ("!! INVALID !!", True, False);
                            end if;
                        else --"STRING"
                            valid := True;
                        end if;

                    end loop;

                    valid          := False;
                    pkcols.all (x) := new String'(line.all);
                end if;
            end if;

        end loop;
    end getprimarykeynamesandvalues;

    procedure gettablename is
        count : Integer := 1;
    begin
        pl ("Enter the table name in CAPITAL letters >>", False);
        tablename     := new String'(Ada.Text_IO.Get_Line);
        tablename.all := To_Upper (tablename.all);

        while not Ada.Directories.Exists (tablename.all) and count < 5
loop
            pl ("Enter the table name in CAPITAL letters >>", False);
            tablename     := new String'(Ada.Text_IO.Get_Line);
            tablename.all := To_Upper (tablename.all);
            count         := count + 1;
        end loop;

        if count >= 5 then
            raise Constraint_Error;
        end if;

    end gettablename;

    procedure getchosenoptiondata is
    begin
        gettablename;

        --we don't do "4" here because it is just a select and we
don't
        --need values for it and we already have the attribute names
in
        --the schemas(sindex) object for which to SELECT or SHOW the
        --data.
        if line.all = "1" then
            getcolumnnamesandvalues;
        elsif line.all = "2" then
            getprimarykeynamesandvalues;
            pl (" ", True, True);
            pl ("Please enter new values for each item.  You can enter
the same ", True, True);
            pl ("data if you don't want it modified.", True, True);
            pl (" ", True, True);
            getcolumnnamesandvalues;
        elsif line.all = "3" then
            getprimarykeynamesandvalues;

        end if;

    end getchosenoptiondata;

    procedure parsechosenoption is
        pkattribs  : attribute_array_ptr;
        newvalues  : attribute_array_ptr;
        linelength : Integer;
        outline    : string_ptr;
    begin
        if line.all = "1" then

            -------------------
            --  INSERT DATA  --
            -------------------
            newvalues := new attribute_array (1 .. schemas
(sindex).attributes'length);

            --fill in the values on the objects and pass that to
insert.
            for x in  1 .. newvalues'length loop
                if Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) =
                   "BOOLEAN"
                then
                    newvalues (x) :=
                     new booleanattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => Boolean'value (datacols
(x).all));
                elsif Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) =
                      "STRING"
                then
                    newvalues (x) :=
                     new stringattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => max_stringlength * ' ');

                    Replace_Slice
                       (stringattribute (newvalues (x).all).value,
                        1,
                        max_stringlength,
                        datacols (x).all);

                elsif Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) =
                      "INTEGER"
                then
                    newvalues (x) :=
                     new integerattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => Integer'value (datacols
(x).all));

                else -- "DATE"
                    newvalues (x) :=
                     new dateattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => Value (datacols (x).all),
                        year         => Year (Value (datacols
(x).all)),
                        month        => Month (Value (datacols
(x).all)),
                        day          => Day (Value (datacols
(x).all)));
                end if;
            end loop;

            insertrec (schemas (sindex).all, newvalues.all);

        elsif line.all = "2" then

            -------------------
            --  UPDATE DATA  --
            -------------------
            pkattribs := new attribute_array (1 .. pkcols'length);

            --fill in the values on the objects and pass that to
insert.
            for x in  1 .. pkcols'length loop
                if Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) =
                   "BOOLEAN"
                then
                    pkattribs (x) :=
                     new booleanattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => Boolean'value (pkcols
(x).all));
                elsif Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) =
                      "STRING"
                then

                    pkattribs (x) :=
                     new stringattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => max_stringlength * ' ');

                    Replace_Slice
                       (stringattribute (pkattribs (x).all).value,
                        1,
                        max_stringlength,
                        pkcols (x).all);

                elsif Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) =
                      "INTEGER"
                then
                    pkattribs (x) :=
                     new integerattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => Integer'value (pkcols
(x).all));

                else -- "DATE"
                    pkattribs (x) :=
                     new dateattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => Value (pkcols (x).all),
                        year         => Year (Value (pkcols (x).all)),
                        month        => Month (Value (pkcols
(x).all)),
                        day          => Day (Value (pkcols (x).all)));
                end if;
            end loop;

            newvalues := new attribute_array (1 .. schemas
(sindex).attributes'length);

            --fill in the values on the objects and pass that to
insert.
            for x in  1 .. newvalues'length loop
                if Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) =
                   "BOOLEAN"
                then
                    newvalues (x) :=
                     new booleanattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => Boolean'value (datacols
(x).all));
                elsif Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) =
                      "STRING"
                then
                    newvalues (x) :=
                     new stringattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => max_stringlength * ' ');

                    Replace_Slice
                       (stringattribute (newvalues (x).all).value,
                        1,
                        max_stringlength,
                        datacols (x).all);

                elsif Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) =
                      "INTEGER"
                then
                    newvalues (x) :=
                     new integerattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => Integer'value (datacols
(x).all));

                else -- "DATE"
                    newvalues (x) :=
                     new dateattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => Value (datacols (x).all),
                        year         => Year (Value (datacols
(x).all)),
                        month        => Month (Value (datacols
(x).all)),
                        day          => Day (Value (datacols
(x).all)));
                end if;
            end loop;

            updaterec (schemas (sindex).all, pkattribs.all,
newvalues.all);

        elsif line.all = "3" then

            -------------------
            --  DELETE DATA  --
            -------------------
            Ada.Text_IO.Put_Line (Integer'image (sindex));
            Ada.Text_IO.Put_Line (tablename.all);

            pkattribs := new attribute_array (1 .. pkcols'length);

            --fill in the values on the objects and pass that to
delete.
            for x in  1 .. pkcols'length loop
                if Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) =
                   "BOOLEAN"
                then
                    pkattribs (x) :=
                     new booleanattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => Boolean'value (pkcols
(x).all));
                elsif Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) =
                      "STRING"
                then

                    pkattribs (x) :=
                     new stringattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => max_stringlength * ' ');

                    Replace_Slice
                       (stringattribute (pkattribs (x).all).value,
                        1,
                        max_stringlength,
                        pkcols (x).all);

                elsif Trim (schemas (sindex).attributes (x).domain,
Ada.Strings.Both) =
                      "INTEGER"
                then
                    pkattribs (x) :=
                     new integerattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => Integer'value (pkcols
(x).all));

                else -- "DATE"
                    pkattribs (x) :=
                     new dateattribute'
                       (name         => schemas (sindex).attributes
(x).name,
                        domain       => schemas (sindex).attributes
(x).domain,
                        isprimarykey => schemas (sindex).attributes
(x).isprimarykey,
                        byte_start   => 0,
                        byte_end     => 0,
                        value        => Value (pkcols (x).all),
                        year         => Year (Value (pkcols (x).all)),
                        month        => Month (Value (pkcols
(x).all)),
                        day          => Day (Value (pkcols (x).all)));
                end if;
            end loop;

            deleterec (schemas (sindex).all, pkattribs.all);

        elsif line.all = "4" then

            ----------------------
            --  SELECT RECORDS  --
            ----------------------
            linelength := 60;
            sindex     := markschema;
            outline    := new String'(1 .. linelength => '-');
            pl (outline.all, True, False);
            pl (schemas (sindex).tablename, True, False);
            pl (outline.all, True, False);
            pl ("| ", False, False);
            for x in  1 .. schemas (sindex).attributes'length loop
                pl (Trim (schemas (sindex).attributes (x).name,
Ada.Strings.Both), False, False);

                if x < schemas (sindex).attributes'length then
                    pl (" | ", False, False);
                end if;

            end loop;
            pl (" |", True, False);
            pl (outline.all, True, False);

            tupls := selectrec (schemas (sindex).all);

            if tupls = null then
                pl ("No Data", True, False);
            else
                for y in  1 .. tupls'length loop
                    newvalues := tupls (y);

                    for x in  1 .. newvalues'length loop
                        if Trim (newvalues (x).domain,
Ada.Strings.Both) = "BOOLEAN" then
                            pl
                               (Trim
                                    (Boolean'image (booleanattribute
(newvalues (x).all).value),
                                     Ada.Strings.Both),
                                False,
                                False);
                        elsif Trim (newvalues (x).domain,
Ada.Strings.Both) = "STRING" then
                            pl
                               (Trim
                                    (stringattribute (newvalues
(x).all).value,
                                     Ada.Strings.Both),
                                False,
                                False);
                        elsif Trim (newvalues (x).domain,
Ada.Strings.Both) = "INTEGER" then
                            pl
                               (Trim
                                    (Integer'image (integerattribute
(newvalues (x).all).value),
                                     Ada.Strings.Both),
                                False,
                                False);
                        else -- "DATE"
                            pl
                               (Trim
                                    (Image (dateattribute (newvalues
(x).all).value, ISO_Date),
                                     Ada.Strings.Both),
                                False,
                                False);
                        end if;

                        if x < newvalues'length then
                            pl ("   ", False, False);
                        end if;

                    end loop;
                    pl (" ", True, False);
                end loop;
            end if;

            pl (outline.all, True, False);
            pl ("Press Enter  >>", False, False);
            Ada.Text_IO.Get_Immediate (char);
        end if;

        sindex    := 0;
        tablename := null;
        datacols  := null;
        pkcols    := null;
        tupls     := null;

    end parsechosenoption;

begin

    cls;
    pl ("---------------------------------------------------", True);
    pl ("Put your table definitions in a file named ", True);
    pl ("tables.txt and place the file in the same folder as", True);
    pl ("this program (Parser.exe).  Type C to continue or.", True);
    pl ("~ to quit.", True);
    pl ("---------------------------------------------------", True);
    pl (">>", False);
    Ada.Text_IO.Get (char);
    line := new String'(Ada.Text_IO.Get_Line);

    if char = ETX or char = Tilde then
        raise Ada.IO_Exceptions.End_Error;
    end if;

    setinputfile ("tables.txt");
    schemas := parsetables;
    closeinputfile;
    showoptionsmenu;

    while line.all /= "~" loop

        if line.all = "help" or line.all = "HELP" then
            pl ("---------------------------------------------------",
True);
            pl ("If you want to quit type the tilde '~' character",
True);
            pl ("---------------------------------------------------",
True);
            pl (">>", False);
            line := new String'(Ada.Text_IO.Get_Line);
            cls;
        elsif line.all = "goodbye" or
              line.all = "GOODBYE" or
              line.all = "exit" or
              line.all = "EXIT" or
              line.all = "quit" or
              line.all = "QUIT" or
              line.all = "q" or
              line.all = "Q"
        then
            line := new String'("~");
        else
            ------------------------
            --   output results   --
            ------------------------
            getchosenoptiondata;
            parsechosenoption;
            showoptionsmenu;

        end if;

    end loop;

    cls;
    pl ("---------------------------------------------------", True);
    pl ("Goodbye!", True);
    pl ("---------------------------------------------------", True);

exception
    when Ada.IO_Exceptions.End_Error =>
        if Ada.Text_IO.Is_Open (input) then
            Ada.Text_IO.Close (input);
        end if;
        cls;
        pl ("---------------------------------------------------",
True);
        pl ("An error occured while reading data.  Possibly a
missing", True);
        pl ("semi-colon or other format character.  Or, you pressed ",
True);
        pl ("CTRL + C.  Goodbye!", True);
        pl ("---------------------------------------------------",
True);

    when Ada.Calendar.Time_Error =>
        pl ("A date value was not entered correctly.", True);
        pl ("Unfortunately this will cause the program to exit.",
True);
        pl ("Your data is safe so long as you don't 'create fresh'.",
True);
        pl ("the table when you start the program again.", True);
    when Ada.IO_Exceptions.Data_Error =>
        if Ada.Text_IO.Is_Open (input) then
            Ada.Text_IO.Close (input);
        end if;
    when Constraint_Error =>
        Ada.Text_IO.Put_Line ("You entered the data wrong.");

end dbprog;


with Ada.Text_IO, schema_types, attribute_types;

use schema_types, attribute_types;

package parser is

    file : Ada.Text_IO.File_Type;

    ---------------------------
    --    Utility Methods    --
    ---------------------------
    procedure setinputfile (filename : String);
    procedure closeinputfile;
    function parsetables return schema_array_ptr;
    function parsetable return schema'class;
    function parseattributes return attribute_array_ptr;
    function parseattribute return attribute'class;

end parser;


with Ada.Text_IO, Ada.Directories, Ada.Integer_Text_IO,
Ada.Strings.Fixed, Ada.Characters.Latin_1,
 Ada.IO_Exceptions, schema_types, attribute_types, util;

use Ada.Strings.Fixed, Ada.Characters.Latin_1, schema_types,
attribute_types, util;

package body parser is

    procedure setinputfile (filename : String) is

    begin
        Ada.Text_IO.Open (file, Ada.Text_IO.In_File, filename);
    end setinputfile;

    procedure closeinputfile is
    begin
        if Ada.Text_IO.Is_Open (file) then
            Ada.Text_IO.Close (file);
        end if;
    end closeinputfile;

    -----------------------
    --    parseTables    --
    -----------------------
    function parsetables return schema_array_ptr is
        eof        : Boolean          := False;
        char       : Character;
        schemas    : schema_array_ptr := null;
        swap       : schema_array_ptr := null;
        schemainfo : schema_ptr       := null;
        i          : Integer          := 1;
    begin
        eatWhite (file, eof);

        if not eof then
            Ada.Text_IO.Look_Ahead (file, char, eof);
        else
            raise Ada.IO_Exceptions.End_Error;
        end if;

        --at this point we should be ready to read the table name.
        swap := new schema_array (1 .. max_tables);

        while not eof loop

            schemainfo := new schema'class'(parsetable);

            pl ("Create the table fresh? [y/Y] >>", False, True);
            Ada.Text_IO.Get (char);

	    swap(i) := new schema(schemainfo.attributes'length);

            if char = 'y' or char = 'Y' then
                swap (i)     := schemainfo;
                createtable (swap (i));
            else
                if Ada.Directories.Exists (schemainfo.tablename) then
                    swap (i) := loadtable (schemainfo.tablename);
                else
                    pl ("No table exists on disc with name = " &
schemainfo.tablename, True, True);
                    pl ("You will not be able to query " &
schemainfo.tablename, True, True);
                    pl (" ", True, False);
                end if;
            end if;

	    i := i + 1;
            eatWhite (file, eof);

            if not eof then
                Ada.Text_IO.Look_Ahead (file, char, eof);
            end if;
        end loop;

        i := i - 1;

        if i < 1 then
            schemas := null;
            swap    := null;
        else
            schemas := new schema_array (1 .. i);

            for x in  1 .. i loop
                schemas (x) := swap (x);
            end loop;

            swap := null;

        end if;

        return schemas;

    end parsetables;

    ----------------------
    --    parseTable    --
    ----------------------
    function parsetable return schema'class is
        temp    : schema_ptr := null;
        eof     : Boolean    := False;
        char    : Character;
        tname   : String (1 .. max_tablename_length);
        attribs : attribute_array_ptr;
        i       : Integer    := 1;
    begin

        eatWhite (file, eof);

        --at this point we should be ready to read the table name.
        --the call to eatwhite might be redundant from the instance
that
        --called 'me' but we want to ensure we are in the right
location within
        --the file.
        if not eof then
            Ada.Text_IO.Look_Ahead (file, char, eof);
        else
            raise Ada.IO_Exceptions.End_Error;
        end if;

        while char /= Space and
              char /= HT and
              char /= LF and
              char /= CR and
              char /= Left_Parenthesis and
              not eof
        loop

            Ada.Text_IO.Get (file, char);
            tname (i) := char;
            i         := i + 1;
            Ada.Text_IO.Look_Ahead (file, char, eof);
        end loop;

        for x in  i .. max_tablename_length loop
            tname (x) := ' ';
        end loop;

        --We just read the table name.  We are expecting an opening
'('.
        --If it's not there then there is a problem with the input
file
        --format.
        eatWhite (file, eof);

        if not eof then
            Ada.Text_IO.Look_Ahead (file, char, eof);

            if char = Left_Parenthesis then
                Ada.Text_IO.Get (file, char);
            else
                Ada.Text_IO.Put_Line(
"        Error in input file format:  No attributes found.  Must have
(<attribute list>)");
            end if;
        else
            raise Ada.IO_Exceptions.End_Error;
        end if;

        attribs := parseattributes;

        if attribs /= null then

            temp            := new schema (attribs.all'length);
            temp.attributes := attribs.all;
            temp.tablename  := tname;

            for x in  1 .. temp.attributes'length loop
                if temp.attributes (x).all.isprimarykey then
                    temp.primary_key_count := temp.primary_key_count +
1;
                end if;
            end loop;
        else
            temp := null;
        end if;

        --at this point we should have read the ')' for the whole
table spec.
        --if we peek, we should find a ';'.
        eatWhite (file, eof);

        if not eof then
            Ada.Text_IO.Look_Ahead (file, char, eof);

            if char = Semicolon then
                Ada.Text_IO.Get (file, char);
            else
                Ada.Text_IO.Put_Line
                   ("        Error in input file format:  Missing
closing ';' on table spec.");
                temp := null;
            end if;
        else
            Ada.Text_IO.Put_Line
               ("        Error in input file format:  Missing closing
')' on table spec.");
            temp := null;
        end if;

        return temp.all;

    end parsetable;

    ---------------------------
    --    parseAttributes    --
    ---------------------------
    function parseattributes return attribute_array_ptr is
        eof     : Boolean             := False;
        char    : Character;
        attribs : attribute_array_ptr := null;
        swap    : attribute_array_ptr := null;
        i       : Integer             := 1;
    begin
        eatWhite (file, eof);

        if not eof then
            Ada.Text_IO.Look_Ahead (file, char, eof);
        else
            raise Ada.IO_Exceptions.End_Error;
        end if;

        --at this point we should be ready to read the attribute name.
        if not eof and char /= Right_Parenthesis then
            Ada.Text_IO.Look_Ahead (file, char, eof);
        else
            Ada.Text_IO.Put_Line ("            found eof prematurely
or ')' is in wrong place.");
            raise Ada.IO_Exceptions.End_Error;
        end if;

        swap := new attribute_array (1 .. max_columns);

        while char /= Right_Parenthesis and char /= Semicolon and not
eof loop
            swap (i) := new attribute'class'(parseattribute);
            i        := i + 1;
            eatWhite (file, eof);

            if not eof and char /= Right_Parenthesis then
                --we are expecting a ')' or a comma.
                Ada.Text_IO.Look_Ahead (file, char, eof);
            else
                raise Ada.IO_Exceptions.End_Error;
            end if;

            if char /= Comma and char /= Right_Parenthesis and not eof
then
                Ada.Text_IO.Put_Line
                   ("            Error in input file:  Missing comma
between attributes.");
                eof  := True;
                swap := null;
            elsif not eof then
                --read the comma or the ')'
                Ada.Text_IO.Get (file, char);
            end if;

            eatWhite (file, eof);

            if eof then
                Ada.Text_IO.Put_Line ("Missing semi-colon or other
format error.");
                raise Ada.IO_Exceptions.End_Error;
            end if;

        end loop;

        i := i - 1;

        if i < 1 then
            swap := null;
        else
            attribs := new attribute_array (1 .. i);

            for x in  1 .. i loop
                attribs (x) := swap (x);
            end loop;

            swap := null;

        end if;

        return attribs;

    end parseattributes;

    --------------------------
    --    parseAttribute    --
    --------------------------
    function parseattribute return attribute'class is
        temp         : attribute_types.attribute_ptr;
        eof          : Boolean := False;
        char         : Character;
        aname        : String (1 .. max_attributename_length);
        atype        : String (1 .. max_typename_length);
        asize        : Integer;
        isprimarykey : Boolean := False;
        i            : Integer := 1;
    begin

        if not eof then
            Ada.Text_IO.Look_Ahead (file, char, eof);
        else
            raise Ada.IO_Exceptions.End_Error;
        end if;

        while char /= Space and
              char /= HT and
              char /= LF and
              char /= CR and
              char /= Left_Parenthesis and
              char /= Colon and
              not eof
        loop
            Ada.Text_IO.Get (file, char);
            aname (i) := char;
            i         := i + 1;
            Ada.Text_IO.Look_Ahead (file, char, eof);
        end loop;

        for x in  i .. max_attributename_length loop
            aname (x) := ' ';
        end loop;

        --at this point we have the attribute name.  Read white space
to
        --a parenthesis or an colon.
        eatWhite (file, eof);

        if not eof then
            Ada.Text_IO.Look_Ahead (file, char, eof);
        else
            raise Ada.IO_Exceptions.End_Error;
        end if;

        --the next character should be '(' or ':'
        if char = Left_Parenthesis then
            Ada.Text_IO.Get (file, char);
            eatWhite (file, eof);

            i := 1;

            --read "primary"
            while char /= Space and
                  char /= HT and
                  char /= LF and
                  char /= CR and
                  char /= Right_Parenthesis and
                  not eof
            loop
                Ada.Text_IO.Get (file, char);
                atype (i) := char;
                i         := i + 1;
                Ada.Text_IO.Look_Ahead (file, char, eof);
            end loop;

            for x in  i .. max_typename_length loop
                atype (x) := ' ';
            end loop;

            if Trim (atype, Ada.Strings.Both) = "PRIMARY" then
                isprimarykey := True;
            end if;

            eatWhite (file, eof);

            if not eof then
                Ada.Text_IO.Look_Ahead (file, char, eof);
            else
                raise Ada.IO_Exceptions.End_Error;
            end if;

            i := 1;

            --read "key"
            while char /= Space and
                  char /= HT and
                  char /= LF and
                  char /= CR and
                  char /= Right_Parenthesis and
                  not eof
            loop
                Ada.Text_IO.Get (file, char);
                atype (i) := char;
                i         := i + 1;
                Ada.Text_IO.Look_Ahead (file, char, eof);
            end loop;

            for x in  i .. max_typename_length loop
                atype (x) := ' ';
            end loop;

            if Trim (atype, Ada.Strings.Both) = "KEY" then
                isprimarykey := True;
            else
                isprimarykey := False;
            end if;

            eatWhite (file, eof);

            if not eof then
                Ada.Text_IO.Look_Ahead (file, char, eof);
            else
                raise Ada.IO_Exceptions.End_Error;
            end if;

            if char = ')' then
                Ada.Text_IO.Get (file, char);
            else
                Ada.Text_IO.Put_Line
                   ("            Error in input:  Missing ')' after
Primary Key designation.");
            end if;

            eatWhite (file, eof);

            if not eof then
                Ada.Text_IO.Look_Ahead (file, char, eof);
            else
                raise Ada.IO_Exceptions.End_Error;
            end if;

        end if;

        if char = Colon then
            Ada.Text_IO.Get (file, char);

            eatWhite (file, eof);

            if not eof then
                Ada.Text_IO.Look_Ahead (file, char, eof);
            else
                raise Ada.IO_Exceptions.End_Error;
            end if;

            i := 1;

            --read the type of the attribute into atype variable
            while char /= Space and
                  char /= HT and
                  char /= LF and
                  char /= CR and
                  char /= Comma and
                  char /= Left_Parenthesis and
                  char /= Right_Parenthesis and
                  char /= Semicolon and
                  not eof
            loop
                Ada.Text_IO.Get (file, char);
                atype (i) := char;
                i         := i + 1;
                Ada.Text_IO.Look_Ahead (file, char, eof);
            end loop;

            for x in  i .. max_typename_length loop
                atype (x) := ' ';
            end loop;

            eatWhite (file, eof);

            --read the left parenthesis
            if not eof and
               char = Left_Parenthesis and
               Trim (atype, Ada.Strings.Both) = "STRING"
            then
                Ada.Text_IO.Get (file, char);
                Ada.Text_IO.Look_Ahead (file, char, eof);
            elsif not eof and
                  char /= Left_Parenthesis and
                  Trim (atype, Ada.Strings.Both) = "STRING"
            then
                Ada.Text_IO.Put_Line ("            Incorrect syntax:
missing (size) for string.");
            elsif eof then
                raise Ada.IO_Exceptions.End_Error;
            end if;

            eatWhite (file, eof);

            if not eof then
                Ada.Text_IO.Look_Ahead (file, char, eof);
            else
                raise Ada.IO_Exceptions.End_Error;
            end if;

            --read the size of the type of the attribute into atype
variable
            while char /= Space and
                  char /= HT and
                  char /= LF and
                  char /= CR and
                  char /= Comma and
                  char /= Right_Parenthesis and
                  char /= Left_Parenthesis and
                  not eof
            loop

                Ada.Integer_Text_IO.Get (file, asize, 0);
                Ada.Text_IO.Look_Ahead (file, char, eof);
            end loop;

            --I have to do this temporarily to get this program
            --to work.  ALL strings are the same length.  The reason
            --is because there is no way to know how long the string
is
            --when serializing it in from a file (see loadtable in
            --schema_types) before we serialize it so that we can
            --provide a length discriminant to the type defined in
            --attribute_types.  So, we just make them all the same
            --length.
            asize := max_stringlength;

            eatWhite (file, eof);

            --read the right parenthesis
            if not eof and
               char = Right_Parenthesis and
               Trim (atype, Ada.Strings.Both) = "STRING"
            then
                Ada.Text_IO.Get (file, char);
                Ada.Text_IO.Look_Ahead (file, char, eof);
            elsif not eof and
                  char /= Right_Parenthesis and
                  Trim (atype, Ada.Strings.Both) = "STRING"
            then
                Ada.Text_IO.Put_Line
                   ("            Incorrect syntax:  missing (size ~)~
for string.");
            elsif eof then
                raise Ada.IO_Exceptions.End_Error;
            end if;

            eatWhite (file, eof);

            if Trim (atype, Ada.Strings.Both) = "BOOLEAN" then

                temp        := new booleanattribute;
                temp.name   := aname;
                temp.domain := atype;

                if isprimarykey then
                    temp.isprimarykey := True;
                end if;

            elsif Trim (atype, Ada.Strings.Both) = "STRING" then

                temp        := new stringattribute;
                temp.name   := aname;
                temp.domain := atype;

                if isprimarykey then
                    temp.isprimarykey := True;
                end if;

            elsif Trim (atype, Ada.Strings.Both) = "INTEGER" then

                temp        := new integerattribute;
                temp.name   := aname;
                temp.domain := atype;

                if isprimarykey then
                    temp.isprimarykey := True;
                end if;

            elsif Trim (atype, Ada.Strings.Both) = "DATE" then

                temp        := new dateattribute;
                temp.name   := aname;
                temp.domain := atype;

                if isprimarykey then
                    temp.isprimarykey := True;
                end if;

            else
                Ada.Text_IO.Put_Line ("            unknown type
specified.");
            end if;

            --after eating the white space we should be left at the
',' or
            --the ')'.
            eatWhite (file, eof);

            if not eof then
                Ada.Text_IO.Look_Ahead (file, char, eof);
            else
                raise Ada.IO_Exceptions.End_Error;
            end if;

            --we leave the comma in the stream so that parseAttributes
can
            --pick it up and loop for the next attribute.  We leave
the second
            --')' for parseAttributes to read to know when to exit the
loop and
            --quit parsing attributes.
            if char /= Comma and char /= Right_Parenthesis then
                Ada.Text_IO.Put_Line(
"            Error in input:  Missing ')' after Primary Key
designation or ',' between attributes.")
;
                temp := null;
            end if;

        else
            Ada.Text_IO.Put_Line
               (
"            Error in input file:  Format not correct, no type
specified for attribute " &
                aname);
            temp := null;
        end if;

        return temp.all;

    end parseattribute;

begin

    null;

end parser;


with Ada.Text_IO, Ada.Characters.Latin_1, Ada.Strings.Fixed,
Ada.Strings.Maps, Ada.IO_Exceptions;

use Ada.Characters.Latin_1;

package util is
    type string_ptr is access all String;
    type string_array is array (Integer range <>) of string_ptr;
    type string_array_ptr is access all string_array;

    max_columns              : Integer := 5;
    max_tables               : Integer := 5;
    max_tablename_length     : Integer := 25;
    max_attributename_length : Integer := 25;
    max_stringlength         : Integer := 255;
    max_typename_length      : Integer := 7;
    max_filename_length      : Integer := 45;
    max_index_namelength: integer := 50;

    procedure cls;
    procedure pl (text : in String; newline : in Boolean; setcolumn :
in Boolean := True);
    function tokenize (text : in String) return string_array_ptr;
    procedure eatWhite (fin : in out Ada.Text_IO.File_Type; eof : in
out Boolean);
end util;


package body Util is

    procedure cls is
        i : Integer := 1;
    begin
        while i < 40 loop
            Ada.Text_IO.New_Line;
            i := i + 1;
        end loop;
    end cls;

    procedure pl (text : in String; newline : in Boolean; setcolumn :
in Boolean := True) is
    begin

        if newline then
            if setcolumn then
                Ada.Text_IO.Set_Col (15);
            end if;
            Ada.Text_IO.Put_Line (text);
        elsif setcolumn then
            Ada.Text_IO.Set_Col (15);
            Ada.Text_IO.Put (text);
        else
            Ada.Text_IO.Put (text);
        end if;

    end pl;

    function tokenize (text : in String) return string_array_ptr is
        temp             : string_array_ptr;
        first            : Integer := 1;
        i                : Integer := 1;
        number_of_commas : Integer := 0;
        data             : string_ptr;
        data2            : string_ptr;
    begin
        data             := new String'(text);
        number_of_commas := Ada.Strings.Fixed.Count (data.all,
Ada.Strings.Maps.To_Set (','));

        if number_of_commas > max_columns then
            pl ("Invalid number of columns specified", True);
            raise Ada.IO_Exceptions.Data_Error;
        end if;

        temp := new string_array (1 .. number_of_commas + 1);

        --first will point to the first comma.
        first :=
            Ada.Strings.Fixed.Index
               (data.all,
                Ada.Strings.Maps.To_Set (','),
                Ada.Strings.Inside,
                Ada.Strings.Forward);

        while i <= number_of_commas and number_of_commas < max_columns
loop

            temp.all (i) := new String'(data.all (1 .. first - 1));
            data2        := new String (1 .. data.all'length - first);
            data2.all    := data.all (first + 1 .. data.all'length);
            data         := new String'(data2.all);
            i            := i + 1;
            first        :=
                Ada.Strings.Fixed.Index
                   (data.all,
                    Ada.Strings.Maps.To_Set (','),
                    Ada.Strings.Inside,
                    Ada.Strings.Forward);

        end loop;

        temp.all (i) := new String'(data.all);

        return temp;
    end tokenize;

    --------------------
    --    eatWhite    --
    --------------------
    procedure eatWhite (fin : in out Ada.Text_IO.File_Type; eof : in
out Boolean) is
        char : Character;
    begin

        Ada.Text_IO.Look_Ahead (fin, char, eof);

        while Ada.Text_IO.End_Of_Line (fin) and not
Ada.Text_IO.End_Of_File (fin) loop
            Ada.Text_IO.Skip_Line (fin);
        end loop;

        Ada.Text_IO.Look_Ahead (fin, char, eof);

        while (char = Space or char = HT or char = LF or char = CR)
and
              not Ada.Text_IO.End_Of_File (fin)
        loop

            Ada.Text_IO.Get (fin, char);

            while Ada.Text_IO.End_Of_Line (fin) and not
Ada.Text_IO.End_Of_File (fin) loop
                Ada.Text_IO.Skip_Line (fin);
            end loop;

            Ada.Text_IO.Look_Ahead (fin, char, eof);
        end loop;

    end eatWhite;

begin
    null;
end Util;


with util, Ada.Calendar, attribute_types, Ada.Streams.Stream_IO;

use util, attribute_types;

package schema_types is

    ---------------------------------
    --    Variable Declarations    --
    ---------------------------------
    fin  : Ada.Streams.Stream_IO.File_Type;
    fout : Ada.Streams.Stream_IO.File_Type;

    type schema (number_of_attributes : Integer) is tagged record
        tablename : String (1 .. max_tablename_length) := (1 ..
max_tablename_length => ' ');
        attributes        : attribute_array (1 ..
number_of_attributes);
        byte_start        : Integer := 0;
        byte_end          : Integer := 0;
        primary_key_count : Integer := 0;
    end record;
    type schema_ptr is access all schema'class;
    type schema_array is array (Integer range <>) of schema_ptr;
    type schema_array_ptr is access all schema_array;
    type tuple is array (Integer range <>) of attribute_array_ptr;
    type tuple_ptr is access all tuple;

    procedure createtable (schemainfo : schema_ptr);
    function loadtable (sname : String) return schema_ptr;
    function findrecord (schemainfo : schema; values :
attribute_array) return Integer;
    procedure insertrec (schemainfo : schema; values :
attribute_array);
    procedure deleterec (schemainfo : schema; primary_key_values :
attribute_array);
    procedure updaterec
       (schemainfo : schema;
        pkattribs  : attribute_array;
        values     : attribute_array);
    function selectrec (schemainfo : schema) return tuple_ptr;

end schema_types;


with Ada.Streams.Stream_IO, Ada.Calendar, GNAT.Calendar.Time_IO,
Ada.Text_IO, Ada.Strings.Fixed,
 Ada.Directories, Ada.IO_Exceptions;
use Ada.Streams.Stream_IO, Ada.Calendar, GNAT.Calendar.Time_IO,
Ada.Strings.Fixed;

package body schema_types is

    procedure createtable (schemainfo : schema_ptr) is
        fout     : File_Type;
        attribs  : attribute_array_ptr;
        attribs2 : attribute_array_ptr;
        i        : Integer := 1;
        ii       : Integer := 1;
        temp     : access attribute'class;
    begin

        if schemainfo = null then
            return;
        end if;

        --  put them in order first
        for x in  1 .. schemainfo.attributes'length loop
            for y in  x + 1 .. schemainfo.attributes'length loop

                if schemainfo.attributes (y).name <
schemainfo.attributes (x).name then
                    temp                      := schemainfo.attributes
(y);
                    schemainfo.attributes (y) := schemainfo.attributes
(x);
                    schemainfo.attributes (x).all := temp.all;
                end if;
            end loop;
        end loop;

        attribs  := new attribute_array (1 ..
schemainfo.attributes'length);
        attribs2 := new attribute_array (1 ..
schemainfo.attributes'length);

        for x in  1 .. schemainfo.attributes'length loop
            if schemainfo.attributes (x).isprimarykey then
                attribs (i) := schemainfo.attributes (x);
                i           := i + 1;
            else
                attribs2 (ii) := schemainfo.attributes (x);
                ii            := ii + 1;
            end if;
        end loop;

        i  := i - 1;
        ii := ii - 1;

        --  the primary_key attributes first
        for x in  1 .. i loop
            schemainfo.attributes (x) := attribs (x);
        end loop;

        --  non-primary key attributes next
        for x in  1 .. ii loop
            schemainfo.attributes (x + i) := attribs2 (x);
        end loop;

        Create (fout, Out_File, Trim (schemainfo.all.tablename,
Ada.Strings.Both));
        --We are writing the number of attributes so that when we load
        --the table we can determine the number of attributes to put
        --into the new, loading schema.
        Integer'write (Stream (fout),
schemainfo.all.attributes'length);

        schemainfo.all.byte_start := Integer'val (Index (fout));

	--we output it once so that we can capture the file position for
byte_end
        schema'output (Stream (fout), schemainfo.all);

	--fill in byte_end
        schemainfo.all.byte_end := Integer'val (Index (fout));

	close(fout);
	Open (fout, Out_File, Trim (schemainfo.all.tablename,
Ada.Strings.Both));

        Integer'write (Stream (fout),
schemainfo.all.attributes'length);

	--now we have byte_start and byte_end
        schema'output (Stream (fout), schemainfo.all);

        for x in  1 .. schemainfo.all.attributes'length loop
	    to_disc(fout, schemainfo.all.attributes(x).all);
        end loop;

        Close (fout);

    end createtable;

    function loadtable (sname : String) return schema_ptr is
        schemainfo : schema_ptr;
        fin        : File_Type;
        length     : Integer;
        position   : integer;
    begin
        Open (fin, In_File, Trim (sname, Ada.Strings.Both));

        Integer'read (Stream (fin), length);

        schemainfo                := new schema (length);
        schemainfo.all            := schema'class'input (Stream
(fin));

	--mark where we are at in the file to start reading attributes.
        position                  := Integer'val (Index (fin));

        for x in  1 .. schemainfo.attributes'length loop
-----------------------------------------------------
-- Old code I plan on removing
-----------------------------------------------------
--              schemainfo.all.attributes (x).all.byte_start :=
position;
--
--              if Trim (schemainfo.all.attributes (x).domain,
Ada.Strings.Both) = "BOOLEAN" then
--  		schemainfo.all.attributes (x)                := new
booleanattribute;
--                  schemainfo.all.attributes (x).all            :=
--                      booleanattribute'input (Stream (fin));
--              elsif Trim (schemainfo.all.attributes (x).domain,
Ada.Strings.Both) = "STRING" then
--                  schemainfo.all.attributes (x)                :=
new stringattribute;
--                  schemainfo.all.attributes (x).all            :=
--                      stringattribute'input (Stream (fin));
--              elsif Trim (schemainfo.all.attributes (x).domain,
Ada.Strings.Both) = "INTEGER" then
--                  schemainfo.all.attributes (x)                :=
new integerattribute;
--                  schemainfo.all.attributes (x).all            :=
--                      integerattribute'input (Stream (fin));
--              else --  "DATE"
--                  schemainfo.all.attributes (x)                :=
new dateattribute;
--                  schemainfo.all.attributes (x).all            :=
--                      dateattribute'input (Stream (fin));
--              end if;
--              position := Integer'val (Index (fin));
--              schemainfo.all.attributes (x).all.byte_end   :=
position;
-- End old code
------------------------------------------------------
-----------------------------------------------------------
-- The code I want to use for dispatching
-----------------------------------------------------------
--  	    schemainfo.all.attributes (x) := new
attribute'class'(from_disc(fin, schemainfo.all.attributes (x).all));
-----------------------------------------------------------

------------------------------------------------------------
-- Debug code below --
------------------------------------------------------------
-- For some reason some of the attributes on schemainfo come through
-- as "unknown" after the schemainfo was filled in from
'input(stream).
-- It doesn't appear to me that createtable procedure in this package
-- writes the schema object incorrectly so I don't understand why
-- the attributes of the schemainfo object we retrieve with 'input are
-- "unknown".  Well, the domain member of the attribute is not one of
-- BOOLEAN, STRING, INTEGER or DATE; that's why it prints it but why
-- isn't the domain member one of those values?

            if Trim (schemainfo.all.attributes (x).domain,
Ada.Strings.Both) = "BOOLEAN" then
ada.text_io.put_line(schemainfo.all.attributes (x).name);
ada.text_io.put_line(schemainfo.all.attributes (x).domain);

            elsif Trim (schemainfo.all.attributes (x).domain,
Ada.Strings.Both) = "STRING" then
ada.text_io.put_line(schemainfo.all.attributes (x).name);
ada.text_io.put_line(schemainfo.all.attributes (x).domain);

	    elsif Trim (schemainfo.all.attributes (x).domain,
Ada.Strings.Both) = "INTEGER" then
ada.text_io.put_line(schemainfo.all.attributes (x).name);
ada.text_io.put_line(schemainfo.all.attributes (x).domain);

            elsif Trim (schemainfo.all.attributes (x).domain,
Ada.Strings.Both) = "DATE" then
ada.text_io.put_line(schemainfo.all.attributes (x).name);
ada.text_io.put_line(schemainfo.all.attributes (x).domain);
	    else
ada.text_io.put_line("unknown");
            end if;
        end loop;

-- End Debug Code
---------------------------------------------------------------
        Close (fin);

        return schemainfo;

    exception
        when Ada.IO_Exceptions.Status_Error =>
            Ada.Text_IO.Put_Line ("Status error in loadtable");
            return null;
    end loadtable;

    ---------------------
    --  INSERT RECORD  --
    ---------------------
    procedure insertrec (schemainfo : schema; values :
attribute_array) is
        location : Integer := -1;
        char     : Character;
    begin

        location := findrecord (schemainfo, values);

        --if the record isn't in there it is -1
        if location = -1 then

            Open (fout, Append_File, Trim (schemainfo.tablename,
Ada.Strings.Both));

            for x in  1 .. schemainfo.attributes'length loop
		to_disc(fout, values (x).all);
            end loop;

            Close (fout);
        else
            pl ("Record already exists with that key", True, True);
            pl ("Press Enter to continue...", True, True);
            Ada.Text_IO.Get_Immediate (char);
        end if;

    end insertrec;

    ---------------------
    --  SELECT RECORD  --
    ---------------------
    function selectrec (schemainfo : schema) return tuple_ptr is
        temp  : attribute_array_ptr;
        recs  : tuple_ptr;
        recs2 : tuple_ptr;
        i     : Integer := 1;

    begin
        Open (fin, In_File, Trim (schemainfo.tablename,
Ada.Strings.Both));
        Set_Index
           (fin,
            Ada.Streams.Stream_IO.Count'val
                (schemainfo.attributes
(schemainfo.attributes'length).all.byte_end));

        temp := new attribute_array (1 ..
schemainfo.attributes'length);

        if End_Of_File (fin) then
            Close (fin);
            return null;
        end if;

        recs := new tuple (1 .. 1);

        while not End_Of_File (fin) loop
            for x in  1 .. temp.all'length loop
		temp(x) := new attribute'class'(from_disc(fin, schemainfo.attributes
(x).all));
            end loop;

            if i < 2 then
                recs (recs'last) := temp;
            else
                recs2 := new tuple (1 .. recs'length);

                for z in  1 .. recs'length loop
                    recs2 (z) := recs (z);
                end loop;

                recs := new tuple (1 .. i);

                for z in  1 .. recs2'length loop
                    recs (z) := recs2 (z);
                end loop;

                recs (recs'last) := temp;
            end if;
            temp := new attribute_array (1 ..
schemainfo.attributes'length);
            i    := i + 1;
        end loop;

        Close (fin);

        return recs;

    end selectrec;

    -------------------
    --  FIND RECORD  --
    -------------------
    function findrecord (schemainfo : schema; values :
attribute_array) return Integer is
        temp         : attribute_array_ptr;
        location     : Ada.Streams.Stream_IO.Count;
        found        : Integer := 0;
        done         : Boolean := False;
        comparrisons : Integer := 0;
    begin

        Open (fin, In_File, Trim (schemainfo.tablename,
Ada.Strings.Both));

        Set_Index
           (fin,
            Ada.Streams.Stream_IO.Count'val
                (schemainfo.attributes
(schemainfo.attributes'length).all.byte_end));
        temp := new attribute_array (1 ..
schemainfo.attributes'length);

        while not End_Of_File (fin) and then not done loop
            --mark our current location in the file.
            location := Index (fin);

            --read the whole line from the file,
            for x in  1 .. schemainfo.attributes'length loop
		temp(x) := new attribute'class'(from_disc(fin,
schemainfo.attributes(x).all));
            end loop;

            --then compare them.
            comparrisons := 0;
            found        := 0;

            for x in  1 .. values'length loop

                if schemainfo.attributes (x).isprimarykey then

                    comparrisons := comparrisons + 1;

                    if Trim (values (x).domain, Ada.Strings.Both) =
"BOOLEAN" then
                        if booleanattribute (temp (x).all).value =
                           booleanattribute (values (x).all).value
                        then
                            found := found + 1;
                        end if;
                        --
ada.text_io.put_line(boolean'image(booleanattribute(temp(x).all).value
                        --));
                    elsif Trim (values (x).domain, Ada.Strings.Both) =
"STRING" then
                        if stringattribute (temp (x).all).value =
                           stringattribute (values (x).all).value
                        then
                            found := found + 1;
                        end if;
                        --
ada.text_io.put_line(stringattribute(temp(x).all).value);
                    elsif Trim (values (x).domain, Ada.Strings.Both) =
"INTEGER" then
                        if integerattribute (temp (x).all).value =
                           integerattribute (values (x).all).value
                        then
                            found := found + 1;
                        end if;
                        --
ada.text_io.put_line(integer'image(integerattribute(temp(x).all).value
                        --));
                    else -- "DATE"
                        if dateattribute (temp (x).all).value =
                           dateattribute (values (x).all).value
                        then
                            found := found + 1;
                        end if;
                        --
ada.text_io.put_line(image(dateattribute(temp(x).all).value,
                        --iso_date));
                    end if;
                end if;
            end loop;

            if found = comparrisons and then comparrisons > 0 then
                done := True;
            end if;

            if End_Of_File (fin) then
                done := True;
            end if;
        end loop;

        Close (fin);

        if found < comparrisons then
            return -1;
        elsif found = 0 and then comparrisons = 0 then
            return -1;
        else
            return Integer'val (location);
        end if;

    end findrecord;

    ---------------------
    --  DELETE RECORD  --
    ---------------------
    procedure deleterec (schemainfo : schema; primary_key_values :
attribute_array) is
        location          : Integer;
        original_byte_end : Integer := schemainfo.attributes
(schemainfo.attributes'last).byte_end;
        temp              : attribute_array_ptr;
        char              : Character;
    begin
        location := findrecord (schemainfo, primary_key_values);

        --If findrecord seeks past the schema info header in the file
and ends
        --on the end of file it will return -1.  Therefore, no records
to delete
        --in the file.
        if location = -1 then
            pl ("No records to delete with that key", True, True);
            pl ("Press Enter to continue...", True, True);
            Ada.Text_IO.Get_Immediate (char);
            return;
        end if;

        Create (fout, Out_File, "swapfile");
        Open (fin, In_File, Trim (schemainfo.tablename,
Ada.Strings.Both));

        --output the schema header information to the file
        Integer'write (Stream (fout), schemainfo.attributes'length);

	--I took these out so that we could create a function for
	--updating records that returns an rrn.  functions do not
	--allow out mode parameters and deleterec had an out mode
	--parameter because of this next line.
        --schemainfo.byte_start := Integer'val (Index (fout));
        schema'output (Stream (fout), schemainfo);

	--I took these out so that we could create a function for
	--updating records that returns an rrn.  functions do not
	--allow out mode parameters and deleterec had an out mode
	--parameter because of this next line.
        --schemainfo.byte_end := Integer'val (Index (fout));

        for x in  1 .. schemainfo.attributes'length loop

		to_disc(fout, schemainfo.attributes(x).all);
        end loop;

        --set the index on the input file so we skip the header on
input file.
        Set_Index (fin, Ada.Streams.Stream_IO.Count'val
(original_byte_end));
        temp := new attribute_array (1 ..
schemainfo.attributes'length);

        --Read records from one file and insert them into the other
file until
        --we get to the location of the record we want to delete.
        while Index (fin) < Ada.Streams.Stream_IO.Count'val (location)
loop

            for x in  1 .. temp.all'length loop
		temp(x) := new attribute'class'(from_disc(fin,
schemainfo.attributes(x).all));
		to_disc(fin, temp(x).all);
            end loop;
        end loop;

        --do a blank read to move past the line to delete
        for x in  1 .. schemainfo.attributes'length loop

	    temp(x) := new attribute'class'(from_disc(fin,
schemainfo.attributes(x).all));
        end loop;

	--output the rest of the records.
        while not End_Of_File (fin) loop
            for x in  1 .. temp.all'length loop
		temp(x) := new attribute'class'(from_disc(fin,
schemainfo.attributes(x).all));
		to_disc(fout, temp(x).all);
            end loop;
        end loop;

        Close (fin);
        Close (fout);
        Ada.Directories.Delete_File (Trim (schemainfo.tablename,
Ada.Strings.Both));
        Ada.Directories.Rename ("swapfile", Trim
(schemainfo.tablename, Ada.Strings.Both));

        location := findrecord (schemainfo, primary_key_values);

        if location >= 1 then
            deleterec (schemainfo, primary_key_values);
        end if;

    end deleterec;

    ---------------------
    --  UPDATE RECORD  --
    ---------------------
    procedure updaterec
       (schemainfo : schema;
        pkattribs  : attribute_array;
        values     : attribute_array)
    is
        position : Integer := 0;
        char     : Character;
    begin
        position := findrecord (schemainfo, pkattribs);

        --if the record doesn't exist then insert it
        if position < 1 then
            pl ("That record doesn't exist in the database.", True,
True);
            pl ("Insert it instead (menu item 1).", True, True);
            pl ("Press Enter to continue...", True, True);
            Ada.Text_IO.Get_Immediate (char);
        elsif position >= 1 then
            deleterec (schemainfo, pkattribs);
            insertrec (schemainfo, values);
        end if;
    end updaterec;

begin
    null;
end schema_types;


with util, Ada.Calendar, ada.streams.stream_io;

use util, Ada.Calendar, ada.streams.stream_io;

package attribute_types is

    -----------------------------------
    --    Forwarding Declarations    --
    -----------------------------------
    type attribute is abstract tagged;
    type booleanattribute is tagged;
    type integerattribute is tagged;
    type stringattribute is tagged;
    type dateattribute is tagged;

    --------------------------------------
    --    Attribute Type Declarations    --
    --------------------------------------
    type attribute is abstract tagged record
        name         : String (1 .. max_attributename_length) :=
           (1 .. max_attributename_length => ' ');
        domain       : String (1 .. max_typename_length) := (1 ..
max_typename_length => ' ');
        isprimarykey : Boolean                                :=
False;
        byte_start   : Integer                                := 0;
        byte_end     : Integer                                := 0;
    end record;

    --------------------------------------
    --    Basic Pointer Declarations    --
    --------------------------------------
    type attribute_ptr is access attribute'class;
    type attribute_array is array (Integer range <>) of access
attribute'class;
    type attribute_array_ptr is access all attribute_array;

    procedure to_disc (fout: file_type; item: in out attribute) is
abstract;
    function from_disc(fout: file_type; item: attribute) return
attribute'class is abstract;


    -----------------------------------
    --    Extended Attribute Types   --
    -----------------------------------
    type booleanattribute is new attribute with record
        value : Boolean := False;
    end record;
    type booleanattribute_ptr is access all booleanattribute'class;
    procedure to_disc (fout: file_type; item: in out
booleanattribute);
    function from_disc(fin: file_type; item: booleanattribute) return
attribute'class;

    type integerattribute is new attribute with record
        value : Integer := 0;
    end record;
    type integerattribute_ptr is access all integerattribute'class;
    procedure to_disc (fout: file_type; item: in out
integerattribute);
    function from_disc(fin: file_type; item: integerattribute) return
attribute'class;

    type stringattribute is new attribute with record
        value : String (1 .. max_stringlength) := (1 ..
max_stringlength => ' ');
    end record;
    type stringattribute_ptr is access all stringattribute'class;
    procedure to_disc (fout: file_type; item: in out stringattribute);
    function from_disc(fin: file_type; item: stringattribute) return
attribute'class;

    type dateattribute is new attribute with record
        year  : Year_Number  := 1901;
        month : Month_Number := 1;
        day   : Day_Number   := 1;
        value : Time         := Time_Of (1901, 1, 1);
    end record;
    type dateattribute_ptr is access all dateattribute'class;
    procedure to_disc (fout: file_type; item: in out dateattribute);
    function from_disc(fin: file_type; item: dateattribute) return
attribute'class;

end attribute_types;


with ada.text_io, util, ada.calendar;
use util, ada.calendar;

package body attribute_types is

    procedure to_disc (fout: file_type; item: in out booleanattribute)
is
    begin
        item.byte_start := Integer'val (Index (fout));
        item.byte_end := Integer'val (Index (fout)) +
(booleanattribute'size / 8) - 7;
        booleanattribute'class'output(Stream(fout), item);
    end to_disc;

    function from_disc(fin: file_type; item: booleanattribute) return
attribute'class is
        temp : access attribute'class;
    begin
      temp := new booleanattribute;
      temp.all := booleanattribute'class'input (Stream (fin));
      return temp.all;
    end from_disc;

    procedure to_disc (fout: file_type; item: in out integerattribute)
is
    begin
        item.byte_start := Integer'val (Index (fout));
        item.byte_end := Integer'val (Index (fout)) +
(integerattribute'size / 8) - 7;
        integerattribute'class'output(Stream(fout), item);
    end to_disc;

    function from_disc(fin: file_type; item: integerattribute) return
attribute'class is
    	temp : access attribute'class;
    begin
  	temp := new integerattribute;
	temp.all := integerattribute'class'input (Stream (fin));
	return temp.all;
    end from_disc;

    procedure to_disc (fout: file_type; item: in out stringattribute)
is
    begin
        item.byte_start := Integer'val (Index (fout));
        item.byte_end := Integer'val (Index (fout)) +
(stringattribute'size / 8) - 7;
        stringattribute'class'output(Stream(fout), item);
    end to_disc;

    function from_disc(fin: file_type; item: stringattribute) return
attribute'class is
    	temp: access attribute'class;
    begin
  	temp := new stringattribute;
	temp.all := stringattribute'class'input (Stream (fin));
	return temp.all;
    end from_disc;

    procedure to_disc (fout: file_type; item: in out dateattribute) is
    begin
        item.byte_start := Integer'val (Index (fout));
        item.byte_end := Integer'val (Index (fout)) +
(dateattribute'size / 8) - 11;
        dateattribute'class'output(Stream(fout), item);
    end to_disc;

    function from_disc(fin: file_type; item: dateattribute) return
attribute'class is
    	temp: access attribute'class;
    begin
    	temp := new dateattribute;
	temp.all := dateattribute'class'input (Stream (fin));
	return temp.all;
    end from_disc;

begin
    null;
end attribute_types;


with Ada.Streams.Stream_IO, util, attribute_types,Ada.Calendar; use
util, attribute_types,Ada.Calendar;

package index_types is

    ---------------------------------
    --    Variable Declarations    --
    ---------------------------------
    fin  : Ada.Streams.Stream_IO.File_Type;
    fout : Ada.Streams.Stream_IO.File_Type;
--------------------------------------------------------
--  THIS FILE IS NOT COMPLETE NOR USED YET!!!
--  IT IS INCLUDED BECAUSE IT IS WITH'D
--------------------------------------------------------
    --an index is a file
    --it contains the primary key value and file position for the
primary key for a primary index
	    --the spec sounds like only one attribute will make up a primary
key.
    --for a secondary index it contains an attribute and a position.
	    --The spec says only one attribute.
    --primary indexes are named after the table it belongs to
<tablename>_PIDX
    --secondary indexes are named after the table it belongs to like
<tablename>_SIDX

    --each schema object has a list of index names for a table
	    --initially the list of index names is empty
    --the user adds an index to the table and then the index name goes
into the list of indexes on
    --the schema
    --the schema information will have to be re-written to the table
file when an index is added.
	    --This is the same for the secondary indexes
    --if a tuple that an index is based on is inserted, deleted or
updated then the index must be
    --loaded and re-created.
    ----on updates we only have to change the index if the index value
is being changed.

--The attributes store the name of an index on itself.  When we load
the schema
--we go through each attribute and determine if it is indexed then
load that
--index if it is.  This gives us the "type" on the index value,
elleviates the
--need to maintain a list of index names in the schema object,
----what do we load an index into?


    --There are two types of indexes: primary and secondary
    --** note ** the primary index is just like the secondary; it only
has one entry per item
    --because there is only
    --one item allowed per entry due to the fact that primary keys are
unique.
    --The differences in indexes are:
    ----if we remove a value from a secondary we must match the rrn to
remove the correct
    --item; with a primary key there is only one to remove.
    ----when finding a record, with a primary index when we find the
value we don't
    ----have to search a bunch of records for the exact tuple match.
With secondary
    ----, because there are multiple values that are the same with
different rrn's
    ----we have to search each rrn and compare values to match the
tuple.

    --we don't sort as we read the table, we read the table and then
sort the index file.

    type index is abstract tagged record
        filename : String (1 .. max_index_namelength);
        rrn  : Ada.Streams.Stream_IO.Count := 0;
    end record;
    type index_ptr is access all index;
    type index_array is array (Integer range <>) of index_ptr;

    type booleanindex is tagged record
        key : boolean;
    end record;

    type integerindex is tagged record
        key : integer;
    end record;

    type stringindex is tagged record
        key : string(1..max_stringlength);
    end record;

    type dateindex is tagged record
        key : time;
    end record;
end index_types;


*************************
* Contents of the table.txt file
* This file is used by the main procedure dbprog.
* It must be labeled tables.txt and placed in the
* same directory as the executable dbprog.exe
*************************
T3(
ID(PRIMARY KEY):INTEGER
);

T2(
DATA(PRIMARY KEY):STRING(15)
);

T4(
II(PRIMARY KEY):DATE
);

T1(
mine(PRIMARY KEY):BOOLEAN
);
*************************




^ permalink raw reply	[relevance 3%]

* Re: I/O streaming with custom data transport
  @ 2006-11-22  9:16 10%   ` Maciej Sobczak
  0 siblings, 0 replies; 162+ results
From: Maciej Sobczak @ 2006-11-22  9:16 UTC (permalink / raw)


Alex R. Mosteo wrote:

>> I'm looking for something like this in Ada.
>>
>> The basic I/O facilities in the standard library don't seem to provide
>> anything like this.
>> I hoped that Ada.Streams allows this by subclassing Root_Stream_Type and
>> providing some overriding operations, but unfortunately I cannot even
>> find the specification of Root_Stream_Type (looks like there isn't any
>> and this type is just a name placeholder in ARM).
> 
> I think you haven't looked right.

Indeed - it's in 13.13.1.

> That's precisely how it's done.

> And you do this just as you say: you extend
> Ada.Streams.Root_Stream_Type and provide the read/write subprograms.

And I actually managed to do this.
Consider the following example of custom stream that for the sake of 
presentation is bound to standard IO and just converts characters to 
uppercase when writing (the point is that if I can do *this*, I can do 
anything else):

-- file my_streams.ads:
with Ada.Streams;
package My_Streams is
    use Ada.Streams;

    type My_Stream is new Root_Stream_Type with null record;

    procedure Read(Stream : in out My_Stream;
                   Item : out Stream_Element_Array;
                   Last : out Stream_Element_Offset);

    procedure Write(Stream : in out My_Stream;
                    Item : in Stream_Element_Array);
end My_Streams;

-- file my_streams.adb:
with Ada.Text_IO.Text_Streams;
with Ada.Characters.Handling;
package body My_Streams is
    use Ada.Text_IO;
    use Ada.Text_IO.Text_Streams;

    Std_Stream : Stream_Access := Stream(Current_Output);

    procedure Read(Stream : in out My_Stream;
                   Item : out Stream_Element_Array;
                   Last : out Stream_Element_Offset) is
    begin
       -- forward to standard streams:
       Read(Std_Stream.all, Item, Last);
    end Read;

    procedure Write(Stream : in out My_Stream;
                    Item : in Stream_Element_Array) is
       Item_Uppercase : Stream_Element_Array := Item;
       C : Character;
    begin
       for I in Item_Uppercase'Range loop
          C := Character'Val(Item_Uppercase(I));
          C := Ada.Characters.Handling.To_Upper(C);
          Item_Uppercase(I) := Stream_Element(Character'Pos(C));
       end loop;

       -- forward to standard streams:
       Write(Std_Stream.all, Item_Uppercase);
    end Write;
end My_Streams;

-- file hello.adb:
with Ada.Text_IO.Text_Streams;
with My_Streams;

procedure Hello is
    use Ada.Text_IO;
    use Ada.Text_IO.Text_Streams;
    use My_Streams;

    procedure Write_Hello(Stream : in out Stream_Access) is
    begin
       String'Write(Stream, "Hello");
    end Write_Hello;

    S1 : Stream_Access := Stream(Current_Output);
    S2 : Stream_Access := new My_Stream;
begin
    Write_Hello(S1);
    New_Line;
    Write_Hello(S2);
    New_Line;
end Hello;

The result is:

$ ./hello
Hello
HELLO
$

The point here is that the Write_Hello procedure can be reused with 
various streams, just like my foo functions in C++ (from initial post).

Is the code above correct? Any traps or problems that I don't see at the 
moment?


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



^ permalink raw reply	[relevance 10%]

* Re: Char type verification
  @ 2006-11-16 23:30  6%       ` Yves Bailly
  0 siblings, 0 replies; 162+ results
From: Yves Bailly @ 2006-11-16 23:30 UTC (permalink / raw)


Jeffrey R. Carter wrote:
>> It was intended as "How do you translate this example to Ada? How would
>> you, as a presumably experienced Ada coder, do it? What hoops would we
>> jump through?
> 
> What this example does is output whether the 1st character of the 1st
> command-line argument is in the range 'A' .. 'Z'. In the Ada world, we
> tend to ignore the details of badly designed examples in poorly designed
> languages and simply implement the same functionality. Since there is no
> reason for your conversions and home-grown function, we're not going to
> waste effort translating them.

I'm very sorry Jeffrey, but I'm afraid you're missing the point. The given
example is no more than what it is : an example. There are plenty of ways
to know if a character is upper-case or not (what about the procedure
Is_Upper in the package Ada.Characters.Handling, by the way? did I missed
it in the replies?), and I'm quite sure Koray would have found most of them,
if not all (assuming it's possible).

As I understand it, the real question was : "having a list of contiguous
values of some type, how to know if a given value of that same type is
contained into the list". It's a kind of basic hashing: you can assume
to always be able to map your type's values to integers. So you can
replace "list of contiguous values" by "range of values".

So, here's my modest contribution. Don't bother to say it's overcomplex.

First create a generic package:
--8<-----8<-----8<-----8<-----8<-----8<-----8<---
generic
   type T is private;
   type H is range <>;
   with function Hash(val: in T) return H;
package P is
   function Is_In_Range(lower: in T;
                        upper: in T;
                        value: in T)
      return Boolean;
end P;
--8<-----8<-----8<-----8<-----8<-----8<-----8<---

The body performs the actual check of validity:
--8<-----8<-----8<-----8<-----8<-----8<-----8<---
package body P is

   function Is_In_Range(lower: in T;
                        upper: in T;
                        value: in T)
      return Boolean is
   begin
      return Hash(value) in Hash(lower)..Hash(upper);
   end Is_In_Range;

end P;
--8<-----8<-----8<-----8<-----8<-----8<-----8<---

And now use it in a test program:
--8<-----8<-----8<-----8<-----8<-----8<-----8<---
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Command_Line; use Ada.Command_Line;
with P;
procedure Test is

   function To_Natural(c: in Character)
      return Natural is
   begin
      return Natural(Character'Pos(c));
   end To_Natural;

   package P_Char is new P(T => Character,
                           H => Natural,
                           Hash => To_Natural);
   c: Character;
begin
   c := Argument(1)(1);
   Put("Is_Upper('" & c & "') = ");
   Put_Line(Boolean'Image(P_Char.Is_In_Range('A', 'Z', c)));
end Test;
--8<-----8<-----8<-----8<-----8<-----8<-----8<---

Isn't Ada delightfull?  :-)

Regards,

-- 
(o< | Yves Bailly  : http://kafka-fr.net   | -o)
//\ | Linux Dijon  : http://www.coagul.org | //\
\_/ |                                      | \_/`



^ permalink raw reply	[relevance 6%]

* Re: Char type verification
  2006-11-15 21:57 12% ` Georg Bauhaus
@ 2006-11-15 23:15  0%   ` KE
    0 siblings, 1 reply; 162+ results
From: KE @ 2006-11-15 23:15 UTC (permalink / raw)


Dear George

Many thanks for your detailed answer. I'll most certainly make use of
your advice. However, if you look again, my question was not

- How can I verify whether a character is upper case

Nor was it

- Where, in the library hierarchies of Ada, can I find the character
handling routines

It was intended as "How do you translate this example to Ada? How would
you, as a presumably experienced Ada coder, do it? What hoops would we
jump through?

In other words, I wanted to see some Ada idioms in action to create a
transparent coding of this.

If you believe this simple exercise is not a productive use of your
time, though, I can understand.

Thanks again.


-- KE


Georg Bauhaus wrote:
[snip...]
>
> Or use Ada.Characters.Handling.Is_Upper(c), if you want
> to include characters outside 7bit ASCII.
>
> The C type char, which IIRC might start at -127 or
> at 0, has an implementation defined representation,
> and is a bit vague. The Ada standard frowns upon vague
> things, hence Ada's character type does not have
> theses issues. OTOH, for interfacing with C,
> look at the standard package Interfaces.C.
>
> For more general uses, there are standard packages
> Ada.Strings.Maps, Ada.Strings.Maps.Constants,
> Ada.Characters.Handling, and Ada.Characters.Latin_1.
> There are all kinds of character predicates and
> translation subprograms.
>
> There are variants for Wide_Character, covering
> the BMP of ISO 10646.
> 
> Ada 2005, in addition supports Unicode and related
> subprograms.




^ permalink raw reply	[relevance 0%]

* Re: Char type verification
  @ 2006-11-15 21:57 12% ` Georg Bauhaus
  2006-11-15 23:15  0%   ` KE
  0 siblings, 1 reply; 162+ results
From: Georg Bauhaus @ 2006-11-15 21:57 UTC (permalink / raw)


On Wed, 2006-11-15 at 14:00 -0800, KE wrote:
> Hi
> 
> Assume that I have the following C code:
> 
> #include <stdio.h>
> 
> #define uchar   unsigned char
> 
> 
> static uchar UCASE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

This is the character range 'A' .. 'Z'.
You can simply write
  c in 'A' .. 'Z'
in any Boolean context where c is of type Character.

Or use Ada.Characters.Handling.Is_Upper(c), if you want
to include characters outside 7bit ASCII.

The C type char, which IIRC might start at -127 or
at 0, has an implementation defined representation,
and is a bit vague. The Ada standard frowns upon vague
things, hence Ada's character type does not have
theses issues. OTOH, for interfacing with C,
look at the standard package Interfaces.C.

For more general uses, there are standard packages
Ada.Strings.Maps, Ada.Strings.Maps.Constants,
Ada.Characters.Handling, and Ada.Characters.Latin_1.
There are all kinds of character predicates and
translation subprograms.

There are variants for Wide_Character, covering
the BMP of ISO 10646.

Ada 2005, in addition supports Unicode and related
subprograms.





^ permalink raw reply	[relevance 12%]

* Re: Advice Please
  2006-11-10  6:52 10% Advice Please laehyung
@ 2006-11-10  9:27  0% ` Dmitry A. Kazakov
  0 siblings, 0 replies; 162+ results
From: Dmitry A. Kazakov @ 2006-11-10  9:27 UTC (permalink / raw)


On 9 Nov 2006 22:52:15 -0800, laehyung wrote:

> Advice & comments please.
> my test code is ...
> 
> with Ada.Text_IO; use Ada.Text_IO;
> 
> with Ada.Characters.Handling;
> use Ada.Characters.Handling;
> with Ada.Unchecked_Conversion;
> with Interfaces;   use Interfaces;
> with Interfaces.C;
> 
> procedure Test_Str is
> 
> ---------------------------------------
>    function Conv_U8_To_Char is
>       new Ada.Unchecked_Conversion(Source => Unsigned_8,
>       	                           Target => Character);
>    function Conv_Char_To_U8 is
>       new Ada.Unchecked_Conversion(Source => Character,
>       	                           Target => Unsigned_8);
> 
> ---------------------------------------
> 
>    function Strhex_To_Ascii_Strbyte (Item : in String) return String is
> 
>       Strsize    : Natural  := Item'Length;
>       Rtn_Length : Natural  := (Strsize)/2;
> 
>       Str_Val    : String(1..Rtn_Length);
> 
>       Strtemp1 : Unsigned_8;
>       Strtemp2 : Unsigned_8;
>       C        : array(1..Strsize) of Unsigned_8;
> 
>    begin
> 
>       for Idx in Item'range loop
>          if Is_Hexadecimal_Digit(Item(Idx)) then
>             if Is_Digit(Item(Idx)) then
>                C(Idx):=
> Unsigned_8(Character'Pos(Item(Idx))-Character'Pos('0'));
>             else
>                C(Idx):= Unsigned_8(Character'Pos(To_Upper(Item(Idx)))
>                      -Character'Pos('A')+16#A#);
>             end if;
>          else
>             Put_Line("Program Code contains NON-HexaDecimal character.
> program Break");
>             raise Data_Error;
>          end if;
>       end loop;
> 
>       for I in 1..Rtn_Length loop
>          Strtemp1 := Shift_Left(Unsigned_8(C(2*I-1)),4) and
> Unsigned_8(16#FF#);
>          Strtemp2 := Unsigned_8(C(2*I)) and Unsigned_8(16#FF#);
> 
>          Str_Val(I) := Conv_U8_To_Char( Strtemp1 or Strtemp2 );
> 
>       end loop;
> 
>       return Str_Val;
>    end Strhex_To_Ascii_Strbyte;
> ---------------------------------------
> 
> 
>    Input_Str : String := "0000002D0F010000002E0F000000000A10A3";
> 
> begin
> 
>    --Put("Output_Str =>");
>    Put(Strhex_To_Ascii_Strbyte(Input_Str));
> 
> end Test_Str;
> 
> ----------------------------------------------------------------
> (my machine is windows XP)
> Compile & Run:
> 
> c:\work>gnatmke -O2 -gnatvf test_str
> gcc -c -O2 -gnatvf test_str.adb
> 
> GNAT GPL 2006 (20060522-34)
> Copyright 1992-2006, Free Software Foundation, Inc.
> 
> Compiling: test_str.adb (source file time stamp: 2006-11-10 05:22:28)
>  68 lines: No errors
> gnatbind -x test_str.ali
> gnatlink test_str.ali
> 
> c:\work> test_str > code_test.txt
> 
> edit code_test.txt file with hexa code editor(ex. UltraEdit-32)
> 
> output data shold be
> 00000000h:00 00 00 2D 0F 01 00 00 00 2E 0F 00 00 00 00 00
> ;...-............
> 00000010h:0A 10 A3 0D 0A                                  ;..?.

No, it should not. I should be (in a binary output mode):

00 00 00 2D 0F 01 00 00 00 2E 0F 00 00 00 00 0A 10 A3

four zeros before the last triplet. Note also that when you write a text
file the OS may translate formatters (like LF and CR). That explains the
effect you've got. 0A was translated into 0D 0A pair.

> but result is
> 00000000h:00 00 00 2D 0F 01 00 00 00 2E 0F 00 00 00 00 0D
> ;...-............
> 00000010h:0A 10 A3 0D 0A                                  ;..?.
> 
> the data of address 0Fh is 0D, why?
> How to correct this problem.

There is no problem, your code works.

Admittedly, the code needs much rework both in terms of efficiency and
clarity. Use case statement for character classification or else a
translation map. You don't need the array C, everything can be done in one
pass. You don't need modular arithmetic and masking. Use integer
multiplication and addition. Use 'Val attribute instead of
Unchecked_Conversion. What would be the result for an odd-length string?

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



^ permalink raw reply	[relevance 0%]

* Advice Please
@ 2006-11-10  6:52 10% laehyung
  2006-11-10  9:27  0% ` Dmitry A. Kazakov
  0 siblings, 1 reply; 162+ results
From: laehyung @ 2006-11-10  6:52 UTC (permalink / raw)


Advice & comments please.
my test code is ...

with Ada.Text_IO; use Ada.Text_IO;

with Ada.Characters.Handling;
use Ada.Characters.Handling;
with Ada.Unchecked_Conversion;
with Interfaces;   use Interfaces;
with Interfaces.C;

procedure Test_Str is

---------------------------------------
   function Conv_U8_To_Char is
      new Ada.Unchecked_Conversion(Source => Unsigned_8,
      	                           Target => Character);
   function Conv_Char_To_U8 is
      new Ada.Unchecked_Conversion(Source => Character,
      	                           Target => Unsigned_8);

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

   function Strhex_To_Ascii_Strbyte (Item : in String) return String is

      Strsize    : Natural  := Item'Length;
      Rtn_Length : Natural  := (Strsize)/2;

      Str_Val    : String(1..Rtn_Length);

      Strtemp1 : Unsigned_8;
      Strtemp2 : Unsigned_8;
      C        : array(1..Strsize) of Unsigned_8;

   begin

      for Idx in Item'range loop
         if Is_Hexadecimal_Digit(Item(Idx)) then
            if Is_Digit(Item(Idx)) then
               C(Idx):=
Unsigned_8(Character'Pos(Item(Idx))-Character'Pos('0'));
            else
               C(Idx):= Unsigned_8(Character'Pos(To_Upper(Item(Idx)))
                     -Character'Pos('A')+16#A#);
            end if;
         else
            Put_Line("Program Code contains NON-HexaDecimal character.
program Break");
            raise Data_Error;
         end if;
      end loop;

      for I in 1..Rtn_Length loop
         Strtemp1 := Shift_Left(Unsigned_8(C(2*I-1)),4) and
Unsigned_8(16#FF#);
         Strtemp2 := Unsigned_8(C(2*I)) and Unsigned_8(16#FF#);

         Str_Val(I) := Conv_U8_To_Char( Strtemp1 or Strtemp2 );

      end loop;

      return Str_Val;
   end Strhex_To_Ascii_Strbyte;
---------------------------------------


   Input_Str : String := "0000002D0F010000002E0F000000000A10A3";

begin

   --Put("Output_Str =>");
   Put(Strhex_To_Ascii_Strbyte(Input_Str));

end Test_Str;

----------------------------------------------------------------
(my machine is windows XP)
Compile & Run:

c:\work>gnatmke -O2 -gnatvf test_str
gcc -c -O2 -gnatvf test_str.adb

GNAT GPL 2006 (20060522-34)
Copyright 1992-2006, Free Software Foundation, Inc.

Compiling: test_str.adb (source file time stamp: 2006-11-10 05:22:28)
 68 lines: No errors
gnatbind -x test_str.ali
gnatlink test_str.ali

c:\work> test_str > code_test.txt

edit code_test.txt file with hexa code editor(ex. UltraEdit-32)

output data shold be
00000000h:00 00 00 2D 0F 01 00 00 00 2E 0F 00 00 00 00 00
;...-............
00000010h:0A 10 A3 0D 0A                                  ;..?.

but result is
00000000h:00 00 00 2D 0F 01 00 00 00 2E 0F 00 00 00 00 0D
;...-............
00000010h:0A 10 A3 0D 0A                                  ;..?.

the data of address 0Fh is 0D, why?
How to correct this problem.




^ permalink raw reply	[relevance 10%]

* Re: ANNOUNCE: Avatox 1.0 is now available
  2006-09-09 12:21 11%                 ` Simon Wright
@ 2006-09-11  7:58  0%                   ` Manuel Collado
  0 siblings, 0 replies; 162+ results
From: Manuel Collado @ 2006-09-11  7:58 UTC (permalink / raw)


Simon Wright escribi�:
> Manuel Collado <m.collado@fi.upm.es> writes:
> 
>> What puzzles me is that the XML structure (nesting) doesn't follows
>> the lexical Ada source structure. Example from avatox.adb -->
>> avatox.adb.xml:
>>
>> <A_CLAUSE ... startLine="29" endLine="29" startCol="1" endCol="29">
>>   <A_WITH_CLAUSE ... startLine="29" endLine="29" startCol="1" endCol="29"/>
>>   <AN_EXPRESSION ... startLine="29" endLine="29" startCol="6" endCol="28">
>>     <A_SELECTED_COMPONENT ... startLine="29" endLine="29" startCol="6"
>> endCol="28"/>
>>     <AN_EXPRESSION ... startLine="29" endLine="29" startCol="6" endCol="19">
>>       ....
>>
>> You can see that <A_WITH_CLAUSE> from (29,1) to (29,29) lexically
>> contains <AN_EXPRESSION> from (29,6) to (29,28). But the latest is not
>> nested inside the former. Instead, it appears as a sibling of it.
> 
> Marc and I disagree on this one. My approach in asis2xml is to have
> 
>     <context_clauses>
>       <with_clause>
>         <selected_component>
>           <selected_component>
>             <identifier>Ada</identifier>
>             <identifier>Characters</identifier>
>           </selected_component>
>           <identifier>Handling</identifier>
>         </selected_component>
>       </with_clause>
> 
> but it would be just as sensible to have
> 
>     <clause kind="with_clause">
> 
> The XPATH expressions aren't that different:
> 
>    A_CLAUSE[A_WITH_CLAUSE]
>    with_clause
>    clause[@kind='with_clause']
> 
> It depends what would be most useful. As an example of where user
> input would be good, what about that <selected_component> structure,
> which does follow the lexical structure of the language, but imagine
> the query to find all withs of Ada.Characters.Handling!

Well, the // (descendant) axis of XPATH looks directly for inner nodes, 
skipping intermediate levels.

-- 
Manuel Collado



^ permalink raw reply	[relevance 0%]

* Re: ANNOUNCE: Avatox 1.0 is now available
  @ 2006-09-09 12:21 11%                 ` Simon Wright
  2006-09-11  7:58  0%                   ` Manuel Collado
  0 siblings, 1 reply; 162+ results
From: Simon Wright @ 2006-09-09 12:21 UTC (permalink / raw)


Manuel Collado <m.collado@fi.upm.es> writes:

> What puzzles me is that the XML structure (nesting) doesn't follows
> the lexical Ada source structure. Example from avatox.adb -->
> avatox.adb.xml:
>
> <A_CLAUSE ... startLine="29" endLine="29" startCol="1" endCol="29">
>   <A_WITH_CLAUSE ... startLine="29" endLine="29" startCol="1" endCol="29"/>
>   <AN_EXPRESSION ... startLine="29" endLine="29" startCol="6" endCol="28">
>     <A_SELECTED_COMPONENT ... startLine="29" endLine="29" startCol="6"
> endCol="28"/>
>     <AN_EXPRESSION ... startLine="29" endLine="29" startCol="6" endCol="19">
>       ....
>
> You can see that <A_WITH_CLAUSE> from (29,1) to (29,29) lexically
> contains <AN_EXPRESSION> from (29,6) to (29,28). But the latest is not
> nested inside the former. Instead, it appears as a sibling of it.

Marc and I disagree on this one. My approach in asis2xml is to have

    <context_clauses>
      <with_clause>
        <selected_component>
          <selected_component>
            <identifier>Ada</identifier>
            <identifier>Characters</identifier>
          </selected_component>
          <identifier>Handling</identifier>
        </selected_component>
      </with_clause>

but it would be just as sensible to have

    <clause kind="with_clause">

The XPATH expressions aren't that different:

   A_CLAUSE[A_WITH_CLAUSE]
   with_clause
   clause[@kind='with_clause']

It depends what would be most useful. As an example of where user
input would be good, what about that <selected_component> structure,
which does follow the lexical structure of the language, but imagine
the query to find all withs of Ada.Characters.Handling!



^ permalink raw reply	[relevance 11%]

* Re: New to Ada, noticing something strange.
  2005-09-29 23:58  7%       ` mike.martelli
  2005-09-30  0:28  9%         ` mike.martelli
@ 2005-09-30  6:06  8%         ` Jeffrey R. Carter
  1 sibling, 0 replies; 162+ results
From: Jeffrey R. Carter @ 2005-09-30  6:06 UTC (permalink / raw)


mike.martelli@gmail.com wrote:

> 		charMap: array (Character) of Integer;

You have undefined elements of this array, and may well be referencing them. You 
should probably initialize all of them:

type Char_Mapping is array (Character) of Integer;

Char_Map : Char_Mapping :=
('0' => 0, '1' => 1, '2' => 2, ... 'F' => 15, others => -16);

> 		NumOfArgs, size, carry: Integer := 0;

By making these Integer, you're implying that negative values are meaningful. 
These should probably be Natural. Size should probably be Positive.

> 				size := Length(operand1);

Why are you using a global variable here? Especially since it doesn't seem to be 
referenced anywhere else?

> 				when others => return strChar(1);

when others =>
    return Strchar (Strchar'First);

> 			--converts all lowercase characters to uppercase

Ada.Characters.Handling.To_Upper, as you noted elsewhere.

> 				if charMap(To_String(operand1)(i)) >= charMap(charBase) then

Here you can be referencing uninitialized values of Charmap, since the program 
has no control over the arguments it receives.

> 			for i in reverse 1 .. ResultSize(operand1,operand2) loop
> 				digit := AddDigits(To_String(operand1)(i), To_String(operand2)(i));

One of these strings may be shorter than the result of Resultsize, and when you 
try to index it with that value (first time through the loop), this should raise 
Constraint_Error.

So, what inputs did you run this with, and what output did you obtain?

-- 
Jeff Carter
"There's no messiah here. There's a mess all right, but no messiah."
Monty Python's Life of Brian
84



^ permalink raw reply	[relevance 8%]

* Re: New to Ada, noticing something strange.
  2005-09-29 23:58  7%       ` mike.martelli
@ 2005-09-30  0:28  9%         ` mike.martelli
  2005-09-30  6:06  8%         ` Jeffrey R. Carter
  1 sibling, 0 replies; 162+ results
From: mike.martelli @ 2005-09-30  0:28 UTC (permalink / raw)


Also, I know I could use the To_Upper function in the
Ada.Characters.Handling package.  I wasn't using it at first for some
reason, but now am.




^ permalink raw reply	[relevance 9%]

* Re: New to Ada, noticing something strange.
  @ 2005-09-29 23:58  7%       ` mike.martelli
  2005-09-30  0:28  9%         ` mike.martelli
  2005-09-30  6:06  8%         ` Jeffrey R. Carter
  0 siblings, 2 replies; 162+ results
From: mike.martelli @ 2005-09-29 23:58 UTC (permalink / raw)


Ok, Randy sounds good here is my code.  I also tried compiling in on
Laptop with the latest GNAT compilier and I get the same results.

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

with Ada.Text_IO;
with Ada.Integer_Text_IO;
with Ada.Command_Line;
with Ada.Strings.Unbounded;
with Ada.Characters.Handling;

use Ada.Text_IO;
use Ada.Integer_Text_IO;
use Ada.Command_Line;
use Ada.Strings.Unbounded;

	procedure BigInts is
		base, operand1, operand2: Unbounded_String :=
To_Unbounded_String("");
		charMap: array (Character) of Integer;
		NumOfArgs, size, carry: Integer := 0;
		charBase, digit, charDigit: Character;

		procedure PopulateArray is
		begin
			charMap('0') := 0;
			charMap('1') := 1;
			charMap('2') := 2;
			charMap('3') := 3;
			charMap('4') := 4;
			charMap('5') := 5;
			charMap('6') := 6;
			charMap('7') := 7;
			charMap('8') := 8;
			charMap('9') := 9;
			charMap('A') := 10;
			charMap('B') := 11;
			charMap('C') := 12;
			charMap('D') := 13;
			charMap('E') := 14;
			charMap('F') := 15;
		end PopulateArray;

		function ResultSize(operand1, operand2: Unbounded_String) return
Integer is
		begin
			if Length(operand1) > Length(operand2)  then
				size := Length(operand1);
			else
				size := Length(operand2);
			end if;

			return size;
		end ResultSize;

		function Convert2Character(strChar: String) return Character is
		begin
		--Put_Line(strChar);
			case Integer'Value(strChar) is
				when 10 => return 'A';
				when 11 => return 'B';
				when 12 => return 'C';
				when 13 => return 'D';
				when 14 => return 'E';
				when 15 => return 'F';
				when others => return strChar(1);
			end case;
		end Convert2Character;

		function AddDigits(charOp1, charOp2: Character) return Character is
		begin
			charDigit := Convert2Character(Integer'Image(charMap(charOp1) +
charMap(charOp2) + carry));
			Put("Print1: ");
			Put(Convert2Character(Integer'Image(charMap(charOp1) +
charMap(charOp2) + carry)));
			if (charMap(charOp1) + charMap(charOp2) + carry) >
(charMap(charBase) - 1) then
				Put_Line("here1: ");
				charDigit := Convert2Character(Integer'Image(charMap(charBase) -
1)); --Set the digit to the highest possible values
				carry := (charMap(charOp1) + charMap(charOp2) + carry) -
(charMap(charBase) - 1); --carry is all of the rest
			else
				Put_Line("here2: ");
				carry := 0; --there is no carry
			end if;
			Put("Digit: ");
			Put(charDigit);
			New_Line;
			Put("Carry: ");
			Put(carry);
			New_Line;
			return charDigit;
		end AddDigits;

	begin
		NumOfArgs := ARGUMENT_COUNT;

		if NumOfArgs = 3 then
			base := To_Unbounded_String(Argument(1));
			operand1 := To_Unbounded_String(Argument(2));
			operand2 := To_Unbounded_String(Argument(3));

			if not (Integer'Value(To_String(base)) > 1) or not
(Integer'Value(To_String(base)) < 16) then
					Put("The base entered is not valid.");
					return;
			end if;

			charBase := Convert2Character(To_String(base));

			--converts all lowercase characters to uppercase
			for i in 1 .. Length(operand1) loop
				case Element(operand1, i) is
					when 'a' => Replace_Element(operand1, i, 'A');
					when 'b' => Replace_Element(operand1, i, 'B');
					when 'c' => Replace_Element(operand1, i, 'C');
					when 'd' => Replace_Element(operand1, i, 'D');
					when 'e' => Replace_Element(operand1, i, 'E');
					when 'f' => Replace_Element(operand1, i, 'F');
					when others => Replace_Element(operand1, i, Element(operand1, i));
				end case;
			end loop;

			--converts all lowercase characters to uppercase
			for i in 1 .. Length(operand2) loop
				case Element(operand2, i) is
					when 'a' => Replace_Element(operand2, i, 'A');
					when 'b' => Replace_Element(operand2, i, 'B');
					when 'c' => Replace_Element(operand2, i, 'C');
					when 'd' => Replace_Element(operand2, i, 'D');
					when 'e' => Replace_Element(operand2, i, 'E');
					when 'f' => Replace_Element(operand2, i, 'F');
					when others => Replace_Element(operand2, i, Element(operand2, i));
				end case;
			end loop;

			PopulateArray;

			for i in 1 .. Length(operand1) loop
				if charMap(To_String(operand1)(i)) >= charMap(charBase) then
						Put_Line("Operand 1 is not valid with the base entered");
						return;
				end if;
			end loop;

			for i in 1 .. Length(operand2) loop
				if charMap(To_String(operand2)(i)) >= charMap(charBase) then
						Put_Line("Operand 2 is not valid with the base entered");
						return;
				end if;
			end loop;

			for i in reverse 1 .. ResultSize(operand1,operand2) loop
				digit := AddDigits(To_String(operand1)(i), To_String(operand2)(i));
				Put(digit);
				New_Line;
			end loop;
			--Print final carry digit
			Put("Final Carry: ");
			Put(carry);
			New_Line;
		else
			Put("Not enough args");
			return;
		end if;
	end BigInts;




^ permalink raw reply	[relevance 7%]

* New to Ada, noticing something strange.
@ 2005-09-29 17:20  6% mike.martelli
    0 siblings, 1 reply; 162+ results
From: mike.martelli @ 2005-09-29 17:20 UTC (permalink / raw)


Here is an excerpt of my code.  Every function works as it should, the
program is set up correct, and the correct values are being passed to
all functions.

The idea of the program is perform arithmetic on arbitrarily long
integers that are inputted as strings using the paper and pencil
approach (digit by digit, from right from right to left, with a carry
digit).  The user will enter a base, operand1, and operan2 via command
line arguments.  (if you need more explanation let me know).

with Ada.Text_IO;
with Ada.Integer_Text_IO;
with Ada.Command_Line;
with Ada.Strings.Unbounded;
with Ada.Characters.Handling;

use Ada.Text_IO;
use Ada.Integer_Text_IO;
use Ada.Command_Line;
use Ada.Strings.Unbounded;

procedure BigInts is
...

charMap: array (Character) of Integer;

charMap('0') := 0;
charMap('1') := 1;
charMap('2') := 2;
...
charMap('E') := 14;
charMap('F') := 15;

 function C2C(strChar: String) return Character is
 begin
    Put_Line(strChar);
    case Integer'Value(strChar) is
	when 10 => return 'A';
	when 11 => return 'B';
	when 12 => return 'C';
	when 13 => return 'D';
	when 14 => return 'E';
	when 15 => return 'F';
	when others => return strChar(1);
    end case;
 end C2C;

 function AddDigits(op1, op2: Character) return Character is
 begin
    charDigit:=C2C(Integer'Image(charMap(op1)+charMap(op2)+carry));

    Put("Print1: ");
    Put(C2C(Integer'Image(charMap(op1)+charMap(op2)+carry)));

    if(charMap(op1)+charMap(op2)+carry)>(charMap(charBase)-1) then
        Put_Line("here1: ");

        --Set the digit to the highest possible values
	charDigit:=C2C(Integer'Image(charMap(charBase)-1));

        --carry is all of the rest
	carry:=(charMap(op1)+charMap(op2)+carry)-(charMap(charBase)-1);
    else
	Put_Line("here2: ");
	carry:=0; --there is no carry
    end if;

    Put("Digit: ");
    Put(charDigit);
    New_Line;
    Put("Carry: ");
    Put(carry);
    New_Line;
    return charDigit;
 end AddDigits;
...
end BigInts;

(I removed some extra white space so it would align better in the post)

I have some Put()/Put_Line() statements in AddDigits() for debugging
purposes.  The problem is in Convert2Character(), nothing was ever
being returned by that function.  I added the Put_Line(strChar) to make
sure a correct value was being passed to it.  Once I added that
Put_Line() a value was being returned by the function and it was
correct.  It seems that a Put_Line() is needed for some reason or it
does not do what it is supposed to do.




^ permalink raw reply	[relevance 6%]

* Re: Lower
  @ 2005-08-31 17:35  9% ` Frode Tennebø
  0 siblings, 0 replies; 162+ results
From: Frode Tennebø @ 2005-08-31 17:35 UTC (permalink / raw)


On Wednesday 31 August 2005 19:07 TC wrote:

> there is a function that make lower of string?

Ada.Characters.Handling.To_Lower

 -Frode

-- 
^ Frode Tenneb� | email: frode@tennebo.com | Frode@IRC ^
|  with Standard.Disclaimer; use Standard.Disclaimer;  |



^ permalink raw reply	[relevance 9%]

* Re: Character set conversion
  @ 2005-08-02  9:45 10% ` Dmitry A. Kazakov
  0 siblings, 0 replies; 162+ results
From: Dmitry A. Kazakov @ 2005-08-02  9:45 UTC (permalink / raw)


On Tue, 02 Aug 2005 03:57:42 -0400, Adaddict wrote:

> I'm looking for an Ada package that could provide me functions to convert
> strings from one to another character set, for example from Windows to
> MSDOS or to Unicode. Does that even exist? I've been looking everywhere
> but haven't found anything.

It is not clear what you actually need.

Windows Unicode = Wide_Character in Ada. So to convert Latin-1 (=Ada
String) to UCS-2 (=Ada Wide_String) you need just To_Wide_String (from
Ada.Characters.Handling.) [ If UTF-8 encoding is what you are looking for,
see http://www.dmitry-kazakov.de/ada/strings_edit.htm ]

As for MS-DOS character set, what do you mean by that, graphical
characters? I'm not sure if they are present in Unicode. Anyway, as others
have noted, Translate might be useful for you.

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



^ permalink raw reply	[relevance 10%]

* Re: ATC, an  example please.
  @ 2005-07-02  8:18  9% ` Craig Carey
  0 siblings, 0 replies; 162+ results
From: Craig Carey @ 2005-07-02  8:18 UTC (permalink / raw)


On 30 Jun 2005 01:44:52 -0700, "e.coli" wrote:

>How [does] ATC work?
>Can you fix this example, please?.


with Ada.Text_IO;
with Ada.Characters.Handling;
with Ada.Exceptions;


procedure ATC_Test is
      --  If compile with gnatmake in Windows, use "-gnatP" polling

   package Tio renames Ada.Text_IO;
   package ACH renames Ada.Characters.Handling;

   procedure Put (X : String) renames Tio.Put;
   procedure PutL (X : String) renames Tio.Put_Line;


   procedure Slave;                 --  This procedure gets interrupted
   procedure Slave is
   begin
            --  Seeming GNAT 3.15p NT bug: Abort_Defer kills the delay
            --  statement (as well as blocking the abort as expected):
      --  pragma Abort_Defer;
      PutL ("Slave starts");
      for Iteration in 1 .. 1_000 loop
         Put (".");
         delay 0.100;
      end loop;
      PutL (ASCII.LF & "Slave ends by itself");
   end Slave;


   task type Keyboard_Task_Type is
      entry Got_Quit_Key;
   end Keyboard_Task_Type;

   type Keyboard_Task_Type_AP is access all Keyboard_Task_Type;

   task body Keyboard_Task_Type
   is
      Ch       : Character;
   begin
      PutL ("Keyboard task starts");
      loop
         Tio.Get_Immediate (Item => Ch);
         Ch := ACH.To_Lower (String'(1 => Ch)) (1);
         PutL (" """ & Ch & '"');
         if Ch = 'q' then
            accept Got_Quit_Key;
            exit;
         end if;
      end loop;
      PutL ("Keyboard task ends");
   exception
      when others => null;
   end Keyboard_Task_Type;


   task type Interruptible_Task is
      entry Start (KT_In : Keyboard_Task_Type_AP);
   end Interruptible_Task;

   task body Interruptible_Task
   is
      KT    : Keyboard_Task_Type_AP;
   begin
      PutL ("Interruptible task starts");
      accept Start (KT_In : Keyboard_Task_Type_AP) do
         KT := KT_In;
      end Start;
      <<REDO>>
      select         --  No aborting when not inside a task
         KT.all.Got_Quit_Key;       --  Now KT maybe becomes unusable
         PutL ("Computation aborted");
      then abort
         PutL ("Starting computation. Press Q to quit");
         Slave;
         PutL ("Finished computation without abrting");
      end select;
      --  goto REDO;             --  If a loop around the select, then
   exception                     --  a "Tasking_Error" error occurs
      when E : others =>         --  when a terminated KT task is used
         PutL ("Interruptible_Task: " &      -- GNAT hides error
                  Ada.Exceptions.Exception_Information (E));
   end Interruptible_Task;

begin
   declare
      KT    : aliased Keyboard_Task_Type;
      IT    : Interruptible_Task;
   begin
      IT.Start (KT_In => KT'Unchecked_Access);
   end;                          --  First declared is last finalized
   PutL ("Main program ends");
end ATC_Test;

% Compiled and run. Only tested in Windows 2003.

$ gnatmake atc_test.adb -gnatP -gnata -gnato -gnatq -O0 -g -gnatf
  -gnatU -m -i -gnatwacfHlpru -gnatR3s -gnaty3abcefhiklM79nprt
  -bargs -E -p -we -s -static -largs -v -v

$ atc_test.exe
---------------------------------------
Keyboard task starts
Interruptible task starts
Starting computation. Press Q to quit
Slave starts
.............. "y"
........ "q"
Keyboard task ends
Computation aborted
Main program ends
---------------------------------------

Perhaps experts (e.g. Mr Obry) can say why GNAT 3.15p ATC:
 (a) only runs inside a task, and/or
 (b) what's up with Abort_Defer feature of disabling the delay statement?.


Craig Carey
Auckland





^ permalink raw reply	[relevance 9%]

* Shootout: Word Frequency
@ 2005-04-14  1:28  9% Jeffrey Carter
  0 siblings, 0 replies; 162+ results
From: Jeffrey Carter @ 2005-04-14  1:28 UTC (permalink / raw)


There have been some postings a solution to this in Ada, but I've only 
now had a chance to check out the problem. I see that the Ada solution 
is 168 LOC and 111 terminator semicolons. I'd be interested to know how 
it compares to this version, which I posted here some time ago in 
response to something else (some lines may wrap):

with Ada.Characters.Handling;
with Ada.Text_IO;

with Word_Count_Help;
procedure Word_Count is
    use Ada.Characters.Handling;
    use Ada.Text_IO;
    use Word_Count_Help;

    Word   : Word_Input.Word;
    Result : Word_Search.Result;
    Set    : Word_Search.Skip_List;
    Item   : Word_Info;
begin -- Word_Count
    All_Words : loop
       exit All_Words when End_Of_File;

       Word_Input.Get (Word);
       Item.Word := +To_Lower (+Word);
       Result := Word_Search.Search (Set, Item);

       if Result.Found then
          Item.Count := Result.Item.Count + 1;
       else
          Item.Count := 1;
       end if;

       Word_Search.Insert (List => Set, Item => Item);
    end loop All_Words;

    Sort_Words : declare
       type Context_Info is record
          Index : Positive := 1;
          List  : Word_List (1 .. Word_Search.Length (Set) );
       end record;

       procedure Word_To_List (Item : in Word_Info; Context : in out 
Context_Info; Continue : out Boolean) is
          -- null;
       begin -- Word_To_List
          Continue := True;
          Context.List (Context.Index) := Item;
          Context.Index := Context.Index + 1;
       end Word_To_List;

       procedure Set_To_List is new Word_Search.Iterate (Context_Data => 
Context_Info, Action => Word_To_List);

       Context : Context_Info;
    begin -- Sort_Words
       Set_To_List (List => Set, Context => Context);
       Sort (Set => Context.List);

       Output : for I in Context.List'range loop
          Put_Line (Item => +Context.List (I).Word & Integer'Image 
(Context.List (I).Count) );
       end loop Output;
    end Sort_Words;
end Word_Count;

with PragmARC.Assignment;
with PragmARC.Skip_List_Unbounded;
with PragmARC.Sort_Quick_In_Place;
with PragmARC.Word_Input;
package Word_Count_Help is
    package Word_Input is new PragmARC.Word_Input;

    function "+" (Right : Word_Input.Word) return String renames 
Word_Input.V_String.To_String;
    function "+" (Right : String) return Word_Input.Word;

    type Word_Info is record
       Word  : Word_Input.Word;
       Count : Natural := 0;
    end record;

    function "<" (Left : Word_Info; Right : Word_Info) return Boolean;
    function ">" (Left : Word_Info; Right : Word_Info) return Boolean;
    function "=" (Left : Word_Info; Right : Word_Info) return Boolean;

    type Word_List is array (Positive range <>) of Word_Info;

    procedure Assign is new PragmARC.Assignment (Element => Word_Info);
    procedure Sort is new PragmARC.Sort_Quick_In_Place (Element => 
Word_Info, Index => Positive, Sort_Set => Word_List, "<" => ">");

    package Word_Search is new PragmARC.Skip_List_Unbounded (Element => 
Word_Info);
end Word_Count_Help;

package body Word_Count_Help is
    use type Word_Input.V_String.Bounded_String;

    function "+" (Right : String) return Word_Input.Word is
       -- null;
    begin -- "+"
       return Word_Input.V_String.To_Bounded_String (Right);
    end "+";

    function "<" (Left : Word_Info; Right : Word_Info) return Boolean is
       -- null;
    begin -- "<"
       return Left.Word < Right.Word;
    end "<";

    function ">" (Left : Word_Info; Right : Word_Info) return Boolean is
       -- null;
    begin -- ">"
       if Left.Count = Right.Count then
          return Left.Word < Right.Word;
       else
          return Left.Count > Right.Count;
       end if;
    end ">";

    function "=" (Left : Word_Info; Right : Word_Info) return Boolean is
       -- null;
    begin -- "="
       return Left.Word = Right.Word;
    end "=";
end Word_Count_Help;

which is 115 SLOC and 64 terminator semicolons. It could perhaps be sped 
up by not checking End_Of_File and handling End_Error instead.

-- 
Jeff Carter
"Apart from the sanitation, the medicine, education, wine,
public order, irrigation, roads, the fresh water system,
and public health, what have the Romans ever done for us?"
Monty Python's Life of Brian
80



^ permalink raw reply	[relevance 9%]

* Re: Ada bench : count words
  2005-03-23 15:09 10%               ` Marius Amado Alves
@ 2005-03-30 16:08  0%                 ` Andre
  0 siblings, 0 replies; 162+ results
From: Andre @ 2005-03-30 16:08 UTC (permalink / raw)



Marius Amado Alves wrote:
>> I'll review this tomorrow on the bus to work (I think your program is 
>> separating words at buffer end, and it should not).
> 
> 
> Done. Tmoran, sorry, my first sight was wrong, your algorithm is mostly 
> fine. Minor reservations:
> - special statute given to CR; personally I think all characters 
> (control or not) should count to total
> - reliance on Stream_Element representing one character; portable across 
> all range of environments?
> 
> My own program rewritten with Text_Streams attains the same speed as 
> yours. The fact that it is structured doesn't hit performance 
> significantly. Pragma Inline improves a little bit. Real times (ms) on 
> my iBook, for input file repeated 2500 times, all compiled with only -O3:
> C ........................ 600
> Yours, or mine inlined ... 700
> Mine not inlined ......... 750
> 
> So we should submit yours, or mine inlined. It will put Ada right after 
> the Cs w.r.t. speed. W.r.t. executable file size Ada is much bigger. On 
> my iBook:
> C .......  15k
> Mine .... 423k
> Yours ... 459k
> 
> W.r.t. source code size all are similar. Number of significant 
> semicolons (Ada), or semicolons + {} blocks + #includes + #defines (C):
> C .............. 27
> Yours .......... 33
> Mine inlined ... 52
> 
> My program follows for reference. It accepts the code for EOL as an 
> argument. Default = 10 (LF).
> 
> -- The Great Computer Language Shootout
> -- http://shootout.alioth.debian.org/
> -- 
> -- contributed by Guys De Cla
> 
> with Ada.Characters.Handling;
> with Ada.Characters.Latin_1;
> with Ada.Command_Line;
> with Ada.Streams;
> with Ada.Streams.Stream_IO;
> with Ada.Strings.Fixed;
> with Ada.Text_IO;
> with Ada.Text_IO.Text_Streams;
> 
> procedure Count_Words_Portable is
> 
>    use Ada.Characters.Handling;
>    use Ada.Characters.Latin_1;
>    use Ada.Command_Line;
>    use Ada.Streams;
>    use Ada.Streams.Stream_IO;
>    use Ada.Text_IO;
>    use Ada.Text_IO.Text_Streams;
> 
>    Buffer : Stream_Element_Array (1 .. 4096);
>    Input_Stream : Ada.Text_IO.Text_Streams.Stream_Access
>      := Ada.Text_IO.Text_Streams.Stream (Current_Input);
>    EOL_Character_Pos : Stream_Element := Character'Pos (LF);
>    Lines : Natural := 0;
>    Words : Natural := 0;
>    Total : Natural := 0;
>    In_Word : Boolean := False;
>    N : Stream_Element_Offset;
>    Is_Separator : array (Stream_Element) of Boolean :=
>      (0 .. 32 | 127 .. 159 => True, others => False);
> 
>    procedure Begin_Word is
>    begin
>       Words := Words + 1;
>       In_Word := True;
>    end;
> 
>    procedure End_Word is
>    begin
>       In_Word := False;
>    end;
> 
>    procedure End_Line is
>    begin
>       Lines := Lines + 1;
>       End_Word;
>    end;
> 
>    procedure Count_Words (S : in Stream_Element_Array) is
>    begin
>       Total := Total + S'Length;
>       for I in S'Range loop
>          if S (I) = EOL_Character_Pos then
>             End_Line;
>          else
>             if Is_Separator (S (I)) then
>                if In_Word then End_Word; end if;
>             else
>                if not In_Word then Begin_Word; end if;
>             end if;
>          end if;
>       end loop;
>    end;
> 
>    pragma Inline (Begin_Word, End_Word, End_Line, Count_Words);
> 
> begin
>    begin
>       EOL_Character_Pos := Stream_Element'Value (Argument (1));
>    exception
>       when Constraint_Error => null;
>    end;
>    Ada.Text_IO.Put_Line ("EOL =>" & Stream_Element'Image 
> (EOL_Character_Pos));
> 
>    loop
>       Read (Root_Stream_Type'Class (Input_Stream.all), Buffer, N);
>       Count_Words (Buffer (1 .. N));
>       exit when N < Buffer'Length;
>    end loop;
> 
>    Ada.Text_IO.Put_Line
>      (Natural'Image (Lines) &
>       Natural'Image (Words) &
>       Natural'Image (Total));
> end;
> 

I checked with the Shootout side. The Ada program sent in was rated with 
Error. So, maybe you can check why and correct it.

Andr�


^ permalink raw reply	[relevance 0%]

* Re: Ada bench : word frequency
  @ 2005-03-24  1:24  9%       ` Marius Amado Alves
  0 siblings, 0 replies; 162+ results
From: Marius Amado Alves @ 2005-03-24  1:24 UTC (permalink / raw)
  To: comp.lang.ada

Program fixed. Zero differences with the reference result.

It's two times slower than the GCC C benchmark :-(

(CPU times (user+sys) on my iBook for n=25 repetitions of the input 
file: C => 0.75, Ada => 1.45)

However that's already enough to put Ada on the 7th place, after OCaml 
and before Eiffel :-)

Program follows.

with Ada.Characters.Handling;
with Ada.Characters.Latin_1;
with Ada.Command_Line;
with Ada.Streams;
with Ada.Streams.Stream_IO;
with Ada.Strings.Fixed;
with Ada.Text_IO;
with Ada.Text_IO.Text_Streams;

procedure Word_Frequency is

    use Ada.Characters.Handling;
    use Ada.Characters.Latin_1;
    use Ada.Command_Line;
    use Ada.Streams;
    use Ada.Streams.Stream_IO;
    use Ada.Text_IO;
    use Ada.Text_IO.Text_Streams;

    Buffer : Stream_Element_Array (1 .. 4096);
    Input_Stream : Ada.Text_IO.Text_Streams.Stream_Access
      := Ada.Text_IO.Text_Streams.Stream (Current_Input);
    N : Stream_Element_Offset;
    Is_Separator : array (Stream_Element) of Boolean :=
      (Character'Pos ('A') .. Character'Pos ('Z') |
       Character'Pos ('a') .. Character'Pos ('z') => False,
       others => True);

    -- N-ary tree of word counts
    -- used to increment the counts in one pass of the input file
    -- branches on the letter
    -- carries the count
    -- very fast
    -- but very space consuming

    subtype Letter is Stream_Element range
      Character'Pos ('a') .. Character'Pos ('z');
    type Word is array (Positive range <>) of Letter;
    type Tree;
    type Tree_Ptr is access Tree;
    type Node is
       record
          Count : Natural := 0;
          Subtree : Tree_Ptr := null;
       end record;
    type Tree is array (Letter) of Node;

    procedure Inc (X : in out Integer) is begin X := X + 1; end;
    procedure Dec (X : in out Integer) is begin X := X - 1; end;

    procedure Inc_Word (Parent : Tree_Ptr; Descendents : Word) is
    begin
       if Descendents'Length > 0 then
          declare
             Child_Index : Positive := Descendents'First;
             Child : Letter renames Descendents (Child_Index);
          begin
             if Descendents'Length = 1 then
                Inc (Parent (Child).Count);
             else
                if Parent (Child).Subtree = null then
                   Parent (Child).Subtree := new Tree;
                end if;
                Inc_Word
                  (Parent (Child).Subtree,
                   Descendents (Child_Index + 1 .. Descendents'Last));
             end if;
          end;
       end if;
    end;

    -- Binary tree of word counts
    -- used for sorting the result by the count (frequency)
    -- branches on the word count
    -- carries the word form

    type Form_Ptr is access Word;
    type Binary_Tree;
    type Binary_Tree_Ptr is access Binary_Tree;
    type Binary_Tree is
       record
          Form : Form_Ptr;
          Count : Natural;
          Left, Right : Binary_Tree_Ptr;
       end record;

    procedure Add_Node (Parent : in out Binary_Tree_Ptr; Form : 
Form_Ptr; Count : Natural) is
    begin
       if Parent = null then
          Parent := new Binary_Tree;
          Parent.Form := Form;
          Parent.Count := Count;
       else
          if Count < Parent.Count then
             Add_Node (Parent.Left, Form, Count);
          else
             Add_Node (Parent.Right, Form, Count);
          end if;
       end if;
    end;

    -- end of binary tree primitives

    Root : Tree_Ptr := new Tree;
    Btree : Binary_Tree_Ptr := null;
    Current_Word : Word (1 .. 1000);
    Current_Word_Length : Natural range 0 .. Current_Word'Last := 0;
    In_Word : Boolean := False;

    procedure Append_To_Word (E : Letter) is
    begin
       Inc (Current_Word_Length);
       Current_Word (Current_Word_Length) := E;
       In_Word := True;
    end;

    procedure End_Word is
    begin
       if Current_Word_Length > 0 then
          Inc_Word (Root, Current_Word (1 .. Current_Word_Length));
       end if;
       Current_Word_Length := 0;
       In_Word := False;
    end;

    To_Lower : array (Stream_Element) of Letter;

    procedure Initialise_To_Lower_Map is
       D : Integer := Character'Pos ('a') - Character'Pos ('A');
    begin
       for I in Character'Pos ('a') .. Character'Pos ('z') loop
          To_Lower (Stream_Element (I)) := Letter (I);
          To_Lower (Stream_Element (I - D)) := Letter (I);
       end loop;
    end;

    procedure Process (S : Stream_Element_Array) is
    begin
       for I in S'Range loop
          if Is_Separator (S (I)) then
             if In_Word then End_Word; end if;
          else
             Append_To_Word (To_Lower (S (I)));
          end if;
       end loop;
    end;

    procedure Populate_Btree (Ntree : Tree_Ptr) is
    begin
       Inc (Current_Word_Length);
       for I in Letter'Range loop
          Current_Word (Current_Word_Length) := I;
          if Ntree (I).Count > 0 then
             Add_Node
                (Btree,
                 Form => new Word'(Current_Word (1 .. 
Current_Word_Length)),
                 Count => Ntree (I).Count);
          end if;
          if Ntree (I).Subtree /= null then
             Populate_Btree (Ntree (I).Subtree);
          end if;
       end loop;
       Dec (Current_Word_Length);
    end;

    procedure Populate_Btree is
    begin
       Current_Word_Length := 0;
       Populate_Btree (Root);
    end;

    function To_String (X : Form_Ptr) return String is
       S : String (X'Range);
    begin
       for I in X'Range loop
          S (I) := Character'Val (X (I));
       end loop;
       return S;
    end;

    subtype String7 is String (1 .. 7);

    function Img7 (X : Natural) return String7 is
       S : String := Natural'Image (X);
    begin
       return String' (1 .. 8 - S'Length => ' ') & S (2 .. S'Last);
    end;

    procedure Dump_Btree (X : Binary_Tree_Ptr := Btree) is
    begin
       if X /= null then
          Dump_Btree (X.Right);
          Ada.Text_IO.Put_Line
            (Img7 (X.Count) & " " & To_String (X.Form));
          Dump_Btree (X.Left);
       end if;
    end;

begin
    Initialise_To_Lower_Map;
    loop
       Read (Root_Stream_Type'Class (Input_Stream.all), Buffer, N);
       Process (Buffer (1 .. N));
       exit when N < Buffer'Length;
    end loop;
    if In_Word then End_Word; end if;
    Populate_Btree;
    Dump_Btree;
end;




^ permalink raw reply	[relevance 9%]

* Ada bench : word frequency
  @ 2005-03-23 20:39  9%   ` Marius Amado Alves
    0 siblings, 1 reply; 162+ results
From: Marius Amado Alves @ 2005-03-23 20:39 UTC (permalink / raw)
  To: comp.lang.ada

Here's a shot at the word frequency benchmark. By my calculations, it 
is as fast as the GCC C benchmark. I did not compare the output with 
the reference output. A line-by-line comparison requires a criterion 
for words with the same frequency, which AFAICT is not documented. 
Also, my current concept of word separator does not include punctuation 
marks. Again, I could not find a reference definition.

The program does not use any external data structures library. It 
includes its own specific structures, an n-ary tree keyed by word form, 
and a binary tree keyed by word frequency. It increments the counts in 
the n-ary tree, then traverses the n-ary tree to populate the binary 
tree (to order by count), then dumps the latter.

with Ada.Characters.Handling;
with Ada.Characters.Latin_1;
with Ada.Command_Line;
with Ada.Streams;
with Ada.Streams.Stream_IO;
with Ada.Strings.Fixed;
with Ada.Text_IO;
with Ada.Text_IO.Text_Streams;

procedure Word_Frequency is

    use Ada.Characters.Handling;
    use Ada.Characters.Latin_1;
    use Ada.Command_Line;
    use Ada.Streams;
    use Ada.Streams.Stream_IO;
    use Ada.Text_IO;
    use Ada.Text_IO.Text_Streams;

    Buffer : Stream_Element_Array (1 .. 4096);
    Input_Stream : Ada.Text_IO.Text_Streams.Stream_Access
      := Ada.Text_IO.Text_Streams.Stream (Current_Input);
    N : Stream_Element_Offset;
    Is_Separator : array (Stream_Element) of Boolean :=
      (0 .. 32 | 127 .. 159 => True, others => False);

    -- N-ary tree of word counts
    -- used to increment the counts in one pass of the input file
    -- branches on the letter
    -- carries the count
    -- very fast
    -- but very space consuming

    subtype Letter is Stream_Element range 0 .. 255;
    type Word is array (Positive range <>) of Letter;
    type Tree;
    type Tree_Ptr is access Tree;
    type Node is
       record
          Count : Natural := 0;
          Subtree : Tree_Ptr := null;
       end record;
    type Tree is array (Letter) of Node;

    procedure Inc (X : in out Integer) is begin X := X + 1; end;
    procedure Dec (X : in out Integer) is begin X := X - 1; end;

    procedure Inc_Word (Parent : Tree_Ptr; Descendents : Word) is
    begin
       if Descendents'Length > 0 then
          declare
             Child_Index : Positive := Descendents'First;
             Child : Letter renames Descendents (Child_Index);
          begin
             if Descendents'Length = 1 then
                Inc (Parent (Child).Count);
             else
                if Parent (Child).Subtree = null then
                   Parent (Child).Subtree := new Tree;
                end if;
                Inc_Word
                  (Parent (Child).Subtree,
                   Descendents (Child_Index + 1 .. Descendents'Last));
             end if;
          end;
       end if;
    end;

    -- Binary tree of word counts
    -- used for sorting the result by the count (frequency)
    -- branches on the word count
    -- carries the word form

    type Form_Ptr is access Word;
    type Binary_Tree;
    type Binary_Tree_Ptr is access Binary_Tree;
    type Binary_Tree is
       record
          Form : Form_Ptr;
          Count : Natural;
          Left, Right : Binary_Tree_Ptr;
       end record;

    procedure Add_Node (Parent : in out Binary_Tree_Ptr; Form : 
Form_Ptr; Count : Natural) is
    begin
       if Parent = null then
          Parent := new Binary_Tree;
          Parent.Form := Form;
          Parent.Count := Count;
       else
          if Count < Parent.Count then
             Add_Node (Parent.Left, Form, Count);
          else
             Add_Node (Parent.Right, Form, Count);
          end if;
       end if;
    end;

    -- end of binary tree primitives

    Root : Tree_Ptr := new Tree;
    Btree : Binary_Tree_Ptr := null;
    Current_Word : Word (1 .. 1000);
    Current_Word_Length : Natural range 0 .. Current_Word'Last := 0;
    In_Word : Boolean := False;

    procedure Append_To_Word (E : Stream_Element) is
    begin
       Inc (Current_Word_Length);
       Current_Word (Current_Word_Length) := E;
       In_Word := True;
    end;

    procedure End_Word is
    begin
       if Current_Word_Length > 0 then
          Inc_Word (Root, Current_Word (1 .. Current_Word_Length));
       end if;
       Current_Word_Length := 0;
       In_Word := False;
    end;

    procedure Process (S : Stream_Element_Array) is
    begin
       for I in S'Range loop
          if Is_Separator (S (I)) then
             if In_Word then End_Word; end if;
          else
             Append_To_Word (S (I));
          end if;
       end loop;
    end;

    procedure Populate_Btree (Ntree : Tree_Ptr) is
    begin
       Inc (Current_Word_Length);
       for I in Letter'Range loop
          Current_Word (Current_Word_Length) := I;
          if Ntree (I).Count > 0 then
             Add_Node
                (Btree,
                 Form => new Word'(Current_Word (1 .. 
Current_Word_Length)),
                 Count => Ntree (I).Count);
          end if;
          if Ntree (I).Subtree /= null then
             Populate_Btree (Ntree (I).Subtree);
          end if;
       end loop;
       Dec (Current_Word_Length);
    end;

    procedure Populate_Btree is
    begin
       Current_Word_Length := 0;
       Populate_Btree (Root);
    end;

    function To_String (X : Form_Ptr) return String is
       S : String (X'Range);
    begin
       for I in X'Range loop
          S (I) := Character'Val (X (I));
       end loop;
       return S;
    end;

    procedure Dump_Btree (X : Binary_Tree_Ptr := Btree) is
    begin
       if X /= null then
          Dump_Btree (X.Right);
          Ada.Text_IO.Put_Line
            (To_String (X.Form) &
             Natural'Image (X.Count));
          Dump_Btree (X.Left);
       end if;
    end;

begin
    loop
       Read (Root_Stream_Type'Class (Input_Stream.all), Buffer, N);
       Process (Buffer (1 .. N));
       exit when N < Buffer'Length;
    end loop;
    if In_Word then End_Word; end if;
    Populate_Btree;
    Dump_Btree;
end;




^ permalink raw reply	[relevance 9%]

* Re: Ada bench : count words
       [not found]                 ` <00b362390273e6c04844dd4ff1885ee0@netcabo.pt>
@ 2005-03-23 15:09 10%               ` Marius Amado Alves
  2005-03-30 16:08  0%                 ` Andre
  0 siblings, 1 reply; 162+ results
From: Marius Amado Alves @ 2005-03-23 15:09 UTC (permalink / raw)
  To: comp.lang.ada

> I'll review this tomorrow on the bus to work (I think your program is 
> separating words at buffer end, and it should not).

Done. Tmoran, sorry, my first sight was wrong, your algorithm is mostly 
fine. Minor reservations:
- special statute given to CR; personally I think all characters 
(control or not) should count to total
- reliance on Stream_Element representing one character; portable 
across all range of environments?

My own program rewritten with Text_Streams attains the same speed as 
yours. The fact that it is structured doesn't hit performance 
significantly. Pragma Inline improves a little bit. Real times (ms) on 
my iBook, for input file repeated 2500 times, all compiled with only 
-O3:
C ........................ 600
Yours, or mine inlined ... 700
Mine not inlined ......... 750

So we should submit yours, or mine inlined. It will put Ada right after 
the Cs w.r.t. speed. W.r.t. executable file size Ada is much bigger. On 
my iBook:
C .......  15k
Mine .... 423k
Yours ... 459k

W.r.t. source code size all are similar. Number of significant 
semicolons (Ada), or semicolons + {} blocks + #includes + #defines (C):
C .............. 27
Yours .......... 33
Mine inlined ... 52

My program follows for reference. It accepts the code for EOL as an 
argument. Default = 10 (LF).

-- The Great Computer Language Shootout
-- http://shootout.alioth.debian.org/
--
-- contributed by Guys De Cla

with Ada.Characters.Handling;
with Ada.Characters.Latin_1;
with Ada.Command_Line;
with Ada.Streams;
with Ada.Streams.Stream_IO;
with Ada.Strings.Fixed;
with Ada.Text_IO;
with Ada.Text_IO.Text_Streams;

procedure Count_Words_Portable is

    use Ada.Characters.Handling;
    use Ada.Characters.Latin_1;
    use Ada.Command_Line;
    use Ada.Streams;
    use Ada.Streams.Stream_IO;
    use Ada.Text_IO;
    use Ada.Text_IO.Text_Streams;

    Buffer : Stream_Element_Array (1 .. 4096);
    Input_Stream : Ada.Text_IO.Text_Streams.Stream_Access
      := Ada.Text_IO.Text_Streams.Stream (Current_Input);
    EOL_Character_Pos : Stream_Element := Character'Pos (LF);
    Lines : Natural := 0;
    Words : Natural := 0;
    Total : Natural := 0;
    In_Word : Boolean := False;
    N : Stream_Element_Offset;
    Is_Separator : array (Stream_Element) of Boolean :=
      (0 .. 32 | 127 .. 159 => True, others => False);

    procedure Begin_Word is
    begin
       Words := Words + 1;
       In_Word := True;
    end;

    procedure End_Word is
    begin
       In_Word := False;
    end;

    procedure End_Line is
    begin
       Lines := Lines + 1;
       End_Word;
    end;

    procedure Count_Words (S : in Stream_Element_Array) is
    begin
       Total := Total + S'Length;
       for I in S'Range loop
          if S (I) = EOL_Character_Pos then
             End_Line;
          else
             if Is_Separator (S (I)) then
                if In_Word then End_Word; end if;
             else
                if not In_Word then Begin_Word; end if;
             end if;
          end if;
       end loop;
    end;

    pragma Inline (Begin_Word, End_Word, End_Line, Count_Words);

begin
    begin
       EOL_Character_Pos := Stream_Element'Value (Argument (1));
    exception
       when Constraint_Error => null;
    end;
    Ada.Text_IO.Put_Line ("EOL =>" & Stream_Element'Image 
(EOL_Character_Pos));

    loop
       Read (Root_Stream_Type'Class (Input_Stream.all), Buffer, N);
       Count_Words (Buffer (1 .. N));
       exit when N < Buffer'Length;
    end loop;

    Ada.Text_IO.Put_Line
      (Natural'Image (Lines) &
       Natural'Image (Words) &
       Natural'Image (Total));
end;




^ permalink raw reply	[relevance 10%]

* Re: Ada bench : count words
  2005-03-22 17:39 11%   ` Marius Amado Alves
@ 2005-03-22 18:59  0%     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 162+ results
From: Dmitry A. Kazakov @ 2005-03-22 18:59 UTC (permalink / raw)


On Tue, 22 Mar 2005 17:39:42 +0000, Marius Amado Alves wrote:

>> Why not use GNAT.OS_Lib.
> 
> I'm trying, but the program does not work properly. It seems to 
> terminate too early, and the results oscillate between 20 and 49 lines. 
> I'll be damned if I understand what's happening.
> 
> -- Count words in Ada for the language shootout
> -- by Marius Amado Alves
> 
> with Ada.Characters.Handling;
> with Ada.Characters.Latin_1;
> with Ada.Strings.Fixed;
> with Ada.Text_IO;
> with GNAT.OS_Lib;
> 
> procedure Count_Words_OS_Lib is
> 
>     use Ada.Characters.Handling;
>     use Ada.Characters.Latin_1;
>     use Ada.Text_IO;
> 
>     Buffer : String (1 .. 4096);
>     EOL : String := (1 => LF);
>     Lines : Natural := 0;
>     Words : Natural := 0;
>     Total : Natural := 0;
>     In_Word : Boolean := False;
>     N : Natural;
> 
>     function Is_Separator (C : Character) return Boolean is
>     begin
>        return Is_Control (C) or C = ' ';
>     end;
> 
>     procedure Begin_Word is
>     begin
>        In_Word := True;
>     end;
> 
>     procedure End_Word is
>     begin
>        if In_Word then
>           Words := Words + 1;
>           In_Word := False;
>        end if;
>     end;
> 
>     procedure End_Line is
>     begin
>        Lines := Lines + 1;
>        Total := Total + 1;
>        End_Word;
>     end;
> 
>     procedure Count_Words (S : in String) is
>     begin
>        Total := Total + S'Length;
>        Lines := Lines + Ada.Strings.Fixed.Count (S, EOL);
>        for I in S'Range loop
>           if Is_Separator (S (I)) then
>              if In_Word then End_Word; end if;
>           else
>              if not In_Word then Begin_Word; end if;
>           end if;
>        end loop;
>     end;
> 
>     pragma Inline (Begin_Word, End_Word, End_Line, Count_Words);
> 
> begin
>     loop
>        N := GNAT.OS_Lib.Read
>          (GNAT.OS_Lib.Standin,
>           Buffer'Address,

Hmm, why not Buffer (Buffer'First)'Address?

>           Buffer'Length);
>        Count_Words (String (Buffer (1 .. N)));
>        exit when N < Buffer'Length;
>     end loop;
> 
>     Ada.Text_IO.Put_Line
>       (Natural'Image (Lines) &
>        Natural'Image (Words) &
>        Natural'Image (Total));
> end;

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



^ permalink raw reply	[relevance 0%]

* Re: Ada bench : count words
  @ 2005-03-22 17:39 11%   ` Marius Amado Alves
  2005-03-22 18:59  0%     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 162+ results
From: Marius Amado Alves @ 2005-03-22 17:39 UTC (permalink / raw)
  To: comp.lang.ada

> Why not use GNAT.OS_Lib.

I'm trying, but the program does not work properly. It seems to 
terminate too early, and the results oscillate between 20 and 49 lines. 
I'll be damned if I understand what's happening.

-- Count words in Ada for the language shootout
-- by Marius Amado Alves

with Ada.Characters.Handling;
with Ada.Characters.Latin_1;
with Ada.Strings.Fixed;
with Ada.Text_IO;
with GNAT.OS_Lib;

procedure Count_Words_OS_Lib is

    use Ada.Characters.Handling;
    use Ada.Characters.Latin_1;
    use Ada.Text_IO;

    Buffer : String (1 .. 4096);
    EOL : String := (1 => LF);
    Lines : Natural := 0;
    Words : Natural := 0;
    Total : Natural := 0;
    In_Word : Boolean := False;
    N : Natural;

    function Is_Separator (C : Character) return Boolean is
    begin
       return Is_Control (C) or C = ' ';
    end;

    procedure Begin_Word is
    begin
       In_Word := True;
    end;

    procedure End_Word is
    begin
       if In_Word then
          Words := Words + 1;
          In_Word := False;
       end if;
    end;

    procedure End_Line is
    begin
       Lines := Lines + 1;
       Total := Total + 1;
       End_Word;
    end;

    procedure Count_Words (S : in String) is
    begin
       Total := Total + S'Length;
       Lines := Lines + Ada.Strings.Fixed.Count (S, EOL);
       for I in S'Range loop
          if Is_Separator (S (I)) then
             if In_Word then End_Word; end if;
          else
             if not In_Word then Begin_Word; end if;
          end if;
       end loop;
    end;

    pragma Inline (Begin_Word, End_Word, End_Line, Count_Words);

begin
    loop
       N := GNAT.OS_Lib.Read
         (GNAT.OS_Lib.Standin,
          Buffer'Address,
          Buffer'Length);
       Count_Words (String (Buffer (1 .. N)));
       exit when N < Buffer'Length;
    end loop;

    Ada.Text_IO.Put_Line
      (Natural'Image (Lines) &
       Natural'Image (Words) &
       Natural'Image (Total));
end;




^ permalink raw reply	[relevance 11%]

* Re: Ada bench : count words
  2005-03-22 12:47 12%                 ` Marius Amado Alves
@ 2005-03-22 13:08  0%                   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 162+ results
From: Dmitry A. Kazakov @ 2005-03-22 13:08 UTC (permalink / raw)


On Tue, 22 Mar 2005 12:47:51 +0000, Marius Amado Alves wrote:

>>>> Is Text_IO that bad?
>>>
>>> No, if you can solve The Get_Line puzzle :-)
>>
>> What about Get (Item : out Character)?
> 
> I tried and was too slow. Anyway I think I cracked the Get_Line puzzle 
> (review welcome). So now it reads from standard input as required. But 
> it's still 3 to 4 times slower than the C version.
> 
> -- Count words in Ada for the language shootout
> -- by Marius Amado Alves
> 
> with Ada.Characters.Handling;
> with Ada.Characters.Latin_1;
> with Ada.Text_IO;
> 
> procedure Count_Words is
> 
>     use Ada.Characters.Handling;
>     use Ada.Characters.Latin_1;
>     use Ada.Text_IO;
> 
>     Buffer : String (1 .. 4096);
>     Lines : Natural := 0;
>     Words : Natural := 0;
>     Total : Natural := 0;
>     In_Word : Boolean := False;
>     N : Natural;
> 
>     function Is_Separator (C : Character) return Boolean is
>     begin
>        return Is_Control (C) or C = ' ';
>     end;
> 
>     procedure Begin_Word is
>     begin
>        In_Word := True;
>     end;
> 
>     procedure End_Word is
>     begin
>        if In_Word then
>           Words := Words + 1;
>           In_Word := False;
>        end if;
>     end;
> 
>     procedure End_Line is
>     begin
>        Lines := Lines + 1;
>        Total := Total + 1;
>        End_Word;
>     end;
> 
>     procedure Count_Words (S : in String) is
>     begin
>        Total := Total + S'Length;
>        for I in S'Range loop
>           if Is_Separator (S (I)) then
>              if In_Word then End_Word; end if;
>           else
>              if not In_Word then Begin_Word; end if;
>           end if;
>        end loop;
>     end;
> 
> begin
>     while not End_Of_File loop

Replace End_Of_File with End_Error handling.

>        Get_Line (Buffer, N);

Get_Line does one extra line scan. So it will be inherently slower. Then it
would not take any advantage of having Buffer if lines are shorter than 4K.
Once Count_Words is inlined the buffer size does not matter.

BTW, you can safely declare Buffer either 1 or 1G bytes, because hidden
buffering happens anyway in Text_IO. (You only save calls to Get_Line.) Who
knows how large are buffers there? This probably disqualifies Text_IO, as
well as C's getc! It should be raw "read".

>        Count_Words (Buffer (1 .. N));

Wouldn't it count buffer ends as word separators for lines longer than 4K?

>        if N < Buffer'Length then
>           End_Line;
>        end if;
>     end loop;
> 
>     Ada.Text_IO.Put_Line
>       (Natural'Image (Lines) &
>        Natural'Image (Words) &
>        Natural'Image (Total));
> end;

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



^ permalink raw reply	[relevance 0%]

* Re: Ada bench : count words
  @ 2005-03-22 12:47 12%                 ` Marius Amado Alves
  2005-03-22 13:08  0%                   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 162+ results
From: Marius Amado Alves @ 2005-03-22 12:47 UTC (permalink / raw)
  To: comp.lang.ada

>>> Is Text_IO that bad?
>>
>> No, if you can solve The Get_Line puzzle :-)
>
> What about Get (Item : out Character)?

I tried and was too slow. Anyway I think I cracked the Get_Line puzzle 
(review welcome). So now it reads from standard input as required. But 
it's still 3 to 4 times slower than the C version.

-- Count words in Ada for the language shootout
-- by Marius Amado Alves

with Ada.Characters.Handling;
with Ada.Characters.Latin_1;
with Ada.Text_IO;

procedure Count_Words is

    use Ada.Characters.Handling;
    use Ada.Characters.Latin_1;
    use Ada.Text_IO;

    Buffer : String (1 .. 4096);
    Lines : Natural := 0;
    Words : Natural := 0;
    Total : Natural := 0;
    In_Word : Boolean := False;
    N : Natural;

    function Is_Separator (C : Character) return Boolean is
    begin
       return Is_Control (C) or C = ' ';
    end;

    procedure Begin_Word is
    begin
       In_Word := True;
    end;

    procedure End_Word is
    begin
       if In_Word then
          Words := Words + 1;
          In_Word := False;
       end if;
    end;

    procedure End_Line is
    begin
       Lines := Lines + 1;
       Total := Total + 1;
       End_Word;
    end;

    procedure Count_Words (S : in String) is
    begin
       Total := Total + S'Length;
       for I in S'Range loop
          if Is_Separator (S (I)) then
             if In_Word then End_Word; end if;
          else
             if not In_Word then Begin_Word; end if;
          end if;
       end loop;
    end;

begin
    while not End_Of_File loop
       Get_Line (Buffer, N);
       Count_Words (Buffer (1 .. N));
       if N < Buffer'Length then
          End_Line;
       end if;
    end loop;

    Ada.Text_IO.Put_Line
      (Natural'Image (Lines) &
       Natural'Image (Words) &
       Natural'Image (Total));
end;




^ permalink raw reply	[relevance 12%]

* Re: Ada bench : count words
  2005-03-22  1:16 11%         ` Ada bench : count words Marius Amado Alves
@ 2005-03-22 10:59  0%           ` Dmitry A. Kazakov
      1 sibling, 1 reply; 162+ results
From: Dmitry A. Kazakov @ 2005-03-22 10:59 UTC (permalink / raw)


On Tue, 22 Mar 2005 01:16:09 +0000, Marius Amado Alves wrote:

> I took a shot at the count-words benchmark, a program to count lines, 
> words and characters. The Ada program currently published there is 
> broken. My program is correct and portable but:
> 
> - the speed is circa 1/3 of the GCC C version
> 
> - it fails to comply with the requirement that the input be taken from 
> standard input. To implement buffering, I have resorted to 
> Ada.Direct_IO, which I think cannot apply to standard input.

Is Text_IO that bad?

> Can you help with any of these points? Thanks. The complete program 
> follows.
> 
> -- Count words in Ada for the language shootout
> -- by Marius Amado Alves
> 
> with Ada.Characters.Handling;
> with Ada.Characters.Latin_1;
> with Ada.Command_Line;
> with Ada.Direct_IO;
> with Ada.Strings.Fixed;
> with Ada.Text_IO;
> 
> procedure Count_Words is
> 
>     use Ada.Characters.Handling;
>     use Ada.Characters.Latin_1;
>     use Ada.Command_Line;
> 
>     Filename : String := Argument (1);
>     Buffer_Size : constant := 4096;
>     EOF : Character := FS;
>     EOL : String := (1 => LF);
>     Lines : Natural := 0;
>     Words : Natural := 0;
>     Total : Natural := 0;
>     In_Word : Boolean := False;
> 
>     function Is_Separator (C : Character) return Boolean is
>     begin
>        return Is_Control (C) or C = ' ';
>     end;

Why don't you use character map here?
 
>     procedure Start_Word is
>     begin
>        In_Word := True;
>     end;
> 
>     procedure Finish_Word is
>     begin
>        Words := Words + 1;
>        In_Word := False;
>     end;
> 
>     procedure Process (S : in String) is
>     begin
>        Lines := Lines + Ada.Strings.Fixed.Count (S, EOL);

Isn't it an extra pass? I think you should do parsing using FSM. Character
classes are: EOL, delimiter, letter. It is either two character map tests
or one case statement. I don't know what is faster. Probably you should
test both.

>        for I in S'Range loop
>           if Is_Separator (S (I)) then
>              if In_Word then Finish_Word; end if;
>           else
>              if not In_Word then Start_Word; end if;
>           end if;
>        end loop;
>     end;
>
> begin
>     declare
>        package Character_IO is new Ada.Direct_IO (Character);
>        use Character_IO;
>        File : File_Type;
>     begin
>        Open (File, In_File, Filename);
>        Total := Natural (Size (File));
>        Close (File);
>     end;
> 
>     declare
>        subtype Buffer_Type is String (1 .. Buffer_Size);
>        package Buffer_IO is new Ada.Direct_IO (Buffer_Type);
>        use Buffer_IO;
>        File : File_Type;
>        S : Buffer_Type;
>     begin
>        Open (File, In_File, Filename);
>        for I in 1 .. Total / Buffer_Size loop
>           Read (File, S);
>           Process (S);
>        end loop;
>        Close (File);
>     end;
> 
>     declare
>        subtype Rest_Type is String (1 .. Total rem Buffer_Size);
>        package Character_IO is new Ada.Direct_IO (Character);
>        use Character_IO;
>        File : File_Type;
>        S : Rest_Type;
>     begin
>        Open (File, In_File, Filename);
>        Set_Index (File, Count (Total - S'Length));
>        for I in 1 .. S'Length loop
>           Read (File, S (I));
>        end loop;
>        Close (File);
>        Process (S);
>     end;
> 
>     if In_Word then Finish_Word; end if;
> 
>     Ada.Text_IO.Put_Line
>       (Natural'Image (Lines) &
>        Natural'Image (Words) &
>        Natural'Image (Total));
> end;

P.S. For word frequencies: gcc version uses hash + sort. I wonder if binary
trees could be better here. Or even sorted arrays for simplicity, there is
no item deletion, search is more often than insert... Of course, for tree
node allocation one could use a stack pool instead of heap.

(That's one of the weaknesses of this contest. Actually the method should
have been specified)

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



^ permalink raw reply	[relevance 0%]

* Ada bench : count words
  @ 2005-03-22  1:16 11%         ` Marius Amado Alves
  2005-03-22 10:59  0%           ` Dmitry A. Kazakov
    0 siblings, 2 replies; 162+ results
From: Marius Amado Alves @ 2005-03-22  1:16 UTC (permalink / raw)
  To: comp.lang.ada

I took a shot at the count-words benchmark, a program to count lines, 
words and characters. The Ada program currently published there is 
broken. My program is correct and portable but:

- the speed is circa 1/3 of the GCC C version

- it fails to comply with the requirement that the input be taken from 
standard input. To implement buffering, I have resorted to 
Ada.Direct_IO, which I think cannot apply to standard input.

Can you help with any of these points? Thanks. The complete program 
follows.

-- Count words in Ada for the language shootout
-- by Marius Amado Alves

with Ada.Characters.Handling;
with Ada.Characters.Latin_1;
with Ada.Command_Line;
with Ada.Direct_IO;
with Ada.Strings.Fixed;
with Ada.Text_IO;

procedure Count_Words is

    use Ada.Characters.Handling;
    use Ada.Characters.Latin_1;
    use Ada.Command_Line;

    Filename : String := Argument (1);
    Buffer_Size : constant := 4096;
    EOF : Character := FS;
    EOL : String := (1 => LF);
    Lines : Natural := 0;
    Words : Natural := 0;
    Total : Natural := 0;
    In_Word : Boolean := False;

    function Is_Separator (C : Character) return Boolean is
    begin
       return Is_Control (C) or C = ' ';
    end;

    procedure Start_Word is
    begin
       In_Word := True;
    end;

    procedure Finish_Word is
    begin
       Words := Words + 1;
       In_Word := False;
    end;

    procedure Process (S : in String) is
    begin
       Lines := Lines + Ada.Strings.Fixed.Count (S, EOL);
       for I in S'Range loop
          if Is_Separator (S (I)) then
             if In_Word then Finish_Word; end if;
          else
             if not In_Word then Start_Word; end if;
          end if;
       end loop;
    end;

begin
    declare
       package Character_IO is new Ada.Direct_IO (Character);
       use Character_IO;
       File : File_Type;
    begin
       Open (File, In_File, Filename);
       Total := Natural (Size (File));
       Close (File);
    end;

    declare
       subtype Buffer_Type is String (1 .. Buffer_Size);
       package Buffer_IO is new Ada.Direct_IO (Buffer_Type);
       use Buffer_IO;
       File : File_Type;
       S : Buffer_Type;
    begin
       Open (File, In_File, Filename);
       for I in 1 .. Total / Buffer_Size loop
          Read (File, S);
          Process (S);
       end loop;
       Close (File);
    end;

    declare
       subtype Rest_Type is String (1 .. Total rem Buffer_Size);
       package Character_IO is new Ada.Direct_IO (Character);
       use Character_IO;
       File : File_Type;
       S : Rest_Type;
    begin
       Open (File, In_File, Filename);
       Set_Index (File, Count (Total - S'Length));
       for I in 1 .. S'Length loop
          Read (File, S (I));
       end loop;
       Close (File);
       Process (S);
    end;

    if In_Word then Finish_Word; end if;

    Ada.Text_IO.Put_Line
      (Natural'Image (Lines) &
       Natural'Image (Words) &
       Natural'Image (Total));
end;




^ permalink raw reply	[relevance 11%]

* Re: Unescape URL Procedure
       [not found]     <000901c4b365$719e8720$0201a8c0@win>
@ 2004-10-16 10:04  9% ` Marius Amado Alves
  0 siblings, 0 replies; 162+ results
From: Marius Amado Alves @ 2004-10-16 10:04 UTC (permalink / raw)
  To: comp.lang.ada

> Does anyone know of an Unescape URL procedure for Ada?

My program Decode_HH does something along this line:

-- It transforms any two hexadecimal digits prefixed by '='
-- into the corresponding character (Latin 1).
-- The first hexadecimal digit must be an uppercase letter.
-- It is a filter (uses standard input and output channels).

The program is published in the SDC forum, area Files / Software:

    http://www.softdevelcoop.org

You must be a member to enter the Files area. Membership is open to all, 
but for your convenience I copy the whole program below.

<<
-- Program Decode_HH
-- Version 1maa (2003-04-01)
-- (C) M�rio Amado Alves

-- ATTENTION: the use of this software is subject to conditions,
-- which the user must know in order to be in a legal state.
-- See bottom of the file.

-- This program restores email-mangled text originally containing Latin 1.
-- It transforms any two hexadecimal digits prefixed by '='
-- into the corresponding character (Latin 1).
-- The first hexadecimal digit must be an uppercase letter.
-- It is a filter (uses standard input and output channels).

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Characters.Handling; use Ada.Characters.Handling;

procedure Decode_HH_1maa is

   T : String (1 .. 3);
   subtype HH_Type is Natural range 0 .. 16#FF#;
   package HH_IO is new Ada.Text_IO.Integer_IO (HH_Type);
   N : HH_Type;
   Dummy_Last: Positive;
   Finish : exception;

   procedure Get (S : out String) is
   begin
     for I in S'Range loop
       begin
         Get_Immediate (S (I));
       exception
         when End_Error =>
           Put (S (S'First .. I - 1));
           raise;
       end;
     end loop;
   end;

begin

   Get (T (1 .. 3));
   loop
     if T (1) = '='
     and then T (2) in 'A' .. 'F'
     and then Is_Hexadecimal_Digit (T (3))
     then
       HH_IO.Get ("16#" & T (2 .. 3) & "#", N, Dummy_Last);
       Put (Character'Val (N));
       Get (T (1 .. 3));
     else
       Put (T (1));
       T (1 .. 2) := T (2 .. 3);
       begin
         Get_Immediate (T (3));
       exception
         when End_Error =>
           Put (T (1 .. 2));
           raise;
       end;
     end if;
   end loop;

exception

   when End_Error => null;

end;

-- REVISION HISTORY
-- 2003-04-01: version 1maa created and tested

-- CONDITIONS OF USE
-- This software is licensed under the terms of the
-- Software Developers Cooperative License, published at
--
--   groups.yahoo.com/group/softdevelcoop
--
-- In short, it is free for non-commercial use,
-- but royalties are due for use in a business.
-- See the website for details and contact information.
 >>




^ permalink raw reply	[relevance 9%]

* Re: character matching
  @ 2004-08-15 17:21  9%   ` Steve
  0 siblings, 0 replies; 162+ results
From: Steve @ 2004-08-15 17:21 UTC (permalink / raw)


First have a look at the standard library Ada.Characters.Handling
   You'll find goodies such as:

    function Is_Alphanumeric      (Item : in Character) return Boolean;

Then have alook at Ada.Strings.Maps.  There you'll find:

  function Is_In (Element : in Character;
                         Set     : in Character_Set)
  return Boolean;

I always recommend perusing the standard Ada library headers described in
Annex A of the Ada 95 reference manual.  You'll find lots of tools that do
the grunt work for you.

Steve
(The Duck)


"John J" <g_001@hotmail.com> wrote in message
news:uNITc.3402$BA5.883@hydra.nntpserver.com...
> Thanks for the suggestions; however, I'm trying to learn a bit about the
> syntax and capabilities of ADA. Would someone be kind enough to give me
some
> examples of how I can use ADA to character match. ie, different ways I can
> use '*', '&' to successfully recognise words and sentences.
>
> Thanks
>
>





^ permalink raw reply	[relevance 9%]

* Re: Improving Ada's image - Was: 7E7 Flight Controls Electronics
  2004-06-26  5:11 10%                                               ` Robert I. Eachus
@ 2004-06-27  1:00  0%                                                 ` Jeffrey Carter
  0 siblings, 0 replies; 162+ results
From: Jeffrey Carter @ 2004-06-27  1:00 UTC (permalink / raw)


Robert I. Eachus wrote:

> with Ada.Characters.Handling;
>   function Mixed (S: in String) return String is
>     use Ada.Characters.Handling;
>     Capitalize: Boolean := True;
>     Result: String := S;
>   begin
>     for I in Result'Range loop
>       if Capitalize
>       then Result(I) := To_Upper(Result(I));
>       else Result(I) := To_Lower(Result(I));
>       end if;
>       Capitalize := Result(I) = '_';
>     end loop;
>     return Result;
>   end Mixed;

Or use PragmARC.Mixed_Case.

-- 
Jeff Carter
"If you think you got a nasty taunting this time,
you ain't heard nothing yet!"
Monty Python and the Holy Grail
23




^ permalink raw reply	[relevance 0%]

* Re: Improving Ada's image - Was: 7E7 Flight Controls Electronics
  @ 2004-06-26  5:11 10%                                               ` Robert I. Eachus
  2004-06-27  1:00  0%                                                 ` Jeffrey Carter
  0 siblings, 1 reply; 162+ results
From: Robert I. Eachus @ 2004-06-26  5:11 UTC (permalink / raw)


Robert I. Eachus wrote:

> I do think it is a shame though that Ada returns the upper case version 
> of the name, not the spelling used to declare the type...

This comment of mine seems to have touched a nerve.  So let's see if we 
can save the good parts of the discussion and turn them into something 
useful.

As I see it there are three approaches to solving the problem:  Explicit 
user code, compiler implemented langage extensions, and changes to the 
language.  I think we should agree that it is too late to chage the 
language this time around--although if there is an approach that is 
universally accepted, it could happen.  But first let's look at the 
candidates and see which fly and which get shot down.

I'll discuss user code first, then tomorrow sum up the other alternatives.

This is almost a "why didn't I think of that?" category. It is certainly 
no big deal to write:

function Image(S: Suit) return String is
begin return Suit'Image(S); end Image;

Then later when it is time to make the output look pretty change the 
body to:

function Image(S: Suit) return String is
begin
   case S is
       when Spades => return "Spades";
       when Hearts => return "Hearts";
       when Clubs => return "Clubs";
       when Diamonds => return "Diamonds";
   end case;
end Image;

or you can write:

with Ada.Characters.Handling;
   function Mixed (S: in String) return String is
     use Ada.Characters.Handling;
     Capitalize: Boolean := True;
     Result: String := S;
   begin
     for I in Result'Range loop
       if Capitalize
       then Result(I) := To_Upper(Result(I));
       else Result(I) := To_Lower(Result(I));
       end if;
       Capitalize := Result(I) = '_';
     end loop;
     return Result;
   end Mixed;

and:

type Direction is (North, NNE, NE, ENE, East, ESE, SE, SSE,
                    South, SSW, SW, WSW, West, WNW, NW, NNW);

function Image(D: Direction) return String is
    Result: String := D'Image;
begin
   if Result'Length < 4
   then return Result;
   else return Mixed(Result);
   end if;
end Image;

or:

type Color is (Red, Orange, Yellow, Blue, Green, Violet,
                White, Gray, Black, Brown, Pink);

function Image (C: Color) return String is
begin return Mixed(C); end Image;

It might be nice to add Mixed above to Ada.Characters.Handling as 
To_Mixed, but that is getting into other options. ;-)

-- 

                                           Robert I. Eachus

"Reason and experience both forbid us to expect that national morality 
can prevail in exclusion of religious principles." -- George Washington




^ permalink raw reply	[relevance 10%]

* Re: Type detection
  2004-04-30 13:54  8% ` Type detection Björn Persson
@ 2004-05-01  0:28 10%   ` Robert I. Eachus
  0 siblings, 0 replies; 162+ results
From: Robert I. Eachus @ 2004-05-01  0:28 UTC (permalink / raw)


Bj�rn Persson wrote:

> For the special case of distinguishing integer types from enumeration 
> types, I've been thinking of using something like this...

I extended the idea a little further, but there is still some work to 
do.  A character type is an enumeration type where at least one of the 
enumeration values is a character literal.  So the test for enumeration 
types could be extended with a loop.

Since a boolean type is either Boolean or a type derived from it, I 
guess checking that 'Size = 1 and that the literals are TRUE and FALSE 
should be close enough.

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

with Ada.Text_IO;
with Ada.Characters.Handling;
procedure Datatype is

   generic
     type Unknown is (<>);
   function Find_Datatype return String;

   function Find_Datatype return String is
   begin
     if Ada.Characters.Handling.Is_Letter
             (Unknown'Image(Unknown'First)(1))
     then return "Enumeration";
     elsif Unknown'Pos( Unknown'Base'First) < 0 then return "Integer";
     elsif Unknown'Pos(Unknown'Base'First) = 0 then
       begin
         if Unknown'Succ(Unknown'Last) = Unknown'First
         then return "Unsigned";
         else return "Enumeration?";
         end if;
       exception
         when others => return "Enumeration too";
         -- It's an enumeration.
       end;
     else return "Unknown Type";
     end if;
   end Find_Datatype;

   type Unsigned_16 is mod 2**16;
   type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday);

   function Find_Boolean is new Find_Datatype(Boolean);
   function Find_Integer is new Find_Datatype(Integer);
   function Find_Character is new Find_Datatype(Character);
   function Find_Unsigned is new Find_Datatype(Unsigned_16);
   function Find_Enumeration is new Find_Datatype(Weekday);

begin

   Ada.Text_IO.Put_Line(" Find_Boolean returned " & Find_Boolean);
   Ada.Text_IO.Put_Line(" Find_Integer returned " & Find_Integer);
   Ada.Text_IO.Put_Line(" Find_Character returned " & Find_Character);
   Ada.Text_IO.Put_Line(" Find_Unsigned returned " & Find_Unsigned);
   Ada.Text_IO.Put_Line(" Find_Enumeration returned " & Find_Enumeration);

end Datatype;


-- 

                                           Robert I. Eachus

"The terrorist enemy holds no territory, defends no population, is 
unconstrained by rules of warfare, and respects no law of morality. Such 
an enemy cannot be deterred, contained, appeased or negotiated with. It 
can only be destroyed--and that, ladies and gentlemen, is the business 
at hand."  -- Dick Cheney




^ permalink raw reply	[relevance 10%]

* Type detection
  @ 2004-04-30 13:54  8% ` Björn Persson
  2004-05-01  0:28 10%   ` Robert I. Eachus
  0 siblings, 1 reply; 162+ results
From: Björn Persson @ 2004-04-30 13:54 UTC (permalink / raw)


Axel Druesnes wrote:

>  i am currently writing a generic package. Despite being really generic 
> one (at least) particular type need a special handling in two functions. 
> I am therefore wondering how i can either detect the type... 

[...]

> function Type_Id ( Value : in Boolean ) return E_Type_Id;
> function Type_Id ( Value : in Integer ) return E_Type_Id;
> 
> -- Inside the body
> procedure I_Need_The_Type ( Value : Generic_Type )
> ....
> Type_Identifier := Type_Id ( Value ); -- i wish it worked here

For the special case of distinguishing integer types from enumeration 
types, I've been thinking of using something like this:

    if Ada.Characters.Handling.Is_Letter
         (Generic_Type'Image(Generic_Type'First)(1)) then
       -- It's an enumeration.
    else
       -- It's an integer type.
    end if;

Further tests could be done to see if an enumeration is Boolean or 
something else.

For more general cases, since the type is known when you instantiate the 
generic package, maybe you can pass an extra parameter (of type 
E_Type_Id)? Or you could keep the common parts in one highly generic 
package and then have a number of more specific generic packages for 
different types. The more specific packages would then instantiate the 
highly generic package and call the common subprograms in it.

-- 
Björn Persson

jor ers @sv ge.
b n_p son eri nu




^ permalink raw reply	[relevance 8%]

* Update - PLEASE SOMEBODY HELP!!!!
  @ 2003-02-27 17:12  6%     ` Paul Gregory
  0 siblings, 0 replies; 162+ results
From: Paul Gregory @ 2003-02-27 17:12 UTC (permalink / raw)


Well...the deadline is now 24 hours away....

I have the excellent program which Dennis Lee Bieber helped me with (thanks a lot Dennis you
are a great guy!) detailed below which works excellent on the GNAT compiler.

The problem is that the project is submitted online and run through a computer system and it
has to translate EXACTLY to the letter to gain a pass (and it is pass or fail...you could
have a program 100x better that does exactly the same but if it missed a full stop then it
won't accept it etc)

Now I need the program to compile like this for each of the four tests...

eg).

----------Sorry expected answer was-------------------------------
Do you wish to add words to the dictionary?: N

Please enter a sentence:
big.

The French translation of your sentence is:
grand.

----------Your answer however was---------------------------------
.
eg 2

----------Sorry expected answer was-------------------------------
Do you wish to add words to the dictionary?: N

Please enter a sentence:
Big cat is black.

The French translation of your sentence is:
Grand chat est noir.

eg3
----------Sorry expected answer was-------------------------------
Do you wish to add words to the dictionary?: Y
English word: red
Equivalent French word: rouge

Do you wish to add more words?: N

Please enter a sentence:
The dog is red.

The French translation of your sentence is:
Le chien est rouge.

eg4
----------Sorry expected answer was-------------------------------
Do you wish to add words to the dictionary?: Y
English word: blue
Equivalent French word: bleu

Do you wish to add more words?: Y

English word: sky
Equivalent French word: ciel

Do you wish to add more words?: N

Please enter a sentence:
Le ciel est bleu.

The English translation of your sentence is:
The sky is blue.
--------------------

However due to the way my program is structured it asks for a "source language" and a "target
language", yet I can't have this for the system.

Eg it compiles on GNAT like so...
-------------------------------------------------------------------------
Do you wish to add words to the dictionary? : n

Enter the Source Language:  English
Enter the Target Language: French
Please enter a sentence:
The big cat

The FRENCH translation of your sentence is:
Le grand chat


Enter the Source Language:
--------------------------------------------------------------------------

So the problems are - French in capitals - uses 'image is there a way round this ?
Don't want it to ask me for a source and target language.
Need a full stop after every sentence.

I'd be the happiest person in the world if somebody could help me resolve these problems and
I'd repay you in whatever favours, cash whatever you require as I've hit the wall and the
deadline is approaching and I'm going to almost certainly fail. :-(

Thanks for your time,

I know I'm very cheeky and as thick as a plank of wood...

but I can't stress how stressed out, physically ill and depressed this damn project is making
me feel.

Even if you can only work out how to do the first test Ie... just a straight one word array
comparison - your help would be greatfully appreciated.

Thanks a million,

Paul (code below, for anyone who is bored/kind enough to help)....

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings; use Ada.Strings;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Characters.Handling; use Ada.Characters.Handling;
procedure main is

        MaxWord : constant := 40;
        MaxLine : constant := 120;
        MaxTranslations : constant := 100;

        type Languages is (English, French);    -- define known languages
        --      For each language named here, the Translations array will
        --      need another Head("word_in_new", MaxWord) added to each
        --      predefined set.

        subtype aWord is String(1..MaxWord);    -- assume words are smaller
        subtype aLine is String(1..MaxLine);

        LineIn : aLine;                 -- lots of poorly named scratch variables
        WordIn : aWord;
        WordOut : aWord;

        Source : Languages;
        Target : Languages;

        SOL : boolean;  -- Start of Line flag

        LineLen : integer range 0..MaxLine;
        Blnk : integer range 0..MaxLine;

        type TranslationSet is array(Languages) of aWord;

        --      use Head(string, size) with default pad to fill short
        --      strings to word length fixed strings
        Translations : array (1..MaxTranslations) of TranslationSet :=
                (       (Head("big", MaxWord), Head("grand", MaxWord)),
                        (Head("black", MaxWord), Head("noir", MaxWord)),
                        (Head("cat", MaxWord), Head("chat", MaxWord)),
                        (Head("dog", MaxWord), Head("chien", MaxWord)),
                        (Head("is", MaxWord), Head("est", MaxWord)),
                        (Head("small", MaxWord), Head("petit", MaxWord)),
                        (Head("the", MaxWord), Head("le", MaxWord)),
                        (Head("white", MaxWord), Head("blanc", MaxWord)),
                        (Head("Brighton", MaxWord),
                                Head("Brighton", MaxWord)),
                        others => (Head(" ", MaxWord), Head(" ", MaxWord))      );

        LastTranslation : integer range 1..MaxTranslations := 9;


begin

        -- allow user to add words to translation dictionary as long as space
        -- is available (note: dictionary is not saved between program runs!!)
        while LastTranslation < MaxTranslations loop
                Put("Do you wish to add words to the dictionary? : ");
                Get_Line(Item => LineIn, Last => LineLen);
                exit When To_Upper(LineIn(1)) /= 'Y';

                LastTranslation := LastTranslation + 1;
                for l in Languages loop
                        Put("Enter the new word in ");
                        Put(Languages'Image(l));
                        Put(": ");
                        Get_Line(Item => WordIn, Last => LineLen);
                        Translations(LastTranslation)(l) :=
                                Head(To_Lower(WordIn(1..LineLen)), MaxWord);
                end loop;
                New_Line;
        end loop;

        -- loop until user enters a blank line for Source language

        loop
                New_Line;

                Put("Enter the Source Language:  ");
                Get_Line(Item => WordIn, Last => LineLen);

                exit when LineLen = 0;

                Source := Languages'Value(WordIn(1..LineLen));

                Put("Enter the Target Language: ");
                Get_Line(Item => WordIn, Last => LineLen);
                Target := Languages'Value(WordIn(1..LineLen));

                Put_Line("Please enter a sentence: ");
                Get_Line(Item => LineIn, Last => LineLen);

                LineIn := Head(To_Lower(LineIn(1..LineLen)), MaxLine);

                New_Line;
                Put("The ");
                Put(Languages'Image(Target));
                Put_Line(" translation is: ");

                --      loop until the input line has been consumed.

                SOL := True;
                while LineIn(1) /= ' ' loop
                        Blnk := Index(LineIn, " ");
                        if Blnk > 1 and Blnk <= MaxWord then
                                WordIn := Head(LineIn(1..Blnk-1), MaxWord);
                                LineIn := Head(LineIn(Blnk+1..MaxLine), MaxLine);
                        else
                                WordIn := Head(LineIn(1..MaxWord), MaxWord);
                                LineIn := Head(" ", MaxLine);
                        end if;

                        WordOut := Head("<" & Trim(WordIn, BOTH) & ">", MaxWord);
                                                -- if no translation, output input value
                        for i in 1..LastTranslation loop
                                if WordIn = Translations(i)(Source) then
                                        WordOut := Translations(i)(Target);
                                        exit;
                                end if;
                        end loop;

                        if SOL then
                                WordOut(1) := To_Upper(WordOut(1));
                                SOL := False;
                        end if;

                        Put(Item => Trim(WordOut, BOTH));
                        Put(" ");

                end loop;
                New_Line;
                New_Line;
        end loop;
end main;




^ permalink raw reply	[relevance 6%]

* Re: Help!
  2003-02-24 13:08 12% ` Help! Preben Randhol
@ 2003-02-24 13:10  0%   ` Preben Randhol
  0 siblings, 0 replies; 162+ results
From: Preben Randhol @ 2003-02-24 13:10 UTC (permalink / raw)


Preben Randhol wrote:
> with Ada.Characters.Handling;
> use Ada.Characters.Handling;
> 
> To_Lower (Your_String (Your_String'First + 1 .. Your_String'Last);

Oops

 To_Lower (Your_String (Your_String'First + 1 .. Your_String'Last));

-- 
Preben Randhol ---------------- http://www.pvv.org/~randhol/ --
"Violence is the last refuge of the incompetent", Isaac Asimov



^ permalink raw reply	[relevance 0%]

* Re: Help!
  @ 2003-02-24 13:08 12% ` Preben Randhol
  2003-02-24 13:10  0%   ` Help! Preben Randhol
  0 siblings, 1 reply; 162+ results
From: Preben Randhol @ 2003-02-24 13:08 UTC (permalink / raw)


Paul Gregory wrote:
> I'm having a few problems with my school ADA project.
> 
> I have to write a program which translates 10 English words to French
> but when it Translates a sentence it does it in upper case instead of a
> capital letter for the first letter and lower case for the rest.
> 
> Any ideas how I could get round this ?

Is this the assignment or is it only a part of it?

with Ada.Characters.Handling;
use Ada.Characters.Handling;

To_Lower (Your_String (Your_String'First + 1 .. Your_String'Last);

-- 
Preben Randhol ---------------- http://www.pvv.org/~randhol/ --
"Violence is the last refuge of the incompetent", Isaac Asimov



^ permalink raw reply	[relevance 12%]

* RE: Character Sets
  2002-12-14 22:53  8%   ` Vadim Godunko
@ 2002-12-15 23:26  7%     ` Robert C. Leif
  0 siblings, 0 replies; 162+ results
From: Robert C. Leif @ 2002-12-15 23:26 UTC (permalink / raw)


I believe that we need to change to Latin_9. The European Economic
Community needs to have a Euro character. In the long-run, an XML_Io or
Unicode_Io package will have to be created. However it should be an
Applications Program Interface, rather than being part of the core
language or an annex.
Bob Leif

-----Original Message-----
From: comp.lang.ada-admin@ada.eu.org
[mailto:comp.lang.ada-admin@ada.eu.org] On Behalf Of Vadim Godunko
Sent: Saturday, December 14, 2002 2:54 PM
To: comp.lang.ada@ada.eu.org
Subject: Re: Character Sets

starner@okstate.edu (David Starner) wrote in message
news:<81f70ac6.0212131927.4fa6b642@posting.google.com>...
> 
> > This seems reasonable if we don't want to have to amend Ada each
time a
> > bunch of characters are added to 10646.
> 
> Why would you have to amend Ada? Add a Unicode version constant, and
> define the data in terms of its Unicode properties. Then the
> recentness of the characters is just a quality of implementation
> issue.
> 
How many memory required for save all data from Unicode Character
Database? What you do if this constant changed? Retest all existing
applications?

> From: Robert Dewar
> > We certainly
> > put in a lot of work in GNAT in implementing wide character with
many
> > different representation schemes,
> 
> GNAT supports input files in a dozen mostly bizzare or archaic
> formats. It doesn't strike me as very useful, especially considering
> as it supports Latin-1, Latin-2 (both useful), but also Latin-4
> (completely unused) and Latin-3 (good for Maltese and Esperanto, and
> most Esperanto users don't use it). It doesn't support ISO-8859-5 or
> KOI8-R (Russian), or ISO-8859-7 (Greek).
Latest public GNAT version and GCC3/GNAT both support ISO-8859-5
encoding in identifiers. And don't known any GNAT users who use
KOI8-R/U/B encodings outside comment, character and string literals.

> It doesn't support changing
> formats on the fly - many users have multiple encodings around,
> besides the fact that having to compile a different binary for each
> user is a pain. 
> 
You may propose any method for detect encoding of Ada source file "on
the fly"?

> From: Pascal Leroy
> > Remember, we are talking Ada applications here.  There are probably
many
> > applications out there that deal with mathematical symbols or with
Tengwar, 
> > but I doubt that they are written in Ada.
> 
> Mathematical symbols and Tengwar are text. Any text handling system
> that supports Unicode should handle them like any other text, because
> sooner or later users will expect it to handle them. (If you're
> unlucky, it will be the day that you're showing your system off in
> Hong Kong, and the potential buyer decides to put in his name that
> isn't in the BMP.) If people don't want Ada to be a general-purpose
> programming language, then that's fine; but it's not acceptable for a
> general-purpose programming language not to be able to handle text,
> and for a modern language, that means Unicode.

The main problem with encodings in Ada is a history. 

Many programs assume what Character is Latin-1. If we change semantic
of Ada.Characters.Handling, that results we get?

Ada83 define type Character as enumeration. The order of symbols
defined by its order in this enumeration not by real code. This allow
simple programs portation from, for example, ASCII to EBCDIC
encodings. Ada95 simple extend 7-bit ASCII to 8-bit ISO-8859-1.

The difference between logical code order in encoding and collation
order of current user language environment is another problem. Both
Ada9X and AI-00285 not solve this.

The best way for implement localization/internationalization support
in Ada is define special needs annex, but not change existing
interfaces because (1) this not affect to portability and (2) allow
new applications (if internationalization is critic) use new
interfaces.


Vadim Godunko




^ permalink raw reply	[relevance 7%]

* Re: Character Sets
  @ 2002-12-14 22:53  8%   ` Vadim Godunko
  2002-12-15 23:26  7%     ` Robert C. Leif
  0 siblings, 1 reply; 162+ results
From: Vadim Godunko @ 2002-12-14 22:53 UTC (permalink / raw)


starner@okstate.edu (David Starner) wrote in message news:<81f70ac6.0212131927.4fa6b642@posting.google.com>...
> 
> > This seems reasonable if we don't want to have to amend Ada each time a
> > bunch of characters are added to 10646.
> 
> Why would you have to amend Ada? Add a Unicode version constant, and
> define the data in terms of its Unicode properties. Then the
> recentness of the characters is just a quality of implementation
> issue.
> 
How many memory required for save all data from Unicode Character
Database? What you do if this constant changed? Retest all existing
applications?

> From: Robert Dewar
> > We certainly
> > put in a lot of work in GNAT in implementing wide character with many
> > different representation schemes,
> 
> GNAT supports input files in a dozen mostly bizzare or archaic
> formats. It doesn't strike me as very useful, especially considering
> as it supports Latin-1, Latin-2 (both useful), but also Latin-4
> (completely unused) and Latin-3 (good for Maltese and Esperanto, and
> most Esperanto users don't use it). It doesn't support ISO-8859-5 or
> KOI8-R (Russian), or ISO-8859-7 (Greek).
Latest public GNAT version and GCC3/GNAT both support ISO-8859-5
encoding in identifiers. And don't known any GNAT users who use
KOI8-R/U/B encodings outside comment, character and string literals.

> It doesn't support changing
> formats on the fly - many users have multiple encodings around,
> besides the fact that having to compile a different binary for each
> user is a pain. 
> 
You may propose any method for detect encoding of Ada source file "on
the fly"?

> From: Pascal Leroy
> > Remember, we are talking Ada applications here.  There are probably many
> > applications out there that deal with mathematical symbols or with Tengwar, 
> > but I doubt that they are written in Ada.
> 
> Mathematical symbols and Tengwar are text. Any text handling system
> that supports Unicode should handle them like any other text, because
> sooner or later users will expect it to handle them. (If you're
> unlucky, it will be the day that you're showing your system off in
> Hong Kong, and the potential buyer decides to put in his name that
> isn't in the BMP.) If people don't want Ada to be a general-purpose
> programming language, then that's fine; but it's not acceptable for a
> general-purpose programming language not to be able to handle text,
> and for a modern language, that means Unicode.

The main problem with encodings in Ada is a history. 

Many programs assume what Character is Latin-1. If we change semantic
of Ada.Characters.Handling, that results we get?

Ada83 define type Character as enumeration. The order of symbols
defined by its order in this enumeration not by real code. This allow
simple programs portation from, for example, ASCII to EBCDIC
encodings. Ada95 simple extend 7-bit ASCII to 8-bit ISO-8859-1.

The difference between logical code order in encoding and collation
order of current user language environment is another problem. Both
Ada9X and AI-00285 not solve this.

The best way for implement localization/internationalization support
in Ada is define special needs annex, but not change existing
interfaces because (1) this not affect to portability and (2) allow
new applications (if internationalization is critic) use new
interfaces.


Vadim Godunko



^ permalink raw reply	[relevance 8%]

* Re: Character Sets
  @ 2002-12-03 15:32 11%   ` Juanma Barranquero
  0 siblings, 0 replies; 162+ results
From: Juanma Barranquero @ 2002-12-03 15:32 UTC (permalink / raw)


On Tue, 3 Dec 2002 13:33:24 GMT, Robert A Duff
<bobduff@shell01.TheWorld.com> wrote:

>There is also an AI in the works, having something to do with 32-bit
>characters.  I don't remember the AI number.

AI-00285, perhaps:

!subject Latin-9, Ada.Characters.Handling, and 32-bit characters


                                                      /L/e/k/t/u




^ permalink raw reply	[relevance 11%]

* Re: how to check if a string variable contains a number or string?
  @ 2002-11-19  0:44  8% ` sk
  0 siblings, 0 replies; 162+ results
From: sk @ 2002-11-19  0:44 UTC (permalink / raw)


Hi, 

1) Stephen Leake <stephen.a.leake.1@gsfc.nasa.gov>
> Try reading the number from the string using Ada.Text_IO.*.


2) "David C. Hoos" <david.c.hoos.sr@ada95.com>
> If that's OK, then if calling Long_Float'Value doesn't 
> raise Constraint_Error, then the string is a valid 
> decimal representation of a number.

OR, 

3) Tokenize the string separating on spaces and use
the Ada.Characters.Handling package ...

   function Is_Control           (Item : in Character) return Boolean;
   function Is_Graphic           (Item : in Character) return Boolean;
   function Is_Letter            (Item : in Character) return Boolean;
   function Is_Lower             (Item : in Character) return Boolean;
   function Is_Upper             (Item : in Character) return Boolean;
   function Is_Basic             (Item : in Character) return Boolean;
   function Is_Digit             (Item : in Character) return Boolean;
   function Is_Decimal_Digit     (Item : in Character) return Boolean
                                                          renames
Is_Digit;
   function Is_Hexadecimal_Digit (Item : in Character) return Boolean;
   function Is_Alphanumeric      (Item : in Character) return Boolean;
   function Is_Special           (Item : in Character) return Boolean;

... yes, time consuming, boring and not "sexy" but better,
IMO, than using exception routines for predictable error
circumstances.

-- 
-------------------------------------
-- Merge vertically for real address
-------------------------------------
s n p @ t . o
 k i e k c c m
-------------------------------------



^ permalink raw reply	[relevance 8%]

* Re: Newbie question on Ada TExt_IO
  2002-10-04 17:34 10% ` Justin Birtwell
  2002-10-04 20:07  7%   ` Jeffrey Carter
@ 2002-10-05  2:43  0%   ` SteveD
  1 sibling, 0 replies; 162+ results
From: SteveD @ 2002-10-05  2:43 UTC (permalink / raw)


"Justin Birtwell" <jbirtwell@yahoo.com> wrote in message
news:Sikn9.1513$Mw4.1034@nwrddc01.gnilink.net...

> Is_Digit a hack of a procedure that compares the 1 character string to all
> 10 digits characters.  I really have a lot to learn.   What's giving me
the
> hardest time is working within the confines of strict/strong typing.  The
> Ada.Characters.Handling  package already has an Is_Digit function, but
it's
> expecting a character not a single item String array!  How can I convert
> from one into the other?  I have the distinct feelling like I'm
reinventing
> the wheel.  Aren't packages aready made to do alot of this
> converting/validation?  If so where are they?  How can one access them?
> Does the RM list all the packages provided by Ada or are there more to be
> discovered?
>

First, if you happen to be using GNAT on windows, go to the help file "Ada
95 Reference Manual".  Select "Annexes", then "Annex A: Predefined Language
Environment", then "A. Predefined Language Environment".

Or you can go to http://www.adaic.org/standards/95lrm/html/RM-A.html which
has the same information.

This page shows the standard libraries include in Ada 95.  I recommend
perusing these to see what is available.

Second... about your program.  It runs if you change the Input_Data( 1..1)
to Input_Data(1) and add a couple of "with" and "use" clauses to make the
built in library function available... but...  If you enter "42" the program
is happy and recognizes the value entered as "4".  Hmmm... I suspect not
what the user would expect.

Try this one (and please reassure me that this is not a homework assignment
I just completed for you)

with Ada.Text_Io;
 use Ada.Text_Io;
with Ada.Strings;
 use Ada.Strings;
with Ada.Strings.Fixed;
 use Ada.Strings.Fixed;

procedure Test_IO_3 is
  Input: String(1..256);
  Last:Integer;
  result : Integer;
begin
  ReadLoop:
    loop
      Put("Please enter a number between 1 and 6 > ");
      Get_Line(Item=>Input,Last=>Last);
      declare
        Input_Data : String := Trim( Input( 1 .. Last ), Both );
      begin
        if Input_Data'Length = 1 and then
           Input_Data(1) in '1' .. '6' then
           result := Integer'Value( Input_Data( 1 .. 1 ) );
           Exit ReadLoop;
        end if;
        Put_Line("Invalid entry, try again.");
      end;
    end loop ReadLoop;
    Put_Line("Thank you");
exception
  when others=>
    Put_Line("Error, Invalid data.");
end Test_IO_3;



> thanks to one and all,
> Justin
>
>
>
>





^ permalink raw reply	[relevance 0%]

* Re: Newbie question on Ada TExt_IO
  2002-10-04 17:34 10% ` Justin Birtwell
@ 2002-10-04 20:07  7%   ` Jeffrey Carter
  2002-10-05  2:43  0%   ` SteveD
  1 sibling, 0 replies; 162+ results
From: Jeffrey Carter @ 2002-10-04 20:07 UTC (permalink / raw)


Justin Birtwell wrote:
> Accept entire line using Get_Line into string(1..256);
> Check if first character is a digit
> Check if digit is between 1 and 6
> error handling
> 
> Here's the code:
> 
> with Text_Io;use Text_Io;
> with StringFunctions;use StringFunctions;
> 
> procedure Test_IO_2 is
>    Input: String(1..256);
>    N:Integer;
>    Success:Boolean:=false;
>    Last:Integer;
> begin
>       while success /=true loop

Constructs like this frequently indicate a lack of understanding of what 
a Boolean value is. This could be

while not Success loop

That's kind of hard to understand when you go around the loop and when 
you stop. It's easier to understand if written

loop
    exit when Success;

However, Success is an unnecessary flag. It would be better to eliminate 
it, as shown below.

>       Put("PLease enter a number between 1 and 6");
>       Get_Line(Item=>Input,Last=>Last);
>          if Is_Digit(Input(1..1)) then

You could write

if Ada.Characters.Handling.Is_Digit (Input (Input'First) ) then

rather than writing your own function.

>             N:=Integer'Value(Input(1..1));
>             if N>=1 and N<=6 then

if N in 1 .. 6 then

>                Success:=True;
>             end if;
>          else
>             success:=false;
>             Put_Line("Invalid entry, try again.");
>          end if;
>        end loop;
>       Put_Line("Thank you");
>      exception
>       when others=>
>          Put_Line("Error, Invalid data.");
> end;

If the user enters "60" you're going to interpret it as 6, and if " 1" 
will be an error. Is that really what you want? Doing

subtype Valid_Number is Integer range 1 .. 6;
N : Valid_Number;
...
N := Integer'Value (Input (Input'First .. Last) );

will reject "60" (not in range) and interpret " 1" as 1.

You can write what you have as:

subtype Valid_Number is Integer range 1 .. 6;

N : Valid_Number;
...
Get_Number : loop
    -- Get_Line

    Check : begin
       N := Integer'Value (Input (Input'First .. Last) );

       exit Get_Number;
    exception -- Check
    when others =>
       -- Error message
    end Check;
end loop Get_Number;

which seems a lot shorter and clearer (though admittedly some of the 
simplification comes from changing how the input is interpreted). It may 
take you a little while to become comfortable with Ada to the point that 
you come up with things like the above rather than the more complicated 
version you have, so don't get discouraged.

> 
> Is_Digit a hack of a procedure that compares the 1 character string to all
> 10 digits characters.  I really have a lot to learn.   What's giving me the
> hardest time is working within the confines of strict/strong typing.  The
> Ada.Characters.Handling  package already has an Is_Digit function, but it's
> expecting a character not a single item String array!  How can I convert
> from one into the other?  I have the distinct feelling like I'm reinventing
> the wheel.  Aren't packages aready made to do alot of this
> converting/validation?  If so where are they?  How can one access them?

Type String is an array of type Character, so Input (N) is of type 
Character. See my suggestion above.

> Does the RM list all the packages provided by Ada or are there more to be
> discovered?

The ARM lists all the standard packages that come with all compilers. 
There are lots of other packages available. www.adapower.com is probably 
a good place to start if you want to find others.

-- 
Jeff Carter
"I wave my private parts at your aunties."
Monty Python & the Holy Grail




^ permalink raw reply	[relevance 7%]

* Re: Newbie question on Ada TExt_IO
  @ 2002-10-04 17:34 10% ` Justin Birtwell
  2002-10-04 20:07  7%   ` Jeffrey Carter
  2002-10-05  2:43  0%   ` SteveD
  0 siblings, 2 replies; 162+ results
From: Justin Birtwell @ 2002-10-04 17:34 UTC (permalink / raw)


Hello All,

To everyone that replied to my question..thank you.  Through your responses
I learned allot.  I learned how I could raise an error with in a loop by
nesting a block,  I also learned about Skip_Line and Get_Line, the
Ada.Strings.Trim and the Ada.Strings.Fixed.Index packages.  After reading
everyone's post I"ve decided that the best course of action is to validate
the input as much as I possibly can but still supply some exception handling
for anything that I haven't anticipated.  So my validation looks like this

Accept entire line using Get_Line into string(1..256);
Check if first character is a digit
Check if digit is between 1 and 6
error handling

Here's the code:

with Text_Io;use Text_Io;
with StringFunctions;use StringFunctions;

procedure Test_IO_2 is
   Input: String(1..256);
   N:Integer;
   Success:Boolean:=false;
   Last:Integer;
begin
      while success /=true loop
      Put("PLease enter a number between 1 and 6");
      Get_Line(Item=>Input,Last=>Last);
         if Is_Digit(Input(1..1)) then
            N:=Integer'Value(Input(1..1));
            if N>=1 and N<=6 then
               Success:=True;
            end if;
         else
            success:=false;
            Put_Line("Invalid entry, try again.");
         end if;
       end loop;
      Put_Line("Thank you");
     exception
      when others=>
         Put_Line("Error, Invalid data.");
end;

Is_Digit a hack of a procedure that compares the 1 character string to all
10 digits characters.  I really have a lot to learn.   What's giving me the
hardest time is working within the confines of strict/strong typing.  The
Ada.Characters.Handling  package already has an Is_Digit function, but it's
expecting a character not a single item String array!  How can I convert
from one into the other?  I have the distinct feelling like I'm reinventing
the wheel.  Aren't packages aready made to do alot of this
converting/validation?  If so where are they?  How can one access them?
Does the RM list all the packages provided by Ada or are there more to be
discovered?

thanks to one and all,
Justin







^ permalink raw reply	[relevance 10%]

* Re: how to create an array of N elements?
       [not found]     <c923f575.0208170639.344c3c21@posting.google.com>
@ 2002-08-17 16:16  8% ` Warren W. Gay VE3WWG
  0 siblings, 0 replies; 162+ results
From: Warren W. Gay VE3WWG @ 2002-08-17 16:16 UTC (permalink / raw)


This should be called a RFAQ question (Real Frequently AQ) ;-)

drmed wrote:
> hi,
> my code:
> 
> procedure main is
> type abc is array(Positive range <>) of Character;
> letters : abc(1 .. 26)
> begin
> end main;
> 
> now in my code, letters is an array with 26 elements.
> how can I do it, that the size of the array changes in runtime?
> sometimes only 20 elements, then add one element, delete one and etc.
> jonas

This was just recently rehashed days ago, as this question so often is
here. To requote myself from a prior posting (an example that starts
with a 10 character array, then progressing to other lengths):

with Ada.Text_IO;

procedure EG is
     use Ada.Text_IO;

     function Length(S : String) return Natural is
     begin
        return S'Length;
     end Length;

     S :      String(1..10) := "1234567890";
     Last :   Natural := S'Last;
begin
     Put_Line("S='" & S(1..Last) & "'");

-- Last       := 3; -- or..
     Last       := Length("Cat");  -- Because can't use "Cat"'Last
     S(1..Last) := "Cat";

     Put_Line("S='" & S(1..Last) & "'");

end EG;

The idea is that you work with a variable called Last
(or something like it). If you don't like counting
characters in a larger constant like "Some message..."
then the use of a Lenght() function can be helpful (see
the statement Last := Length("cat");). Unfortunately,
doing "Some very long string constant"'Length is not legal.

At other times, you declare the variable when you
know its length, like:

declare
     My_New_String : String(1..Computed_Length);
     Another_String : String := String_1 & String_2;
begin
     ...

Or you have a function return the exact length string
you need, as in:

declare
     Returned_String : String := My_Function(whatever);
begin
     ...

and then thow it away when you're done with it using:

end;

of the declare..begin..end block. You can do this for
each iteration within a loop as well.

This requires a little different planning than C programmers
are used to. But once you catch onto the general paradigm
shift, you'll find that Ada fixed strings, packages
Ada.Strings.Fixed and Ada.Characters.Handling cover most
of your string needs.

If you deal with a number of variable length strings, then
sometimes resorting to Ada.Strings.Unbounded makes your
life easier as many have already pointed out. However, I
find that once you cross over to Ada.Strings.Unbounded, then
other features of these strings become "less natural" (for
example you must use a Length function instead of a Length
attribute, and slices become more of a nuisance etc.)

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[relevance 8%]

* Re: Anyway to change the length of a string ?
@ 2002-08-14 21:31  8% Warren W. Gay VE3WWG
  0 siblings, 0 replies; 162+ results
From: Warren W. Gay VE3WWG @ 2002-08-14 21:31 UTC (permalink / raw)


Stephen Leake wrote:
 > genx54321@hotmail.com (Jim) writes:
 >>.... after you have already declared it before BEGIN ?
 >>
 >>i am making a Hangman game with words up to 10 letters long.
 >>
 >>now i declare a string which would be used in the program for the word
 >>which can be 1-10 letters.
 >>
 >>so i say
 >>
 >>s : string(1..10)
 >>
 >>but in the program i cant say
 >>
 >>s:= "hello"
 >
 > You can say
 >
 > S (1 .. 5) := "hello";
 >
 > or
 >
 > S := "hello" & "     ";

These are all reasonable solutions.

Expanding upon the above solutions slightly, examine the
following tested piece of code for an example:

with Ada.Text_IO;

procedure EG is
     use Ada.Text_IO;

     function Length(S : String) return Natural is
     begin
        return S'Length;
     end Length;

     S :      String(1..10) := "1234567890";
     Last :   Natural := S'Last;
begin
     Put_Line("S='" & S(1..Last) & "'");

-- Last       := 3; -- or..
     Last       := Length("Cat");  -- Because can't use "Cat"'Last
     S(1..Last) := "Cat";

     Put_Line("S='" & S(1..Last) & "'");

end EG;

The idea is that you work with a variable called Last
(or something like it). If you don't like counting
characters in a larger constant like "Some message..."
then the use of a Lenght() function can be helpful (see
the statement Last := Length("cat");). Unfortunately,
doing "Some very long string constant"'Last is not legal.

At other times, you declare the variable when you
know its length, like:

declare
     My_New_String : String(1..Computed_Length);
begin
     ...

Or you have a function return the exact length string
you need, as in:

declare
     Returned_String : String := My_Function(whatever);
begin
     ...

and then thow it away when you're done with it using:

end;

of the declare..begin..end block. You can do this for
each iteration within a loop as well.

This requires a little different planning than C programmers
are used to. But once you catch onto the general paradigm
shift, you'll find that Ada fixed strings, packages
Ada.Strings.Fixed and Ada.Characters.Handling cover most
of your string needs.

If you deal with a number of variable length strings, then
sometimes resorting to Ada.Strings.Unbounded makes your
life easier as many have already pointed out. However, I
find that once you cross over to Ada.Strings.Unbounded, then
other features of these strings become "less natural" (for
example you must use a Length function instead of a Length
attribute).

Hope this helps, Warren.
-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg





^ permalink raw reply	[relevance 8%]

* Possible bug / need confirmation
@ 2002-06-11  0:00  4% Anh_Vo
  0 siblings, 0 replies; 162+ results
From: Anh_Vo @ 2002-06-11  0:00 UTC (permalink / raw)


The codes below causes Program_Error, EXCEPTION_ACCESS_VIOLATION,
under Windows 2K and Constrain_Error, SIGSEGV, under Solaris when
compiled with GNAT-3.14p.
Any one having GNAT 3.15 or later, please check if this problem has
been corrected. In addition, the exact error message are included
also. If confirmed, I will submit a bug report. Thanks in advance for
your help.

Anh Vo

gcc -c phone.adb
+===========================GNAT BUG
DETECTED==============================+
| 3.14p (20010503) (sparc-sun-solaris2.5.1) Constraint_Error SIGSEGV  
    |
| Error detected at phone.adb:113:57                                  
    |
| Please submit bug report by email to report@gnat.com.               
    |
| Include the entire contents of this bug box in the report.          
    |
| Include the exact gcc or gnatmake command that you entered.         
    |
| Also include sources listed below in gnatchop format                
    |
| (concatenated together with no headers between files).              
    |
| (use plain ASCII or MIME attachment).                               
    |
| See gnatinfo.txt for full info on procedure for submitting bugs.    
    |
+==========================================================================+

Please include these source files with error report

phone.adb
sockets.ads
sockets-stream_io.ads


GNAT 3.14p  (20010503) Copyright 1992-2001 Free Software Foundation,
Inc.

Compiling: c:\ada_95\bugs\gnat\3.14\phone.adb (source file time stamp:
2002-06-10 23:30:46)
+===========================GNAT BUG
DETECTED==============================+
| 3.14p  (20010503) (i586-pc-mingw32msv) Program_Error
EXCEPTION_ACCESS_VIOLATION|
| Error detected at c:\ada_95\bugs\gnat\3.14\phone.adb:113:57         
    |
| Please submit bug report by email to report@gnat.com.               
    |
| Include the entire contents of this bug box in the report.          
    |
| Include the exact gcc or gnatmake command that you entered.         
    |
| Also include sources listed below in gnatchop format                
    |
| (concatenated together with no headers between files).              
    |
| (use plain ASCII or MIME attachment).                               
    |
| See gnatinfo.txt for full info on procedure for submitting bugs.    
    |
+==========================================================================+

Please include these source files with error report

c:\ada_95\bugs\gnat\3.14\phone.adb
c:\ada_95\bugs\gnat\3.14\sockets.ads
c:\ada_95\bugs\gnat\3.14\sockets-stream_io.ads

-----------------------------------------------------------------------------
--                                                                    
    --
--                         ADASOCKETS COMPONENTS                      
    --
--                                                                    
    --
--                             S O C K E T S                          
    --
--                                                                    
    --
--                                S p e c                             
    --
--                                                                    
    --
--                        $ReleaseVersion: 0.1.6 $                    
    --
--                                                                    
    --
--                        Copyright (C) 1998-2000                     
    --
--             �cole Nationale Sup�rieure des T�l�communications      
    --
--                                                                    
    --
--   AdaSockets is free software; you can  redistribute it and/or
modify   --
--   it  under terms of the GNU  General  Public License as published
by   --
--   the Free Software Foundation; either version 2, or (at your
option)   --
--   any later version.   AdaSockets is distributed  in the hope that
it   --
--   will be useful, but WITHOUT ANY  WARRANTY; without even the
implied   --
--   warranty of MERCHANTABILITY   or FITNESS FOR  A PARTICULAR
PURPOSE.   --
--   See the GNU General Public  License  for more details.  You 
should   --
--   have received a copy of the  GNU General Public License
distributed   --
--   with AdaSockets; see   file COPYING.  If  not,  write  to  the
Free   --
--   Software  Foundation, 59   Temple Place -   Suite  330,  Boston,
MA   --
--   02111-1307, USA.                                                 
    --
--                                                                    
    --
--   As a special exception, if  other  files instantiate generics 
from   --
--   this unit, or  you link this  unit with other  files to produce 
an   --
--   executable,  this  unit does  not  by  itself cause  the 
resulting   --
--   executable to be  covered by the  GNU General Public License. 
This   --
--   exception does  not  however invalidate any  other reasons  why
the   --
--   executable file might be covered by the GNU Public License.      
    --
--                                                                    
    --
--   The main repository for this software is located at:             
    --
--       http://www.infres.enst.fr/ANC/                               
    --
--                                                                    
    --
--   If you have any question, please send a mail to                  
    --
--       Samuel Tardieu <sam@inf.enst.fr>                             
    --
--                                                                    
    --
-----------------------------------------------------------------------------

with Ada.Streams;
with Interfaces.C;

package Sockets is

   type Socket_FD is tagged private;
   --  A socket

   type Socket_Domain is (AF_INET);
   --  AF_INET: Internet sockets (yes, should be PF_INET, but they
hold the
   --  same value)

   type Socket_Type is (SOCK_STREAM, SOCK_DGRAM);
   --  SOCK_STREAM: Stream mode   (TCP)
   --  SOCK_DGRAM:  Datagram mode (UDP, Multicast)

   procedure Socket
     (Sock   : out Socket_FD;
      Domain : in Socket_Domain := AF_INET;
      Typ    : in Socket_Type   := SOCK_STREAM);
   --  Create a socket of the given mode

   Connection_Refused : exception;

   procedure Connect
     (Socket : in Socket_FD;
      Host   : in String;
      Port   : in Positive);
   --  Connect a socket on a given host/port. Raise Connection_Refused
if
   --  the connection has not been accepted by the other end.

   procedure Bind
     (Socket : in Socket_FD;
      Port   : in Natural;
      Host   : in String := "");
   --  Bind a socket on a given port. Using 0 for the port will tell
the
   --  OS to allocate a non-privileged free port. The port can be
later
   --  retrieved using Get_Sock_Port on the bound socket.
   --  If Host is not the empty string, it is used to designate the
interface
   --  to bind on.

   procedure Listen
     (Socket     : in Socket_FD;
      Queue_Size : in Positive := 5);
   --  Create a socket's listen queue

   type Socket_Level is (SOL_SOCKET, IPPROTO_IP);

   type Socket_Option is (SO_REUSEADDR, IP_MULTICAST_TTL,
                          IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP,
                          IP_MULTICAST_LOOP);

   procedure Setsockopt
     (Socket  : in Socket_FD'Class;
      Level   : in Socket_Level := SOL_SOCKET;
      Optname : in Socket_Option;
      Optval  : in Integer);
   --  Set a socket option

   generic
      Level   : Socket_Level;
      Optname : Socket_Option;
      type Opt_Type is private;
   procedure Customized_Setsockopt (Socket : in Socket_FD'Class;
                                    Optval : in Opt_Type);
   --  Low level control on setsockopt

   procedure Accept_Socket (Socket     : in Socket_FD;
                            New_Socket : out Socket_FD);
   --  Accept a connection on a socket

   Connection_Closed : exception;

   procedure Send (Socket : in Socket_FD;
                   Data   : in Ada.Streams.Stream_Element_Array);
   --  Send data on a socket. Raise Connection_Closed if the socket
   --  has been closed.

   function Receive (Socket : Socket_FD;
                     Max    : Ada.Streams.Stream_Element_Count :=
4096)
     return Ada.Streams.Stream_Element_Array;
   --  Receive data from a socket. May raise Connection_Closed

   procedure Receive (Socket : in Socket_FD'Class;
                      Data   : out Ada.Streams.Stream_Element_Array);
   --  Get data from a socket. Raise Connection_Closed if the socket
has
   --  been closed before the end of the array.

   procedure Receive_Some
     (Socket : in Socket_FD'Class;
      Data   : out Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset);
   --  Get some data from a socket. The index of the last element will
   --  be placed in Last.

   type Shutdown_Type is (Receive, Send, Both);

   procedure Shutdown (Socket : in out Socket_FD;
                       How    : in Shutdown_Type := Both);
   --  Close a previously opened socket

   procedure Socketpair
     (Read_End  : out Socket_FD;
      Write_End : out Socket_FD;
      Domain    : in Socket_Domain := AF_INET;
      Typ       : in Socket_Type   := SOCK_STREAM);
   --  Create a socketpair.

   function Get_FD (Socket : in Socket_FD)
     return Interfaces.C.int;
   --  Get a socket's FD field

   ---------------------------------
   -- String-oriented subprograms --
   ---------------------------------

   procedure Put (Socket : in Socket_FD'Class;
                  Str    : in String);
   --  Send a string on the socket

   procedure New_Line (Socket : in Socket_FD'Class;
                       Count  : in Natural := 1);
   --  Send CR/LF sequences on the socket

   procedure Put_Line (Socket : in Socket_FD'Class;
                       Str    : in String);
   --  Send a string + CR/LF on the socket

   function Get (Socket : Socket_FD'Class) return String;
   --  Get a string from the socket

   function Get_Line (Socket : Socket_FD'Class) return String;
   --  Get a full line from the socket. CR is ignored and LF is
considered
   --  as an end-of-line marker.

private

   type Shutdown_Array is array (Receive .. Send) of Boolean;

   type Socket_FD is tagged record
      FD       : Interfaces.C.int;
      Shutdown : Shutdown_Array;
   end record;

end Sockets;

-----------------------------------------------------------------------------
--                                                                    
    --
--                         ADASOCKETS COMPONENTS                      
    --
--                                                                    
    --
--                   S O C K E T S . S T R E A M _ I O                
    --
--                                                                    
    --
--                                S p e c                             
    --
--                                                                    
    --
--                        $ReleaseVersion: 0.1.0 $                    
    --
--                                                                    
    --
--                        Copyright (C) 1998-2000                     
    --
--             �cole Nationale Sup�rieure des T�l�communications      
    --
--                                                                    
    --
--   AdaSockets is free software; you can  redistribute it and/or
modify   --
--   it  under terms of the GNU  General  Public License as published
by   --
--   the Free Software Foundation; either version 2, or (at your
option)   --
--   any later version.   AdaSockets is distributed  in the hope that
it   --
--   will be useful, but WITHOUT ANY  WARRANTY; without even the
implied   --
--   warranty of MERCHANTABILITY   or FITNESS FOR  A PARTICULAR
PURPOSE.   --
--   See the GNU General Public  License  for more details.  You 
should   --
--   have received a copy of the  GNU General Public License
distributed   --
--   with AdaSockets; see   file COPYING.  If  not,  write  to  the
Free   --
--   Software  Foundation, 59   Temple Place -   Suite  330,  Boston,
MA   --
--   02111-1307, USA.                                                 
    --
--                                                                    
    --
--   As a special exception, if  other  files instantiate generics 
from   --
--   this unit, or  you link this  unit with other  files to produce 
an   --
--   executable,  this  unit does  not  by  itself cause  the 
resulting   --
--   executable to be  covered by the  GNU General Public License. 
This   --
--   exception does  not  however invalidate any  other reasons  why
the   --
--   executable file might be covered by the GNU Public License.      
    --
--                                                                    
    --
--   The main repository for this software is located at:             
    --
--       http://www.infres.enst.fr/ANC/                               
    --
--                                                                    
    --
--   If you have any question, please send a mail to                  
    --
--       Samuel Tardieu <sam@inf.enst.fr>                             
    --
--                                                                    
    --
-----------------------------------------------------------------------------

with Ada.Streams;

package Sockets.Stream_IO is

   type Socket_Stream_Type is new Ada.Streams.Root_Stream_Type with
private;

   procedure Initialize
     (Stream : in out Socket_Stream_Type;
      FD     : in Socket_FD);
   --  Initialize must be called with an opened socket as parameter
before
   --  being used as a stream.

   procedure Read
     (Stream : in out Socket_Stream_Type;
      Item   : out Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset);

   procedure Write
     (Stream : in out Socket_Stream_Type;
      Item   : in Ada.Streams.Stream_Element_Array);

private

   type Socket_Stream_Type is new Ada.Streams.Root_Stream_Type with
record
      FD : Socket_FD;
   end record;

end Sockets.Stream_IO;

-----------------------------------------------------------------------------
--                                                                    
    --
--                         ADASOCKETS COMPONENTS                      
    --
--                                                                    
    --
--                       S T R E A M _ S E N D E R                    
    --
--                                                                    
    --
--                                B o d y                             
    --
--                                                                    
    --
--                        $ReleaseVersion: 0.1.0 $                    
    --
--                                                                    
    --
--                        Copyright (C) 1998-2000                     
    --
--              cole Nationale Sup rieure des T l communications      
    --
--                                                                    
    --
--   AdaSockets is free software; you can  redistribute it and/or
modify   --
--   it  under terms of the GNU  General  Public License as published
by   --
--   the Free Software Foundation; either version 2, or (at your
option)   --
--   any later version.   AdaSockets is distributed  in the hope that
it   --
--   will be useful, but WITHOUT ANY  WARRANTY; without even the
implied   --
--   warranty of MERCHANTABILITY   or FITNESS FOR  A PARTICULAR
PURPOSE.   --
--   See the GNU General Public  License  for more details.  You 
should   --
--   have received a copy of the  GNU General Public License
distributed   --
--   with AdaSockets; see   file COPYING.  If  not,  write  to  the
Free   --
--   Software  Foundation, 59   Temple Place -   Suite  330,  Boston,
MA   --
--   02111-1307, USA.                                                 
    --
--                                                                    
    --
--   As a special exception, if  other  files instantiate generics 
from   --
--   this unit, or  you link this  unit with other  files to produce 
an   --
--   executable,  this  unit does  not  by  itself cause  the 
resulting   --
--   executable to be  covered by the  GNU General Public License. 
This   --
--   exception does  not  however invalidate any  other reasons  why
the   --
--   executable file might be covered by the GNU Public License.      
    --
--                                                                    
    --
--   The main repository for this software is located at:             
    --
--       http://www.infres.enst.fr/ANC/                               
    --
--                                                                    
    --
--   If you have any question, please send a mail to                  
    --
--       Samuel Tardieu <sam@inf.enst.fr>                             
    --
--                                                                    
    --
-- 25 May 2001 - Anh Vo <anh_vo@udlp.com>                             
    --
--                                                                    
    --
-- Based on Stream_Listener from Samuel Tardieu                       
    --
-- It allowed two people to communicate if the host name and the ip   
    --
-- address of the communicators are known.                            
    --
--                                                                    
    --
-----------------------------------------------------------------------------

with Ada.Command_Line;  use Ada.Command_Line;
with Ada.Exceptions;    use Ada.Exceptions;
with Ada.Text_IO;       use Ada.Text_IO;
with Sockets.Stream_IO; use Sockets, Sockets.Stream_IO;
with Ada.Characters.Handling;
with Ada.Strings.Unbounded;

procedure Phone is

   --  Usage: stream_sender remotehost remoteport
   --  Example: stream_sender localhost 5000

   use Ada;
   use Text_Io;
   use Command_Line;
   use Characters.Handling;
   use Strings.Unbounded;

   Outgoing_Socket : Socket_FD;
   Stream          : aliased Socket_Stream_Type;
   Line            : String (1 .. 200);
   Last            : Natural;
   Goodbye_Msg     : constant String := "goodbye";
   Goodbye_Ack     : constant String := "byebye";
   Msg_Received : Unbounded_String;
   
   task Receiver is
      entry Start_Receive (Msg : out Unbounded_String);
   end Receiver;
   
   task body Receiver is
   begin
      loop
         select 
            accept Start_Receive (Msg : out Unbounded_String) do
               Msg := To_Unbounded_String (String'Input
(Stream'Access));
--               Put_Line ("Acknowledged Message received: " &
To_String (Msg));
            end Start_Receive;
         or
            terminate;
         end select;
      end loop;
   end Receiver;
   
   
begin   -- Phone body --

   if Argument_Count /= 2 then
      Raise_Exception
        (Constraint_Error'Identity,
         "Usage: " & Command_Name & " remotehost remoteport");
   end if;
   
   Socket (Outgoing_Socket, AF_INET, SOCK_STREAM);
   Connect (Outgoing_Socket, Argument (1), Positive'Value (Argument
(2)));
   Initialize (Stream, Outgoing_Socket);
               
   Forever:
   loop
   
      Put ("Type a message -> ");
      Flush;
      Get_Line (Line, Last);
      
      select

         String'Output (Stream'Access, Line (Line'First .. Last));

         if To_Lower (Line (Line'First .. Last)) = 
                                            To_Lower (Goodbye_Msg) or
else
            To_Lower (Line (Line'First .. Last)) = To_Lower ("Quit")
or else
            To_Lower (Line (Line'First .. Last)) = To_Lower ("Exit")
or else
            To_Lower (Line (Line'First .. Last)) = To_Lower ("Bye")
then
            Put_Line ("Acknowledged Message received: " & 
                                              String'Input
(Stream'Access));
         exit Forever;
      end if;
      
      then abort
         delay 20.0;
         Receiver.Start_Receive (Msg_Received);
         Put_Line ("Last message received: " & To_String
(Msg_Received));
         exit;
      end select;  
    
      select
         delay 20.0;
         Put_Line ("Phone is inactive for 20 seconds. Hand up.");
         String'Output (Stream'Access, 
                        "You do not respond for 20 seconds. I give
up!");
         String'Output (Stream'Access, Goodbye_Msg);
         exit;
      then abort
         Receiver.Start_Receive (Msg_Received);
         declare 
            Message : constant String := To_String (Msg_Received);
         begin
            Put_Line ("Message received: " & Message);
            if To_Lower (Message) = To_Lower ("Goodbye") or else
               To_Lower (Message) = To_Lower ("Bye") or else
               To_Lower (Message) = To_Lower ("Quit") or else
               To_Lower (Message) = To_Lower ("Exit") then
               String'Output (Stream'Access, Goodbye_Ack);
               return;        
            end if;
         end;
      end select;

   end loop Forever;
      
   begin
      Shutdown (Outgoing_Socket, Both);
   exception
      when Connection_Closed =>
         null;  -- expected if other side dropped out
   end;
   
exception
   when Error : others =>
      Put_Line ("Communication problem with the reason of: " & 
         Exceptions.Exception_Information (Error));
      Put_Line ("Run again.");
   
end Phone;



^ permalink raw reply	[relevance 4%]

* Constraint error help..
@ 2002-05-20 23:09 10% tr4ck
  0 siblings, 0 replies; 162+ results
From: tr4ck @ 2002-05-20 23:09 UTC (permalink / raw)


I am getting a constraint error for this line Word_Array(I) := Word; and I
can't figure out why, the program compiles fine.  Below is the code for the
program.  The program reads in a text file, say the file has the line, This
is a test, it just reads character by character seeing if the item is
actually a character if so it puts it into a string called word.  Then the
word gets put into an word_Array.  This is something simple that I am
trying, so it just returns if the item is not a character or if their are
spaces.  Can someone tell my why I am getting a constaint error?

Thanks.
WITH Ada.Text_IO;
WITH Ada.Characters.Handling;
WITH Ada.IO_Exceptions;
PROCEDURE FileArray IS

  FileName  : String(1..80);
  MaxName   : CONSTANT Positive := 80;
  SUBTYPE NameRange IS Positive RANGE 1..MaxName;
  Length    : NameRange;
  DataFile  : Ada.Text_IO.File_Type;
  Letter    : Character;
  Word      : String(1..10);
  I         : Integer := 0;
  Word_Array : ARRAY(1..30) OF String(1..10);

PROCEDURE OpenFile IS --Opens a file

BEGIN

  LOOP
    BEGIN
      Ada.Text_IO.Put(Item => "Enter the name of the file > ");
      Ada.Text_IO.Get_Line(Item => FileName, Last => Length);
      Ada.Text_IO.Open(File => DataFile, Mode => Ada.Text_IO.In_File, Name
=> FileName(1..Length));
      Ada.Text_IO.Put("File Opened");
      EXIT;

      EXCEPTION
      WHEN Constraint_Error =>
      Ada.Text_IO.Put(Item => "Constraint Error! ");
      Ada.Text_IO.Skip_Line;

      WHEN Ada.Text_IO.Data_Error =>
      Ada.Text_IO.Put(Item => "Data Error! ");
      Ada.Text_IO.Skip_Line;

      WHEN Ada.Text_IO.End_Error =>
      Ada.Text_IO.Put(Item => "End Error! ");
      Ada.Text_IO.Skip_Line;

      WHEN Ada.IO_Exceptions.Status_Error => Ada.Text_IO.Skip_Line;
      WHEN Ada.IO_Exceptions.Name_Error =>
      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line ("Cannot Open " & FileName(1..Length) & "!");
      Ada.Text_IO.New_Line;
    END;
  END LOOP;
END OpenFile;

PROCEDURE Convert IS -- Changes the characters to lowercase

BEGIN

  LOOP
    EXIT WHEN Ada.Text_IO.End_Of_File(File => DataFile);
    LOOP
      EXIT WHEN Ada.Text_IO.End_Of_Line(File => DataFile);
      Ada.Text_IO.Get(File => DataFile, Item => Letter);
      Letter := Ada.Characters.Handling.To_Lower(Item => Letter);
    END LOOP;
    Ada.Text_IO.Skip_Line(File => DataFile);
  END LOOP;

END Convert;

PROCEDURE CheckChar IS -- Check one item at a time to see if its a
character,
                       -- if it is then it puts it in the word string

BEGIN

  LOOP
   IF Letter IN 'a'..'z' THEN
      Word(I) := Letter;
    ELSE
      RETURN;
    END IF;
  I := I + 1;
  END LOOP;

END CheckChar;

PROCEDURE Store IS -- Puts the words in the word_array

BEGIN

    I := 0;
  LOOP
    IF I <= 30 THEN
      Word_Array(I) := Word;
    ELSE
      RETURN;
    END IF;
  I := I + 1;
  END LOOP;

END Store;

PROCEDURE Display IS  -- Displays the contents of the word array

BEGIN

  I := 1;
  LOOP
    Ada.Text_IO.Put(Item => Word_Array(I));
    I := I + 1;
  END LOOP;

END Display;

BEGIN

  OpenFile;
  Convert;
  CheckChar;
  Store;
  Display;

END FileArray;









^ permalink raw reply	[relevance 10%]

* Re: string to uppercase
@ 2002-04-23  9:13  9% Gautier Write-only-address
  0 siblings, 0 replies; 162+ results
From: Gautier Write-only-address @ 2002-04-23  9:13 UTC (permalink / raw)


>This is probably a simple question and I apologise for it, but is
>their a simple way to change the case of a string
>ie. from lower to upper.

In Ada.Characters.Handling you have...

...
   ---------------------------------------------------
   -- Conversion Functions for Character and String --
   ---------------------------------------------------

   function To_Lower (Item : in Character) return Character;
   function To_Upper (Item : in Character) return Character;
   function To_Basic (Item : in Character) return Character;

   function To_Lower (Item : in String) return String;
   function To_Upper (Item : in String) return String;
   function To_Basic (Item : in String) return String;
...

HTH
________________________________________________________
Gautier  --  http://www.mysunrise.ch/users/gdm/gsoft.htm

NB: For a direct answer, address on the Web site!


_________________________________________________________________
Chat with friends online, try MSN Messenger: http://messenger.msn.com




^ permalink raw reply	[relevance 9%]

* Re: Ada Characters?
  2002-02-28  2:07 10% Ada Characters? Wannabe h4x0r
  2002-02-28  2:28 13% ` Jim Rogers
@ 2002-02-28 22:54  0% ` Jeffrey Carter
  1 sibling, 0 replies; 162+ results
From: Jeffrey Carter @ 2002-02-28 22:54 UTC (permalink / raw)


Wannabe h4x0r wrote:
> 
> I'm trying to figure out how to get my Ada program to single out ASCII
> control codes without hosing the output of the rest of the text file.
> 
> Basically, I'm doing it like this...
> with Ada.Characters; use Ada.Characters.Handling;
> 
>         TEXT : string(1..200);
>         chk_char: character;  -- Check to see if this is a control character.
>         chk_result : boolean;
> 
> and the code goes like this ...
> 
>         for l in TEXT'range loop
>                 chk_char := TEXT(l);
>                 chk_result := Is_control(chk_char);
>                         if chk_result is True then
>                                 if <how do I check to see if it's a NL(new line) character?> then
>                                         NEW_LINE;
>                                 else
>                                         NULL;
>                                 end if;
>                         else
>                                 Put(chk_char); --Put each character individually
>                         end if;
>         end loop;
> 
> Anyways, that's the general gist of it.

I don't understand what you're trying to do. How do you fill Text and
how does it get control characters in it? What character do you mean by
NL? No such character is defined in Ada.Characters.Latin_1. Ada.Text_IO
line terminators are not defined by the language and differ from OS to
OS; on some systems a line terminator is a single character while on
others it is a sequence of characters.

-- 
Jeffrey Carter



^ permalink raw reply	[relevance 0%]

* Re: Ada Characters?
  2002-02-28  2:07 10% Ada Characters? Wannabe h4x0r
@ 2002-02-28  2:28 13% ` Jim Rogers
  2002-02-28 22:54  0% ` Jeffrey Carter
  1 sibling, 0 replies; 162+ results
From: Jim Rogers @ 2002-02-28  2:28 UTC (permalink / raw)


Wannabe h4x0r wrote:

> I'm trying to figure out how to get my Ada program to single out ASCII
> control codes without hosing the output of the rest of the text file. 
> 
> Basically, I'm doing it like this...
> with Ada.Characters; use Ada.Characters.Handling;
> 
> 	TEXT : string(1..200);
> 	chk_char: character;  -- Check to see if this is a control character.
> 	chk_result : boolean;
> 	
> and the code goes like this ...
> 
> 	for l in TEXT'range loop
> 		chk_char := TEXT(l);
> 		chk_result := Is_control(chk_char);
> 			if chk_result is True then
> 				if <how do I check to see if it's a NL(new line) character?> then
> 					NEW_LINE;
> 				else
> 					NULL;
> 				end if;
> 			else
> 				Put(chk_char); --Put each character individually
> 			end if;
> 	end loop;


with Ada.Characters.Latin_1;
with Ada.Characters.Handling; use Ada.Characters.Handling;

...

for l in TEXT'range loop
    chk_char := TEXT(l);
    if Is_Control(chk_char) then
       if chk_char = Ada.Characters.Latin_1.LF then
          Ada.Text_IO.Put(chk_char);
       end if;
     else
       Ada.Text_IO.Put(chk_char);
     end if;
end loop;

Jim Rogers





^ permalink raw reply	[relevance 13%]

* Ada Characters?
@ 2002-02-28  2:07 10% Wannabe h4x0r
  2002-02-28  2:28 13% ` Jim Rogers
  2002-02-28 22:54  0% ` Jeffrey Carter
  0 siblings, 2 replies; 162+ results
From: Wannabe h4x0r @ 2002-02-28  2:07 UTC (permalink / raw)


I'm trying to figure out how to get my Ada program to single out ASCII
control codes without hosing the output of the rest of the text file. 

Basically, I'm doing it like this...
with Ada.Characters; use Ada.Characters.Handling;

	TEXT : string(1..200);
	chk_char: character;  -- Check to see if this is a control character.
	chk_result : boolean;
	
and the code goes like this ...

	for l in TEXT'range loop
		chk_char := TEXT(l);
		chk_result := Is_control(chk_char);
			if chk_result is True then
				if <how do I check to see if it's a NL(new line) character?> then
					NEW_LINE;
				else
					NULL;
				end if;
			else
				Put(chk_char); --Put each character individually
			end if;
	end loop;

Anyways, that's the general gist of it.

Now, I got a short program that opens a text file, and reads from it, but
all it does is spew out control codes. Really odd. I really dont have a
handle on this as I can tell.

Tips?

Chris



^ permalink raw reply	[relevance 10%]

* Re: List container strawman
  @ 2001-11-10 20:59  7%                               ` Nick Roberts
  0 siblings, 0 replies; 162+ results
From: Nick Roberts @ 2001-11-10 20:59 UTC (permalink / raw)


"Ted Dennison" <dennison@telepath.com> wrote in message
news:L6dH7.20105$xS6.32596@www.newsranger.com...
> In article <9sib27$13aeg3$5@ID-25716.news.dfncis.de>, Nick Roberts says...
> >For a start, all this mularchy about insertion and deletion is just plain
> >silly! It really is. You don't need them, and shouldn't implement them.
Yes,
> >really. Let me show you why.
>
> I'm not sure I understand this. It looks like you are talking about having
the
> users manage the internal details of all their own data structures, to
which my
> first reaction would be "ewwwww.". I'll admit there may be some
interesting
> possiblities I don't see in this though.

In general, of course, you want to hide details such as pointers. But don't
get carried away! Sometimes the application programmer has got to deal with
things like pointers.

In the example I gave, the fact that the list container was used to
(explicitly) contain pointers is likely to actually have many advantages for
the application programmer: other manipulations of the data - not involving
containers - can also be carried out more efficiently (and sometimes more
conveniently) using those same pointers.

> >It also gives me another opportunity to demonstrate the idea of having a
set
> >of abstract container types, upon which operations (such as
Normalize_Names)
> >can be hung, thus freeing you of: (1) having to worry about which
container
> >type to use when writing the procedure; (2) the procedure shackling you
to
> >one particular container type. Do you turn away from this Utopia? ;-)
>
> But remember that one of our stipulations is essentially "no multilevel
generic
> instantiations required". Does this work that way? Without that
restriction you
> could do all sorts of cool things, as has been done in Booch and others.
In that
> enviroment I'd say that we already have plenty of players, and one of them
is
> liable to be perfectly suitable (although I suppose more are always
welcome). I
> don't want to discourage you from making the ultimate container library.
But for
> the purposes of what we are doing here it has to be very easy to use, and
> frankly I couldn't figure out quite what was going on in the code you
presented.

I'm not quite trying to make 'the ultimate library' ;-) but I suppose I am
aiming at something that would be useful for 'real' programming, rather than
just for students and demos. Ada is not a toy language, it's not a Pascal or
BASIC, it's an industrial language intended for building real, big software.
Honestly, I think it's a mistake to try to defend students (or anyone else)
from this fact.

When we make a wooden box for the first time in kindergarten we use one nail
per joint. As grown ups, when we make a box for some real purpose, we use
two nails per joint. When making toy programs at university we may have used
one instantiation per data type; but when as professionals we start writing
real software, we use two instantiations per data type! (It's all a part of
the maturing process ;-)

At the end of the day, a box that falls to pieces (because you only used one
nail) doesn't make life easier for anyone. As I say in my reply to Ehud, I
really believe this is a situation where trying to make things easier for
the user will end up making things much harder for them.

To me, you really seem to be saying something like "Oh, there shouldn't be
any safety catches on guns: it makes them too complicated for the user! Our
guns have just the trigger and nothing else." It may sound nice, but you are
inevitably going to cause of lot of users to end up shooting themselves (in
the foot, or worse :-)

I hope you'll forgive me if I re-post the code I gave, corrected and cleaned
up a little, and with a blow-by-blow commentary on what's going on.

   with Ada.Characters.Handling; use Ada.Characters.Handling;

This is to conveniently obtain some character-handling functions provided by
Ada.

   type Name_Ref is access [all] String;

Here we declare the access type that is going to be the 'data type' stored
by containers.

   package Name_Ref_Iteration is new Iteration(Name_Ref);

This instantiates the package of abstract container types (including
Sequence_Recorder), so that they are specialised for Name_Refs (but they are
still abstract).

   procedure Normalize_Names (
      Source: in out Name_Ref_Iteration.Sequence_Recorder'Class;
      Target: in out Name_Ref_Iteration.Sequence_Recorder'Class) is

Source and Target are both in the class of the abstract container type
Sequence_Recorder. This means that the corresponding actuals, when the
procedure is called, must be (concrete types) derived from
Sequence_Recorder, and therefore that they must, at the very least,
implement the procedures Read, Restart, Rewrite, and Write, and the function
End_of_Data.

      Ref: Name_Ref;
      N: Natural;

Just a couple of temporary variables.

   begin
      while not End_of_Data(Source) loop

We will iterate over the elements (name pointers, of type Name_Ref) in the
Source container.

         Read(Source,Ref);

We read one reference in from the Source container. This is a dispatching
call: the correct Read for the actual container will be called.

         if Ref /= null and then Ref.all'Length > 0 and then
Ref(Ref.all'First) /= '?' then

This just checks various conditions to ensure the name pointer (in Ref) is
usable, and not to be deleted (indicated by the leading '?').

            To_Upper(Ref.all);

Convert the string (pointed to by the pointer in Ref) to uppercase.

            Write(Target,Ref);

Write the pointer into the Target container. Again, this is a dispatching
call.

            N := Ref.all.First-1; -- in case string doesn't start at 1
            if Ref.all'Length >= 5 and then Ref(N+1..N+3) = "MAC" and then
Is_Letter(Ref(N+4)) then
               Write(Target, new String'("MC"&Ref(N+4..Ref.all'Last)));
            end if;

This is just a bit of messing about with the Macs. The important thing to
note is that another Write may be performed, thus achieving the effect of
insertion.

         else
            Ref := null; -- or maybe use Unchecked_Deallocation

The effect of deletion is achieved by simply not writing the pointer into
Target.

         end if;
      end loop;
   end Normalize_Names;

The usage of this procedure, in conjunction with a (concrete) list container
type (which we assume is derived from Sequence_Recorder), might be:

   package Name_Ref_Lists is new SCL.Lists.Unbounded(Name_Ref_Iteration);

Now we instantiate the package that will export a list type for use
(List_Type) wich is specialised for name pointers (type Name_Ref).

   subtype Name_List is Name_Ref_Lists.List_Type;

This just conveniently renames the exported list type.

   L1, L2: Name_List;

Here we declare two list variables.

   ... set up L1 with names

We will do something (not shown, but e.g. read a file) to read the names,
and put the pointers to them into L1.

   Rewrite(L2);

This prepares (and erases, if necessary) L2 for being written into.

   Restart(L1);

This prepares (and rewinds to the start, if necessary) L1 for being read
from.

   Normalize_Names(L1,L2);

We call the procedure. The actuals, L1 and L2, could have been of any
container type (provided they were both derived from Sequence_Recorder). In
this case, they happen to both be lists.

   Rewrite(L1);

This is just a simple way to erase L1.

   Restart(L2);

Get L2 ready to be read, for the next step in the overall processing
(whatever that might be).

I really hope this helps clarify things. The vital point is that the
procedure Normalize_Names can be used with any container type (derived from
Sequence_Recorder), rather than being permanently tied down to one container
type.

--
Best wishes,
Nick Roberts






^ permalink raw reply	[relevance 7%]

* Re: List container strawman
  @ 2001-11-10  1:48  8%                           ` Nick Roberts
    0 siblings, 1 reply; 162+ results
From: Nick Roberts @ 2001-11-10  1:48 UTC (permalink / raw)


I'm sorry, I'm throw one of classic spanners in the works here, but I'm
afraid I think you've got your approach horribly horribly wrong!

For a start, all this mularchy about insertion and deletion is just plain
silly! It really is. You don't need them, and shouldn't implement them. Yes,
really. Let me show you why.

Suppose you want to have a list of names (strings), and you want to
normalise them as follows:

(a) convert them all to uppercase;
(b) all beginning with "MACxy", where x is a letter, to have "MCxy" inserted
afterwards;
(c) all beginning with "?" to be deleted.

I'm going to frame the answer in terms of my own proposal, please forgive me
for that. The essential answer is that you don't keep a list of the strings,
but you keep a list of access values to them. You then simply build a new
list (of access values), and then delete the old one:

   with Ada.Characters.Handling; use Ada.Characters.Handling;
   ...
   type Name_Ref is access [all] String;
   package Name_Ref_Iteration is new Iteration(Name_Ref);

   procedure Normalize_Names (
      From: in out Name_Ref_Iteration.Sequence_Recorder'Class;
      Into: Name_Ref_Iteration.Sequence_Recorder'Class) is
      Ref: Name_Ref; N: Natural;
   begin
      Rewrite(Into); -- possibly redundant (possibly poor design, actually)
      Restart(From); -- ditto
      while not End_of_Data(From) loop
         Read(From,Ref);
         if Ref /= null and then Ref.all'Length > 0 and then
Ref(Ref.all'First) /= '?' then
            To_Upper(Ref.all);
            Write(Into,Ref);
            N := Ref.all.First-1; -- in case string doesn't start at 1
            if Ref.all'Length >= 5 and then Ref(N+1..N+3) = "MAC" and then
Is_Letter(Ref(N+4)) then
               Write(Into, new String'("MC"&Ref(N+4..Ref.all'Last)));
            end if;
         else
            Ref := null; -- or maybe use Unchecked_Deallocation
         end if;
      end loop;
      Rewrite(From); -- erases it (again, possibly wrong here)
      Restart(Into); -- again possibly redundant
   end Normalize_Names;

Note how this procedure can be passed parameters of ANY 'sequence recorder'
container type (instantiated on Name_Ref), not just lists. Supposing we
wanted to use a list container type:

   package Name_Ref_Lists is new xyz.Lists(Name_Ref_Iteration);
   subtype Name_List is Name_Ref_Lists.List_Type;
   L1, L2: Name_List;
   ... set up L1 with names
   Normalize_Names(L1,L2);

A note about the Restarts and Rewrites: they are probably better left
outside procedures such as this, in fact. I have quietly deleted oddities
like null pointers: a real program should probably raise exceptions.

Trust me, guys, this approach is majorly better in every way (easier to use,
easier to read & understand, easier to implement, more memory efficient,
more speed efficient) than messing around with inserts and deletes, for the
vast majority of situations.

I know I can seem pompous, overbearing, etc., etc., especially about this
subject, but it pains me to see you going so far astray, and spending so
much time arguing about features that you don't need anyway!

It also gives me another opportunity to demonstrate the idea of having a set
of abstract container types, upon which operations (such as Normalize_Names)
can be hung, thus freeing you of: (1) having to worry about which container
type to use when writing the procedure; (2) the procedure shackling you to
one particular container type. Do you turn away from this Utopia? ;-)

--
Best wishes,
Nick Roberts






^ permalink raw reply	[relevance 8%]

* Re: Text_IO on WinNT  problem
  2001-09-25 18:48  9%   ` Richard Riehle
@ 2001-09-25 20:07  0%     ` David Starner
  0 siblings, 0 replies; 162+ results
From: David Starner @ 2001-09-25 20:07 UTC (permalink / raw)


On Tue, 25 Sep 2001 11:48:04 -0700, Richard Riehle <richard@adaworks.com> wrote:
> David Starner wrote:
> 
>> Looking at the GNAT Reference manual, under Wide_Text_IO, there's no way
>> to load it in as Wide_Character. There's no standard way to handle it
>> with Text_IO - this seems like a fairly unusual case - but you could
>> always try reading them in one by one and discarding half of them.
> 
> See Ada.Characters.Handling,  ALRM, Annex A.3.2
> 
>       function To_Character(Item : in Wide_Character;
>                                            Substitute : in Character := ' ')
> return Character;

As I pointed out, GNAT can't read in UTF-16LE using Wide_Text_IO. The 
problem is getting them into the program, not converting them to the 
right form.

-- 
David Starner - dstarner98@aasaa.ofe.org
Pointless website: http://dvdeug.dhis.org
When the aliens come, when the deathrays hum, when the bombers bomb,
we'll still be freakin' friends. - "Freakin' Friends"



^ permalink raw reply	[relevance 0%]

* Re: Text_IO on WinNT  problem
  @ 2001-09-25 18:48  9%   ` Richard Riehle
  2001-09-25 20:07  0%     ` David Starner
  0 siblings, 1 reply; 162+ results
From: Richard Riehle @ 2001-09-25 18:48 UTC (permalink / raw)


David Starner wrote:

> Looking at the GNAT Reference manual, under Wide_Text_IO, there's no way
> to load it in as Wide_Character. There's no standard way to handle it
> with Text_IO - this seems like a fairly unusual case - but you could
> always try reading them in one by one and discarding half of them.

See Ada.Characters.Handling,  ALRM, Annex A.3.2

      function To_Character(Item : in Wide_Character;
                                           Substitute : in Character := ' ')
return Character;

and other useful functions for this kind of thing.

Richard Riehle
richard@adaworks.com






^ permalink raw reply	[relevance 9%]

* Re: Hebrew language character set
  @ 2001-04-05 18:41 10%           ` Paul Storm
  0 siblings, 0 replies; 162+ results
From: Paul Storm @ 2001-04-05 18:41 UTC (permalink / raw)


I modified my program as follows, [begin code]

with Ada.Characters.Handling; use Ada.Characters.Handling;
with Ada.Wide_Text_IO; use Ada.Wide_Text_IO;

procedure aleph is
begin
  Ada.Wide_Text_IO.Put (Item => Wide_Character'Val(16#0590#));
end aleph;

[end code]

Now I get the following results,

D:\TEMP>gnatmake -gnatW8 aleph.adb
gcc -c -gnatW8 aleph.adb
gnatbind -x aleph.ali
gnatlink aleph.ali

D:\TEMP>aleph.exe
+�

I made some mistake in coding my character in decimal instead of hex??

I found this in the GNAT User's Guide, btw,

-gnatWe 
Specify the method of encoding for wide characters. e is one of the
following: 
h Hex encoding (brackets coding also recognized) 
u Upper half encoding (brackets encoding also recognized) 
s Shift/JIS encoding (brackets encoding also recognized) 
e EUC encoding (brackets encoding also recognized) 
8 UTF-8 encoding (brackets encoding also recognized) 
b Brackets encoding only (default value) 

For full details on the these encoding methods see See section Wide
Character Encodings. Note that brackets coding is always accepted, even
if one of the other options is specified, so for example -gnatW8
specifies that both brackets and UTF-8 encodings will be recognized. The
units that are with'ed directly or indirectly will be scanned using the
specified representation scheme, and so if one of the non-brackets
scheme is used, it must be used consistently throughout the program.
However, since brackets encoding is always recognized, it may be
conveniently used in standard libraries, allowing these libraries to be
used with any of the available coding schemes. scheme. If no -gnatW?
parameter is present, then the default representation is Brackets
encoding only. Note that the wide character representation that is
specified (explicitly or by default) for the main program also acts as
the default encoding used for Wide_Text_IO files if not specifically
overridden by a WCEM form parameter. 

Paul Storm



^ permalink raw reply	[relevance 10%]

* Re: Hebrew language character set
  2001-04-04 21:36 12%   ` Paul Storm
  2001-04-05  3:03  0%     ` David Starner
  2001-04-05  6:42  0%     ` Ehud Lamm
@ 2001-04-05 13:11  0%     ` Jean-Marc Bourguet
    2 siblings, 1 reply; 162+ results
From: Jean-Marc Bourguet @ 2001-04-05 13:11 UTC (permalink / raw)


Paul Storm wrote:
> 
> For those that are interested, I produce code that (I think) produces
> a Hebrew character.  Here is the code:
> 
> with Ada.Characters.Handling; use Ada.Characters.Handling;
> with Ada.Wide_Text_IO; use Ada.Wide_Text_IO;
> 
> procedure aleph is
> begin
>   Ada.Wide_Text_IO.Put (Item => Wide_Character'Val(1488));
> end aleph;
> 
> end of code
> 
> Here is the output.
> 
> ["05D0"]
> 
> end of output
> 
> 1448 decimal is 05D0 hexidecimal.
> 
> I said think produces.  I am thinking that my display showed the
> character as a code due to the lack of support for that character
> (set) on my system.  Can anyone confirm this for me?  Does that make
> sense?

I think this is one of the way gnat produces (and accept) wide
character.  You should be able to choose the format you want with the
FORM parameter.  Check the reference manual, there is a whole section on
wide characters.

-- Jean-Marc



^ permalink raw reply	[relevance 0%]

* Re: Hebrew language character set
  2001-04-04 21:36 12%   ` Paul Storm
  2001-04-05  3:03  0%     ` David Starner
@ 2001-04-05  6:42  0%     ` Ehud Lamm
  2001-04-05 13:11  0%     ` Jean-Marc Bourguet
  2 siblings, 0 replies; 162+ results
From: Ehud Lamm @ 2001-04-05  6:42 UTC (permalink / raw)


Paul Storm <paul.a.storm@lmco.com> wrote in message
news:3ACB85DF.9E6DBD03@lmco.com...
> For those that are interested, I produce code that (I think) produces
> a Hebrew character.  Here is the code:
>
> with Ada.Characters.Handling; use Ada.Characters.Handling;
> with Ada.Wide_Text_IO; use Ada.Wide_Text_IO;
>
> procedure aleph is
> begin
>   Ada.Wide_Text_IO.Put (Item => Wide_Character'Val(1488));
> end aleph;
>
> end of code
>
> Here is the output.
>
> ["05D0"]
>
> end of output
>

That's the output I get (the string literal, not the Hebrew echaracter) on
my PC, which has Hebrew support, Hebre enable windows etc. (I am in Israel).


Ehud





^ permalink raw reply	[relevance 0%]

* Re: Hebrew language character set
  2001-04-04 21:36 12%   ` Paul Storm
@ 2001-04-05  3:03  0%     ` David Starner
  2001-04-05  6:42  0%     ` Ehud Lamm
  2001-04-05 13:11  0%     ` Jean-Marc Bourguet
  2 siblings, 0 replies; 162+ results
From: David Starner @ 2001-04-05  3:03 UTC (permalink / raw)


On Wed, 04 Apr 2001 13:36:47 -0800, Paul Storm <paul.a.storm@lmco.com> wrote:
>For those that are interested, I produce code that (I think) produces
>a Hebrew character.  Here is the code:
>
>with Ada.Characters.Handling; use Ada.Characters.Handling;
>with Ada.Wide_Text_IO; use Ada.Wide_Text_IO;
>
>procedure aleph is
>begin
>  Ada.Wide_Text_IO.Put (Item => Wide_Character'Val(1488));
>end aleph;
>
>end of code
>
>Here is the output.
>
>["05D0"]
>
>end of output
>
>1448 decimal is 05D0 hexidecimal.
>
>I said think produces.  I am thinking that my display showed the
>character as a code due to the lack of support for that character
>(set) on my system.  Can anyone confirm this for me?  Does that make
>sense?

Nope. It looks like your Ada system uses a ["abcd"] encoding by
default, since it has no way to know what the correct encoding
should be. If you're using GNAT, the GNAT RM has a section about
wide text IO and changing it to output in different encodings.
If you have a recent version (>4.0) of XFree86, you can run 
xterm -u8 which will properly understand UTF-8; otherwise, there's
probably no way to get readable Hebrew output.

-- 
David Starner - dstarner98@aasaa.ofe.org
Pointless website: http://dvdeug.dhis.org
"I don't care if Bill personally has my name and reads my email and 
laughs at me. In fact, I'd be rather honored." - Joseph_Greg



^ permalink raw reply	[relevance 0%]

* Re: Hebrew language character set
  @ 2001-04-04 21:36 12%   ` Paul Storm
  2001-04-05  3:03  0%     ` David Starner
                       ` (2 more replies)
  0 siblings, 3 replies; 162+ results
From: Paul Storm @ 2001-04-04 21:36 UTC (permalink / raw)


For those that are interested, I produce code that (I think) produces
a Hebrew character.  Here is the code:

with Ada.Characters.Handling; use Ada.Characters.Handling;
with Ada.Wide_Text_IO; use Ada.Wide_Text_IO;

procedure aleph is
begin
  Ada.Wide_Text_IO.Put (Item => Wide_Character'Val(1488));
end aleph;

end of code

Here is the output.

["05D0"]

end of output

1448 decimal is 05D0 hexidecimal.

I said think produces.  I am thinking that my display showed the
character as a code due to the lack of support for that character
(set) on my system.  Can anyone confirm this for me?  Does that make
sense?



^ permalink raw reply	[relevance 12%]

* RE: Ada95 tutorials with sample code.
@ 2001-03-06 23:58 10% Beard, Frank
  0 siblings, 0 replies; 162+ results
From: Beard, Frank @ 2001-03-06 23:58 UTC (permalink / raw)
  To: 'comp.lang.ada@ada.eu.org'

Oops!  Forgot to move a statement after cut-and-paste.


with Ada.Characters.Handling;  use Ada.Characters.Handling;

procedure Xyz is

  opt_is : character := ' ';

begin

  while opt_is /= 'V' and then opt_is /= 'A' loop
    Put( opt_prompt );
    NEW_LINE;
    Ada.Text_IO.Put_Line( "Please enter either a 'V' or an 'A' );
    Get( opt_is );
    opt_is := To_Upper(opt_is);
  end loop;

end Xyz;


-----Original Message-----
From: mcdoobie [mailto:chainsaw.two.thousand@nospam.dot.home.dot.com]
Sent: Tuesday, March 06, 2001 5:39 PM
To: comp.lang.ada@ada.eu.org
Subject: Re: Ada95 tutorials with sample code.


I'm definitely gonna check it out, in addition to the www.mcondic.com
website mentioned in another post.

Now I have a quick question. I'm using a loop to test for the existence
of a certain variable, but I'm not quite sure how to go about it.  Heres
what it looks like right now...

while opt_is not 'V' or 'A' loop
	Put( opt_prompt );
	NEW_LINE;
	Ada.Text_IO.Put_Line( "Please enter either a 'V' or an 'A' );
	Get( opt_is );
end loop;

Now, I'm not sure what I'm supposed to be doing at the start of the loop.
 Any help woiuld be appreciated.

Thanks.

McDoobie
mcdoobie@hotmail.com
_______________________________________________
comp.lang.ada mailing list
comp.lang.ada@ada.eu.org
http://ada.eu.org/mailman/listinfo/comp.lang.ada

_______________________________________________
comp.lang.ada mailing list
comp.lang.ada@ada.eu.org
http://ada.eu.org/mailman/listinfo/comp.lang.ada




^ permalink raw reply	[relevance 10%]

* RE: Ada95 tutorials with sample code.
@ 2001-03-06 23:51 10% Beard, Frank
  0 siblings, 0 replies; 162+ results
From: Beard, Frank @ 2001-03-06 23:51 UTC (permalink / raw)
  To: 'comp.lang.ada@ada.eu.org'

Without caring or trying to figure out why,
to answer what I think your question is:

with Ada.Characters.Handling;  use Ada.Characters.Handling;

procedure Xyz is

  opt_is : character := ' ';

begin

  opt_is := To_Upper(opt_is);
  while opt_is /= 'V' and then opt_is /= 'A' loop
    Put( opt_prompt );
    NEW_LINE;
    Ada.Text_IO.Put_Line( "Please enter either a 'V' or an 'A' );
    Get( opt_is );
  end loop;

end Xyz;


-----Original Message-----
From: mcdoobie [mailto:chainsaw.two.thousand@nospam.dot.home.dot.com]
Sent: Tuesday, March 06, 2001 5:39 PM
To: comp.lang.ada@ada.eu.org
Subject: Re: Ada95 tutorials with sample code.


I'm definitely gonna check it out, in addition to the www.mcondic.com
website mentioned in another post.

Now I have a quick question. I'm using a loop to test for the existence
of a certain variable, but I'm not quite sure how to go about it.  Heres
what it looks like right now...

while opt_is not 'V' or 'A' loop
	Put( opt_prompt );
	NEW_LINE;
	Ada.Text_IO.Put_Line( "Please enter either a 'V' or an 'A' );
	Get( opt_is );
end loop;

Now, I'm not sure what I'm supposed to be doing at the start of the loop.
 Any help woiuld be appreciated.

Thanks.

McDoobie
mcdoobie@hotmail.com
_______________________________________________
comp.lang.ada mailing list
comp.lang.ada@ada.eu.org
http://ada.eu.org/mailman/listinfo/comp.lang.ada




^ permalink raw reply	[relevance 10%]

* Re: logical operations in Ada
  2001-02-13  3:40  9%   ` Freelancer
  2001-02-13  6:43  0%     ` Dale Stanbrough
  2001-02-13 11:54  0%     ` Jeff Creem
@ 2001-02-13 17:44  0%     ` David C. Hoos, Sr.
  2 siblings, 0 replies; 162+ results
From: David C. Hoos, Sr. @ 2001-02-13 17:44 UTC (permalink / raw)


Here's an example of bit-wise operations on modular types
with conversions to and from characters to do what you
said you wanted to do.
-- begin source code --
with Ada.Text_IO;
with Ada.Unchecked_Conversion;
with Interfaces;
procedure Bit_Ops
is
   function To_Character is new Ada.Unchecked_Conversion
     (Source => Interfaces.Unsigned_8,
      Target => Character);
   function To_Unsigned_8 is new Ada.Unchecked_Conversion
     (Source => Character,
      Target => Interfaces.Unsigned_8);
   Mask : constant Interfaces.Unsigned_8 := 2#1101_1111#;
   use type Interfaces.Unsigned_8;
begin
   for C in CHARACTER'('a') .. CHARACTER'('z') loop
      Ada.Text_IO.Put
        (To_Character (Mask and To_Unsigned_8 (C)));
   end loop;
   Ada.Text_IO.New_Line;
end Bit_Ops;
--end source code --
"Freelancer" <freelancer_2001@hotmail.com> wrote in message
news:512i6.239390$JT5.8526649@news20.bellglobal.com...
> I am well aware of ada.characters.handling. That isn't my objective.
> As you said, I am trying to fiddle with bits. How to do this in Ada?
>
> A small example would be greatly appreciated. :)
> Thank you for your references though.
>
>
> "Florian Weimer" <fw@deneb.enyo.de> wrote in message
> news:87pugp2x4p.fsf@deneb.enyo.de...
> > "Freelancer" <freelancer_2001@hotmail.com> writes:
> >
> > > Could anyone tell me how to do basic operation on ASCii characters?
> >
> > Why do you think these are 'logical operations'?
> >
> > > More specifically, I would like to do a to_upper function for example
:
> > >
> > > 'a' becomes 'A' ( a to_upper function)
> >
> > Do you need a function for case conversion, or do you want to do
> > fiddle with bits?  Have a look at the package Ada.Characters.Handling
> > or modular types (for which logical operations are defined).
> >
> > > Is it possible to define a block of assembly language code in an ada
> > > program as well?
> >
> > Yes, see your compiler documentation on 'Machine Code Insertions'.
>
>





^ permalink raw reply	[relevance 0%]

* Re: logical operations in Ada
  2001-02-13  3:40  9%   ` Freelancer
  2001-02-13  6:43  0%     ` Dale Stanbrough
@ 2001-02-13 11:54  0%     ` Jeff Creem
  2001-02-13 17:44  0%     ` David C. Hoos, Sr.
  2 siblings, 0 replies; 162+ results
From: Jeff Creem @ 2001-02-13 11:54 UTC (permalink / raw)


Note that the reason people keep pointing out alternatives is that more
often than
not when someone asks how to fiddle bits it is because that is the way they
would
attack the problem in a different language. This is not always the best way
to do it in
Ada so if you want a more helpful answer, try giving an example that more
closely matches
your actual problem. (Perhaps this one did in which case the other advice
people gave was
correct).



"Freelancer" <freelancer_2001@hotmail.com> wrote in message
news:512i6.239390$JT5.8526649@news20.bellglobal.com...
> I am well aware of ada.characters.handling. That isn't my objective.
> As you said, I am trying to fiddle with bits. How to do this in Ada?
>
> A small example would be greatly appreciated. :)
> Thank you for your references though.
>
>






^ permalink raw reply	[relevance 0%]

* Re: logical operations in Ada
  2001-02-13  3:40  9%   ` Freelancer
@ 2001-02-13  6:43  0%     ` Dale Stanbrough
  2001-02-13 11:54  0%     ` Jeff Creem
  2001-02-13 17:44  0%     ` David C. Hoos, Sr.
  2 siblings, 0 replies; 162+ results
From: Dale Stanbrough @ 2001-02-13  6:43 UTC (permalink / raw)


Freelancer wrote:

> I am well aware of ada.characters.handling. That isn't my objective.
> As you said, I am trying to fiddle with bits. How to do this in Ada?
> 
> A small example would be greatly appreciated. :)
> Thank you for your references though.

You can use the appropriate routines, either by converting to 
an unsigned type, or to a packed boolean type.


e.g.

   type Bit_Array is array (natural range <>) of Boolean;

   subtype Bit_Array_32 is Bit_Array (0..31);
   pragma Pack (Bit_Array_32);


   X : Bit_Array_32;
   X (1) := True;
   X := not X;
   X := X xor X;

or...

   Item : Interfaces.Unsigned_16;

   Item := Item xor 2#0000_0000_1111_1010#;


You can use Unchecked_Conversion to convert back and forth
b/w your favourite type to do an even wider range of bit 
fiddling.


Dale



^ permalink raw reply	[relevance 0%]

* Re: logical operations in Ada
  2001-02-11 12:59  9% ` Florian Weimer
@ 2001-02-13  3:40  9%   ` Freelancer
  2001-02-13  6:43  0%     ` Dale Stanbrough
                       ` (2 more replies)
  0 siblings, 3 replies; 162+ results
From: Freelancer @ 2001-02-13  3:40 UTC (permalink / raw)


I am well aware of ada.characters.handling. That isn't my objective.
As you said, I am trying to fiddle with bits. How to do this in Ada?

A small example would be greatly appreciated. :)
Thank you for your references though.


"Florian Weimer" <fw@deneb.enyo.de> wrote in message
news:87pugp2x4p.fsf@deneb.enyo.de...
> "Freelancer" <freelancer_2001@hotmail.com> writes:
>
> > Could anyone tell me how to do basic operation on ASCii characters?
>
> Why do you think these are 'logical operations'?
>
> > More specifically, I would like to do a to_upper function for example :
> >
> > 'a' becomes 'A' ( a to_upper function)
>
> Do you need a function for case conversion, or do you want to do
> fiddle with bits?  Have a look at the package Ada.Characters.Handling
> or modular types (for which logical operations are defined).
>
> > Is it possible to define a block of assembly language code in an ada
> > program as well?
>
> Yes, see your compiler documentation on 'Machine Code Insertions'.





^ permalink raw reply	[relevance 9%]

* Re: logical operations in Ada
    2001-02-11 12:24  9% ` David C. Hoos, Sr.
@ 2001-02-11 12:59  9% ` Florian Weimer
  2001-02-13  3:40  9%   ` Freelancer
  1 sibling, 1 reply; 162+ results
From: Florian Weimer @ 2001-02-11 12:59 UTC (permalink / raw)


"Freelancer" <freelancer_2001@hotmail.com> writes:

> Could anyone tell me how to do basic operation on ASCii characters?

Why do you think these are 'logical operations'?

> More specifically, I would like to do a to_upper function for example :
> 
> 'a' becomes 'A' ( a to_upper function)

Do you need a function for case conversion, or do you want to do
fiddle with bits?  Have a look at the package Ada.Characters.Handling
or modular types (for which logical operations are defined).

> Is it possible to define a block of assembly language code in an ada
> program as well?

Yes, see your compiler documentation on 'Machine Code Insertions'.



^ permalink raw reply	[relevance 9%]

* Re: logical operations in Ada
  @ 2001-02-11 12:24  9% ` David C. Hoos, Sr.
  2001-02-11 12:59  9% ` Florian Weimer
  1 sibling, 0 replies; 162+ results
From: David C. Hoos, Sr. @ 2001-02-11 12:24 UTC (permalink / raw)


It is not necessary to use bit-wise logical operations to
implement a To_Upper function, since that operation
is defined by the language in the package
Ada.Characters.Handling, defined in section A.3.2 of
the Ada Reference Manual.

Logical operations are predefined for Boolean types,
modular types, and one-dimensional arrays of
Boolean types -- see section 4.5.1

Section 13.8 of the manual describes what are termed
Machine Code Insertions in Ada.  However, Ada is
so powerful and flexible, that Machine Code Insertions
are rarely necessary.


"Freelancer" <freelancer_2001@hotmail.com> wrote in message
news:Rhth6.92238$Pm2.1876497@news20.bellglobal.com...
> Could anyone tell me how to do basic operation on ASCii characters?
>
> More specifically, I would like to do a to_upper function for example :
>
> 'a' becomes 'A' ( a to_upper function)
>
> 1101 1111 "and" 0110 0001 becomes 0100 0001 (ASCii 'a' becomes ASCII 'A')
> ________________________________________
>
> I would like to do a bit 'or' or 'and' or 'xor' operations, but I don't
know
> how...
>
> Is it possible to define a block of assembly language code in an ada
program
> as well?
>
> Thanks in advance.
>
>




^ permalink raw reply	[relevance 9%]

* Optimization Question
@ 2001-01-22  0:05 11% dvdeug
  0 siblings, 0 replies; 162+ results
From: dvdeug @ 2001-01-22  0:05 UTC (permalink / raw)


I'm trying to write a program similar to the Unix utility strings, as my
copy of strings refuses to run a 17GB file. It seems to work, but it's
about 10x slower than strings, and rough calculations puts running time
on that 17GB file at 10 hours. I'm running the woody Debian version of
GNAT (3.13) on i686-linux-gnu, and I compiled the program with gnatmake
-g -gnatwa -gnatpn -Wall -W -O3 strings.adb. Is there anything I've
missed that speed this program a lot? (It's been run through gcov, so
the numbers up front are execution counts.)


		with Ada.Characters.Handling; use Ada.Characters.Handling;
		with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
		with Ada.Sequential_IO;
		with Ada.Command_Line; use Ada.Command_Line;
		with Ada.Text_IO;

           2    procedure Strings is

           1       type Byte is mod 2 ** 8;
		   package Byte_IO is new Ada.Sequential_IO (Byte);
		   use Byte_IO;

       56710       function String_Charp (A : Character) return Boolean
is
		   begin
       56710          return Is_ISO_646 (A) and then
		        (Is_Graphic (A) or else A = HT or else A = LF or else A = CR);
		   end String_Charp;
		   pragma Inline (String_Charp);

           1       Binary_File : File_Type;
           1       Letter_Buffer : String (1 .. 4);
		   subtype Buffer_Size is Integer range 0 .. 4;
           1       Letters_Found : Buffer_Size := 0;
           1       Current_Char : Byte;

           1       Seperating_String : constant String := (LF, NUL);

		begin
           1       if Argument_Count /= 1 then
      ######          Set_Exit_Status (1);
      ######          Ada.Text_IO.Put ("One file name only!");
      ######          return;
		   end if;

           1       Open (Binary_File, In_File, Argument(1));
       56711       loop
       56711          Read (Binary_File, Current_Char);

       56710          if String_Charp (Character'Val (Current_Char))
then
       29610             if Letters_Found < 4 then
        8453                Letters_Found := Letters_Found + 1;
        8453                Letter_Buffer (Letters_Found) :=
Character'Val (Current_Char);
        8453                if Letters_Found = 4 then
         916                   Ada.Text_IO.Put (Letter_Buffer);
		            end if;
		         else
       21157                Ada.Text_IO.Put (Character'Val
(Current_Char));
		         end if;
		      else
       27100             if Letters_Found = 4 then
         916                Ada.Text_IO.Put (Seperating_String);
		         end if;
       27100             Letters_Found := 0;
		      end if;
		   end loop;
      ######       Ada.Text_IO.Put ("Invalid end!");
      ######       Set_Exit_Status (2);
		exception
           1       when End_Error =>
           1          Close (Binary_File);
      ######       when others =>
      ######          raise;
		end Strings;



--
David Starner - dstarner98@aasaa.ofe.org


Sent via Deja.com
http://www.deja.com/



^ permalink raw reply	[relevance 11%]

* Re: Strings
  @ 2000-05-27  0:00  9% ` David C. Hoos, Sr.
  0 siblings, 0 replies; 162+ results
From: David C. Hoos, Sr. @ 2000-05-27  0:00 UTC (permalink / raw)



Karlene <kejohnso@student.ecu.edu.au> wrote in message
news:8gntbr$mei$2@news.cowan.edu.au...
> How can you validate a string (eg a name of a person) to check that it
only
> contains characters, not integers?  I have tried exceptions in my program,
> but it dosent seem to cover it.
>
Look at the character classification functions in the package
Ada.Characters.Handling.







^ permalink raw reply	[relevance 9%]

* Re: Ada and Literate Programming
  @ 2000-05-10  0:00 11%   ` Georg Bauhaus
  0 siblings, 0 replies; 162+ results
From: Georg Bauhaus @ 2000-05-10  0:00 UTC (permalink / raw)


Robert Dewar (robert_dewar@my-deja.com) wrote:

: Seeing as the substance of literate programming is very little
: more than writing code that is properly documented,

Well some people in c.l.literate would strongly object.
Noweb, by default, produces no pretty printing of source lines,
though you can plug in a filter. But the main points of LP have
often been said to be these:

- a way of reordering pieces of code according to the way you
  prefer thinking about them, not in the sequence the computer
  needs its sources, without using subprograms.
  (much of this can be done using declare and pragma Inline in Ada,
  I suppose)

- automatic and semiautomatic indexing of identifiers or anything
  you wish.

If the compiler supports repeated [[#line]] directives, in the Ada case
repeated occurences of [[pragma Source_Reference]] in one source file,
working with WEBs can be fun :)

@ An ad hoc scrambled eggs non-exciting example of noweb code, hardly working
at best, just to give an impression. Here is the main routine, having some
vague similarities with a FSM, hobbyist's work, mind you.
(If you are reading the WEB sources: Note that [[<<]] does not introduce
Ada labels.)
<<test.adb>>=
<<with some used units>>
procedure Test is
   Symbol: Character;  -- one symbol from input
begin
   loop
      <<read a symbol and switch state>>
   end loop;
end Test;

@ Now read [[input symbols]], one by one, and according to whether a
symbol is a digit, a letter, or something else, go on and further
distinguish what needs to be done for each character in its category.
<<read a symbol and switch state>>=
Text_IO.Get(Symbol);
if Is_Digit(Symbol) then
   <<cases for digits>>
elsif Is_Letter(Symbol) then
   <<cases for letters>>
else
   <<cases for other characters>>
end if;

@ You are maybe thinking about digits already (because they appear
first in the above conditional), but first, I have to tell you
about letters, because then some things about digits will become
clear more easily.

Characters are categorized to be vowels, consonants, punctuation,
candidates for the start of a sentecnce, ...
<<cases for letters>>=
case Symbol is
   when 'a' .. 'z' =>
      -- ...
      null;
   when 'A'|'E'|'I'|'O'|'U' =>
      -- ...
      null;
   when '.'|',' =>
      -- ...
      null;
   when others =>
      -- ...
      raise Programmer_s_Error;
end case;

@ So, here is the promised section about digits.
Digits can either be [[< 5]] or otherwise [[< 9]] ...
In that case ...
<<cases for digits>>=
case Symbol is
   when '0'|'1'|'2'|'3'|'4' =>
      -- ...
      null;
   when '5'|'6'|'7'|'8'|'9' =>
      -- ...
      null;
   when others =>
      -- ...
      raise Programmer_s_Error;
end case;

@ Some symbols remain. Each of these has a special meaning.
For example, [['*']] introduces a comment iff it is the
first character on a line,...
<<cases for other characters>>=
  -- ...
  null;

@ Maybe unexpectedly, the list of units this program needs, appears in
The End. :)
<<with some used units>>=
with Ada.Characters.Handling, Ada.Text_IO;
use Ada.Characters.Handling, Ada;

><snip><
Now here is the same untangled, i.e. with original comments included.
Note that this is not what you would work with.

-- An ad hoc scrambled eggs non-exciting example of noweb code, hardly working
-- at best, just to give an impression. Here is the main routine, having some
-- vague similarities with a FSM, hobbyist's work, mind you.
-- (If you are reading the WEB sources: Note that [[<<]] does not introduce
-- Ada labels.)
--
-- <test.adb>=
-- Maybe unexpectedly, the list of units this program needs, appears in
-- The End. :)
--
-- <with some used units>=
with Ada.Characters.Handling, Ada.Text_IO;
use Ada.Characters.Handling, Ada;
procedure Test is
   Symbol: Character;  -- one symbol from input
begin
   loop
      -- Now read [[input symbols]], one by one, and according to whether a
      -- symbol is a digit, a letter, or something else, go on and further
      -- distinguish what needs to be done for each character in its category.
      --
      -- <read a symbol and switch state>=
      Text_IO.Get(Symbol);
      if Is_Digit(Symbol) then
         -- So, here is the promised section about digits.
         -- Digits can either be [[< 5]] or otherwise [[< 9]] ...
         -- In that case ...
         --
         -- <cases for digits>=
         case Symbol is
            when '0'|'1'|'2'|'3'|'4' =>
               -- ...
               null;
            when '5'|'6'|'7'|'8'|'9' =>
               -- ...
               null;
            when others =>
               -- ...
               raise Programmer_s_Error;
         end case;

      elsif Is_Letter(Symbol) then
         -- You are maybe thinking about digits already (because they appear
         -- first in the above conditional), but first, I have to tell you
         -- about letters, because then some things about digits will become
         -- clear more easily.
         --
         -- Characters are categorized to be vowels, consonants, punctuation,
         -- candidates for the start of a sentecnce, ...
         --
         -- <cases for letters>=
         case Symbol is
            when 'a' .. 'z' =>
               -- ...
               null;
            when 'A'|'E'|'I'|'O'|'U' =>
               -- ...
               null;
            when '.'|',' =>
               -- ...
               null;
            when others =>
               -- ...
               raise Programmer_s_Error;
         end case;

      else
         -- Some symbols remain. Each of these has a special meaning.
         -- For example, [['*']] introduces a comment iff it is the
         -- first character on a line,...
         --
         -- <cases for other characters>=
           -- ...
           null;

      end if;

   end loop;
end Test;

Hope this wasn't too long (though so much is missing ...;-).

-# Georg Bauhaus






^ permalink raw reply	[relevance 11%]

* Re: Exit Loop_Statement
  @ 2000-05-09  0:00  8% ` John English
  2000-05-09  0:00  0%   ` Robert Dewar
  0 siblings, 1 reply; 162+ results
From: John English @ 2000-05-09  0:00 UTC (permalink / raw)


David Freshwater wrote:
> procedure Buy is
> begin
>   [...snip...]
>    Any_File :
>       Loop
> 
>            Put("Please enter the clients name : ");
>           Get_Line(Item => Any (I + 1).Clients, Last => P_L_C);
>           Put("Olympic Sponsor? (Enter True or False) : ");
>           Boolean_Io.Get(Sponsor);
>           exit Any_File when Any(I+1).Clients(1..3) = "Stop";

That should be Clients(1..4), right?

You should convert to e.g. lower case if you want case insensitivity:
  if Ada.Characters.Handling.To_Lower(Clients(1..4)) = "stop" then ...

>     [...snip...]
>     end loop Any_File;
> 
>     exception
> 
>    when DATA_ERROR|NUMERIC_ERROR =>

You should really use Constraint_Error instead of Numeric_Error (although
they both mean the same thing).

Also, don't you want the exception to be handled inside the loop so the
user can re-enter the data? At the moment, it'll print an error message,
call Save_File, and then you're at the end of the program...

Try something like this:

   loop
     begin
       ...
     exception
       ...
     end;
   end loop;

Your exit statement will get you out of the loop; an exception will be
handled by the exception handler inside the loop, so after you've handled
the exception you'll go round the loop again.
HTH,

-----------------------------------------------------------------
 John English              | mailto:je@brighton.ac.uk
 Senior Lecturer           | http://www.it.bton.ac.uk/staff/je
 Dept. of Computing        | ** NON-PROFIT CD FOR CS STUDENTS **
 University of Brighton    |    -- see http://burks.bton.ac.uk
-----------------------------------------------------------------




^ permalink raw reply	[relevance 8%]

* Re: Exit Loop_Statement
  2000-05-09  0:00  8% ` John English
@ 2000-05-09  0:00  0%   ` Robert Dewar
  2000-05-09  0:00  0%     ` David Freshwater
  0 siblings, 1 reply; 162+ results
From: Robert Dewar @ 2000-05-09  0:00 UTC (permalink / raw)


In article <3917C83E.D088C4DF@bton.ac.uk>,
  John English <je@bton.ac.uk> wrote:
> That should be Clients(1..4), right?

Well yes, of course, and of course we all saw that. But don't
you think it is instructive for people to find a bug like that
for themselves. I preferred the previous post which gave a
useful pointed hint (think about whether this will ever be
true), to this one that provides the correction directly.

A hard part of computer programming is figuring out why what
you have written does not work, and learning to be careful
and avoid writing such things in the first place. Practice
is really essential in this task. The purpose of assignments
is to provide this practice, and you have to be careful that
in an attempt to be helpful you do not bypass this very
important function.

> You should convert to e.g. lower case if you want case
> insensitivity:
>   if Ada.Characters.Handling.To_Lower(Clients(1..4)) = "stop"
> then ...

Again, I would point to the reference for this routine, rather
than give the exact code, which the student can then just cut
and paste without any understanding.




Sent via Deja.com http://www.deja.com/
Before you buy.




^ permalink raw reply	[relevance 0%]

* Re: Exit Loop_Statement
  2000-05-09  0:00  0%   ` Robert Dewar
@ 2000-05-09  0:00  0%     ` David Freshwater
  0 siblings, 0 replies; 162+ results
From: David Freshwater @ 2000-05-09  0:00 UTC (permalink / raw)


Hi,
   Thanks for the help....I had picked up the (1..3) error.
I actually have written 2 programs for this assignment. One works well, the
other is a different approach to what we have been taught. Let me point out
that I am an external student studying this, which makes it hard as I don't
have any one to bounce ideas off or get any helpful input. So any help
whether pointers or snippets of code are really appreciated.
I do understand the need to do this by myself but it just gets frustrating.

David
Robert Dewar <robert_dewar@my-deja.com> wrote in message
news:8f91ps$vb3$1@nnrp1.deja.com...
> In article <3917C83E.D088C4DF@bton.ac.uk>,
>   John English <je@bton.ac.uk> wrote:
> > That should be Clients(1..4), right?
>
> Well yes, of course, and of course we all saw that. But don't
> you think it is instructive for people to find a bug like that
> for themselves. I preferred the previous post which gave a
> useful pointed hint (think about whether this will ever be
> true), to this one that provides the correction directly.
>
> A hard part of computer programming is figuring out why what
> you have written does not work, and learning to be careful
> and avoid writing such things in the first place. Practice
> is really essential in this task. The purpose of assignments
> is to provide this practice, and you have to be careful that
> in an attempt to be helpful you do not bypass this very
> important function.
>
> > You should convert to e.g. lower case if you want case
> > insensitivity:
> >   if Ada.Characters.Handling.To_Lower(Clients(1..4)) = "stop"
> > then ...
>
> Again, I would point to the reference for this routine, rather
> than give the exact code, which the student can then just cut
> and paste without any understanding.
>
>
>
>
> Sent via Deja.com http://www.deja.com/
> Before you buy.






^ permalink raw reply	[relevance 0%]

* Re: Character Handling
  2000-04-30  0:00 13% Character Handling Robert Stephen Breen
  2000-04-30  0:00  8% ` Marin D. Condic
@ 2000-04-30  0:00 14% ` DuckE
  2000-04-30  0:00  0% ` Ken Garlington
  2 siblings, 0 replies; 162+ results
From: DuckE @ 2000-04-30  0:00 UTC (permalink / raw)


The function To_Upper is a function that takes a string as an argument and
returns a string.  Here's a working sample program that uses
Ada.Characters.Handling.To_Upper:

-- == Start of file: DemoHandling.adb =========
WITH Ada.Characters.Handling;

WITH Ada.Text_Io;

PROCEDURE DemoHandling IS

PACKAGE Text_Io RENAMES Ada.Text_Io;

PACKAGE Handling RENAMES Ada.Characters.Handling;

inputText : String(1..80);

lastIndex : Natural;

BEGIN

Text_Io.Put( "Enter Text > " );

Text_Io.Get_Line( inputText, lastIndex );

DECLARE

ucText : String := Handling.To_Upper( inputText(1..lastIndex) );

lcText : String := Handling.To_Lower( inputText(1..lastIndex) );

BEGIN

Text_Io.Put_Line( "Upper case: " & ucText );

Text_Io.Put_Line( "Lower case: " & lcText );

END;

END DemoHandling;

--========End of File: DemoHandling.adb=============

I hope this helps,
SteveD

"Robert Stephen Breen" <emages@cantech.net.au> wrote in message
news:390D1159.83CAEA7F@cantech.net.au...
> Hi everyone,
> I am currently working on an assigment at uni and I have to convert a
> String input to upper case. I have discovered that package
> Characters.Handling will do the trick, however mebe its because I am
> Irish, but I can not make heads or tails of how you actually use it in
> your code!
>
> I have put
>
> With Text_io,Ada.Characters.Handling;
> Use Text_io;
>
> and in one of my procedures I have tried to convert an input.
>
> Ada.Characters.Handling.To_upper(Clients_Name(Name_Last)) etc
>
> all I get is a message stating Ivalid parameter call ? How
>
> could someone please explain!!!!!!!!!!!!!!!!!
>
> Thanks
> Rob
>






^ permalink raw reply	[relevance 14%]

* Character Handling
@ 2000-04-30  0:00 13% Robert Stephen Breen
  2000-04-30  0:00  8% ` Marin D. Condic
                   ` (2 more replies)
  0 siblings, 3 replies; 162+ results
From: Robert Stephen Breen @ 2000-04-30  0:00 UTC (permalink / raw)


Hi everyone,
I am currently working on an assigment at uni and I have to convert a
String input to upper case. I have discovered that package
Characters.Handling will do the trick, however mebe its because I am
Irish, but I can not make heads or tails of how you actually use it in
your code!

I have put

With Text_io,Ada.Characters.Handling;
Use Text_io;

and in one of my procedures I have tried to convert an input.

Ada.Characters.Handling.To_upper(Clients_Name(Name_Last)) etc

all I get is a message stating Ivalid parameter call ? How

could someone please explain!!!!!!!!!!!!!!!!!

Thanks
Rob





^ permalink raw reply	[relevance 13%]

* Re: Character Handling
  2000-04-30  0:00 13% Character Handling Robert Stephen Breen
@ 2000-04-30  0:00  8% ` Marin D. Condic
  2000-04-30  0:00 14% ` DuckE
  2000-04-30  0:00  0% ` Ken Garlington
  2 siblings, 0 replies; 162+ results
From: Marin D. Condic @ 2000-04-30  0:00 UTC (permalink / raw)


Robert Stephen Breen wrote:
> 
> Hi everyone,
> I am currently working on an assigment at uni and I have to convert a
> String input to upper case. I have discovered that package
> Characters.Handling will do the trick, however mebe its because I am
> Irish, but I can not make heads or tails of how you actually use it in
> your code!
> 
> I have put
> 
> With Text_io,Ada.Characters.Handling;
> Use Text_io;
> 
> and in one of my procedures I have tried to convert an input.
> 
> Ada.Characters.Handling.To_upper(Clients_Name(Name_Last)) etc
> 
> all I get is a message stating Ivalid parameter call ? How
> 
You don't have sufficient information here to diagnose the exact
problem. The answer is that it depends o what the function (I'm
presuming its a function) Clients_Name returns. A correct usage of the
call would be:

....
String_1 : String (1..10) := "abcdefghik" ;
String_2 : String (1..10) ;
....
String_2 := Ada.Characters.Handling.To_Upper (String_1) ;
....


Note that the sizes and types of both String_1 and String_2 match. Note
that they are of the type "String" which is the expected type as an
input parameter to the function "To_Upper". Ada is very fussy that all
the types match. It may seem like a pain, but this is how Ada can catch
otherwise hard to diagnose errors in program logic.

If you need additional examples, I've got lots of Ada code on my web
page. Look specifically at the code under  GNAT_Examples.chop where I
have lots of small programs that illustrate basic Ada features.

MDC
-- 
======================================================================
Marin David Condic - Quadrus Corporation - http://www.quadruscorp.com/
Send Replies To: m c o n d i c @ q u a d r u s c o r p . c o m
Visit my web site at:  http://www.mcondic.com/

"I'd trade it all for just a little more"
    --  Charles Montgomery Burns, [4F10]
======================================================================




^ permalink raw reply	[relevance 8%]

* Re: Character Handling
  2000-04-30  0:00 13% Character Handling Robert Stephen Breen
  2000-04-30  0:00  8% ` Marin D. Condic
  2000-04-30  0:00 14% ` DuckE
@ 2000-04-30  0:00  0% ` Ken Garlington
  2 siblings, 0 replies; 162+ results
From: Ken Garlington @ 2000-04-30  0:00 UTC (permalink / raw)


"Robert Stephen Breen" <emages@cantech.net.au> wrote in message
news:390D1159.83CAEA7F@cantech.net.au...
> Hi everyone,
> I am currently working on an assigment at uni and I have to convert a
> String input to upper case. I have discovered that package
> Characters.Handling will do the trick, however mebe its because I am
> Irish, but I can not make heads or tails of how you actually use it in
> your code!
>
> I have put
>
> With Text_io,Ada.Characters.Handling;
> Use Text_io;
>
> and in one of my procedures I have tried to convert an input.
>
> Ada.Characters.Handling.To_upper(Clients_Name(Name_Last)) etc
>
> all I get is a message stating Ivalid parameter call ? How
>
> could someone please explain!!!!!!!!!!!!!!!!!
>
> Thanks
> Rob
>

OK: According to the language manual, section A.3.2, there are two such
functions:

function To_Upper (Item : in Character) return Character;
function To_Upper (Item : in String) return String;

So:

1. If Clients_Name(Name_Last) is a neither a character nor a string (e.g. an
access value), then it is invalid regardless of the context.

2. If Clients_Name(Name_Last) is a character, then you should be using
To_Upper in a context where it should be returning a character.

3. If Clients_Name(Name_Last) is a string, then you should be using To_Upper
in a context where it should be returning a string.







^ permalink raw reply	[relevance 0%]

* Re: Characters package
  2000-04-27  0:00 13% Characters package Anderson
@ 2000-04-27  0:00 14% ` Robert A Duff
  0 siblings, 0 replies; 162+ results
From: Robert A Duff @ 2000-04-27  0:00 UTC (permalink / raw)


"Anderson" <anderson@wa.apana.org.au> writes:

> I want to use the to_lower and to_higher function in the characters package
> in ada. I can do it by using
> 
> with Ada.Characters.Handling;
> use Ada.Characters.Handling;
> 
> but I am told I is bad code to make it visible throughtout the program, so
> how do I declear it as a package
> ie package char ..... ?

I haven't seen your program, so I don't know if the above is bad style
or not.  Some alternatives are:

    Move the use clause into a smaller scope.

    Eliminate the use clause, and call it using the full name
    Ada.Characters.Handling.To_Upper.

    Say "with Ada.Characters.Handling; use Ada;", and call it using the
    name Characters.Handling.To_Upper.

    Rename Ada.Characters.Handling to, say, Chars, and write
    Chars.To_Upper.

- Bob




^ permalink raw reply	[relevance 14%]

* Characters package
@ 2000-04-27  0:00 13% Anderson
  2000-04-27  0:00 14% ` Robert A Duff
  0 siblings, 1 reply; 162+ results
From: Anderson @ 2000-04-27  0:00 UTC (permalink / raw)


I want to use the to_lower and to_higher function in the characters package
in ada. I can do it by using

with Ada.Characters.Handling;
use Ada.Characters.Handling;

but I am told I is bad code to make it visible throughtout the program, so
how do I declear it as a package
ie package char ..... ?







^ permalink raw reply	[relevance 13%]

* Re: Printing Enum Variable Re: Linux World
  @ 1999-03-07  0:00  7%                   ` Hans Marqvardsen
  0 siblings, 0 replies; 162+ results
From: Hans Marqvardsen @ 1999-03-07  0:00 UTC (permalink / raw)


dewar@gnat.com wrote:
> Note that for most purposes, it does not matter at all
> what the external relationships are (you put characters
> into your program, and they come out "right").

However, the programmer (and the maintainer of his program) must
remember that they may get strange results,

if they ever compare strings except for equality 

or if they ever use the otherwise nice 
classification functions of Ada.Characters.Handling,  
Is_Control, Is_Graphic, Is_Letter, Is_Lower, Is_Upper,

or conversion functions:
To_Lower, To_Upper, To_Basic.

In conclusion: 
this is really a poor mans way of dealing with the full
character set.

> If the wrong
> characters are coming out, talk to your OS vendor, not
> your compiler vendor

There are in fact these two approaches:

a) Make the OS do the right thing
b) Give your program a suitable interface to the OS at hand

OF COURSE, in theory option a is preferable, but in practice
this approach can be difficult.

In Windows NT one can use the OS-supplied procedures
SetConsoleCP and SetConsoleOutputCP to use the proper codepage.
However one still has to select a non-default font, Lucida console,
manually at execution. 

Under Windows 95, it just cant be done, IMHO.

Option b may look more messy, but it works better IMHO.

The desired interface, such as Console_Io, can be constructed from the
OS-supplied procedures  CharToOemA and OemToCharA. 
No need to select any non-default font.
Works for W95 and NT alike.

Hence in practice option b is preferable, maybe the only possible.




^ permalink raw reply	[relevance 7%]

* Re: Printing Enum Variable Re: Linux World
  @ 1999-03-04  0:00 12%           ` Ehud Lamm
  0 siblings, 0 replies; 162+ results
From: Ehud Lamm @ 1999-03-04  0:00 UTC (permalink / raw)


> > Mine. For my example printed out "Red apple" as opposed to "RED_APPLE",

A little example of using generics, producing a menu, and pretry printing:

with ada.text_io; use ada.text_io;
with ada.integer_text_io; use ada.integer_text_io;
with Ada.Characters.Handling;

--generic
--   type Menu_Choice is (<>);
procedure Get_Menu_Choice (Choice:out Menu_Choice)  is
   Input:Integer range 0..Menu_Choice'Pos(Menu_Choice'Last);
   Done :Boolean;
   

   function Pretty(S:String) return String is
      -- This code is independent of 'image behaviuor.
      -- just deals with _ and capitalizes first letter in "words"
      Aux    :String(1..S'Length):=(others=>' ');
      Capital:Boolean:=True;
   begin
      for i in S'range loop
         if S(i)='_' then
               Aux(i):=' ';
               Capital:=True;
         elsif Capital then
               Aux(i):=Ada.Characters.Handling.To_Upper(S(i));
               Capital:=False;
         else
               Aux(i):=Ada.Characters.Handling.To_lower(S(i));
         end if;
      end loop;
      return Aux;
   end;

begin  -- Get_Menu
   for Choice in Menu_Choice loop
      put_line(Integer'Image(Menu_Choice'Pos(Choice)) & ' ' & 
               Pretty(Menu_Choice'image(Choice)));
   end loop;
   loop
      begin
         get(Input);
         Done:=True;
      exception
         when others =>
            put_line("minimal error message");
            Skip_Line;
            Done:=False;
      end;
      exit when Done;
    end loop;
    Choice:=Menu_Choice'val(Input);
end;

And a simple driver:

with get_menu_choice;
with ada.text_Io;
use ada.text_io;
procedure try_menu_choice is
   type menu is (First_Option,Second_Option_For_You);
   procedure Get_My_Menu_Choice is new Get_Menu_Choice(Menu_Choice=>Menu);
   
   package EIO is new Enumeration_Io(Menu);
   use EIO;
   C:menu;
begin
   get_My_Menu_Choice(C);
   put(C);
   
end;

Ehud Lamm     mslamm@pluto.mscc.huji.ac.il
http://www2.cybercities.com/e/ehud





^ permalink raw reply	[relevance 12%]

* Re: Printing Enum Variable Re: Linux World
    @ 1999-03-04  0:00 12%         ` Richard D Riehle
  1 sibling, 0 replies; 162+ results
From: Richard D Riehle @ 1999-03-04  0:00 UTC (permalink / raw)


>Actually, it rather annoyed me to find it in all caps. I typed into the
>program with initial caps for a reason. If it's not something that goes
>out to a user, why worry about it? 

 A follow-up to my earlier post about Put in Enumeration_IO.  I
 notice you are concerned about this problem with the 'Image
 attribute.  The following code should handle this problem
 quite nicely,

  with Ada.Characters.Handling;
  with Ada.Text_IO;
  use  Ada;
  use  Characters;
  procedure Test_Handling is
  begin
    Ada.Text_IO.Put(Handling.To_Lower(Boolean'Image(True)));
  end Test_Handling;

For some odd reason, people are still not getting used to the idea
of using the Character and String packages pre-defined in Annex A.
A lot of problems are solved easily using these services.

Richard Riehle
richard@adaworks.com
http://www.adaworks.com




^ permalink raw reply	[relevance 12%]

* Re: String type conversions
  @ 1999-02-09  0:00  9% ` Robert I. Eachus
  0 siblings, 0 replies; 162+ results
From: Robert I. Eachus @ 1999-02-09  0:00 UTC (permalink / raw)


In article <36C08E00.C3904670@Botton.com> David Botton <David@Botton.com> writes:

  > What is the best way to convert back forth between:

  > Wide_String to/from String

   Is this a trick question?  To convert from String to Wide_String is
easy, call Ada.Characters.Handling.To_Wide_String. ;-)  To go in the
other direction, there is a To_String function.  But what you may
really need is something with a better mapping for Wide_Characters not
in Character.  Note that you may want to make sure your Character type
is Latin-1 and not some other character set if you are using upper page
characters.

  > wchar_array to/from char_array

   Do I send you to the C newsgroup?  Or just tell you that there is
no Ada defined mapping from one to the other, and the actual mapping
will be OS and compiler specific.

   It is a shame that the character mapping arena is such a mess.
That is not an Ada issue, quite the opposite, in Ada it is a lot less
messy than in some other languages.  It is just that there are so many
standard, pseudo-standard, and non-standard character sets out there.


--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[relevance 9%]

* Re: 3 questions from a beginner
  @ 1998-12-07  0:00 11% ` david.c.hoos.sr
  0 siblings, 0 replies; 162+ results
From: david.c.hoos.sr @ 1998-12-07  0:00 UTC (permalink / raw)
  To: chuu

In article <74cdt6$ni3$1@front4.grolier.fr>,
  "Pierre" <chuu@club-internet.fr> wrote:
> Hello,
>
> I want to know 3 things :
>
> 1) how we use the composants from the type RECORD in I-O. Give me an example
> please)
>
Supposing you have the type:
type My_Type is
  record
     Name : String (1 .. 30);
     Name_Last : Natural;
     Address : String (1 .. 30;
     Address_Last : Natural;
  end record;

and the object declaration:

My_Object : My_Type;

then you could read these records like this:

Ada.Text_Io.Get_Line
  (Item => My_Object.Name,
   Last => Name_Last);

Ada.Text_Io.Get_Line
  (Item => My_Object.Address,
   Last => Address_Last);

> 2) how we compare 2 strings letter by letter ?
>
To compare the strings A and B, if you only wish to know for sure whether
the two strings are equal, you can simply say if A = B then .....

When you ask "letter by letter" I assume you want to know the firsr letter
which does not match.  To do this, again between strtings named A and B,
you could do this (assuming you have declared the variable
First_Mismatch : Natural;, and that the two strings might not begin with
identical indices):

First_Mismatch := 0;
for C in A'Range loop
  if A (C) /= B (B'First - A'First + C) then
    First_Mismatch := C;
    exit;
  end if;
end loop;

> 3) how we use the function TO_UPPER for only the first letter of a string.
>
I assume you mean the functions To_Upper declared in Ada.Characters.Handling.

You will note that there are two overloaded functions, one for characters and
one for strings.  So, to change the first character of string A to upper case
if it's lower, you could just say:

A (A'First) := Ada.Characters.Handling.To_Upper (A (A'First));

> Thank you in advance
>
> Pierre
>
>

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[relevance 11%]

* Re: cookies
  @ 1998-09-17  0:00  7% ` Pascal Obry
  0 siblings, 0 replies; 162+ results
From: Pascal Obry @ 1998-09-17  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 12086 bytes --]


Lisa Winkworth a �crit dans le message <6tpv6c$o1l$1@emu.cs.rmit.edu.au>...
>Hi, does anyone have any idea how to accept/generally do stuff with cookies
>in ada95??
>Any help would be much appreciated :)
>Thanks in advance,
>Lisa
>


Lisa,

I have done a child package of cgi.ads (from David A. Wheeler) to handle
cookies.

The packages spec/body are small so I have included them in this message.

Pascal.

---------------------------------- CUT
HERE -----------------------------------------------

--         File Name : cgi-cookies.ads
--
--       Created by  : Pascal Obry
--               on  : Mon Mar 10 16:05:01 1997

with Ada.Strings.Unbounded;

package CGI.Cookies is

   use Ada.Strings.Unbounded;

   --  Get cookie number
   function Count return Natural;


   --  Get cookies value
   function Value
     (Key      : in Unbounded_String;
      Required : in Boolean          := False)
      return Unbounded_String;

   function Value
     (Key      : in String;
      Required : in Boolean := False)
      return Unbounded_String;

   function Value
     (Key      : in String;
      Required : in Boolean := False)
      return String;

   function Value
     (Key      : in Unbounded_String;
      Required : in Boolean          := False)
      return String;


   --  Was a given key provided?
   function Key_Exists (Key : in String)           return Boolean;
   function Key_Exists (Key : in Unbounded_String) return Boolean;


   --  Set cookies value
   procedure Set (Key     : in String;
                  Value   : in String;
                  Expires : in String  := "";
                  Path    : in String  := "/";
                  Domain  : in String  := "";
                  Secure  : in Boolean := False);


   --  Send cookies to client with HTML header.
   procedure Put_CGI_Header_With_Cookies
     (Header : in String := "Content-type: text/html");

end CGI.Cookies;


--         File Name : cgi-cookies.adb
--
--       Created by  : Pascal Obry
--               on  : Mon Mar 10 16:05:01 1997

with Ada.Text_IO;
with Ada.Strings.Maps;
with Ada.Characters.Handling;

with Table_Of_Static_Keys_And_Static_Values_G;

package body CGI.Cookies is

   use Ada;
   use Ada.Strings.Maps;

   --  to set cookie
   type Key_Values_Record is
      record
         Value   : Unbounded_String;
         Expires : Unbounded_String;
         Path    : Unbounded_String;
         Domain  : Unbounded_String;
         Secure  : Boolean := False;
      end record;

   package Cookie_Table is
      new Table_Of_Static_Keys_And_Static_Values_G (Unbounded_String,
                                                    "<",
                                                    "=",
                                                    Key_Values_Record);

   --  to hold cookie value sent be the client
   type Key_Value_Pair is
      record
         Key   : Unbounded_String;
         Value : Unbounded_String;
      end record;

   type Key_Value_Sequence is array (Positive range <>) of Key_Value_Pair;
   type Access_Key_Value_Sequence is access Key_Value_Sequence;

   -- The following are data internal to this package.

   Cookie_Data     : Access_Key_Value_Sequence;

   Set_Cookie_Data : Cookie_Table.Table_Type;


   Ampersands :    constant Character_Set      := To_Set ('&');
   Equals     :    constant Character_Set      := To_Set ('=');
   Plus_To_Space : constant Character_Mapping  := To_Mapping ("+", " ");


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

   --  Get cookie number
   function Count return Natural is
   begin
      if Cookie_Data = null then
         return 0;
      else
         return Cookie_Data'Length;
      end if;
   end Count;
                      ------------------------------


   --  Get cookies value
   function Value
     (Key      : in Unbounded_String;
      Required : in Boolean          := False)
      return Unbounded_String is
   begin
      for I in 1 .. Count loop
         if Cookie_Data (I).Key = Key then
            return Cookie_Data (I).Value;
         end if;
      end loop;

      -- Didn't find the Key.
      if Required then
         raise Constraint_Error;
      else
         return Null_Unbounded_String;
      end if;
   end Value;

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

   function Value
     (Key      : in String;
      Required : in Boolean := False)
      return Unbounded_String
   is
   begin
      return Value (To_Unbounded_String (Key), Required);
   end Value;

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

   function Value
     (Key      : in String;
      Required : in Boolean := False)
      return String
   is
   begin
      return To_String (Value (To_Unbounded_String (Key), Required));
   end Value;

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

   function Value
     (Key      : in Unbounded_String;
      Required : in Boolean          := False)
      return String
   is
   begin
      return To_String (Value (Key, Required));
   end Value;


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

   --  Was a given key provided?
   function Key_Exists (Key : in Unbounded_String)
                        return Boolean
   is
   begin
      for I in 1 .. Count loop
         if Cookie_Data (I).Key = Key then
            return True;
         end if;
      end loop;
      return False;
   end Key_Exists;

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

   function Key_Exists (Key : in String)
                        return Boolean
   is
   begin
     return Key_Exists (To_Unbounded_String (Key));
   end Key_Exists;


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

   --  Set cookie value
   procedure Set (Key     : in String;
                  Value   : in String;
                  Expires : in String := "";
                  Path    : in String := "/";
                  Domain  : in String := "";
                  Secure  : in Boolean := False)
   is
      Cookie_Record : Key_Values_Record;
   begin -- Set_Cookies
      Cookie_Record := (To_Unbounded_String (Value),
                        To_Unbounded_String (Expires),
                        To_Unbounded_String (Path),
                        To_Unbounded_String (Domain),
                        Secure);

      Cookie_Table.Insert_Or_Replace_Value (Set_Cookie_Data,
                                            To_Unbounded_String (Key),
                                            Cookie_Record);
   end Set;


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

   procedure Put_CGI_Header_With_Cookies
     (Header : in String := "Content-type: text/html")
   is

      procedure Put_Cookie (Key      : in     Unbounded_String;
                            Datas    : in     Key_Values_Record;
                            N        : in     Positive;
                            Continue : in out Boolean) is
      begin
         Text_IO.Put ("Set-Cookie: ");
         Text_IO.Put (To_String (Key) & '=' & To_String (Datas.Value));

         if Datas.Expires /= Null_Unbounded_String then
            Text_IO.Put ("; expires=" & To_String (Datas.Expires));
         end if;

         if Datas.Path /= Null_Unbounded_String then
            Text_IO.Put ("; path=" & To_String (Datas.Path));
         end if;

         if Datas.Domain /= Null_Unbounded_String then
            Text_IO.Put ("; domain=" & To_String (Datas.Domain));
         end if;

         if Datas.Secure then
            Text_IO.Put ("; secure");
         end if;

         Text_IO.New_Line;

         Continue := True;
      end Put_Cookie;


      procedure For_Every_Cookies is
         new Cookie_Table.Traverse_ASC_G (Put_Cookie);

   begin
      --  CGI Header
      Text_IO.Put_Line (Header);

      --  Cookies
      For_Every_Cookies (Set_Cookie_Data);
      Text_IO.New_Line;
   end Put_CGI_Header_With_Cookies;





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

   -- Initialization routines, including some private procedures only
   -- used during initialization.

   function Field_End
     (Data            : Unbounded_String;
      Field_Separator : Character;
      Starting_At     : Positive         := 1)
      return Natural
   is
      -- Return the end-of-field position in Data after "Starting_Index",
      -- assuming that fields are separated by the Field_Separator.
      -- If there's no Field_Separator, return the end of the Data.
   begin
      for I in Starting_At .. Length (Data) loop
         if Element (Data, I) = Field_Separator then
            return I - 1;
         end if;
      end loop;
      return Length (Data);
   end Field_End;

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

   function Hex_Value (H : in String) return Natural is
      -- Given hex string, return its Value as a Natural.
      Value : Natural := 0;
   begin
      for P in 1.. H'Length loop
         Value := Value * 16;

         if H(P) in '0' .. '9' then
            Value := Value + Character'Pos(H(P)) - Character'Pos('0');
         elsif H(P) in 'A' .. 'F' then
            Value := Value + Character'Pos(H(P)) - Character'Pos('A') + 10;
         elsif H(P) in 'a' .. 'f' then
            Value := Value + Character'Pos(H(P)) - Character'Pos('a') + 10;
         else
            raise Constraint_Error;
         end if;

      end loop;
      return Value;
   end Hex_Value;

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

   procedure Decode (Data : in out Unbounded_String)
   is
      use Characters.Handling;
      I : Positive := 1;
      -- In the given string, convert pattern %HH into alphanumeric
characters,
      -- where HH is a hex number. Since this encoding only permits values
      -- from %00 to %FF, there's no need to handle 16-bit characters.
   begin
      while I <= Length(Data) - 2 loop
         if Element (Data, I) = '%' and
           Is_Hexadecimal_Digit (Element (Data, I+1)) and
           Is_Hexadecimal_Digit (Element (Data, I+2)) then

            Replace_Element
              (Data, I,
               Character'Val (Hex_Value (Slice (Data, I+1, I+2))));
            Delete (Data, I+1, I+2);
         end if;
         I := I + 1;
      end loop;
   end Decode;
                      ------------------------------

   procedure Set_CGI_Position
     (Key_Number : in Positive;
      Datum      : in Unbounded_String)
   is
      Last : Natural := Field_End(Datum, '=');
      -- Given a Key number and a datum of the form key=value
      -- assign the CGI_Data(Key_Number) the values of key and value.
   begin
      Cookie_Data (Key_Number).Key
        := To_Unbounded_String (Slice (Datum, 1, Last));
      Cookie_Data (Key_Number).Value
        := To_Unbounded_String (Slice (Datum, Last+2, Length (Datum)));
      Decode (Cookie_Data (Key_Number).Key);
      Decode (Cookie_Data (Key_Number).Value);
   end Set_CGI_Position;

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

   procedure Set_CGI_Data (Raw_Data : in Unbounded_String) is
      -- Set CGI_Data using Raw_Data.
      Key_Number         : Positive := 1;
      Character_Position : Positive := 1;
      Last : Natural;
   begin
      while Character_Position <= Length (Raw_Data) loop
         Last := Field_End (Raw_Data, ';', Character_Position);
         Set_CGI_Position
           (Key_Number,
            To_Unbounded_String (Slice (Raw_Data, Character_Position,
Last)));
         Character_Position := Last + 3; -- Skip over field separator. "; "
         Key_Number := Key_Number + 1;
      end loop;
   end Set_CGI_Data;

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

   procedure Initialize is
      Raw_Data : Unbounded_String;
   begin
      Raw_Data := To_Unbounded_String (Get_Environment("HTTP_COOKIE"));

      Translate (Raw_Data, Mapping => Plus_To_Space);

      if Length (Raw_Data) > 0 then
         Cookie_Data :=
           new Key_Value_Sequence (1 .. Count (Raw_Data, ";") + 1);
         Set_CGI_Data (Raw_Data);
      end if;

   end Initialize;

begin
   Initialize;
end CGI.Cookies;
---------------------------------- CUT
HERE -----------------------------------------------






^ permalink raw reply	[relevance 7%]

* Re: String Manipulation - Help Needed
  @ 1998-04-05  0:00  9% ` Matthew Heaney
  0 siblings, 0 replies; 162+ results
From: Matthew Heaney @ 1998-04-05  0:00 UTC (permalink / raw)



In article <x3g0MCAC5AK1EwY0@roslyn.demon.co.uk>, Howard Davies
<Howard@roslyn.demon.co.uk> wrote:

>Hi,
>I have a sentence stored in a string and I need to remove all spaces and
>punctuation from the string.
>My 600 page Ada book just says that this requies advanced packages that
>are beyond the scope of the book.
>Can someone help me out?

There are packages that come with the language to do what you want.  The
packages are

Ada.Strings.Fixed
Ada.Strings.Bounded
Ada.Strings.Unbounded
Ada.Strings.Maps
Ada.Characters.Handling

The Trim subprograms can remove whitespace from a string.  Maybe you can
make use of the character mapping functions too.




^ permalink raw reply	[relevance 9%]

* Ada95 Reserved Words Hash Function
@ 1997-10-22  0:00  9% John Cupak {73739}
  0 siblings, 0 replies; 162+ results
From: John Cupak {73739} @ 1997-10-22  0:00 UTC (permalink / raw)



Once upon a time (1986, in fact), Gralia and Kashtan wrote an Ada (83)
reserved word hash package to determine if a word was and Ada (83)
reserved word.

Has anyone looked at, or revised, the package since then for Ada 95
reserved words? The code sure could use some major surgery to take
advantages of Ada 95's predefined packages (e.g.
Ada.Characters.Handling).

Inquiring minds want to know!
-- 
----------------------------------------------------------------
-                   John J. Cupak Jr, CCP                      -
- Raytheon Electronic Systems: Software Engineering Laboratory -
- tel: 508-858-1222     email (work): jcj@swl.msd.ray.com      -
- fax: 508-858-4336     email (home): jcupak@aol.com           -
----------------------------------------------------------------




^ permalink raw reply	[relevance 9%]

* Re: string comparison?
  @ 1997-10-17  0:00  9% ` Steve Doiel
  0 siblings, 0 replies; 162+ results
From: Steve Doiel @ 1997-10-17  0:00 UTC (permalink / raw)



In article <EI5vIH.Et7@seas.ucla.edu>, tram@mulholland.seas.ucla.edu says...
>
>
>        I am new to the ada programming language and I would appreciate it
>if somebody could help me out with a couple of things.
>1.  Is there anyway to do a string comparison in ada?
>    So far, I have done it character by character but I am wondering if there
>    is a better way to do it? 

Sure, how about:

DECLARE
  ucToken : String := "CONST";
BEGIN
  IF ucToken = "CONST" THEN
    DoSomething;
  END IF;
END;

>2.  Is there anyway to exit out of a program inside an if-then-else 
statement?
>    I have a program that waits for a command, and depending on that command,
>    it would do something.  So I thought that the quit command would be 
>    simplest.  But I can't even exit out of the if-then-else block.

IF Ada.Characters.Handling.To_Upper( response ) = "QUIT" THEN
  RETURN;
END IF;

-- Since the main program in Ada is a procedure, you can RETURN to leave
-- the main procedure.

>
>TIA.
>
>-----------------------------------------------------------------
>Tri Tram, Computer Science and Engineering at UCLA
>http://www.seas.ucla.edu/~tram





^ permalink raw reply	[relevance 9%]

* Re: comand line arguments
@ 1997-10-13  0:00  7% Marin David Condic, 561.796.8997, M/S 731-96
  0 siblings, 0 replies; 162+ results
From: Marin David Condic, 561.796.8997, M/S 731-96 @ 1997-10-13  0:00 UTC (permalink / raw)



    Here's some code that should at least get you started developing
    whatever you need for processing a command line.

    MDC

Marin David Condic, Senior Computer Engineer     Voice:     561.796.8997
Pratt & Whitney GESP, M/S 731-96, P.O.B. 109600  Fax:       561.796.4669
West Palm Beach, FL, 33410-9600                  Internet:  CONDICMA@PWFL.COM
===============================================================================
    "Eagles may soar, but a weasle never gets sucked up into a jet engine."
===============================================================================

--
--  This function will return a string containing everything that
--  was on the command line. Due to OS pecularities, you may not
--  get it back exactly as typed. You may not get everything you
--  want, either. Ada can't fix that because it's going to depend on
--  what the OS decides to give you. From experience, Unix and WinNT
--  will produce different effects from the same code.
--
--  A lot of this implementation depends on what sort of command line
--  "language" you intend to be parsing out of the string. You'll
--  have to tailor the function as needed, but it at least
--  illustrates the proper calls to Ada.Command_Line.
--
--  The function presumes that you don't care about spaces between
--  parameters. You could modify it to put spaces between the
--  parameters, etc.
--

with Ada.Command_Line ;
with Ada.Strings ;
with Ada.Strings.Maps ;
with Ada.Strings.Fixed ;
with Ada.Characters.Handling ;
with Ada.Text_IO ;

function Get_Command_Line return String is
    --
    Temp            : String (1..256)   := (others => ' ') ;
    I               : Natural           := 0 ;
    --
    use Ada.Command_Line ;
    use Ada.Strings.Fixed ;
begin
    --
    --  Get the "command" or program name from the system if available.
    --
    Ada.Strings.Fixed.Move (
        Source  => Ada.Command_Line.Command_Name,
        Target  => Temp,
        Drop    => Ada.Strings.Right) ;
    --
    --  Get each of the args into the string - spaces don't matter.
    --
    I := Ada.Strings.Fixed.Index (
        Source  => Temp,
        Pattern => " ") ;
    for X in 1..Ada.Command_Line.Argument_Count loop
        Ada.Strings.Fixed.Move (
            Source  => Ada.Command_Line.Argument (X),
            Target  => Temp (I..Temp'Last),
            Drop    => Ada.Strings.Right) ;
        I := Index_Non_Blank (
            Source  => Temp,
            Going   => Ada.Strings.Backward) + 1 ;
    end loop ;
    --
    return Ada.Strings.Fixed.Trim (
        Source  => Temp,
        Side    => Ada.Strings.Both) ;
exception
    when Constraint_Error =>
        Ada.Text_IO.Put_Line ("Your command line is probably too long.") ;
        return "" ;
end Get_Command_Line ;




^ permalink raw reply	[relevance 7%]

* Re: Yet another efficiency question - To_Lower
  1997-07-02  0:00 11% Yet another efficiency question - To_Lower Dale Stanbrough
@ 1997-07-03  0:00  0% ` Matthew Heaney
  0 siblings, 0 replies; 162+ results
From: Matthew Heaney @ 1997-07-03  0:00 UTC (permalink / raw)



In article <5pclke$203$1@goanna.cs.rmit.edu.au>, Dale Stanbrough
<dale@goanna.cs.rmit.edu.au> wrote:

>I was wondering if the a procedure
>
>   procedure To_Lower (Item : in out String);
>
>would be any more efficient for performing To_Lower operations
>than the equivalent function in Ada.Characters.Handling, for when
>a string is modified in place, i.e.
>
>   Some_String : String (1..Size);
>        
>   Some_String := Ada.Characters.Handling.To_Lower (Some_String);

It would seem that having procedure forms would have been a good idea; I
don't know why they were omitted, nor does the AARM say either.

However, I think you can do what you want using the procedure form of
Translate in package Ada.Strings.Fixed.

--------------------------------------------------------------------
Matthew Heaney
Software Development Consultant
<mailto:matthew_heaney@acm.org>
(818) 985-1271




^ permalink raw reply	[relevance 0%]

* Yet another efficiency question - To_Lower
@ 1997-07-02  0:00 11% Dale Stanbrough
  1997-07-03  0:00  0% ` Matthew Heaney
  0 siblings, 1 reply; 162+ results
From: Dale Stanbrough @ 1997-07-02  0:00 UTC (permalink / raw)



I was wondering if the a procedure

   procedure To_Lower (Item : in out String);

would be any more efficient for performing To_Lower operations
than the equivalent function in Ada.Characters.Handling, for when
a string is modified in place, i.e.

   Some_String : String (1..Size);
	
   Some_String := Ada.Characters.Handling.To_Lower (Some_String);

My simple view of the implementation of the function would be that it
allocates space (heap? secondary stack?), copies the values from 
Some_String to the temporary, modifies the value, and then copies it
back. (I'm always concerned when I think I see cases of copies being
made for no good reason).

C's to_lower, of course, just does an in place modification of the
'string'.


Dale




^ permalink raw reply	[relevance 11%]

* Re: array conversion - how to do?
  @ 1997-06-27  0:00 12% ` Wes Groleau
  0 siblings, 0 replies; 162+ results
From: Wes Groleau @ 1997-06-27  0:00 UTC (permalink / raw)



If I didn't misunderstand your intent, you could use 
Ada.Characters.Handling.To_Basic to eliminate most (not 
all) of the characters outside of the ASCII range, and
Ada.Characters.Handling.To_ISO_646 to convert the rest 
to something you specify.

To eliminate the non-printable characters--please note 
that Character'Val (127) is non-printable)--you could use
Ada.Strings.Fixed.Translate (in fact, you could use it for 
the whole thing).

Geert Bosch wrote:
> Here is a simple situation illustrating a problem I encountered
> in using arrays of pointers to tagged objects. I have an
> application that should only use printable ASCII characters in its
> string processing. So I declare the following:
> 
>    subtype ASCII_Character is Character
>      range Character'Val (32) .. Character'Val (127);
>    type ASCII_String is array (Positive range <>) of ASCII_Character;
> 
> Now this string is clearly convertible to the String type, since
> the components have the same type, the ASCII_Character is only
> more constrained. Thus when my application wants to output its
> ASCII_String results, it uses:
> 
>    with Ada.Text_IO; use Ada.Text_IO;
>    procedure Test is
>       Warning_Message : ASCII_String := "Warning: only use 7-bit ASCII";
>    begin
>       ...
>       Put_Line (String (Warning_Message));
>    end Test;
> 
> Although this is IMHO a solution with clear semantics, this is
> not legal Ada because of the rule that array conversions are only
> allowed between array types that have components of the same subtype.
> The workaround is both ugly and inefficient using a typical Ada
> implementation:
> 
>    procedure Put_Line (Item : in ASCII_String) is
>       Standard_String : String (Item'Range);
>    begin
>       for I in Item'Range loop
>          Standard_String (I) := Item (I);
>       end loop;
>    end Put_Line;
> 
>    ...  -- And so on for all subprograms that use strings
> 
> I could imagine why it would not be possible to convert String
> to ASCII_String, since that conversion might need time-consuming
> checks. The conversion in the example is completely safe though,
> which is statically checkable for the compiler.
> 
> Actually in my real program where I use arrays of
> access-to-classwide types it really makes sense to convert
> arrays of access B'Class to arrays of access A'Class, when
> B is an extension of A.
> 
> In some situations it is really useful to use arrays of
> (access-to) tagged types, but it is quite annoying that
> I cannot convert arrays to more general types but need
> to copy them or use Unchecked_Conversion.
> 
> Can somebody give me a reason why this limitation is
> in the language? A good work-around would also be very
> welcome.
> 
> Regards,
>    Geert

-- 
----------------------------------------------------------------------
    Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA
Senior Software Engineer - AFATDS                  Tool-smith Wanna-be
                    wwgrol AT pseserv3.fw.hac.com

Don't send advertisements to this domain unless asked!  All disk space
on fw.hac.com hosts belongs to either Hughes Defense Communications or 
the United States government.  Using email to store YOUR advertising 
on them is trespassing!
----------------------------------------------------------------------




^ permalink raw reply	[relevance 12%]

* Re: Help! How to setup GNAT 3.09 for Windows NT?
  @ 1997-04-27  0:00 10% ` Matthew Kennedy
  0 siblings, 0 replies; 162+ results
From: Matthew Kennedy @ 1997-04-27  0:00 UTC (permalink / raw)




I think I have a similar problem. Please let me know if you solve it.

I have installed the Win95/NT GNAT 3.09 compiler and I run Win95. My
problem goes like this: I get the yes_no.adb file (from the Lovelace
tutorial) which is:

----
with Text_IO; use Text_IO;
with Ada.Characters.Handling;
  use Ada.Characters.Handling;
procedure Yes_No is
Response : Character;
begin
  Put("Would you like me to say Hello?");
  Get(Response);  -- Get first character.
  if (To_Lower(Response) = 'y') then
    Put("Hello!");
  else
    Put("Okay, I won't.");
  end if;
end Yes_No;
----

Then I compile it in my /usr directory by typing 'gnatmake yes_no.adb'
and then I get the following output error:

----
f:\usr >gnatmake yes_no.adb
gcc -c yes_no.adb
gnatbind -x yes_no.ali
gnatlink yes_no.ali
f:/usr/bin/ld.exe: cannot open ./yes_no: No such file or directory
(ENOENT)
gnatmake: *** link failed.
f:\usr >
----

Please note I have followed the instructions about installation on
drives other than c:.

What could be going wrong? Any help - many thanks.

xyz wrote:
>   I could not find any "gnatpath.bat" or something so on my PC
> after (successful) installation of GNAT 3.09 for Windows NT.
> Only a command "set path=c:\usr" is added in my autoexec.bat.
>   The application does not work at all.
>   Who can send me a setup file or show me where I can download
> such a file, or tell me how to setup GNAT?

-- 
Matthew Kennedy
Student of Electronics Engineering, USQ Australia
  " Hey pig, nothing's turning out the way I planned " 
      - Nine Inch Nails




^ permalink raw reply	[relevance 10%]

* Re: Clear Screen
  1997-03-03  0:00 11%             ` Robert Dewar
@ 1997-03-05  0:00  0%               ` Keith Thompson
  0 siblings, 0 replies; 162+ results
From: Keith Thompson @ 1997-03-05  0:00 UTC (permalink / raw)



In <dewar.857447446@merv> dewar@merv.cs.nyu.edu (Robert Dewar) writes:
> <<This will also make any other declarations within Ada.Characters visible.
> (It happens that the only such declaration is the child package
> Ada.Characters.Handling, and that only if you "with" it.)>>
> 
> And that presumably is what you want, if you with it, or are you recommending
> that the single use clause be replaced by two of your renamings in this case?
> :-)

The original discussion mentioned only Ada.Characters.Latin_1.  A use
clause for Ada.Characters makes Latin_1 directly visible, but it can
have other side effects (especially if the implementation provides other
children of Ada.Characters, like GNAT's Wide_Latin_1).

One argument in favor of the renames, in this particular case, is that
the name Latin_1 is far less ambiguous than Handling.

As I said, I'm not recommending anything, just pointing out alternatives.

-- 
Keith Thompson (The_Other_Keith) kst@sd.aonix.com <http://www.aonix.com> <*>
TeleSo^H^H^H^H^H^H Alsy^H^H^H^H Thomson Softw^H^H^H^H^H^H^H^H^H^H^H^H^H Aonix
10251 Vista Sorrento Parkway, Suite 300, San Diego, CA, USA, 92121-2706
"Humor is such a subjective thing." -- Cartagia




^ permalink raw reply	[relevance 0%]

* Re: Clear Screen
  @ 1997-03-03  0:00 11%           ` Keith Thompson
  1997-03-03  0:00 11%             ` Robert Dewar
  0 siblings, 1 reply; 162+ results
From: Keith Thompson @ 1997-03-03  0:00 UTC (permalink / raw)



In <3316EFA0.7970@watson.ibm.com> "Norman H. Cohen" <ncohen@watson.ibm.com> writes:
[...]
> (Concerning the ASCII package, I would take the trouble in new programs
> to write
> 
>    with Ada.Characters.Latin_1; use Ada.Characters;
> 
> This allows me to write Latin_1.Esc rather than ASCII.Esc, and, more
> important, it allows me to write things such as
> Latin_1.Registered_Trade_Mark_Sign.)

This will also make any other declarations within Ada.Characters visible.
(It happens that the only such declaration is the child package
Ada.Characters.Handling, and that only if you "with" it.)

If that's what you want to do, that's fine.  Another way to do this is

   with Ada.Characters.Latin_1;
   ...
   package Latin_1 renames Ada.Characters.Latin_1;

(I'm not trying to start another use clause flame war, just pointing
out an alternative.)

-- 
Keith Thompson (The_Other_Keith) kst@sd.aonix.com <http://www.aonix.com> <*>
TeleSo^H^H^H^H^H^H Alsy^H^H^H^H Thomson Softw^H^H^H^H^H^H^H^H^H^H^H^H^H Aonix
10251 Vista Sorrento Parkway, Suite 300, San Diego, CA, USA, 92121-2706
"Humor is such a subjective thing." -- Cartagia




^ permalink raw reply	[relevance 11%]

* Re: Clear Screen
  1997-03-03  0:00 11%           ` Keith Thompson
@ 1997-03-03  0:00 11%             ` Robert Dewar
  1997-03-05  0:00  0%               ` Keith Thompson
  0 siblings, 1 reply; 162+ results
From: Robert Dewar @ 1997-03-03  0:00 UTC (permalink / raw)



<<This will also make any other declarations within Ada.Characters visible.
(It happens that the only such declaration is the child package
Ada.Characters.Handling, and that only if you "with" it.)>>

And that presumably is what you want, if you with it, or are you recommending
that the single use clause be replaced by two of your renamings in this case?
:-)





^ permalink raw reply	[relevance 11%]

* Re: How do I use the package characters?
  @ 1996-10-09  0:00 12% ` Robert Dewar
  0 siblings, 0 replies; 162+ results
From: Robert Dewar @ 1996-10-09  0:00 UTC (permalink / raw)



John Herro said

"     I'm posting this before my earlier post appears in CLA, because I saw
Stephen's reply to Ben.  Yes, the package you mentioned is an Ada 95
package, and Ada 83 packages don't have children, hence no periods.
    But you can reference package ASCII in Ada 83, and the steps are a
little different, because ASCII is inside Standard, and you never have to
WITH Standard; it's automatically WITHed in every compilation.  You can
optionally write a USE clause for ASCII, but it goes in the declarative
region of your program.  For example, here are two ways to beep the
terminal in Ada 83:"



That's confused. The original question was about Ada.Characters.Handling
which is not related to Standard.Ascii.

Standard.Ascii provides a subset of the functionality of
Ada.Characters.Latin_1, but none of the functoinality
of Ada.Characters.Handling.





^ permalink raw reply	[relevance 12%]

* Re: How do I use the package characters?
    1996-10-08  0:00 14% ` Stephen Leake
@ 1996-10-09  0:00  9% ` Michael Feldman
  1 sibling, 0 replies; 162+ results
From: Michael Feldman @ 1996-10-09  0:00 UTC (permalink / raw)



In article <DyxDvs.n54@most.fw.hac.com>,
Stephen M O'Shaughnessy <smosha@most.fw.hac.com> wrote:
>I would like to use the functions in the package characters.
>handling described in paragraph A.3.2 of the ARM.  How do I
>instantiate/reference these functions?

Like any other package -

with Ada.Characters.Handling

should do the trick. Did I miss something more subtle inthe question?

Mike Feldman








^ permalink raw reply	[relevance 9%]

* Re: How do I use the package characters?
  @ 1996-10-08  0:00 14% ` Stephen Leake
  1996-10-09  0:00  9% ` Michael Feldman
  1 sibling, 0 replies; 162+ results
From: Stephen Leake @ 1996-10-08  0:00 UTC (permalink / raw)



Stephen M O'Shaughnessy wrote:
> 
> I would like to use the functions in the package characters.
> handling described in paragraph A.3.2 of the ARM.  How do I
> instantiate/reference these functions?
> 
> Thanks
> 
> Steve O

You need the full name of the package:

with Ada.Characters.Handling;
procedure Foo is
    A : CHARACTER;
begin
    ... other code that sets A

    if Ada.Characters.Handling.Is_Control (A) then
     ...
    end if;
end Foo;

or you can use the `use' clause:

with Ada.Characters.Handling;
use Ada.Characters.Handling;
procedure Foo is
    A : CHARACTER;
begin
    ... other code that sets A

    if Is_Control (A) then
     ...
    end if;
end Foo;

Happy coding!
-- 
- Stephe




^ permalink raw reply	[relevance 14%]

* OLE Automation with Win32Ada and Personal ObjectAda
@ 1996-09-25  0:00  8% Paul Whittington
  0 siblings, 0 replies; 162+ results
From: Paul Whittington @ 1996-09-25  0:00 UTC (permalink / raw)



Can anyone help?

I'm trying to get a very small OLE program working as part of a larger
effort.  As GNAT/NT with Win32Ada is not yet available I've only tried to
compile and link with Personal ObjectAda.  I get several "unresolved
external symbol"s and can't seem to find a .lib or .obj(s) to link with to
resolve externals.  

I've called Thompson Software twice for tech support and e-mail them with
no response in 18 hours.

Here are the linker errors:

ObjectAda (tm) version 7.0.100: adabuild
    Copyright (c) 1996, Alsys, Inc.  All Rights Reserved.
obj\controller.eltab.obj
link /nologo @controller.rsp 
av$win32.lib(objbases.obj) : error LNK2001: unresolved external symbol
_IID_IWeakRef
av$win32.lib(objbases.obj) : error LNK2001: unresolved external symbol
___MIDL__intf_0000_v0_0_s_ifspec
av$win32.lib(objbases.obj) : error LNK2001: unresolved external symbol
___MIDL__intf_0000_v0_0_c_ifspec
av$win32.lib(objbases.obj) : error LNK2001: unresolved external symbol
_IWinTypes_v0_1_s_ifspec
av$win32.lib(objbases.obj) : error LNK2001: unresolved external symbol
_IWinTypes_v0_1_c_ifspec
controller.exe : fatal error LNK1120: 5 unresolved externals
Link of controller failed rc=25.
Tool execution failed.


Here is the source:

with OLE.OLE_String; 
with Win32.Objbase;  use Win32.Objbase;
with Win32.Winerror; use Win32.Winerror;
with Win32.Winnls;   use Win32.Winnls;

procedure Controller is
  Server_Name : OLE.OLE_String.Class;
  LpCLSID     : aliased CLSID;
  Status      : Win32.Objbase.HRESULT;
begin
  OLE.OLE_String.Construct (Server_Name,"Excel.Application");

  Status :=
CLSIDFromProgID(OLE.OLE_String.LPCOLESTR(Server_Name),LpCLSID'Access);
  if FAILED (Win32.Winerror.HRESULT (Status)) then
    raise PROGRAM_ERROR;
  end if;
end Controller;
 
package OLE is
end OLE;

with Ada.Finalization;
with OLE.OLE_String_Rep;
with Win32.Objbase;

package OLE.OLE_String is

  type Class is new Ada.Finalization.Limited_Controlled with private;

  procedure Construct  (Object : in out Class;
                        Value  : in     String);
  function  LPCOLESTR  (Object : in     Class) return
Win32.Objbase.LPCOLESTR;

private
  type Class is new Ada.Finalization.Limited_Controlled with record
    State : OLE.OLE_String_Rep.Class;
  end record;


  procedure Initialize(Object : in out Class);
  procedure Finalize  (Object : in out Class);

end OLE.OLE_String;


with Win32.Objbase;

package OLE.OLE_String_Rep is

  type Class is private;

  procedure Construct  (Object : in out Class;
                        Value  : in     String);
  procedure Destruct   (Object : in out Class);
  function  LPCOLESTR  (Object : in     Class) return
Win32.Objbase.LPCOLESTR;

private
  type State;
  type Class is access State;
end OLE.OLE_String_Rep;

package body OLE.OLE_String is

  procedure Initialize(Object : in out Class) is
  begin
    null;
  end Initialize;

  procedure Finalize (Object : in out Class) is
  begin
    OLE.OLE_String_Rep.Destruct (Object.State);
  end Finalize;


  procedure Construct (Object : in out Class;
                       Value  : in     String) is
  begin
    OLE.OLE_String_Rep.Construct (Object.State,Value);
  end Construct;


  function LPCOLESTR (Object : in Class) return Win32.Objbase.LPCOLESTR is
  begin
    return OLE.OLE_String_Rep.LPCOLESTR (Object.State);
  end LPCOLESTR;

end OLE.OLE_String;


with Ada.Characters.Handling;
with Ada.Unchecked_Deallocation;

package body OLE.OLE_String_Rep is

  type OLE_Char_Array is array (Positive range <>) of aliased
Win32.Objbase.OLECHAR;
  type OLE_Char_Array_Access is access OLE_Char_Array;

  type State is record
    The_Array : OLE_Char_Array_Access;
  end record;


  procedure Construct (Object : in out Class;
                       Value  : in     String) is
  begin
    Object.The_Array := new OLE_Char_Array (1..Value'Length+1);

    if Value'Length /= 0 then
      declare
        WValue : Wide_String := Ada.Characters.Handling.To_Wide_String
(Value);
      begin
        for Index in Value'First..Value'Last loop
          Object.The_Array (Index) := Win32.Objbase.OLECHAR(WValue
(Index));
        end loop;
      end;
    end if;

    Object.The_Array (Object.The_Array'Last) := Win32.Objbase.OLECHAR'Val
(0);
  end Construct;


  procedure Destruct (Object : in out Class) is
    procedure Free_OLE_Char_Array_Access is 
      new Ada.Unchecked_Deallocation
(OLE_Char_Array,OLE_Char_Array_Access);
  begin
    Free_OLE_Char_Array_Access (Object.The_Array);
  end Destruct;


  function LPCOLESTR (Object : in Class) return Win32.Objbase.LPCOLESTR is
  begin
    return Object.The_Array (Object.The_Array'First)'Access;
  end LPCOLESTR;

end OLE.OLE_String_Rep;





^ permalink raw reply	[relevance 8%]

* Re: GNAT for NT Linking Problem
  1996-09-23  0:00  0%     ` Klaus Wyss
@ 1996-09-25  0:00  0%       ` Matt O'Hara
  0 siblings, 0 replies; 162+ results
From: Matt O'Hara @ 1996-09-25  0:00 UTC (permalink / raw)



> 
> Michael Feldman wrote:
>

Michael -

Sorry; I started this topic and then got pulled away from it.
 
> > Since you are porting to GNAT, why not take the opportunity to
> > Ada 95-ize your program and get away from using those C libraries.
> > For example, toupper, etc., are part of the Ada 95 standard libs,
> > in this case Ada.Characters.Handling.
> >

I have started to do this, although I have discovered a limitation with
Ada95 that I did not care for. See the next response...

> > And why use the C IO routines? Is there a problem with Ada.Text_IO?
> >
> > The only thing I can think of that would require the C libs is if
> > (possibly) those f* routines are unbuffered. Do you need unbuffered
> > input/output?
> >

We used the C IO routines because Ada 83 Text IO (which the original
code was based on) could not handle Japanese (Wide) characters, and we
needed to Internationalize our program. Since we were Solaris based, and
Solaris has all these nice, neat Wide libraries, we simply built our own
text_io replacement package which used our own wide_character types, and
interfaced to the Solaris C wide libraries.

Ada 95 does have wide_character functions, including I/O. Although I am
still playing around with converting this to Ada95, I have noticed that
its Wide_Io does not handle wide_character file/path names; they are
String only. This seems like an unnecessary restriction; the wide_io
package we developed allowed wide_character file names. Why should Ada
95 force non-English developers to use only English names?

> > Mike Feldman
> 
> 

-- 
Matthew H. O'Hara
Principal S/W Engineer
Lockheed Martin Tactical Defense Systems, Eagan, MN
612-456-3228               matthew.h.ohara@lmco.com




^ permalink raw reply	[relevance 0%]

* Re: GNAT for NT Linking Problem
  1996-09-09  0:00  8%   ` Michael Feldman
@ 1996-09-23  0:00  0%     ` Klaus Wyss
  1996-09-25  0:00  0%       ` Matt O'Hara
  0 siblings, 1 reply; 162+ results
From: Klaus Wyss @ 1996-09-23  0:00 UTC (permalink / raw)



Michael Feldman wrote:
 
> Since you are porting to GNAT, why not take the opportunity to
> Ada 95-ize your program and get away from using those C libraries.
> For example, toupper, etc., are part of the Ada 95 standard libs,
> in this case Ada.Characters.Handling.
> 
> And why use the C IO routines? Is there a problem with Ada.Text_IO?
> 
> >Gnat uses some of the stdio routines to implement Ada file-io.
> >Look in the 'adaincludes' directory for i-cstrea.ads
> >and you find what is available via Gnat. If you need more you would
> >have to include these interfaces yourself via some library or .obj
> >file.
> 
> All this is true, but maybe you should have a look at your code to
> see if you can make use of Ada 95 stuff that will free you from
> (most of) the C lib facilities.
> 
> The only thing I can think of that would require the C libs is if
> (possibly) those f* routines are unbuffered. Do you need unbuffered
> input/output?
> 
> Mike Feldman


                                                                     
That's a typical sugestion of somebody living in the pure clean Ada
world
But the real world is not clean. It has dirty things like Windows,OLE
3rd party libraries .....
                                                                    
It would be crazy the reimplent all that stuff (maybe people in the
military aerea can do that)
                                                          
So what we need is a quick way to access all this C stuff from Ada.
A standard way to take C or C++ headers and make the this modules
acessible in Ada. 
                                                                
If we don't be able to access all this C,C++ things in a elegant simple
way, more and more applications will change from Ada to C/C++. 
The greater productivity of Ada programming doesn't help me if i lose
the time in solving the interface problems to other libraries.

Klaus Wyss
Union Bank of Switzerland




^ permalink raw reply	[relevance 0%]

* Re: GNAT for NT Linking Problem
    @ 1996-09-09  0:00  9% ` Tom Griest
  1 sibling, 0 replies; 162+ results
From: Tom Griest @ 1996-09-09  0:00 UTC (permalink / raw)



Matt O'Hara <mohara@planet8.eag.unisysgsg.com> writes:

[snip]

>All the Ada code compiles correctly, yet when I try to link I am getting
>errors referencing some of these C libraries. For example, it cant find
>things like toupper or feof, yet it (evidently, based on the lack of
>error message) can find things like tolower and fputc.

Only functions actually required by the Ada compiler and standard
Ada libraries are part of the libada libraries.  Hopefully, a version
of the Cygnus libc will be available for the next release on the
win32 platforms, and this should solve your problem.  Or, you
could try using the Ada equivalent libraries instead of the
"C" library,   like:    Ada.Characters.Handling.To_Upper.  :-)

-Tom




^ permalink raw reply	[relevance 9%]

* Re: GNAT for NT Linking Problem
  @ 1996-09-09  0:00  8%   ` Michael Feldman
  1996-09-23  0:00  0%     ` Klaus Wyss
  0 siblings, 1 reply; 162+ results
From: Michael Feldman @ 1996-09-09  0:00 UTC (permalink / raw)



In article <3234724E.251E@joy.ericsson.se>,
Jonas Nygren  <jonas@joy.ericsson.se> wrote:
>Matt O'Hara wrote:

>> I'm in the process of porting a Solaris Ada program to the PC, using
>> GNAT 304a for Windows NT (freshly ftp'd and installed). This Ada program
>> uses the C libraries extensively (basic things, like fputc, fgetc, feof,
>> toupper, etc).

Since you are porting to GNAT, why not take the opportunity to
Ada 95-ize your program and get away from using those C libraries.
For example, toupper, etc., are part of the Ada 95 standard libs,
in this case Ada.Characters.Handling.

And why use the C IO routines? Is there a problem with Ada.Text_IO?

>Gnat uses some of the stdio routines to implement Ada file-io. 
>Look in the 'adaincludes' directory for i-cstrea.ads
>and you find what is available via Gnat. If you need more you would
>have to include these interfaces yourself via some library or .obj
>file.

All this is true, but maybe you should have a look at your code to
see if you can make use of Ada 95 stuff that will free you from
(most of) the C lib facilities.

The only thing I can think of that would require the C libs is if
(possibly) those f* routines are unbuffered. Do you need unbuffered 
input/output?

Mike Feldman
------------------------------------------------------------------------
Michael B. Feldman -  chair, SIGAda Education Working Group
Professor, Dept. of Electrical Engineering and Computer Science
The George Washington University -  Washington, DC 20052 USA
202-994-5919 (voice) - 202-994-0227 (fax) 
http://www.seas.gwu.edu/faculty/mfeldman
------------------------------------------------------------------------
       Pork is all that money the government gives the other guys.
------------------------------------------------------------------------
WWW: http://lglwww.epfl.ch/Ada/ or http://info.acm.org/sigada/education
------------------------------------------------------------------------




^ permalink raw reply	[relevance 8%]

* Re: How to do case conversion?
  @ 1996-08-11  0:00 11% ` David C. Hoos, Sr.
  1996-08-11  0:00  8%   ` Robert Dewar
  0 siblings, 1 reply; 162+ results
From: David C. Hoos, Sr. @ 1996-08-11  0:00 UTC (permalink / raw)



Hi Mike,
The standard package Ada.Characters.Handling has subprograms To_Lower, and
To_Upper, for both characters and strings.
Hope this helps 
David C. Hoos, Sr.,
http://www.dbhwww.com
http://www.ada95.com

Mike Shen <mshen+@cs.cmu.edu> wrote in article
<320D5A34.41C67EA6@cs.cmu.edu>...
> I am trying to do case conversion in GNAT. Does anyone
> know a simple way to do it? I expected the Ada.Strings(.Maps)
> package to provide something for my purpose, but it doesn't.
> 
> Thanks in advance.
> 
> -Mike Shen
> 




^ permalink raw reply	[relevance 11%]

* Re: How to do case conversion?
  1996-08-11  0:00 11% ` David C. Hoos, Sr.
@ 1996-08-11  0:00  8%   ` Robert Dewar
  0 siblings, 0 replies; 162+ results
From: Robert Dewar @ 1996-08-11  0:00 UTC (permalink / raw)



David Hoos points out that Ada.Characters.Handling contains ready made
routines that use the maps in Ada.Strings.Maps.Constants, and yes, you
may as well use them if they fit. The coding is quite trivial:

   function To_Lower (Item : in Character) return Character is
   begin
      return Value (Lower_Case_Map, Item);
   end To_Lower;

   function To_Lower (Item : in String) return String is
      Result : String (1 .. Item'Length);

   begin
      for J in Item'Range loop
         Result (J - (Item'First - 1)) := Value (Lower_Case_Map, Item (J));
      end loop;

      return Result;
   end To_Lower;

It is Lower_Case_Map that is the difficult part! Note that in Ada 95 days
it is better if you can to always use this map rather than the old 
add/subtract 32 ASCII trick, since that way your code work fine for
all Latin-1 letters without any extra effort on your part, and indeed
in an implementation with localizations of these packages for other
Latin sets, your code will still work.





^ permalink raw reply	[relevance 8%]

* Re: Book REview
  @ 1996-05-09  0:00 10%       ` Richard A. O'Keefe
  0 siblings, 0 replies; 162+ results
From: Richard A. O'Keefe @ 1996-05-09  0:00 UTC (permalink / raw)



mfeldman@seas.gwu.edu (Michael Feldman) writes:

>There is some validity to your complaint about a US bias in the
>text; it is odd, though, that the first edition of this book was
>published nearly 5 years ago, and has been used by courses and
>individuals around the world (including Australia), but nobody has 
>mentioned the US bias.

In Australia there is something called "The cultural cringe".
There is a widespread attitude that if things are different overseas
they must be better, so it's our fault.

>That said, 

>(1) I think the tone of your review is a bit harsh;

On the same day I received four books for review.
One was "The Little Schemer".  I haven't looked very far into that one
yet.  "The Little Lisper" was a *great* book except for its "all the
world is America and there are no Jews or Muslims" attitude.
That's an MIT Press example.

The other three all came from Addison-Wesley.
Two of them were C textbooks by the same pair of authors.
They had some good topics, and good or very good presentation, but 
in one 25-line example I found 8 outright errors, and a large chunk
of one chapter is devoted to explaining a technique which has never
been legal in ANSI C, and is likely to cause trouble in segmented
architectures.  I am talking _really_ bad.  Frankly, I was outraged.

So, I turned to your book.  Imagine a poet turning from looking at
a disgusting monster, to look in relief at a beautiful woman, and
then he sees lice wandering over her face.

I was angry:
 * for myself: it was such a disappointment
 * for our students: this _could_ have been such a big help to them
 * for you: there are no really fundamental problems that I can see
            with the book, the proof-reading and formal review process
            let you down.

This may not _excuse_ the tone of the posting, but perhaps it _explains_ it.

Let me publicly apologise for the tone.



>(2) I don't think I'd ever write a review as critical as yours without
>    at least sending a cc to the author; that would just be courteous. 

>I don't read CLA every day (the signal/noise ratio is getting too low
>and I've been very busy), and so I was caught quite by surprise when
>a CLA acquaintance pointed me to your review.

I see that I must apologise again.  I had thought of you as a regular
CLA reader, so I was (without, it turns out, adequate reason) quite
sure that you would see it.  It was certainly my _intent_ that you would
see it.

>You are, of course, entitled to your opinion, and I am thick-skinned
>enough to handle a bad review.

The thing that still has me angry is that at one level it _isn't_ (or
isn't meant as) a bad review of the "World 3" book.  It's really an
angry review of the _proofreading_ and _review_ processes.  How come
such a well planned book by such great authors ended up with a flawed
result?  (By the way, talk to Addison-Wesley about the binding.  I
have had my copy for less than a week; I have handled it gently; but
the back cover now resembles a capital C.)

I am upset because I want to use the book you wanted to publish.

>On the other hand, there's no need to blindside the
>author by not even sending him a copy to respond to.

As I have explained, I did not mean to blindside you.
(I don't actually know what that means, but I think it means something
like "do something behind your back".)
I thought of posting to CLA as, amongst other things, an efficient way
to get you a copy.

I apologise again for being stupid about that.

>Indeed, had you been courteous enough to ask me for an errata list,
>I would have been happy to send it to you.

To be honest, it appears I have been stupid again.
It never occurred to me that a newly published book would _have_ an
errata list, or that Addison-Wesley would have withheld it from a
reviewer if it had.

In my own defence, I can only say that I *did* visit
	http://www.aw,com/cseng/authors/feldman/cs1-ada2e/cs1-ada2e.sup.html
and found the only supplements to be the source files in .tar.Z format for
UNIX and .zip format for Dos,Windows,OS/2.  There was no hint of the present
or likely future existence of an errata sheet there, so I supposed there
was none.

I failed to download the sources "Transaction timeout".
I've had a lot of trouble trying to download such sources from aw.com.

>'Nuff said.

Let me drag this out by pointing out one more example.

I mentioned the "in Character range 'A' .. 'Z'" method of testing whether
something is an upper case letter, and pointed out the flaw.  I was
considerably startled when the book fell open at page 466 just now, and
I saw "FOR c IN UpperCase LOOP".  Honest, the book did fall open at that
page without any prompting.  I then discovered that the example I quoted
before wasn't an isolated slip.

	p463

	Problem Specification
	---------------------
	Write a program which draws a histogram for the frequency
	of occurrence of the letters of the alphabet.   Uppercase
	and lowercase letters are to be counted separately;
	nonletter characters can be ignored.

	p785

	PACKAGE Ada.Characters.Handling IS
	...
	  FUNCTION Is_Lower (Item: IN Character) RETURN Boolean;
	  FUNCTION Is_Upper (Item: IN Character) RETURN Boolean;

This seems like the perfect opportunity to point out that "the alphabet"
in Ada 95 is ISO Latin 1 and that it contains a lot of letters and that
there are some standard functions for handling them, and that a good way
to handle this problem is

	type Character_Count_Table is array (Character) of Natural;

	Uppers: Character_Count_Table := (others => 0);
	Lowers: Character_Count_Table := (others => 0);
	Ch    : Character;

	...

	while not Ada.Text_IO.End_Of_File loop
	    while not Ada.Text_IO.End_Of_Line loop
		Ada.Text_IO.Get(Ch);
		if Ada.Characters.Handling.Is_Upper(Ch) then
		    Uppers(Ch) := Uppers(Ch) + 1;
		end if;
		if Ada.Characters.Handling.Is_Lower(Ch) then
		    Lowers(Ch) := Lowers(Ch) + 1;
		end if;
	    end loop;
	    Ada.Text_IO.Skip_Line;
	end loop;	    

	...

	for C in Character loop
	    if Ada.Characters.Handling.Is_Lower(C) then
		Draw_Bar(Lowers(C));
	    end if;
	end loop;
	Draw_Bar(0);
	for C in Character loop
	    if Ada.Characters.Handling.Is_Upper(C) then
		Draw_Bar(Uppers(C));
	    end	if;
	end for;
	...
	for C in Character loop
	    if Ada.Characters.Handling.Is_Lower(C) then
		Ada.Text_IO.Put(C);
	    end if;
	end loop;
	Ada.Text_IO.Put(' ');
	for C in Character loop
	    if Ada.Characters.Handling.Is_Upper(C) then
		Ada.Text_IO.Put(C);
	    end	if;
	end for;
	...

Instead, the text goes out of its way to hammer home the unintended lesson
that the 52 unaccented letters are the only letters in Ada and that all
the upper case letters are contiguous and all the lower case letters are
contiguous.

    - Uppers and Lowers in the book have non-overlapping index ranges,
      which won't work in Ada 95 if you try to handle _all_ letters.
    - the input loop in the book uses a CASE statement, and while an
      IF statement could have been adapted to Ada 95 letters, the CASE
      statement cannot.
    - the letters at the bottom of the display are in a string literal
      instead of being computed as above.	
	
Taken literally, in the context of Ada 95, the program of Figure 9.4
does not meet its specification.

Do we call this a cultural matter (there are only 52 letters in the world)
or a technical matter (there are only 52 letters in Ada)?  Well, my father's
name and my sister-in-law's name cannot be represented in ASCII, and they
are both of British descent, and their names are genuine (not made up) names.
Perhaps it is a cultural matter.  On the other hand, in Ada 95 there are
114 letters, not 52, so perhaps it is a technical matter.  Certainly, there
are coding techniques that used to work in ASCII that no longer work, and
one of the good things about Ada 95 is that it gives us the tools to do the
job properly.


Now, for this example, the histogram will only work if you have 120
columns on your screen, because 114 columns + a bit is more than will
fit on an 80-column screen.  Is it a good idea to restrict attention to
the American letters so that the display will fit on the screen?  Or is
that another easy hack that breaks when you try to handle the full
Ada 95 character set?  I honestly don't know, and I'm glad it wasn't my
decision.  (Actually, my decision would have been to map upper case letters
to lower case.  I can now see that that would have been the wrong decision,
because it merely delays the problem; my kluge won't adapt to Wide_Character.)

Am I being paranoid about a minor point?

Well, I have two 2nd-year C tutorials on Thursdays.
I asked them

	"What can you tell me about this method of
	 checking for an upper case letter in C?

		if ('A' <= x && x <= 'Z') ..."

The only suggestion I got was "it needs more parentheses" (which of course
it doesn't).  I explained that the system they are using (a SPARC running
Solaris, with X11) is configured to use an 8-bit character set, which has
a lot more capital letters than 26, and that the PC systems some of them
use at home has a _different_ 8-bit character set, which also has more
upper case letters than 26.  Next I asked

	"Can you suggest a way to test for _any_ upper case letter?"

Some of them had K&R2 with them.  It took some _very_ heavy hinting to
get them to look in the index.  Finally they understood that

		#include <ctype.h>
		...
		    if (isupper(x)) ...

would do the job.  Next question:

	"Will you use this?"

The answer:  "The book doesn't; why should we?"  (The book not= K&R2)

The lesson for Ada text-book authors?  "The book doesn't; why should we?"

I checked the index of the Ada95 book.  I could not find "letter",
"Is_Upper", "Is_Lower", "case, alphabetic", "lower case" in the index,
and the sole reference to "upper" was "uppercase and lower case, use of".

Is it reasonable to tell the whole truth in a CS 1 textbook?
No, it is not reasonable; it is not possible.

Is it reasonable to omit any mention of the fact that the character set
used by the language includes more letters than the American 26?
Well, a _lot_ of CS1 books include a chart of the ASCII characters,
and a chart listing all of the members of Character in Ada 95 would
require only a one page appendix.  In fact there _is_ an appendix
"The Ada Character Set..." which says "a number of additional characters
to provide for the additional letters used in non-English languages" but
doesn't say what they _are_.

A very small change to the book would eliminate most of my objections
about letters and ranges thereof.
(1) Change the third sentence in appendix A to say
	"This character set includes the usual upper case (A-Z) and
	 lower case (a-z) letters.  It also includes many other letters
	 useful in some European languages, including English.  For
	 example ....
	 Ada 95 identifiers should not use any of these extra letters.
	 The examples in this book just use the letters found on
	 US keyboards; if you want to use the other letters, you will
	 have to find out locally how to get them on your computer or
	 keyboard, AND YOU WILL HAVE TO CHANGE THE PROGRAMS."

(2) Somewhere about here in appendix A, say
	"Ada 95 programs can tell what kind of character they have been
	 given by using the functions in Ada.Characters.Handling whose
	 names begin with 'Is_'; see appendix G."

(3) At the end or appendix A, add a chart with all the ISO Latin 1
    characters.  I've seen it printed legibly on half a page.

(4) Whenever the current text says or implies that A-Z a-z are the
    only letters, add a footnote
	"* Strictly speaking, there are 114 letters. See Appendix A."
    or something of the kind.

(5) Put "letter", "letter, upper case", "letter, lower case" in the
    index, pointing to appendix A _and_ to all the examples in the
    main text that talk about letters.

While I was looking for "letter" in the index, I found 

	CASE STUDY: FINDING THE ALPHABETICALLY FIRST LETTER

on p141.  Now, the book is elsewhere quite clear that only the 52
character A-Z, a-z count as letters.  I am rather sensitive to this
issue because last year when I tutored the CS 1 class, an assignment
required students to read "letters", and there was massive confusion.
It turned out that, as here, the author meant by "letter" "any
character whatsoever, whether it is a letter or not".

The Ada code in program 4.2
 - reads arbitrary characters, not letters.
 - does not check that they are letters.
 - does not compare the characters "alphabetically", but according
   to their codes in ISO Latin 1.  This matters, because
	'a' < 'F'
   _alphabetically_, because A precedes F in the (English) alphabet
   -- there is historic precedent for considering & to be part of the
   English alphabetic, for what it's worth --
   but it's 'tother way around in ISO Latin 1.

   The alphabetically first _letter_ amongst "Ma!" is "a".
   The program will report '!'.
   The alphabetically first letter amongst "Max" is "a".
   The program will report 'M'.
   Surely a does come before m in the alphabet?

Rename the case study to
	Finding the character with the smallest code
replace "letter" by "character", "alphabet" by "character set",
and the objection vanishes because the confusion vanishes.

I am _not_ going to quarrel with the decision to use two IF statements
instead of just

	AlphaFirst := Character'Max(Character'Max(Ch1, Ch2), Ch3);

because it's a perfectly good educational decision to postpone details
like <scalar_type>'Max to CS2.

-- 
Fifty years of programming language research, and we end up with C++ ???
Richard A. O'Keefe; http://www.cs.rmit.edu.au/~ok; RMIT Comp.Sci.




^ permalink raw reply	[relevance 10%]

* Re: converting lower case to upper case
  @ 1995-04-06  0:00 10% ` Robert Dewar
  0 siblings, 0 replies; 162+ results
From: Robert Dewar @ 1995-04-06  0:00 UTC (permalink / raw)



tmoran says:

"function To_Upper(Item : in Character) return Character is
  Raise_It:constant array('a' .. 'z') of Character
    :="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
begin
  if Item in Raise_It'range then return Raise_It(Item);
  else return Item;
  end if;
end To_Upper;"

this is wrong, it handles only the lower part of the Ada character set,
and not Latin-1 extended characters. It is really quite important in
Ada 95 to abandon this familiar do-it-yourself-its-so-easy idiom for
case convesion, and use the routines in Ada.Characters.Handling. This
little bit of effort will be well paid off in future reuse of your code
in internatational contexts.






^ permalink raw reply	[relevance 10%]

Results 1-162 of 162 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
1995-04-04  0:00     converting lower case to upper case tmoran
1995-04-06  0:00 10% ` Robert Dewar
1996-05-06  0:00     Book REview Richard A. O'Keefe
1996-05-06  0:00     ` Robert Dewar
1996-05-07  0:00       ` Richard A. O'Keefe
1996-05-08  0:00         ` Michael Feldman
1996-05-09  0:00 10%       ` Richard A. O'Keefe
1996-08-10  0:00     How to do case conversion? Mike Shen
1996-08-11  0:00 11% ` David C. Hoos, Sr.
1996-08-11  0:00  8%   ` Robert Dewar
1996-09-09  0:00     GNAT for NT Linking Problem Matt O'Hara
1996-09-09  0:00     ` Jonas Nygren
1996-09-09  0:00  8%   ` Michael Feldman
1996-09-23  0:00  0%     ` Klaus Wyss
1996-09-25  0:00  0%       ` Matt O'Hara
1996-09-09  0:00  9% ` Tom Griest
1996-09-25  0:00  8% OLE Automation with Win32Ada and Personal ObjectAda Paul Whittington
1996-10-07  0:00     How do I use the package characters? Stephen M O'Shaughnessy
1996-10-08  0:00 14% ` Stephen Leake
1996-10-09  0:00  9% ` Michael Feldman
1996-10-09  0:00     John Herro
1996-10-09  0:00 12% ` Robert Dewar
1997-02-22  0:00     Clear Screen Tom Moran
1997-02-24  0:00     ` Jean-Etienne Doucet
1997-02-25  0:00       ` Robert Dewar
1997-02-26  0:00         ` Geert Bosch
1997-02-27  0:00           ` Robert Dewar
1997-02-28  0:00             ` Norman H. Cohen
1997-03-03  0:00 11%           ` Keith Thompson
1997-03-03  0:00 11%             ` Robert Dewar
1997-03-05  0:00  0%               ` Keith Thompson
1997-04-25  0:00     Help! How to setup GNAT 3.09 for Windows NT? xyz
1997-04-27  0:00 10% ` Matthew Kennedy
1997-06-24  0:00     array conversion - how to do? Geert Bosch
1997-06-27  0:00 12% ` Wes Groleau
1997-07-02  0:00 11% Yet another efficiency question - To_Lower Dale Stanbrough
1997-07-03  0:00  0% ` Matthew Heaney
1997-10-13  0:00  7% comand line arguments Marin David Condic, 561.796.8997, M/S 731-96
1997-10-16  0:00     string comparison? Tri Tram
1997-10-17  0:00  9% ` Steve Doiel
1997-10-22  0:00  9% Ada95 Reserved Words Hash Function John Cupak {73739}
1998-04-06  0:00     String Manipulation - Help Needed Howard Davies
1998-04-05  0:00  9% ` Matthew Heaney
1998-09-17  0:00     cookies Lisa Winkworth
1998-09-17  0:00  7% ` cookies Pascal Obry
1998-12-06  0:00     3 questions from a beginner Pierre
1998-12-07  0:00 11% ` david.c.hoos.sr
1999-02-09  0:00     String type conversions David Botton
1999-02-09  0:00  9% ` Robert I. Eachus
1999-03-02  0:00     Linux World Richard D Riehle
1999-03-02  0:00     ` fraser
1999-03-02  0:00       ` Printing Enum Variable " David Starner
1999-03-03  0:00         ` Fraser Wilson
1999-03-03  0:00           ` David Starner
1999-03-04  0:00             ` Magnus Larsson
1999-03-03  0:00               ` Hans Marqvardsen
1999-03-04  0:00                 ` robert_dewar
1999-03-04  0:00                   ` Hans Marqvardsen
1999-03-05  0:00                     ` dewar
1999-03-07  0:00  7%                   ` Hans Marqvardsen
1999-03-04  0:00 12%         ` Richard D Riehle
1999-03-03  0:00         ` fraser
1999-03-03  0:00           ` David Starner
1999-03-04  0:00             ` dennison
1999-03-04  0:00 12%           ` Ehud Lamm
2000-04-27  0:00 13% Characters package Anderson
2000-04-27  0:00 14% ` Robert A Duff
2000-04-30  0:00 13% Character Handling Robert Stephen Breen
2000-04-30  0:00  8% ` Marin D. Condic
2000-04-30  0:00 14% ` DuckE
2000-04-30  0:00  0% ` Ken Garlington
2000-05-08  0:00     Ada and Literate Programming Thomas Preymesser
2000-05-08  0:00     ` Robert Dewar
2000-05-10  0:00 11%   ` Georg Bauhaus
2000-05-09  0:00     Exit Loop_Statement David Freshwater
2000-05-09  0:00  8% ` John English
2000-05-09  0:00  0%   ` Robert Dewar
2000-05-09  0:00  0%     ` David Freshwater
2000-05-27  0:00     Strings Karlene
2000-05-27  0:00  9% ` Strings David C. Hoos, Sr.
2001-01-22  0:05 11% Optimization Question dvdeug
2001-02-11  9:52     logical operations in Ada Freelancer
2001-02-11 12:24  9% ` David C. Hoos, Sr.
2001-02-11 12:59  9% ` Florian Weimer
2001-02-13  3:40  9%   ` Freelancer
2001-02-13  6:43  0%     ` Dale Stanbrough
2001-02-13 11:54  0%     ` Jeff Creem
2001-02-13 17:44  0%     ` David C. Hoos, Sr.
2001-03-06 23:51 10% Ada95 tutorials with sample code Beard, Frank
2001-03-06 23:58 10% Beard, Frank
2001-04-03 19:08     Hebrew language character set Paul Storm
2001-04-04 17:35     ` David Botton
2001-04-04 21:36 12%   ` Paul Storm
2001-04-05  3:03  0%     ` David Starner
2001-04-05  6:42  0%     ` Ehud Lamm
2001-04-05 13:11  0%     ` Jean-Marc Bourguet
2001-04-05 16:56           ` Paul Storm
2001-04-05 16:41             ` Florian Weimer
2001-04-05 18:41 10%           ` Paul Storm
2001-09-25 16:04     Text_IO on WinNT problem Alfred Hilscher
2001-09-25 17:41     ` David Starner
2001-09-25 18:48  9%   ` Richard Riehle
2001-09-25 20:07  0%     ` David Starner
2001-11-02  3:56     List container strawman Ted Dennison
     [not found]     ` <3BE29AF4.80804@telepath.com>
2001-11-02 13:14       ` Ted Dennison
2001-11-02 17:44         ` Jeffrey Carter
2001-11-02 20:07           ` Ted Dennison
2001-11-02 23:19             ` Jeffrey Carter
2001-11-03  6:56               ` Ted Dennison
2001-11-03 19:22                 ` Jeffrey Carter
2001-11-04 18:58                   ` Darren New
2001-11-04 19:40                     ` Larry Kilgallen
2001-11-07 19:07                       ` ramatthews
2001-11-09 18:00                         ` Ted Dennison
2001-11-09 18:13                           ` Jean-Marc Bourguet
2001-11-09 18:55                             ` Ted Dennison
2001-11-10  1:48  8%                           ` Nick Roberts
2001-11-10 17:04                                 ` Ted Dennison
2001-11-10 20:59  7%                               ` Nick Roberts
2002-02-28  2:07 10% Ada Characters? Wannabe h4x0r
2002-02-28  2:28 13% ` Jim Rogers
2002-02-28 22:54  0% ` Jeffrey Carter
2002-04-23  9:13  9% string to uppercase Gautier Write-only-address
2002-05-20 23:09 10% Constraint error help tr4ck
2002-06-11  0:00  4% Possible bug / need confirmation Anh_Vo
2002-08-14 21:31  8% Anyway to change the length of a string ? Warren W. Gay VE3WWG
     [not found]     <c923f575.0208170639.344c3c21@posting.google.com>
2002-08-17 16:16  8% ` how to create an array of N elements? Warren W. Gay VE3WWG
2002-10-03 18:20     Newbie question on Ada TExt_IO Justin
2002-10-04 17:34 10% ` Justin Birtwell
2002-10-04 20:07  7%   ` Jeffrey Carter
2002-10-05  2:43  0%   ` SteveD
2002-11-18 20:41     how to check if a string variable contains a number or string? Sarah Thomas
2002-11-19  0:44  8% ` sk
2002-12-03  2:45     Character Sets Robert C. Leif
2002-12-03 13:33     ` Robert A Duff
2002-12-03 15:32 11%   ` Juanma Barranquero
2002-12-04  0:49     Robert C. Leif
2002-12-14  3:27     ` David Starner
2002-12-14 22:53  8%   ` Vadim Godunko
2002-12-15 23:26  7%     ` Robert C. Leif
2003-02-24 11:44     Help! Paul Gregory
2003-02-24 13:08 12% ` Help! Preben Randhol
2003-02-24 13:10  0%   ` Help! Preben Randhol
2003-02-24 13:52     Thanks guys..my project and my many problems Paul Gregory
2003-02-25 17:31     ` Matthew Heaney
2003-02-26 14:06       ` Paul Gregory
2003-02-27 17:12  6%     ` Update - PLEASE SOMEBODY HELP!!!! Paul Gregory
2004-04-30 12:17     Newbie Ada Axel Druesnes
2004-04-30 13:54  8% ` Type detection Björn Persson
2004-05-01  0:28 10%   ` Robert I. Eachus
2004-05-30 11:46     Improving Ada's image - Was: 7E7 Flight Controls Electronics Per Dalgas Jakobsen
2004-06-08 16:09     ` Warren W. Gay VE3WWG
2004-06-08 17:30       ` Hyman Rosen
2004-06-08 20:38         ` Warren W. Gay VE3WWG
2004-06-08 22:23           ` Hyman Rosen
2004-06-09  2:27             ` Warren W. Gay VE3WWG
2004-06-09  6:39               ` Hyman Rosen
2004-06-10 12:13                 ` Marin David Condic
2004-06-11 12:48                   ` Warren W. Gay VE3WWG
2004-06-11 17:31                     ` Marin David Condic
2004-06-14  2:30                       ` Berend de Boer
2004-06-14  3:10                         ` Hyman Rosen
2004-06-14 11:49                           ` Marin David Condic
2004-06-14 16:28                             ` Warren W. Gay VE3WWG
2004-06-15 11:26                               ` Marin David Condic
2004-06-15 16:43                                 ` Warren W. Gay VE3WWG
2004-06-15 18:51                                   ` Hyman Rosen
2004-06-15 21:02                                     ` Warren W. Gay VE3WWG
2004-06-15 22:01                                       ` Hyman Rosen
2004-06-15 22:08                                         ` Ed Falis
2004-06-15 22:26                                           ` Hyman Rosen
2004-06-17 15:50                                             ` Robert I. Eachus
2004-06-17 16:12                                               ` Hyman Rosen
2004-06-19 20:54                                                 ` Robert I. Eachus
2004-06-26  5:11 10%                                               ` Robert I. Eachus
2004-06-27  1:00  0%                                                 ` Jeffrey Carter
2004-08-13  5:23     character matching John J
2004-08-15 12:36     ` John J
2004-08-15 17:21  9%   ` Steve
     [not found]     <000901c4b365$719e8720$0201a8c0@win>
2004-10-16 10:04  9% ` Unescape URL Procedure Marius Amado Alves
2005-03-19 16:22     Ada bench Pascal Obry
2005-03-19 16:55     ` Dr. Adrian Wrigley
2005-03-19 21:32       ` Michael Bode
2005-03-20  9:20         ` Pascal Obry
2005-03-21 23:27           ` Georg Bauhaus
2005-03-22  1:16 11%         ` Ada bench : count words Marius Amado Alves
2005-03-22 10:59  0%           ` Dmitry A. Kazakov
2005-03-22 11:57                 ` Marius Amado Alves
2005-03-22 12:17                   ` Dmitry A. Kazakov
2005-03-22 12:47 12%                 ` Marius Amado Alves
2005-03-22 13:08  0%                   ` Dmitry A. Kazakov
2005-03-22 19:49               ` tmoran
     [not found]                 ` <00b362390273e6c04844dd4ff1885ee0@netcabo.pt>
2005-03-23 15:09 10%               ` Marius Amado Alves
2005-03-30 16:08  0%                 ` Andre
2005-03-22 16:30     Marius Amado Alves
2005-03-22 16:41     ` Tapio Kelloniemi
2005-03-22 17:39 11%   ` Marius Amado Alves
2005-03-22 18:59  0%     ` Dmitry A. Kazakov
2005-03-23 19:00     tmoran
2005-03-23 19:54     ` Tapio Kelloniemi
2005-03-23 20:39  9%   ` Ada bench : word frequency Marius Amado Alves
2005-03-23 21:26         ` Isaac Gouy
2005-03-24  1:24  9%       ` Marius Amado Alves
2005-04-14  1:28  9% Shootout: Word Frequency Jeffrey Carter
2005-06-30  8:44     ATC, an example please e.coli
2005-07-02  8:18  9% ` Craig Carey
2005-08-02  7:57     Character set conversion Adaddict
2005-08-02  9:45 10% ` Dmitry A. Kazakov
2005-08-31 17:07     Lower TC
2005-08-31 17:35  9% ` Lower Frode Tennebø
2005-09-29 17:20  6% New to Ada, noticing something strange mike.martelli
2005-09-29 18:39     ` Jeffrey R. Carter
2005-09-29 19:05       ` mike.martelli
2005-09-29 22:25         ` Randy Brukardt
2005-09-29 23:58  7%       ` mike.martelli
2005-09-30  0:28  9%         ` mike.martelli
2005-09-30  6:06  8%         ` Jeffrey R. Carter
2006-08-17  0:58     ANNOUNCE: Avatox 1.0 is now available Marc A. Criley
2006-08-21 20:59     ` Simon Wright
2006-08-24  0:41       ` Marc A. Criley
2006-08-24  6:03         ` Simon Wright
2006-09-06 23:29           ` Randy Brukardt
2006-09-07 20:46             ` Simon Wright
2006-09-08  2:40               ` Randy Brukardt
2006-09-08 13:40                 ` Georg Bauhaus
2006-09-09  8:28                   ` Manuel Collado
2006-09-09 12:21 11%                 ` Simon Wright
2006-09-11  7:58  0%                   ` Manuel Collado
2006-11-10  6:52 10% Advice Please laehyung
2006-11-10  9:27  0% ` Dmitry A. Kazakov
2006-11-15 22:00     Char type verification KE
2006-11-15 21:57 12% ` Georg Bauhaus
2006-11-15 23:15  0%   ` KE
2006-11-16  4:48         ` Jeffrey R. Carter
2006-11-16 23:30  6%       ` Yves Bailly
2006-11-21 15:11     I/O streaming with custom data transport Maciej Sobczak
2006-11-21 17:51     ` Alex R. Mosteo
2006-11-22  9:16 10%   ` Maciej Sobczak
2007-04-02  6:13     STORAGE_ERROR : EXCEPTION_STACK_OVERFLOW andrew.carroll
2007-04-02 10:10     ` Stephen Leake
2007-04-02 14:11  3%   ` andrew.carroll
2008-03-30 21:48     Converting Type Characters to type string Georg Bauhaus
2008-03-30 23:52     ` jedivaughn
2008-03-31  3:04  9%   ` george.priv
2008-03-31  4:00         ` tmoran
2008-03-31  8:54 10%       ` Ludovic Brenta
2008-08-01 12:18  5% Gnade/ODBC example - please help azdakiel
2008-10-18  0:48     determining input data type jedivaughn
2008-10-18 18:54 11% ` anon
2009-10-29 17:11     Types, packages & objects : the good old naming conventions question (without religious ware) Hibou57 (Yannick Duchêne)
2009-10-29 18:11     ` Georg Bauhaus
2009-10-30  0:01  9%   ` Robert A Duff
2010-10-23 20:16 12% Problems with String processing George
2010-10-23 20:24  9% ` Niklas Holsti
2010-10-23 20:25  9% ` Dmitry A. Kazakov
2010-10-23 21:08 10% Wrong program structure George
2010-10-23 21:16  0% ` Vinzent Hoefler
2010-10-25 11:55     how to i get the type of a parameter specification is ASIS stuart clark
2010-10-25 13:07     ` Julian Leyh
2010-10-25 13:12       ` stuart clark
2010-10-25 13:24         ` Julian Leyh
2010-10-25 13:32  9%       ` stuart clark
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         ` ytomino
2011-10-18  1:10           ` Adam Beneschan
2011-10-18  2:32             ` ytomino
2011-10-18 15:02 11%           ` Adam Beneschan
2011-10-18 22:54  0%             ` ytomino
2012-02-09  1:03     Need Help On Ada95 Problem Will
2012-02-09  2:01     ` Shark8
2012-02-10  1:36       ` BrianG
2012-02-10  2:22         ` Shark8
2012-02-10  5:32           ` Alex
2012-02-10 15:19             ` Shark8
2012-02-10 20:07               ` Robert A Duff
2012-02-12 19:40 11%             ` Will
2012-04-03  2:11     Checking to see is a string is a letter deuteros
2012-04-03  4:18     ` Leo Brewin
2012-04-03  4:52       ` Checking to see if " deuteros
2012-04-03  5:15         ` Jeffrey Carter
2012-04-03  6:07           ` deuteros
2012-04-03  8:26  8%         ` Simon Wright
2012-04-03 12:56  0%           ` deuteros
2012-04-03 13:46  0%           ` Dmitry A. Kazakov
2012-04-05 17:12  0%           ` deuteros
2012-04-05 17:24  0%             ` Martin Dowie
2012-04-03 20:40  9%         ` Jeffrey Carter
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  3%     ` Niklas Holsti
2012-10-31 16:47     Child packages named Ada illegal? Marius Amado-Alves
2012-10-31 17:20     ` Adam Beneschan
2012-10-31 17:59 13%   ` Marius Amado-Alves
2012-10-31 18:16  9%     ` Adam Beneschan
2012-10-31 18:41           ` Marius Amado-Alves
2012-10-31 19:39  0%         ` Shark8
2013-03-07 11:12  8% string and wide string usage Ali Bendriss
2013-03-07 14:20 11% ` ytomino
2013-03-07 17:14  0%   ` Dmitry A. Kazakov
2013-03-07 23:53  0%   ` Randy Brukardt
2014-01-28  1:06 10% need help learning Ada for a modula-2 programmer agent
2014-02-11 22:27     character literals agent
2014-02-11 23:56     ` adambeneschan
2014-02-12 15:53  8%   ` Robert A Duff
2014-04-04  0:35     gnatmake error I don't understand agent
2014-04-04  0:44 12% ` agent
2014-05-12 19:47  9% Weird error with Dynamic_Predicate mockturtle
2014-05-12 21:01  0% ` Adam Beneschan
2014-05-13  4:59  9% ` Shark8
2014-08-02 13:10     trimming strings agent
2014-08-02 17:22     ` mockturtle
2014-08-03 21:42 13%   ` agent
2014-08-05 20:09     A bad counterintuitive behaviour of Ada about OO Victor Porton
2014-08-05 20:59     ` Dmitry A. Kazakov
2014-08-05 21:11       ` Victor Porton
2014-08-06  7:26         ` Dmitry A. Kazakov
2014-08-07  7:41           ` Maciej Sobczak
2014-08-07  8:58             ` J-P. Rosen
2014-08-07  9:40               ` Dmitry A. Kazakov
2014-08-07 11:17                 ` J-P. Rosen
2014-08-07 12:28                   ` Dmitry A. Kazakov
2014-08-07 13:34                     ` J-P. Rosen
2014-08-07 20:29                       ` Shark8
2014-08-08  7:49                         ` J-P. Rosen
2014-08-08  8:12                           ` Shark8
2014-08-08  8:26                             ` Dmitry A. Kazakov
2014-08-08 11:10                               ` Shark8
2014-08-08 11:20                                 ` Dmitry A. Kazakov
2014-08-08 19:34  7%                               ` Shark8
2015-02-02  5:50  9% Did I find mamory leak in Generic Image Decoder (GID) ? reinkor
2015-04-17 13:42  7% Interesting containers problem Shark8
2015-06-02 11:33     Parsing Ada? Jacob Sparre Andersen
2015-06-03  7:58     ` Stephen Leake
2015-06-03 11:04 11%   ` Simon Wright
2015-07-18  9:00 11% How to check if letters are in a string? Trish Cayetano
2016-09-13  8:46     Question on bounded / unbounded strings Arie van Wingerden
2016-09-14 12:57     ` Arie van Wingerden
2016-09-14 19:39  6%   ` Jeffrey R. Carter
2016-09-17 16:35  6%     ` Arie van Wingerden
2018-03-01  0:27     CONSTRAINT ERROR? access check failed Mehdi Saada
2018-03-01  8:07     ` Niklas Holsti
2018-03-01 12:44       ` Mehdi Saada
2018-03-01 13:45 11%     ` Björn Lundin
2018-04-11  0:52     The extension of Is_Basic to unicode (about AI12-0260-1) ytomino
2018-04-11 14:32     ` Dan'l Miller
2018-04-11 20:54       ` J-P. Rosen
2018-04-11 22:20  9%     ` Randy Brukardt
2018-04-11 23:57  0%       ` ytomino
2019-02-17 11:24     gnat_regpat and unexpected handling of alnum and unicode needed 19.krause.70
2019-02-17 12:50 10% ` Simon Wright
2021-06-19 18:28     XMLAda & unicode symbols 196...@googlemail.com
2021-06-19 19:53  9% ` Jeffrey R. Carter
2021-06-20 17:02  0%   ` 196...@googlemail.com
2021-06-20 17:23  0%     ` Dmitry A. Kazakov
2021-06-20 17:58  0%       ` 196...@googlemail.com
2021-06-20 18:16  0%         ` Dmitry A. Kazakov
2021-06-21 19:40  0%           ` 196...@googlemail.com
2021-06-20 18:21  0%     ` Jeffrey R. Carter

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