source: trunk/dll/error.c@ 616

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

Add DbgMsg
Correct IDS_GENERR1TEXT formatting

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