comp.lang.ada
 help / color / mirror / Atom feed
* Exception handling problem
@ 2000-03-06  0:00 Amun-Ra
  2000-03-06  0:00 ` Ehud Lamm
  2000-03-07  0:00 ` Nick Roberts
  0 siblings, 2 replies; 3+ messages in thread
From: Amun-Ra @ 2000-03-06  0:00 UTC (permalink / raw)


Hi all!

I have a big problem handling exceptions with Ada95 using GNAT.
I need to enter a number and, if something else is entered, the raised
exception
Ada.IO_Exceptions.Data_Error has to be handled and the asking for a
number 
should continue (I guess the problem is probably simple, but I don't see
a 
solution yet). The code I am worrying about is the following:

    -- Procedure "RAS_AskBreakpoint":
    -- Asks if a breakpoint should be set or unset. It returns 0 if the
    -- breakpoint should be unset, 1 if it should be set and also
returns the 
    -- entered breakpoint value as out-argument.
    --
    procedure RAS_AskBreakpoint (Input: out Long_Long_Integer; Mode: out
Integer) is
        Keystroke:      Character;
    begin
        RAS_Set_Position (Position => (Col => 1, Line => 10)); 
        Put (EmptyLine);
        RAS_Set_Position (Position => (Col => 1, Line => 10)); 
        Put ("Do you want to set <S> or unset <U> a breakpoint?");
        RAS_Set_Position (Position => (Col => 1, Line => 10));
        loop
            Get_Immediate (Keystroke);
            if Keystroke = 'S' or Keystroke = 's' then
                Mode := 1;
                Put (EmptyLine);
                RAS_Set_Position (Position => (Col => 1, Line => 10));
                Put ("Set breakpoint at which instruction (<0 to abort):
");
                Get (Input);
                exit;
            elsif Keystroke = 'U' or Keystroke = 'u' then
                Mode := 0;
                Put (EmptyLine);
                RAS_Set_Position (Position => (Col => 1, Line => 10));
                Put ("Unset which breakpoint (<0 to abort): ");
                Get (Input);
                exit;
            end if;
        end loop;
        RAS_Set_Position (Position => (Col => 1, Line => 10));
        Put (EmptyLine);
        RAS_Set_Position (Position => (Col => 1, Line => 11));
    end RAS_AskBreakpoint;

This procedure can be called many times and of course the only inputs
that need
to be done are a 'S'|'s' or 'U'|'u' and subsequently a number of type 
Long_Long_Integer. The only lines where the Data_Error can occur, are
the 
"Get (Input);"-lines. However, if a Data_Error is raised, the asking for
a 
number should continue until the user enters a valid number.

I already tried handling the exception by declaring another block inside
the
loop...end loop-section with own exception handler:

        loop
            begin
                Get_Immediate (Keystroke);
                if Keystroke = 'S' or Keystroke = 's' then
                    Mode := 1;
                    Put (EmptyLine);
                    RAS_Set_Position (Position => (Col => 1, Line =>
10));
                    Put ("Set breakpoint at which instruction (<0 to
abort): ");
                    Get (Input);
                    exit;
                elsif Keystroke = 'U' or Keystroke = 'u' then
                    Mode := 0;
                    Put (EmptyLine);
                    RAS_Set_Position (Position => (Col => 1, Line =>
10));
                    Put ("Unset which breakpoint (<0 to abort): ");
                    Get (Input);
                    exit;
                end if;
            exception
                when others => Put_Line ("Enter a number!");
            end;
        end loop;

as well as trying to localize the exception handling down to the
Get-Instruction:

                    loop
                        begin
                            Get (Input);
                            exit;
                        exception
                            when others => Put_Line ("Enter a number!");
                        end;
                    end loop;

The behaviour of the procedure then (regardless of where in the loop I
put the
handler) is always the same: 
If I enter a number as wanted, I can call the procedure as often as I
want and 
it works perfectly. However, if I enter something else, like a letter (I
want to
trap typing errors), upon subsequent calls of the procedure, the "Get
(Input)"-
Statements are no longer executed (the Put-Statements immediately in
front of 
them are executed), so I cannot enter a number anymore. And strange
enough, the
Put_Line-statement in the exception handler is not executed in the first
code
snippet, but leads to an infinite loop in the second one.
I already thought of doing a "Flush;" in the exception handler, but that
did not
work either.

Does anyone know why that strange behaviour occurs, why after giving
wrong Input
the "Get (Input);"s are no longer executed upon calling the procedure
again and
why the exception is not handled as wanted???
Can anyone tell me, where I made a mistake and how the code must be
written so
that I can keep asking for a number if I mistyped???

I would appreciate any hints!!!

Thanks in advance!!!

Andreas

P.S. Could you please also send answers via e-mail to: Amun_Ra72@gmx.net
Thanks!




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Exception handling problem
  2000-03-06  0:00 Exception handling problem Amun-Ra
@ 2000-03-06  0:00 ` Ehud Lamm
  2000-03-07  0:00 ` Nick Roberts
  1 sibling, 0 replies; 3+ messages in thread
From: Ehud Lamm @ 2000-03-06  0:00 UTC (permalink / raw)
  To: Amun-Ra

Seems like a skip_line proble. When you handle the excpetion, issue
Skip_Line (check the LRM to see what this does).

You can also use the Safe_Io package I put on Adapower, which takes the
burden off your shoulders.

Good luck

Ehud Lamm mslamm@mscc.huji.ac.il
http://purl.oclc.org/NET/ehudlamm <== My home on the web 
Check it out and subscribe to the E-List- for interesting essays and more!






^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Exception handling problem
  2000-03-06  0:00 Exception handling problem Amun-Ra
  2000-03-06  0:00 ` Ehud Lamm
@ 2000-03-07  0:00 ` Nick Roberts
  1 sibling, 0 replies; 3+ messages in thread
From: Nick Roberts @ 2000-03-07  0:00 UTC (permalink / raw)


I have a feeling others will answer this one better than me.

The really short version of the answer to your conundrum is: the letter that
causes the first exception is never removed from the input queue, so it just
goes on causing exceptions forever.

This is not a bug in GNAT; GNAT is following the Ada standard precisely.
Some have suggested it's a fault in the Ada standard, but that's not an
argument I want to dive into (as it's assuredly a muddy issue); for details
search Deja News within comp.lang.ada on ... hmmm ... "Get" maybe.

The (likely) solution to your problem, unfortunately, is to accumulate the
user's input into a string; this is easily done, up to the end of the
current input line, using Get_Line. Having done this, you can then check
(parse) the string, either resulting in a valid number (or whatever), or
outputting an error message and looping round for another input line. This
technique has the potential advantage of allowing you to devise your own
special syntax (e.g. allowing "." as a shorthand for 'current line').

Wishing you god-like powers in your Ada programming,

--
Nick Roberts
http://www.adapower.com/lab/adaos

"Amun-Ra" <Amun_Ra72@gmx.net> wrote in message news:38C34C24.3955@gmx.net...
> Hi all!
>
> I have a big problem handling exceptions with Ada95 using GNAT.
> ...







^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2000-03-07  0:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-03-06  0:00 Exception handling problem Amun-Ra
2000-03-06  0:00 ` Ehud Lamm
2000-03-07  0:00 ` Nick Roberts

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