home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1990
/
08
/
mak.lst
< prev
next >
Wrap
File List
|
1990-06-20
|
9KB
|
267 lines
_HANDLING OS/2 ERROR CODES_
by Nico Mak
[LISTING ONE]
/* OS2ERR.H version 1.0, March, 1989 */
/* Include this file after including OS2.H or OS2DEF.H */
#ifdef OS2ERR
USHORT APIENTRY xos2chk(PSZ, USHORT, PSZ, USHORT);
USHORT APIENTRY xos2(PSZ, USHORT, PSZ, USHORT);
VOID APIENTRY xpoperr(VOID);
#define os2chk(ErrCode) (xos2chk(__FILE__, __LINE__, #ErrCode, ErrCode))
#define os2(ErrCode) (xos2(__FILE__, __LINE__, #ErrCode, ErrCode))
#define poperr() (xpoperr())
#else
#define os2chk(ErrCode) (ErrCode)
#define os2(ErrCode) (ErrCode)
#define poperr()
#endif
[LISTING TWO]
/* OS2ERR.C version 1.1, April 1989 by Nico Mak */
/* These functions are called by the macros in OS2ERR.H */
/* Compile this program with the options you use for the rest of */
/* your application, and link your application with OS2ERR.OBJ */
#define MAX_SAVE_ENTRIES 7 /* maximum number of threads that will use OS2ERR */
#include <stdio.h> /* definitions/declarations for standard I/O routines */
#define INCL_BASE /* to include all of OS/2 base */
#include "os2def.h" /* include OS/2 common definitions */
#include "bse.h" /* include OS/2 base definitions */
#define OS2ERR /* to include OS2ERR declarations and macros */
#include "os2err.h" /* include OS2ERR declarations */
typedef struct _SAVEINFO { /* save */
TID tid;
PSZ pszFileName;
USHORT usLineNumber;
PSZ pszLineSource;
USHORT usErrCode;
} SAVEINFO, FAR *PSAVEINFO;
SAVEINFO save[MAX_SAVE_ENTRIES];
USHORT cSavedEntries = 0; /* number of threads that have used OS2ERR */
BOOL fOverFlow = 0; /* 1 when all entries in "save" table are full */
/* DosErrClass error classifications */
PSZ pszClass[] = {
"",
"Out of Resource",
"Temporary Situation",
"Permission problem",
"Internal System Error",
"Hardware Failure",
"System Failure",
"Application Error",
"Not Found",
"Bad Format",
"Locked",
"Media Failure",
"Collision with Existing Item",
"Unknown/other",
"Can't perform requested action",
"Time-out",
};
/* DosErrClass recommended actions */
PSZ pszAction[] = {
"",
"Retry immediately",
"Delay and retry",
"User error, get new values",
"Abort in orderly manner",
"Abort immediately",
"Ignore this error",
"Retry after user intervention",
};
/* DosErrClass locus */
PSZ pszLocus[] = {
"",
"Unknown",
"Disk",
"Network",
"Serial device",
"Memory parameter",
};
CHAR szWaitMsg[] = "\nPress Esc to abort process or any other key to continue";
CHAR szErrTID[] = "\npoperr() error: no information saved for this thread\n\r";
CHAR szErrOverFlow[] = "\npoperr() error: thread storage area overflowed\n\r";
CHAR szBuffer[400];
USHORT PASCAL PszLen(PSZ psz); /* function returns length of a far string */
PSAVEINFO PASCAL FindSaveEntry(TID); /* function returns PSAVEINFO for TID */
/* xos2chk - handle error (if any) and return error code */
USHORT APIENTRY xos2chk(PSZ pszFileName, USHORT usLineNumber,
PSZ pszLineSource, USHORT usErrCode)
{
if (xos2(pszFileName, usLineNumber, pszLineSource, usErrCode))
xpoperr();
return usErrCode;
}
/* xos2 - save error information and return error code */
USHORT APIENTRY xos2(PSZ pszFileName, USHORT usLineNumber,
PSZ pszLineSource, USHORT usErrCode)
{
PSAVEINFO psave;
PIDINFO pidi;
if (usErrCode)
{
DosGetPID(&pidi);
if ((psave = FindSaveEntry(pidi.tid)) == NULL)
{
DosEnterCritSec();
if (cSavedEntries < MAX_SAVE_ENTRIES)
psave = save + cSavedEntries++;
else
fOverFlow = 1;
DosExitCritSec();
}
if (psave)
{
psave->tid = pidi.tid;
psave->pszFileName = pszFileName;
psave->usLineNumber = usLineNumber;
psave->pszLineSource = pszLineSource;
psave->usErrCode = usErrCode;
}
}
return usErrCode;
}
/* xpoperr - display pop-up screen with error information, return error code */
VOID APIENTRY xpoperr(VOID)
{
KBDKEYINFO kbci;
PIDINFO pidi;
PSZ psz;
USHORT usClass, usAction, usLocus, usWait, usEnviron, usOffsetCmd, cbMsg;
PSAVEINFO psave;
/* open a pop-up screen */
usWait = VP_WAIT | VP_OPAQUE;
VioPopUp(&usWait, 0);
DosGetPID(&pidi);
if ((psave = FindSaveEntry(pidi.tid)) == NULL)
{
VioWrtTTY(szErrTID, sizeof(szErrTID), 0);
if (fOverFlow)
VioWrtTTY(szErrOverFlow, sizeof(szErrOverFlow), 0);
}
else
{
/* display error code, command name, and command tail */
sprintf(szBuffer, "Error Code: %u\n\r", psave->usErrCode);
VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
DosGetEnv(&usEnviron, &usOffsetCmd);
for (psz = MAKEP(usEnviron, 0); *psz; psz += PszLen(psz) + 1)
;
psz += 1;
sprintf(szBuffer, "Command: %Fs\n\r", psz);
VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
psz += PszLen(psz) + 1;
psz += PszLen(psz) + 1;
sprintf(szBuffer, "Command tail: %Fs\n\r", psz);
VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
/* display process id, thread id, and DosErrClass information */
sprintf(szBuffer, "Process ID: %u\n\rThread ID: %u\n\r",
pidi.pid, pidi.tid);
VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
DosErrClass(psave->usErrCode, &usClass, &usAction, &usLocus);
sprintf(szBuffer,
"Action: %Fs\n\rLocus: %Fs\n\rClass: %Fs\n\r",
pszAction[usAction], pszLocus[usLocus], pszClass[usClass]);
VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
/* display source filename, line number, and source code */
sprintf(szBuffer, "Source name: %Fs\n\rSource line: %d (%Fs)\n\r\n\r",
psave->pszFileName, psave->usLineNumber, psave->pszLineSource);
VioWrtTTY(szBuffer, PszLen(szBuffer), 0);
/* display system message (if any) */
if (!DosGetMessage(0, 0, szBuffer, sizeof(szBuffer), psave->usErrCode,
"OSO001.MSG", &cbMsg))
VioWrtTTY(szBuffer, cbMsg, 0);
}
/* wait for a keypress */
VioWrtTTY(szWaitMsg, sizeof(szWaitMsg), 0);
do {
KbdCharIn(&kbci, IO_WAIT, 0);
} while (!(kbci.fbStatus & 0x40));
/* close the pop-up screen and abort if requested */
VioEndPopUp(0);
if (kbci.chChar == 27 && kbci.chScan == 1)
DosExit(EXIT_PROCESS, 1);
}
/* PszLen - return length of a far string */
USHORT PASCAL PszLen(PSZ psz)
{
PSZ pszSearch = psz;
while (*pszSearch)
pszSearch++;
return pszSearch - psz;
}
/* FindSaveEntry - return pointer to SAVEINFO for a thread ID */
PSAVEINFO PASCAL FindSaveEntry(TID tid)
{
PSAVEINFO psave;
for (psave = save; psave < save + cSavedEntries; ++psave)
if (psave->tid == tid)
return psave;
return NULL;
}
[Example 1: Examples of OS/2chk() macro]
os2err(DosClose(hanConfig)); /* display pop-up screen w/error info */
os2err(VioGetFont(&viofi, 0)); /* if system calls return error codes */
[Example 2: Examples of OS/2() and poperr() macros]
SubCommandProcess()
{
if (!setjmp(jmpbuf)) { /* set up error handler */
/* ... processing ... */
err == os2(VioGetFont(&viofi, 0)); /* get current font info */
if (err == ERROR_VIO_EXTENDED_SG) /* if running in a VIO window */
InVioWindow = YES; /* remember we're in window */
else if (err) /* if any other VioGetFont error */
poperr(); /* display pop-up screen with error info */
/* ... more processing ... */
if (os2(DosClose(hanConfig)) /* if DosClose returns an error code */
longjmp(jmpbuf); /* skip to application's error handler */
/* ... yet more processing ... */
}
else
poperr(); /* error handler - display pop-up screen with error info */
}