source: trunk/dll/error.c@ 452

Last change on this file since 452 was 452, checked in by root, 19 years ago

Tweak message formatting

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