home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / crt0msg.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  8KB  |  319 lines

  1. /***
  2. *crt0msg.c - startup error messages
  3. *
  4. *       Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       Prints out banner for runtime error messages.
  8. *
  9. *******************************************************************************/
  10.  
  11. #include <cruntime.h>
  12. #include <internal.h>
  13. #include <stddef.h>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <rterr.h>
  18. #include <cmsgs.h>
  19. #include <awint.h>
  20. #ifdef _MAC
  21. #include <io.h>
  22. #else  /* _MAC */
  23. #include <windows.h>
  24. #endif  /* _MAC */
  25.  
  26. #include <dbgint.h>
  27.  
  28.  
  29. /* struct used to lookup and access runtime error messages */
  30.  
  31. struct rterrmsgs {
  32.         int rterrno;        /* error number */
  33.         char *rterrtxt;     /* text of error message */
  34. };
  35.  
  36. /* runtime error messages */
  37.  
  38. static struct rterrmsgs rterrs[] = {
  39.  
  40. #ifdef _MAC
  41.         /* 0 */
  42.         { _RT_STACK, _RT_STACK_TXT },
  43. #endif  /* _MAC */
  44.  
  45.         /* 2 */
  46.         { _RT_FLOAT, _RT_FLOAT_TXT },
  47.  
  48. #ifdef _MAC
  49.         /* 3 */
  50.         { _RT_INTDIV, _RT_INTDIV_TXT },
  51. #endif  /* _MAC */
  52.  
  53. #ifdef _WIN32
  54.         /* 8 */
  55.         { _RT_SPACEARG, _RT_SPACEARG_TXT },
  56.  
  57.         /* 9 */
  58.         { _RT_SPACEENV, _RT_SPACEENV_TXT },
  59. #endif  /* _WIN32 */
  60.  
  61.         /* 10 */
  62.         { _RT_ABORT, _RT_ABORT_TXT },
  63.  
  64. #ifdef _WIN32
  65.         /* 16 */
  66.         { _RT_THREAD, _RT_THREAD_TXT },
  67.  
  68.         /* 17 */
  69.         { _RT_LOCK, _RT_LOCK_TXT },
  70. #endif  /* _WIN32 */
  71.  
  72.         /* 18 */
  73.         { _RT_HEAP, _RT_HEAP_TXT },
  74.  
  75. #ifdef _WIN32
  76.         /* 19 */
  77.         { _RT_OPENCON, _RT_OPENCON_TXT },
  78. #endif  /* _WIN32 */
  79.  
  80.         /* 22 */
  81.         /* { _RT_NONCONT, _RT_NONCONT_TXT }, */
  82.  
  83.         /* 23 */
  84.         /* { _RT_INVALDISP, _RT_INVALDISP_TXT }, */
  85.  
  86. #ifdef _WIN32
  87.         /* 24 */
  88.         { _RT_ONEXIT, _RT_ONEXIT_TXT },
  89. #endif  /* _WIN32 */
  90.  
  91.         /* 25 */
  92.         { _RT_PUREVIRT, _RT_PUREVIRT_TXT },
  93.  
  94. #ifdef _WIN32
  95.         /* 26 */
  96.         { _RT_STDIOINIT, _RT_STDIOINIT_TXT },
  97.  
  98.         /* 27 */
  99.         { _RT_LOWIOINIT, _RT_LOWIOINIT_TXT },
  100.  
  101.         /* 28 */
  102.         { _RT_HEAPINIT, _RT_HEAPINIT_TXT },
  103. #endif  /* _WIN32 */
  104.  
  105.         /* 120 */
  106.         { _RT_DOMAIN, _RT_DOMAIN_TXT },
  107.  
  108.         /* 121 */
  109.         { _RT_SING, _RT_SING_TXT },
  110.  
  111.         /* 122 */
  112.         { _RT_TLOSS, _RT_TLOSS_TXT },
  113.  
  114.         /* 252 */
  115.         { _RT_CRNL, _RT_CRNL_TXT },
  116.  
  117.         /* 255 */
  118.         { _RT_BANNER, _RT_BANNER_TXT }
  119.  
  120. };
  121.  
  122. /* number of elements in rterrs[] */
  123.  
  124. #define _RTERRCNT   ( sizeof(rterrs) / sizeof(struct rterrmsgs) )
  125.  
  126. /* For C, _FF_DBGMSG is inactive, so _adbgmsg is
  127.    set to null
  128.    For FORTRAN, _adbgmsg is set to point to
  129.    _FF_DBGMSG in dbginit initializer in dbgmsg.asm  */
  130.  
  131. void (*_adbgmsg)(void) = NULL;
  132.  
  133. /***
  134. *_FF_MSGBANNER - writes out first part of run-time error messages
  135. *
  136. *Purpose:
  137. *       This routine writes "\r\nrun-time error " to standard error.
  138. *
  139. *       For FORTRAN $DEBUG error messages, it also uses the _FF_DBGMSG
  140. *       routine whose address is stored in the _adbgmsg variable to print out
  141. *       file and line number information associated with the run-time error.
  142. *       If the value of _adbgmsg is found to be null, then the _FF_DBGMSG
  143. *       routine won't be called from here (the case for C-only programs).
  144. *
  145. *Entry:
  146. *       No arguments.
  147. *
  148. *Exit:
  149. *       Nothing returned.
  150. *
  151. *Exceptions:
  152. *       None handled.
  153. *
  154. *******************************************************************************/
  155.  
  156. void __cdecl _FF_MSGBANNER (
  157.         void
  158.         )
  159. {
  160.  
  161. #ifdef _WIN32
  162.         if ( (__error_mode == _OUT_TO_STDERR) || ((__error_mode ==
  163.                _OUT_TO_DEFAULT) && (__app_type == _CONSOLE_APP)) )
  164. #endif  /* _WIN32 */
  165.         {
  166.             _NMSG_WRITE(_RT_CRNL);  /* new line to begin error message */
  167.             if (_adbgmsg != 0)
  168.                 _adbgmsg(); /* call __FF_DBGMSG for FORTRAN */
  169.             _NMSG_WRITE(_RT_BANNER); /* run-time error message banner */
  170.         }
  171. }
  172.  
  173.  
  174. /***
  175. *__NMSGWRITE(message) - write a given message to handle 2 (stderr)
  176. *
  177. *Purpose:
  178. *       This routine writes the message associated with rterrnum
  179. *       to stderr.
  180. *
  181. *Entry:
  182. *       int rterrnum - runtime error number
  183. *
  184. *Exit:
  185. *       no return value
  186. *
  187. *Exceptions:
  188. *       none
  189. *
  190. *******************************************************************************/
  191.  
  192. void __cdecl _NMSG_WRITE (
  193.         int rterrnum
  194.         )
  195. {
  196.         int tblindx;
  197. #if defined (_WIN32)
  198.         DWORD bytes_written;            /* bytes written */
  199. #endif  /* defined (_WIN32) */
  200.  
  201.         for ( tblindx = 0 ; tblindx < _RTERRCNT ; tblindx++ )
  202.             if ( rterrnum == rterrs[tblindx].rterrno )
  203.                 break;
  204.  
  205.         if ( rterrnum == rterrs[tblindx].rterrno )
  206.         {
  207. #ifdef _DEBUG
  208.             /*
  209.              * Report error.
  210.              *
  211.              * If _CRT_ERROR has _CRTDBG_REPORT_WNDW on, and user chooses
  212.              * "Retry", call the debugger.
  213.              *
  214.              * Otherwise, continue execution.
  215.              *
  216.              */
  217.  
  218.             if (rterrnum != _RT_CRNL)
  219.             {
  220.                 if (1 == _CrtDbgReport(_CRT_ERROR, NULL, 0, NULL, rterrs[tblindx].rterrtxt))
  221.                     _CrtDbgBreak();
  222.             }
  223. #endif  /* _DEBUG */
  224.  
  225. #if defined (_WIN32)
  226.             if ( (__error_mode == _OUT_TO_STDERR) || ((__error_mode ==
  227.                    _OUT_TO_DEFAULT) && (__app_type == _CONSOLE_APP)) )
  228.             {
  229.                 WriteFile( GetStdHandle(STD_ERROR_HANDLE),
  230.                            rterrs[tblindx].rterrtxt,
  231.                            strlen(rterrs[tblindx].rterrtxt),
  232.                            &bytes_written,
  233.                            NULL );
  234.             }
  235.             else if (rterrnum != _RT_CRNL)
  236.             {
  237.                 #define MAXLINELEN 60
  238.                 char * pch;
  239.                 char progname[MAX_PATH];
  240.                 char outmsg[MAXLINELEN+100];
  241.  
  242.                 if (!GetModuleFileName(NULL, progname, MAX_PATH))
  243.                     strcpy(progname, "<program name unknown>");
  244.  
  245.                 pch = (char *)progname;
  246.  
  247.                 if (strlen(pch) + 1 > MAXLINELEN)
  248.                 {
  249.                     pch += strlen(progname) + 1 - MAXLINELEN;
  250.                     strncpy(pch, "...", 3);
  251.                 }
  252.  
  253.                 strcpy(outmsg, "Runtime Error!\n\nProgram: ");
  254.                 strcat(outmsg, pch);
  255.                 strcat(outmsg, "\n\n");
  256.                 strcat(outmsg, rterrs[tblindx].rterrtxt);
  257.  
  258.                 __crtMessageBoxA(outmsg,
  259.                         "Microsoft Visual C++ Runtime Library",
  260.                         MB_OK|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
  261.             }
  262.  
  263. #else  /* defined (_WIN32) */
  264.  
  265. #if defined (_M_M68K) || defined (_M_MPPC)
  266. #if defined (_M_M68K) || defined (_M_MPPC)
  267.             _write(2, rterrs[tblindx].rterrtxt,
  268. #else  /* defined (_M_M68K) || defined (_M_MPPC) */
  269.             write(STDERR_FILENO,rterrs[tblindx].rterrtxt,
  270. #endif  /* defined (_M_M68K) || defined (_M_MPPC) */
  271.             strlen(rterrs[tblindx].rterrtxt));
  272. #else  /* defined (_M_M68K) || defined (_M_MPPC) */
  273.  
  274. #error ERROR - ONLY WIN32 OR POSIX OR MAC TARGET SUPPORTED!
  275.  
  276. #endif  /* defined (_M_M68K) || defined (_M_MPPC) */
  277.  
  278. #endif  /* defined (_WIN32) */
  279.  
  280.         }
  281. }
  282.  
  283.  
  284. #ifdef _WIN32
  285.  
  286. /***
  287. *_GET_RTERRMSG(message) - returns ptr to error text for given runtime error
  288. *
  289. *Purpose:
  290. *       This routine returns the message associated with rterrnum
  291. *
  292. *Entry:
  293. *       int rterrnum - runtime error number
  294. *
  295. *Exit:
  296. *       no return value
  297. *
  298. *Exceptions:
  299. *       none
  300. *
  301. *******************************************************************************/
  302.  
  303. char * __cdecl _GET_RTERRMSG (
  304.         int rterrnum
  305.         )
  306. {
  307.         int tblindx;
  308.  
  309.         for ( tblindx = 0 ; tblindx < _RTERRCNT ; tblindx++ )
  310.             if ( rterrnum == rterrs[tblindx].rterrno )
  311.                 break;
  312.  
  313.         if ( rterrnum == rterrs[tblindx].rterrno )
  314.             return rterrs[tblindx].rterrtxt;
  315.         else
  316.             return NULL;
  317. }
  318. #endif  /* _WIN32 */
  319.