* 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