/* common.c * * Common functions useful for Windows programs. */ //#include #include #include "graphic.h" #include "profile.h" #ifdef DEBUG // On NT, ntavi.h might do an undef debug... #include "common.h" /* globals */ int giDebugLevel = -1; // current debug level (0 = disabled) int gfhDebugFile = -1; // file handle for debug output (or -1) int giTimingLevel = -1; /* InitializeDebugOutput(szAppName) * * Read the current debug level of this application (named ) * from the [debug] section of win.ini, as well as the current location * for debug output. */ void FAR PASCAL InitializeDebugOutput(LPSTR szAppName) { char achLocation[300]; // debug output location /* debugging is disabled by default (and if an error occurs below) */ giDebugLevel = -1; gfhDebugFile = -1; /* get the debug output location */ if ( (mmGetProfileStringA("debug", "Location", "", achLocation, sizeof(achLocation)) == sizeof(achLocation)) || (achLocation[0] == 0) ) return; if (achLocation[0] == '>') { /* is the name of a file to overwrite (if * a single '>' is given) or append to (if '>>' is given) */ if (achLocation[1] == '>') gfhDebugFile = _lopen(achLocation + 2, OF_WRITE); else gfhDebugFile = _lcreat(achLocation + 1, 0); if (gfhDebugFile < 0) return; if (achLocation[1] == '>') _llseek(gfhDebugFile, 0, SEEK_END); } else if (lstrcmpiA(achLocation, "aux") == 0) { /* use OutputDebugString() for debug output */ } else if ((lstrcmpiA(achLocation, "com1") == 0) || (lstrcmpiA(achLocation, "com2") == 0)) { gfhDebugFile = _lopen(achLocation, OF_WRITE); } else { /* invalid "location=" -- keep debugging disabled */ return; } /* get the debug level */ giDebugLevel = mmGetProfileIntA("debug", szAppName, 0); giTimingLevel = mmGetProfileIntA("debug", "Timing", 0); } /* TerminateDebugOutput() * * Terminate debug output for this application. */ void FAR PASCAL TerminateDebugOutput(void) { if (gfhDebugFile >= 0) _lclose(gfhDebugFile); gfhDebugFile = -1; giDebugLevel = -1; } /* _Assert(szExpr, szFile, iLine) * * If is TRUE, then do nothing. If is FALSE, then display * an "assertion failed" message box allowing the user to abort the program, * enter the debugger (the "Retry" button), or igore the error. * * is the name of the source file; is the line number * containing the _Assert() call. */ #ifndef _WIN32 #pragma optimize("", off) #define ASSERTPREFIX #else #define ASSERTPREFIX "(NT) " #endif void FAR PASCAL _Assert(char *szExp, char *szFile, int iLine) { static char ach[300]; // debug output (avoid stack overflow) int id; int iExitCode; void FAR PASCAL DebugBreak(void); /* display error message */ if (szExp) wsprintfA(ach, ASSERTPREFIX "(%s)\nFile %s, line %d", (LPSTR)szExp, (LPSTR)szFile, iLine); else wsprintfA(ach, ASSERTPREFIX "File %s, line %d", (LPSTR)szFile, iLine); MessageBeep(MB_ICONHAND); id = MessageBoxA(NULL, ach, "Assertion Failed", #ifdef BIDI MB_RTL_READING | #endif MB_SYSTEMMODAL | MB_ICONHAND | MB_ABORTRETRYIGNORE); /* abort, debug, or ignore */ switch (id) { case IDABORT: /* kill this application */ iExitCode = 0; #ifndef _WIN32 _asm { mov ah, 4Ch mov al, BYTE PTR iExitCode int 21h } #else FatalAppExit(0, TEXT("Good Bye")); #endif // WIN16 break; case IDRETRY: /* break into the debugger */ DebugBreak(); break; case IDIGNORE: /* ignore the assertion failure */ break; } } #ifndef _WIN32 #pragma optimize("", on) #endif /* _DebugPrintf(szFormat, ...) * * If the application's debug level is at or above , * then output debug string with formatting codes * replaced with arguments in the argument list pointed to by . */ #define MODNAME "MCIAVI" void FAR CDECL _DebugPrintf(LPSTR szFormat, ...) { static char ach[300]; // debug output (avoid stack overflow) int cch; // length of debug output string #ifndef _WIN32 NPSTR pchSrc, pchDst; if (*szFormat == '!') { ++szFormat; } wvsprintf(ach, szFormat, (LPVOID)(&szFormat+1)); #else UINT n; va_list va; va_start(va, szFormat); if (*szFormat == '!') { ++szFormat; n=0; } else if (*szFormat=='.') { n=0; } else { n = wsprintfA(ach, MODNAME ": (tid %x) ", GetCurrentThreadId()); } wvsprintfA(ach+n, szFormat, va); va_end(va); #endif #ifndef _WIN32 /* expand the newlines into carrige-return-line-feed pairs; * first, figure out how long the new (expanded) string will be */ for (pchSrc = pchDst = ach; *pchSrc != 0; pchSrc++, pchDst++) if (*pchSrc == '\n') pchDst++; /* is large enough? */ cch = pchDst - ach; Assert(cch < sizeof(ach)); *pchDst-- = 0; /* working backwards, expand \n's to \r\n's */ while (pchSrc-- > ach) if ((*pchDst-- = *pchSrc) == '\n') *pchDst-- = '\r'; #else cch = strlen(ach); #endif //no expansion on Win32 /* output the debug string */ if (gfhDebugFile > 0) _lwrite(gfhDebugFile, ach, cch); else { OutputDebugStringA(ach); } } #endif