home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ctdemo.zip / classes / @CLSLIB1.ZIP / cls / runtime / test / xh_t1.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-06  |  7.9 KB  |  293 lines

  1. #ifndef INC_XH_T1
  2. #define INC_XH_T1
  3.  
  4. #ifndef __FIRST__
  5. #define __FIRST__
  6. #define __IMPL__XH_T1
  7. #endif
  8.  
  9. /////V XH_t1 PCM f:\cls_ibm\cls\runtime\test 2  PM 06.04.95 15:05:50
  10. /*
  11. /////H
  12. 18.12.94 01:57 PM 2 copied from: XH_t1 TOS f:\cls_ibm\cls\runtime\test 2  PM 19.10.94 01:09:49
  13. 30.03.95 10:34 PM 0 archived: XH_t1 PCM f:\cls_ibm\cls\runtime\test 0 PM 18.12.94 01:57:50
  14. /////
  15. */
  16.  
  17. /////1
  18. #undef inline
  19.  
  20. #include <bsa.h>
  21.  
  22. /////I conio.h @ @ @ @ pre 
  23. #include <conio.h>
  24.  
  25. /////I stdio.h @ @ @ @ pre 
  26. #include <stdio.h>
  27.  
  28. /////I XH @ @ @ @ class pre 
  29. #include <XH.cpp>
  30.  
  31. /////T Aux pre 
  32. struct X {
  33.     char    *msg;
  34.  
  35.     X ( char* s )
  36.         {
  37.             msg = s;
  38.             printf( "\t\t*** X (\"%s\") object created\n", msg);
  39.         }
  40.  
  41.     ~X ()
  42.         {
  43.             printf( "\t\t*** X (\"%s\") object destroyed\n", msg);
  44.         }
  45. };
  46.  
  47.  
  48. class IllegalValue {};
  49. /////
  50.  
  51.  
  52. #ifndef __INLINE__
  53. #define inline
  54. #endif
  55.  
  56. /////C XH_t1 @ @ app define:_VIO_ 
  57. class XH_t1
  58.  
  59. {
  60.  
  61. public:
  62.     static int  doAccessViolation ();
  63.     static int  doCppException ();
  64.     static int  doSomeExceptions (char);
  65.     static int  doUserRaise ();
  66.     static int  doZeroDiv ();
  67.     static int  testInt (int);
  68. };
  69.  
  70.     int _System  secondThread (ULONG);
  71.  
  72. /////2
  73. #undef inline
  74.  
  75.  
  76. #if (defined __INLINE__) || (defined __IMPL__XH_T1)
  77.  
  78. #ifndef __INLINE__
  79. #define inline
  80. #endif
  81.  
  82. /////
  83. #endif
  84.  
  85. /////3
  86. #undef inline
  87.  
  88. #ifdef __IMPL__XH_T1
  89. /////F doAccessViolation @ @ class public 
  90. int XH_t1:: doAccessViolation ()
  91. {
  92.     int  a;
  93.     char *c = 0;
  94.  
  95.     puts( "      entering func doAccessViolation()");
  96.  
  97.     puts( "\t\t*** now we force an access violation");
  98.     a = *c;
  99.  
  100.     puts( "      leaving func doAccessViolation()");
  101.     return a;
  102. }
  103.  
  104. /////F doCppException @ @ class public 
  105. int XH_t1:: doCppException ()
  106. {
  107.     puts( "      entering func doCppException()");
  108.     int     a = 0;
  109.     X        x1("doCppException");                // unwinded by RAISE -> retry
  110.  
  111.     /*
  112.      * This function demonstrates how to combine C++ exception handling (try,
  113.      * catch, throw) with the CTHROUGH exception handling (SAVEPOINT, RAISE).
  114.      * C++ exceptions cannot handle OS/2 raised exceptions, but are capable of
  115.      * storing some additional information about the exception in the
  116.      * corresponding exception class object. Another difference is the control
  117.      * flow: C++ exceptions cause a "forward" jump to the next catch
  118.      * block, CTHROUGH exceptions do a "fall back" to the last SAVEPOINT.
  119.      * While the first one is more structured (in order to "repair" the
  120.      * cause of an exception), the last one is more suitable for GUI programs
  121.      * (with an appropriate "restart" point)
  122.      */
  123.  
  124.     try {
  125.         X    x2("doCppException try {..x..}");        // unwinded by throw in testInt()
  126.  
  127.         testInt( a);                            // will throw an IllegalValue exception
  128.         printf( "\t\t*** 10 / a = %d\n", 10 / a);
  129.     }
  130.     catch ( IllegalValue ) {
  131.         puts( "\t\t*** caught an \"IllegalValue\" Cpp exception in doCppException()");
  132.  
  133.         puts( "\t\t*** we now RAISE a corresponding user exception");
  134.         XStream << "IllegalValue condition detected";
  135.         XRAISE( DA_RETRY);
  136.     }
  137.  
  138.     puts( "      leaving func doCppException()");
  139.     return 1;
  140. }
  141.  
  142. /////F doSomeExceptions @ @ class public 
  143. int XH_t1:: doSomeExceptions ( char cmd )
  144. {
  145.     printf ( "   entering func doSomeExceptions( %c )\n", cmd);
  146.  
  147.     switch ( cmd ) {
  148.         case '1' :    XH_t1::doZeroDiv();         break;
  149.         case '2' :    XH_t1::doUserRaise();         break;
  150.         case '3' :    XH_t1::doAccessViolation(); break;
  151.         case '4' :    XH_t1::doCppException();    break;
  152.     }
  153.  
  154.     puts( "   leaving func doSomeExceptions()");
  155.  
  156.     return 1;
  157. }
  158.  
  159. /////F doUserRaise @ @ class public 
  160. int XH_t1:: doUserRaise ()
  161. {
  162.     puts( "      entering func doUserRaise()");
  163.  
  164.     SET_SAVEPOINT( sp);        // set savepoint for RETRY respond
  165.     puts( "\t\t*** we just passed the SAVPOINT in doUserRaise()");
  166.  
  167.  
  168.     puts( "\t\t*** we now RAISE a user exception");
  169.     XStream << "I got a problem here";    // raise user exception ...
  170.     XRAISE( DA_RETRY);                    // with default action RETRY
  171.  
  172.     puts( "      leaving func doUserRaise()");
  173.     return 1;
  174. }
  175.  
  176. /////F doZeroDiv @ @ class public 
  177. int XH_t1:: doZeroDiv ()
  178. {
  179.     puts( "      entering func doZeroDiv()");
  180.     int a=10,b=0;
  181.     X    x("doZeroDiv");     // will be automatically unwinded if user respond = "retry"
  182.  
  183.     puts( "\t\t*** now we force a division by zero");
  184.     a = a/b;
  185.  
  186.     puts( "      leaving func doZeroDiv()");
  187.     return a;
  188. }
  189.  
  190. /////
  191. #ifdef __APPCLASS__
  192. /////F main @ @ global 
  193. int main ( int argc, char* argv[] )
  194. {
  195.     /*
  196.      *    *** exception handling demo app ***
  197.      *    
  198.      *    Importing XH will cause a duplex pipe connection to the external XProcessor
  199.      *    XHProc.exe ( if running).
  200.      *    Threads are linked to XH processing by macro REGISTER_XCPT.
  201.      *    XH supports internal OS/2 exceptions ( like zero devision) as well as user raised ones.
  202.      *    For user exception simply write a small text explaining your runtime problem to the global
  203.      *    XH instance 'XStream' and raise it with a default action ( DA_ABORT, DA_RETRY, DA_IGNORE).
  204.      *    If XHProc.exe is running, it pops up an error-desribing MessageBox ( or VIO pane, depending
  205.      *    of the raising app type). This respond box provides 3 possible reactions ( ABORT, RETRY, IGNORE).
  206.      *    OS/2 exceptions are suggested ABORT by default, for possible serious runtime problems.
  207.      *    The user respond is passed back to XH ( queued threads are internally dispatched meanwhile).
  208.      *    ABORT will terminate the using app, RETRY jumps to the last registered SAVEPOINT
  209.      *    of the raising thread ( fixed by macro SET_SAVEPOINT(sp) ) and IGNORE skips the exception point.
  210.      *    If the XProcessor is not running the X-causing app will be terminated.
  211.      *    The raise condition is logged to the file 'XH.xlg' anyway. This file can be analyzed by BsaController's
  212.      *    Tools XLogViewer, that shows the raise condition of each entry, the describing text( zero division,
  213.      *    user raise ...) as well as it's call stack back to the X-root.
  214.      */
  215.  
  216.     TID tid;
  217.     REGISTER_XCPT;
  218.  
  219.     //--- we do some IO that requires sync, so reset buffers here
  220.     setbuf( stdin, 0);
  221.     setbuf( stdout, 0);
  222.  
  223.     puts( "!! please make sure that the XProcessor has been started");
  224.     puts( "!! prior to XH_t1 in order to get a visual feedback on the");
  225.     puts( "!! exceptions. Otherwise XH_t1 will die gracefully when");
  226.     puts( "!! encountering the first exception (but will leave an exception");
  227.     puts( "!! log file XCPT.XLG that can be examined later with the XLogViewer\n");
  228.  
  229.     //--- start another thread to demonstrate usage in multi thread environments
  230.     DosCreateThread( &tid, (PFNTHREAD) secondThread, 0, 0, 65535);
  231.  
  232.     DosWaitThread( &tid, 0);
  233.     UNREGISTER_XCPT;
  234.     return 0;
  235. }
  236. /////
  237. #endif
  238.  
  239. /////F secondThread @ @ global 
  240. int _System secondThread( ULONG args)
  241. {
  242.     puts( "entering thread func secondThread()");
  243.     char    c;
  244.  
  245.     REGISTER_XCPT;            // link thread to exception handler
  246.     SET_SAVEPOINT( sp);        // set savepoint for RETRY respond
  247.     puts( "\t\t*** we just passed the SAVPOINT in secondThread()");
  248.  
  249.     /*
  250.      * The RETRY option of the Exception handling is only useful if the
  251.      * application has a suitable "restart point" (=SAVEPOINT). This is
  252.      * usually the case with GUI apps (there always is some kind of a
  253.      * "dispatcher loop"). In this example, we simulate this behaviour with
  254.      * the following loop
  255.      */
  256.  
  257.     while ( 1 ) {
  258.         printf( ">>enter command ('1'..'4', other key for exit) : ");
  259.         if ( (c = getche()) > 52 || c < 49 ){
  260.             puts( "\nloop terminated by user");
  261.             break;
  262.         }
  263.  
  264.         puts( "\n\t\t*** next loop in secondThread()");
  265.         XH_t1::doSomeExceptions( c);
  266.     }
  267.  
  268.     puts( "leaving thread func secondThread()");
  269.  
  270.     UNREGISTER_XCPT;        // remove thread from X handler
  271.     return 1;
  272. }
  273.  
  274. /////F testInt @ @ class public 
  275. int XH_t1:: testInt ( int a )
  276. {
  277.     puts( "         entering func testInt()");
  278.     X    x("testInt");            // will be automatically unwinded after throw
  279.  
  280.     if ( a == 0 ) {
  281.         puts( "\t\t*** we now throw an \"IllegalValue\" exception from testInt()");
  282.         throw IllegalValue();
  283.     }
  284.  
  285.     puts( "         leaving func testInt()");
  286.     return 1;
  287. }
  288.  
  289. /////
  290. #endif
  291.  
  292. #endif
  293.