/* throw.cc
 * Esempio di gestione delle eccezioni
 */
#include <iostream.h>

/* Classe per l'errore.
 * Faremo una throw con un oggetto di questa classe e
 * l'eccezione verra' intercettata dal blocco catch
 * che ha un parametro di tipo 'class errore'
 */
class errore {
public :
  int errn;
  char *errstr;

  errore (int n, char *s) { errn=n; errstr=s; };
};

void funzione1 ()
{
char c;
  cout << "Lancio un'eccezione stringa? [s/n] :";
  cin >> c;
  if (c == 's' || c == 'S')
    throw ("Eccezione Stringa Lanciata");
}

void funzione3 ()
{
char c;
  cout << "Lancio un'eccezione Intero? [s/n] :";
  cin >> c;
  if (c == 's' || c == 'S')
    throw (12);
  cout << "Lancio un'eccezione 'Char'? [s/n] :";
  cin >> c;
  if (c == 's' || c == 'S')
    throw ((char)12);
}

void funzione5 ()
{
char c;
  cout << "Lancio un'eccezione Non Non Gestita? [s/n] :";
  cin >> c;
  if (c == 's' || c == 'S')
    throw (1.5);
}

void funzione4 ()
{
char c;
  cout << "Lancio un'eccezione Classe Errore? [s/n] :";
  cin >> c;
  if (c == 's' || c == 'S')
    throw (errore (22,"Classe di errore"));
  // funzione5 lancia un'eccezione di tipo float
  funzione5 ();
}

void funzione2 () throw (int, errore, double)
{
  // Funzione3 lancia un'eccezione di tipo intero
  funzione3 ();
  // Funzione4 lancia un'eccezione di tipo 'class errore'
  // opure una di tipo double
  funzione4 ();
}

void funzione6 ()
{
char c;
  cout << "Lancio un'eccezione stringa fuori dal try-block? [s/n] :";
  cin >> c;
  if (c == 's' || c == 'S')
    throw ("Eccezione Stringa Lanciata");
}

void main (void)
{
  // funzione6 lancia un'eccezione, ma e' fuori del try-block
  funzione6 ();
  try {
    funzione1 ();
    funzione2 ();
    cout << "Ho terminato il try-block\n";
  }
  catch (const char *s) {
    cout << "E' arrivata l'eccezione '" << s << "'\n";
  }
  catch (int i) {
    cout << "E' arrivata l'eccezione Intera con valore " << i << "\n";
    exit (2);  // Questa eccezione termina il programma
  }
  catch (errore e) {
    cout << "E' arrivata l'eccezione 'errore' " << e.errn <<
      " - '" << e.errstr << "'\n";
  }
  catch (...) {
    cout << "E' arrivata un'eccezione diversa da 'int' ed 'errore'\n";
  }
  cout << "Fine normale del programma\n";
}