comp.lang.ada
 help / color / mirror / Atom feed
From: Ludovic Brenta <ludovic.brenta@insalien.org>
Subject: Re: Handling Exceptions?
Date: 05 Nov 2003 01:13:13 +0100
Date: 2003-11-05T01:13:13+01:00	[thread overview]
Message-ID: <m34qxjn04m.fsf@insalien.org> (raw)
In-Reply-To: pan.2003.11.04.21.19.48.606113.919@nospam.net

Freejack <user@nospam.net> writes:

> I've recently switched back to using Adasockets for my programming needs.
> 
> I never bothered to catch exceptions before, since none of my apps were
> really that important. So, to get a little practice I slung together the
> following program(in about 5 minutes.) using Adasockets.
> 
> The problem is that the compiler will let me use the exceptions declared
> in the first declaritive part but not the second declaritive part.
> 
> Any pointers would be appreciated.

The exception handler is the portion of your code comprised between
the "exception" keyword and the next "end;" or "end loop;" statement.
Thus, after a casual reading of your code, here are my comments:

> with Sockets;
> with Sockets.Naming;
> with Ada.Text_IO;
> with Ada.Numerics.Discrete_Random;
> procedure newconn is
> 	-- Or "Learning to use exceptions the right way." --
> 	package TIO renames Ada.Text_IO;
> 	package SockNames renames Sockets.Naming;
> 	NameQuery : String := "www.yahoo.com"; -- Line Filler --
> 	HostIP : SockNames.Address;
> 	HostImage : String(1..14);
> 	LocalHost : String := "127.0.0.1";
> 	LocalIP	  : String := "<edited for posting to C.L.A.>";
> begin
> 	-- This code left over from an cut+paste operation --
> 	-- And it still works.							   --
> 	HostIP := SockNames.Address_Of(NameQuery);
> 	HostImage := SockNames.Image(HostIP);
> 	TIO.Put_Line(HostImage);
> 	-----------------------------------------------------
> 	declare
> 		Site: Sockets.Socket_FD;
> 		use Sockets;
> 	begin
> 
> 		Socket(Site, AF_INET, SOCK_STREAM);
> 		Connect(Site, LocalHost, 9);	-- Discard service --
> 		exception
> 			when Connection_Refused =>
> 				TIO.Put_Line("Connection Refused.");
> 			when others =>
> 				TIO.Put_Line("Something else went wrong");
> 		Sockets.Shutdown(Site, Both);
> 	end;

Here ends your first exception handler.  So far, so good.  Note
however that you only call Sockets.Shutdown when handling "others",
contrary to what your indentation seems to suggest.
 
> 	declare
> 		Echo : Sockets.Socket_FD;
> 		EchoString : String(1..10);
> 		EchoResponse : String(1..10); -- Could get less. Wont get more than 10 --
> 		use Sockets;
> 	
> 		-- This may look a little fruity, but I just wanna see if it'll work.  --
> 		package RandChar is new Ada.Numerics.Discrete_Random(Character); 
> 		use RandChar;
> 		G : Generator;
> 
> 	begin
> 		Socket(Echo, AF_INET, SOCK_STREAM);
> 		Connect(Echo, LocalIP, 7);
> 		exception
> 			when Connection_Refused =>
> 				TIO.Put_Line("Connection Refused");
> 				exit;
> 			when others =>
> 				Sockets.Shutdown(Echo, Both);
> 				TIO.Put_Line("There was a problem connecting to Echo");
> 				exit;

All of the code after this point is dead code because of the "exit"
statement above, but, although your indentation seems to imply
otherwise, the exception handler for "others" really continues here.

> 		-- Loop a bunch of times and send a bunch of shit to Echo.	  --
> 		-- And get a bunch of shit back.				  --
> 		
> 		EchoString := "1234567890";	
> 		Reset(G);	
> 		
> 		for X in 1..EchoString'Length loop
> 			-- First we send the String. --
> 			Put(Echo, EchoString);
> 			exception
> 				when Connection_Closed =>
> 					TIO.Put_Line("Connection Closed Prematurely");
> 					TIO.Put_Line("Terminating Application.");
> 					Shutdown(Echo, Both);
> 					exit; -- This should break us out of the loop? --
> 			-- Then we get it back. --

Again, the "exit" statement does not end this exception handler.  You
need "end" or "end loop".  We are still within the dead code.

> 			EchoResponse := Get_Line(Echo, 10);
> 			exception
> 				when Connection_Closed =>
> 					TIO.Put_Line("Peer Closed Connection before sending whole line");
> 					TIO.Put_Line("Got characters" & EchoResponse &".");
> 					TIO.Put_Line("Terminating Application.");
> 					Shutdown(Echo, Both);
> 					exit;
> 			
> 			-- Now we modify our string a bit(or a byte, pun intended) --
> 			EchoString(X) := Random(G);
> 		end loop;
> 		Shutdown(Echo, Both);
> 	end;

Now this really ends your second exception handler.
	
> end newconn;

The RM and the Rationale recommend that you indent the "exception"
keyword at the same level as the "begin" keyword, like this:

declare
   -- declarations
begin
   -- statements
exception
   when others =>
      -- statements
end;

This better reflects the grammatical structure for exception handlers.

If you need to execute several statements with different handlers, you
need several "begin" blocks.  You did this properly for the first
exception handler, not for the ones that follow.

HTH

-- 
Ludovic Brenta.



  reply	other threads:[~2003-11-05  0:13 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-11-04 21:13 Handling Exceptions? Freejack
2003-11-05  0:13 ` Ludovic Brenta [this message]
2003-11-05  0:20   ` Ludovic Brenta
2003-11-05  6:57     ` Freejack
2003-11-05  9:09       ` tmoran
2003-11-05 12:33       ` David C. Hoos
replies disabled

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