source: trunk/dll/error.c@ 614

Last change on this file since 614 was 614, checked in by Steven Levine, 18 years ago

Reformat logged errors

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.0 KB
Line 
1
2/***********************************************************************
3
4 $Id: error.c 614 2007-04-19 02:24:12Z stevenhl $
5
6 Error reporting
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2004, 2007 Steven H. Levine
10
11 12 Aug 04 SHL Comments
12 23 May 05 SHL Move saymsg here
13 24 May 05 SHL Rename General_Error to more accurate Win_Error
14 24 May 05 SHL Rename saymsg to more accurate Misc_Error
15 24 May 05 SHL Rework Win_Error args and clean up logic
16 27 May 05 SHL Rework to use common showMsg
17 14 Aug 05 SHL showMsg: suppress write to stdout if not error message
18 13 Jul 06 SHL Add Runtime_Error
19 22 Jul 06 SHL Optimize calling sequences
20 26 Jul 06 SHL Add ..._Error2
21 16 Aug 06 SHL Tweak message formatting
22 07 Jan 07 GKY Move error strings etc. to string file
23 18 Apr 07 SHL showMsg: correct selective logging checks
24
25***********************************************************************/
26
27#define INCL_DOS
28#define INCL_DOSERRORS
29#define INCL_WIN
30
31#include <os2.h>
32#include <stdlib.h>
33#include <stdio.h>
34#include <string.h>
35#include <stdarg.h>
36
37#include "fm3dll.h"
38#include "fm3str.h"
39
40#pragma data_seg(DATA1)
41#pragma alloc_text(FMINPUT,Win_Error,Dos_Error,saymsg,showMsg)
42
43static APIRET showMsg(ULONG mb_type, HWND hwnd, PCSZ pszTitle, PCSZ pszMsg, BOOL wantLog);
44
45//== Win_Error: report Win...() error using passed message string ===
46
47VOID Win_Error(HWND hwndErr, HWND hwndOwner, PCSZ pszFileName, ULONG ulLineNo,
48 PCSZ pszFmt, ...)
49{
50 PERRINFO pErrInfoBlk; /* Pointer to ERRINFO structure filled
51 by WinGetErrorInfo */
52 PSZ pszOffset; /* Pointer to current error message returned
53 by WinGetErrorInfo */
54 CHAR szMsg[4096];
55 PSZ psz;
56 HAB hab;
57 va_list va;
58
59 if (hwndErr == NULLHANDLE)
60 hab = (HAB) 0;
61 else
62 hab = WinQueryAnchorBlock(hwndErr);
63
64 // Format callers message
65 va_start(va, pszFmt);
66 szMsg[sizeof(szMsg) - 1] = 0;
67 vsprintf(szMsg, pszFmt, va);
68 va_end(va);
69
70 if (szMsg[sizeof(szMsg) - 1]) {
71 fprintf(stderr, "Buffer overflow in Win_Error - need %u bytes\n", strlen(szMsg) + 1);
72 fflush(stderr);
73 }
74
75 if (strchr(szMsg, ' ') == NULL)
76 strcat(szMsg, " failed."); // Assume simple function name
77
78 // Append file name and line number
79 sprintf(szMsg + strlen(szMsg),
80 GetPString(IDS_GENERR1TEXT), pszFileName, ulLineNo, " ");
81
82 // Get last PM error for the current thread
83 pErrInfoBlk = WinGetErrorInfo(hab);
84 if (!pErrInfoBlk) {
85 psz = szMsg + strlen(szMsg);
86 strcpy(psz, " WinGetErrorInfo failed.");
87 }
88 else {
89 if (!hwndOwner)
90 hwndOwner = HWND_DESKTOP;
91 /* Find message offset in array of message offsets
92 Assume 1 message - fixme?
93 */
94 pszOffset = ((PSZ) pErrInfoBlk) + pErrInfoBlk->offaoffszMsg;
95 /* Address error message in array of messages and
96 append error message to source code linenumber
97 */
98 psz = szMsg + strlen(szMsg);
99 sprintf(psz, "#0x%04x \"", ERRORIDERROR(pErrInfoBlk->idError));
100 psz += strlen(psz);
101 strcpy(psz, ((PSZ) pErrInfoBlk) + *(PSHORT) pszOffset);
102 psz += strlen(psz);
103 // Chop trailing mush
104 psz--;
105 while (*psz == '\r' || *psz == '\n' || *psz == ' ')
106 *psz-- = 0;
107 if (*psz)
108 psz++;
109 strcpy(psz, "\"");
110 WinFreeErrorInfo(pErrInfoBlk); // Free resource segment
111 }
112
113 showMsg(MB_ENTER | MB_ICONEXCLAMATION, hwndOwner, GetPString(IDS_GENERR2TEXT),
114 szMsg, TRUE);
115
116} // Win_Error
117
118//== Win_Error2: report Win...() error using passed message id ===
119
120VOID Win_Error2(HWND hwndErr, HWND hwndOwner, PCSZ pszFileName,
121 ULONG ulLineNo, UINT idMsg)
122{
123 Win_Error(hwndErr, hwndOwner, pszFileName, ulLineNo, GetPString(idMsg));
124
125} // Win_Error2
126
127//== Dos_Error: report Dos...() error using passed message string ===
128
129INT Dos_Error(ULONG mb_type, ULONG ulRC, HWND hwndOwner, PCSZ pszFileName,
130 ULONG ulLineNo, PCSZ pszFmt, ...)
131{
132 CHAR szMsg[4096];
133 ULONG Class; // Error class
134 ULONG action; // Error action
135 ULONG Locus; // Error location
136 ULONG ulMsgLen;
137 CHAR *pszMsgStart;
138 CHAR *psz;
139 va_list va;
140
141 if (!ulRC)
142 return MBID_ENTER; // Should not have been called
143
144 // Format caller's message
145 va_start(va, pszFmt);
146 szMsg[sizeof(szMsg) - 1] = 0;
147 vsprintf(szMsg, pszFmt, va);
148 va_end(va);
149
150 if (szMsg[sizeof(szMsg) - 1]) {
151 fprintf(stderr, "Buffer overflow in Dos_Error - need %u bytes\n", strlen(szMsg) + 1);
152 fflush(stderr);
153 }
154
155 if (strchr(szMsg, ' ') == NULL)
156 strcat(szMsg, " failed."); // Assume simple function name
157
158 DosErrClass(ulRC, &Class, &action, &Locus);
159
160 sprintf(szMsg + strlen(szMsg),
161 GetPString(IDS_DOSERR1TEXT),
162 pszFileName,
163 ulLineNo,
164 ulRC,
165 GetPString(IDS_ERRCLASS1TEXT + (Class - 1)),
166 GetPString(IDS_ERRACTION1TEXT + (action - 1)),
167 GetPString(IDS_ERRLOCUS1TEXT + (Locus - 1)));
168 pszMsgStart = szMsg + strlen(szMsg) + 1;
169 // Get message leaving space for NL separator
170 if (!DosGetMessage
171 (NULL, 0L, (PCHAR) pszMsgStart + 1, 1024, ulRC, "OSO001.MSG", &ulMsgLen)
172 || !DosGetMessage(NULL, 0L, (PCHAR) pszMsgStart + 1, 1024, ulRC,
173 "OSO001H.MSG", &ulMsgLen)) {
174 // Got message
175 pszMsgStart[ulMsgLen + 1] = 0; // Terminate
176 *(pszMsgStart - 1) = '\n'; // Stuff NL before message text
177 *pszMsgStart = '\"'; // Prefix message text with quote
178
179 psz = pszMsgStart + ulMsgLen; // Point at last char
180 // Chop trailing NL CR TAB
181 while (*psz &&
182 (*psz == '\r' || *psz == '\n' || *psz == ' ' || *psz == '\t')) {
183 *psz-- = 0;
184 }
185 strcat(psz, "\""); // Append trailing quote
186
187 // Convert CR and NL combos to single space
188 psz = pszMsgStart;
189 while (*psz) {
190 if (*psz == '\n' || *psz == '\r') {
191 while (*(psz + 1) == '\n' || *(psz + 1) == '\r')
192 memmove(psz, psz + 1, strlen(psz));
193 *psz = ' ';
194 }
195 else
196 psz++;
197 }
198 }
199
200 return showMsg(mb_type | MB_ICONEXCLAMATION, hwndOwner, GetPString(IDS_DOSERR2TEXT),
201 szMsg, TRUE);
202
203} // Dos_Error
204
205//== Dos_Error2: report Dos...() error using passed message id ===
206
207INT Dos_Error2(ULONG mb_type, ULONG ulRC, HWND hwndOwner, PCSZ pszFileName,
208 ULONG ulLineNo, UINT idMsg)
209{
210 return Dos_Error(mb_type, ulRC, hwndOwner, pszFileName, ulLineNo,
211 GetPString(idMsg));
212} // Dos_Error2
213
214//== Runtime_Error: report runtime library error using passed message string ===
215
216VOID Runtime_Error(PCSZ pszSrcFile, UINT uSrcLineNo, PCSZ pszFmt, ...)
217{
218 CHAR szMsg[4096];
219 va_list va;
220 PSZ psz;
221
222 // Format caller's message
223 va_start(va, pszFmt);
224 szMsg[sizeof(szMsg) - 1] = 0;
225 vsprintf(szMsg, pszFmt, va);
226 va_end(va);
227
228 if (szMsg[sizeof(szMsg) - 1]) {
229 fprintf(stderr, "Buffer overflow in Runtime_Error - need %u bytes\n", strlen(szMsg) + 1);
230 fflush(stderr);
231 }
232
233 if (strchr(szMsg, ' ') == NULL)
234 strcat(szMsg, " failed."); // Assume simple function name
235
236 sprintf(szMsg + strlen(szMsg),
237 GetPString(IDS_GENERR1TEXT), pszSrcFile, uSrcLineNo);
238
239 showMsg(MB_ICONEXCLAMATION, HWND_DESKTOP, DEBUG_STRING, szMsg, TRUE);
240
241} // Runtime_Error
242
243//== Runtime_Error2: report runtime library error using passed message id ===
244
245VOID Runtime_Error2(PCSZ pszSrcFile, UINT uSrcLineNo, UINT idMsg)
246{
247 Runtime_Error(pszSrcFile, uSrcLineNo, GetPString(idMsg));
248
249} // Runtime_Error2
250
251// fixme to be rename to Misc_Error
252
253//=== saymsg: report misc error using passed message ===
254
255APIRET saymsg(ULONG mb_type, HWND hwnd, PCSZ pszTitle, PCSZ pszFmt, ...)
256{
257 CHAR szMsg[4096];
258 va_list va;
259
260 va_start(va, pszFmt);
261 szMsg[sizeof(szMsg) - 1] = 0;
262 vsprintf(szMsg, pszFmt, va);
263 va_end(va);
264
265 if (szMsg[sizeof(szMsg) - 1]) {
266 fprintf(stderr, "Buffer overflow in saymsg - need %u bytes\n", strlen(szMsg) + 1);
267 fflush(stderr);
268 }
269
270 return showMsg(mb_type, hwnd, pszTitle, szMsg, FALSE);
271
272} // saymsg
273
274//=== showMsg: display error popup ===
275
276static APIRET showMsg(ULONG mb_type, HWND hwnd, PCSZ pszTitle, PCSZ pszMsg, BOOL wantLog)
277{
278 if (wantLog) {
279 fputs(pszMsg, stderr);
280 fputc('\n', stderr);
281 fputc('\n', stderr);
282 fflush(stderr);
283 }
284
285 if (!hwnd)
286 hwnd = HWND_DESKTOP;
287
288 DosBeep(250, 100);
289
290 return WinMessageBox(HWND_DESKTOP, // Parent
291 hwnd, // Owner
292 (PSZ) pszMsg, (PSZ) pszTitle, 0, // help id
293 mb_type | MB_MOVEABLE);
294} // showMsg
Note: See TracBrowser for help on using the repository browser.