home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / DDJERROR.ZIP / MAK.LST next >
File List  |  1990-06-20  |  9KB  |  267 lines

  1. _HANDLING OS/2 ERROR CODES_
  2. by Nico Mak
  3.  
  4. [LISTING ONE]
  5.  
  6.  
  7. /* OS2ERR.H version 1.0, March, 1989 */
  8. /* Include this file after including OS2.H or OS2DEF.H */
  9.  
  10. #ifdef OS2ERR
  11.     USHORT APIENTRY xos2chk(PSZ, USHORT, PSZ, USHORT);
  12.     USHORT APIENTRY xos2(PSZ, USHORT, PSZ, USHORT);
  13.     VOID   APIENTRY xpoperr(VOID);
  14.     #define os2chk(ErrCode) (xos2chk(__FILE__, __LINE__, #ErrCode, ErrCode))
  15.     #define os2(ErrCode) (xos2(__FILE__, __LINE__, #ErrCode, ErrCode))
  16.     #define poperr() (xpoperr())
  17. #else
  18.     #define os2chk(ErrCode) (ErrCode)
  19.     #define os2(ErrCode) (ErrCode)
  20.     #define poperr()
  21. #endif
  22.  
  23.  
  24. [LISTING TWO]
  25.  
  26. /* OS2ERR.C version 1.1, April 1989 by Nico Mak */
  27. /* These functions are called by the macros in OS2ERR.H */
  28. /* Compile this program with the options you use for the rest of */
  29. /* your application, and link your application with OS2ERR.OBJ */
  30.  
  31. #define MAX_SAVE_ENTRIES 7 /* maximum number of threads that will use OS2ERR */
  32.  
  33. #include <stdio.h>      /* definitions/declarations for standard I/O routines */
  34. #define INCL_BASE       /* to include all of OS/2 base */
  35. #include "os2def.h"     /* include OS/2 common definitions */
  36. #include "bse.h"        /* include OS/2 base definitions */
  37. #define OS2ERR          /* to include OS2ERR declarations and macros */
  38. #include "os2err.h"     /* include OS2ERR declarations */
  39.  
  40. typedef struct _SAVEINFO {                  /* save */
  41.     TID tid;
  42.     PSZ pszFileName;
  43.     USHORT usLineNumber;
  44.     PSZ pszLineSource;
  45.     USHORT usErrCode;
  46.     } SAVEINFO, FAR *PSAVEINFO;
  47.  
  48. SAVEINFO save[MAX_SAVE_ENTRIES];
  49. USHORT cSavedEntries = 0;   /* number of threads that have used OS2ERR */
  50. BOOL fOverFlow = 0;         /* 1 when all entries in "save" table are full */
  51.  
  52. /* DosErrClass error classifications */
  53. PSZ pszClass[] = {
  54.     "",
  55.     "Out of Resource",
  56.     "Temporary Situation",
  57.     "Permission problem",
  58.     "Internal System Error",
  59.     "Hardware Failure",
  60.     "System Failure",
  61.     "Application Error",
  62.     "Not Found",
  63.     "Bad Format",
  64.     "Locked",
  65.     "Media Failure",
  66.     "Collision with Existing Item",
  67.     "Unknown/other",
  68.     "Can't perform requested action",
  69.     "Time-out",
  70.     };
  71.  
  72. /* DosErrClass recommended actions */
  73. PSZ pszAction[] = {
  74.     "",
  75.     "Retry immediately",
  76.     "Delay and retry",
  77.     "User error, get new values",
  78.     "Abort in orderly manner",
  79.     "Abort immediately",
  80.     "Ignore this error",
  81.     "Retry after user intervention",
  82.     };
  83.  
  84. /* DosErrClass locus */
  85. PSZ pszLocus[] = {
  86.     "",
  87.     "Unknown",
  88.     "Disk",
  89.     "Network",
  90.     "Serial device",
  91.     "Memory parameter",
  92.     };
  93.  
  94. CHAR szWaitMsg[] = "\nPress Esc to abort process or any other key to continue";
  95. CHAR szErrTID[] = "\npoperr() error: no information saved for this thread\n\r";
  96. CHAR szErrOverFlow[] = "\npoperr() error: thread storage area overflowed\n\r";
  97. CHAR szBuffer[400];
  98.  
  99. USHORT PASCAL PszLen(PSZ psz); /* function returns length of a far string */
  100. PSAVEINFO PASCAL FindSaveEntry(TID); /* function returns PSAVEINFO for TID */
  101.  
  102. /* xos2chk - handle error (if any) and return error code */
  103. USHORT APIENTRY xos2chk(PSZ pszFileName, USHORT usLineNumber,
  104.  PSZ pszLineSource, USHORT usErrCode)
  105.     {
  106.     if (xos2(pszFileName, usLineNumber, pszLineSource, usErrCode))
  107.         xpoperr();
  108.     return usErrCode;
  109.     }
  110.  
  111. /* xos2 - save error information and return error code */
  112. USHORT APIENTRY xos2(PSZ pszFileName, USHORT usLineNumber,
  113.  PSZ pszLineSource, USHORT usErrCode)
  114.     {
  115.     PSAVEINFO psave;
  116.     PIDINFO pidi;
  117.  
  118.     if (usErrCode)
  119.         {
  120.         DosGetPID(&pidi);
  121.         if ((psave = FindSaveEntry(pidi.tid)) == NULL)
  122.             {
  123.             DosEnterCritSec();
  124.             if (cSavedEntries < MAX_SAVE_ENTRIES)
  125.                 psave = save + cSavedEntries++;
  126.             else
  127.                 fOverFlow = 1;
  128.             DosExitCritSec();
  129.             }
  130.         if (psave)
  131.             {
  132.             psave->tid = pidi.tid;
  133.             psave->pszFileName = pszFileName;
  134.             psave->usLineNumber = usLineNumber;
  135.             psave->pszLineSource = pszLineSource;
  136.             psave->usErrCode = usErrCode;
  137.             }
  138.         }
  139.     return usErrCode;
  140.     }
  141.  
  142. /* xpoperr - display pop-up screen with error information, return error code */
  143. VOID APIENTRY xpoperr(VOID)
  144.     {
  145.     KBDKEYINFO kbci;
  146.     PIDINFO pidi;
  147.     PSZ psz;
  148.     USHORT usClass, usAction, usLocus, usWait, usEnviron, usOffsetCmd, cbMsg;
  149.     PSAVEINFO psave;
  150.  
  151.     /* open a pop-up screen */
  152.     usWait = VP_WAIT | VP_OPAQUE;
  153.     VioPopUp(&usWait, 0);
  154.  
  155.     DosGetPID(&pidi);
  156.     if ((psave = FindSaveEntry(pidi.tid)) == NULL)
  157.         {
  158.         VioWrtTTY(szErrTID, sizeof(szErrTID), 0);
  159.         if (fOverFlow)
  160.             VioWrtTTY(szErrOverFlow, sizeof(szErrOverFlow), 0);
  161.         }
  162.     else
  163.         {
  164.         /* display error code, command name, and command tail */
  165.         sprintf(szBuffer, "Error Code:   %u\n\r", psave->usErrCode);
  166.         VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
  167.         DosGetEnv(&usEnviron, &usOffsetCmd);
  168.         for (psz = MAKEP(usEnviron, 0); *psz; psz += PszLen(psz) + 1)
  169.            ;
  170.         psz += 1;
  171.         sprintf(szBuffer, "Command:      %Fs\n\r", psz);
  172.         VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
  173.         psz += PszLen(psz) + 1;
  174.         psz += PszLen(psz) + 1;
  175.         sprintf(szBuffer, "Command tail: %Fs\n\r", psz);
  176.         VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
  177.  
  178.         /* display process id, thread id, and DosErrClass information */
  179.         sprintf(szBuffer, "Process ID:   %u\n\rThread ID:    %u\n\r",
  180.          pidi.pid, pidi.tid);
  181.         VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
  182.         DosErrClass(psave->usErrCode, &usClass, &usAction, &usLocus);
  183.         sprintf(szBuffer,
  184.          "Action:       %Fs\n\rLocus:        %Fs\n\rClass:        %Fs\n\r",
  185.          pszAction[usAction], pszLocus[usLocus], pszClass[usClass]);
  186.         VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
  187.  
  188.         /* display source filename, line number, and source code */
  189.         sprintf(szBuffer, "Source name: %Fs\n\rSource line: %d (%Fs)\n\r\n\r",
  190.          psave->pszFileName, psave->usLineNumber, psave->pszLineSource);
  191.         VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
  192.  
  193.         /* display system message (if any) */
  194.         if (!DosGetMessage(0, 0, szBuffer, sizeof(szBuffer), psave->usErrCode,
  195.           "OSO001.MSG", &cbMsg))
  196.             VioWrtTTY(szBuffer, cbMsg, 0);
  197.         }
  198.  
  199.     /* wait for a keypress */
  200.     VioWrtTTY(szWaitMsg, sizeof(szWaitMsg), 0);
  201.     do {
  202.         KbdCharIn(&kbci, IO_WAIT, 0);
  203.         } while (!(kbci.fbStatus & 0x40));
  204.  
  205.     /* close the pop-up screen and abort if requested */
  206.     VioEndPopUp(0);
  207.     if (kbci.chChar == 27 && kbci.chScan == 1)
  208.         DosExit(EXIT_PROCESS, 1);
  209.     }
  210.  
  211. /* PszLen - return length of a far string */
  212. USHORT PASCAL PszLen(PSZ psz)
  213.     {
  214.     PSZ pszSearch = psz;
  215.  
  216.     while (*pszSearch)
  217.         pszSearch++;
  218.     return pszSearch - psz;
  219.     }
  220.  
  221. /* FindSaveEntry - return pointer to SAVEINFO for a thread ID */
  222. PSAVEINFO PASCAL FindSaveEntry(TID tid)
  223.     {
  224.     PSAVEINFO psave;
  225.  
  226.     for (psave = save; psave < save + cSavedEntries; ++psave)
  227.         if (psave->tid == tid)
  228.             return psave;
  229.     return NULL;
  230.     }
  231.  
  232.  
  233.  
  234. [Example 1: Examples of OS/2chk() macro]
  235.  
  236. os2err(DosClose(hanConfig));    /* display pop-up screen w/error info */
  237. os2err(VioGetFont(&viofi, 0));  /* if system calls return error codes */
  238.  
  239.  
  240. [Example 2: Examples of OS/2() and poperr() macros]
  241.  
  242. SubCommandProcess()
  243.     {
  244.  
  245.     if (!setjmp(jmpbuf)) {                         /* set up error handler */
  246.  
  247.         /* ... processing ... */
  248.  
  249.         err == os2(VioGetFont(&viofi, 0));        /* get current font info */
  250.         if (err == ERROR_VIO_EXTENDED_SG)    /* if running in a VIO window */
  251.             InVioWindow = YES;                 /* remember we're in window */
  252.         else if (err)                     /* if any other VioGetFont error */
  253.             poperr();             /* display pop-up screen with error info */
  254.  
  255.         /* ... more processing ... */
  256.  
  257.         if (os2(DosClose(hanConfig)) /* if DosClose returns an error code */
  258.             longjmp(jmpbuf);       /* skip to application's error handler */
  259.  
  260.         /* ... yet more processing ... */
  261.  
  262.         }
  263.     else
  264.         poperr(); /* error handler - display pop-up screen with error info */
  265.     }
  266.  
  267.