1 #include "stdafx.h"
2 #include "MASTER.h"
3 
4 #define TECPLOTENGINEMODULE
5 
6 /*
7 ******************************************************************
8 ******************************************************************
9 *******                                                   ********
10 ******  (C) 1988-2010 Tecplot, Inc.                        *******
11 *******                                                   ********
12 ******************************************************************
13 ******************************************************************
14 */
15 
16 #define Q_MSGMODULE
17 #include "GLOBAL.h"
18 #include "TASSERT.h"
19 #include "Q_UNICODE.h"
20 #include "ALLOC.h"
21 #include "ARRLIST.h"
22 
23 #if defined TECPLOTKERNEL
24 /* CORE SOURCE CODE REMOVED */
25 #if !defined ENGINE
26 #if defined MOTIF
27 #endif
28 #if defined MSWIN
29 #endif
30 #endif
31 #endif
32 
33 #include "STRUTIL.h"
34 #if defined TECPLOTKERNEL
35 /* CORE SOURCE CODE REMOVED */
36 #endif
37 
38 using std::string;
39 using namespace tecplot::strutil;
40 #if defined TECPLOTKERNEL
41 /* CORE SOURCE CODE REMOVED */
42 #endif
43 
44 #define MAXCHARACTERSPERLINE 60
45 /*
46  * Wrap a string so it contains at most CharactersPerLine
47  * characters. Embedded newlines are left alone. Spaces
48  * following newlines are also left alone.
49  */
WrapString(const char * OldString,char ** NewString)50 Boolean_t WrapString(const char  *OldString,
51                      char       **NewString)
52 {
53     size_t L;
54     if (OldString == NULL)
55         return (FALSE);
56 
57     /*
58      *  Assume Old string has ample spaces.  Will only be
59      *  replacing some spaces with newlines and removing
60      *  other spaces.  New string can be allocated to be
61      *  same length as old string.
62      */
63 
64     L = strlen(OldString);
65     *NewString = ALLOC_ARRAY(L + 1, char, "new error message string");
66     if (*NewString == NULL)
67         return (FALSE);
68 
69     strcpy(*NewString, OldString);
70 
71     if (L > MAXCHARACTERSPERLINE)
72     {
73         char *LineStart = *NewString;
74         char *LastWord  = *NewString;
75         char *WPtr      = *NewString;
76         while (WPtr && (*WPtr != '\0'))
77         {
78             size_t CurLen;
79             /*
80              * Find next hard newline.  If there is one befor the
81              * line should be chopped then reset the Last Word to
82              * be at the first word after the newline.
83              */
84             WPtr = strchr(LineStart, '\n');
85             if (WPtr && ((WPtr - LineStart) < MAXCHARACTERSPERLINE))
86             {
87                 WPtr++;
88                 while (*WPtr == '\n')
89                     WPtr++;
90                 LineStart = WPtr;
91                 /*
92                  * Skip over trailing spaces.  Special handling to
93                  * allow indent after hard newline.
94                  */
95                 while (*WPtr == ' ')
96                     WPtr++;
97                 LastWord  = WPtr;
98                 continue;
99             }
100             /*
101              *  Find next "word"
102              */
103             WPtr = strchr(LastWord, ' ');
104             if (WPtr != NULL)
105             {
106                 while (*WPtr == ' ')
107                     WPtr++;
108             }
109 
110             if (WPtr == NULL)
111             {
112                 CurLen = strlen(LineStart);
113             }
114             else
115             {
116                 CurLen = WPtr - LineStart;
117             }
118 
119             if (CurLen > MAXCHARACTERSPERLINE)
120             {
121                 /*
122                  * Line is too long.  Back up to previous
123                  * word and replace preceeding space with
124                  * a newline.
125                  */
126                 if (LastWord == LineStart)
127                 {
128                     /*
129                      * Bad news, line has very long word.
130                      */
131                     if (WPtr && (*WPtr != '\0'))
132                     {
133                         *(WPtr - 1) = '\n';
134                         LastWord = WPtr;
135                     }
136                 }
137                 else
138                 {
139                     *(LastWord - 1) = '\n';
140                 }
141                 LineStart = LastWord;
142             }
143             else
144                 LastWord = WPtr;
145         }
146     }
147     return (TRUE);
148 }
149 
150 
SendWarningToFile(FILE * F,const char * S)151 static void SendWarningToFile(FILE *F,
152                               const char *S)
153 {
154     char *S2;
155     REQUIRE(VALID_REF(F));
156     REQUIRE(VALID_REF(S));
157     if (WrapString(S, &S2))
158     {
159         fprintf(F, "Warning: %s\n", S2);
160         FREE_ARRAY(S2, "temp warning string");
161     }
162 }
163 
164 #if defined TECPLOTKERNEL
165 /* CORE SOURCE CODE REMOVED */
166 #endif
167 
168 
169 /**
170  * Show the warning message. Note that the format string can be the only
171  * argument, in which case it is essentially the warning message itself.
172  *
173  * param format
174  *     C format string or a simple message.
175  * param ...
176  *     Zero or more variable arguments. The number of arguments must correspond
177  *     to the placeholders in the format string.
178  */
Warning(TranslatedString format,...)179 void Warning(TranslatedString format,
180              ...) /* zero or more arguments */
181 {
182     REQUIRE(!format.isNull());
183 
184     static Boolean_t InWarning = FALSE; /* ...used to prevent recursive deadlock */
185     if (!InWarning)
186     {
187 #if defined TECPLOTKERNEL
188 /* CORE SOURCE CODE REMOVED */
189 #endif
190 
191         InWarning = TRUE;
192         {
193             /*
194              * Attempt to format the string. Failing that simply use the original format
195              * string argument which, if we ran out of memory while formatting, is
196              * probably just an warning message saying that we ran out of memory in some
197              * previous operation anyway.
198              */
199             Boolean_t cleanUp = TRUE;
200 
201             va_list  Arguments;
202             va_start(Arguments, format);
203             char* message = vFormatString(format.c_str(), Arguments);
204             va_end(Arguments);
205 
206             if (message == NULL)
207             {
208                 cleanUp = FALSE; // ...this boolean allows us to "carefully" cast away the const'ness
209                 message = (char*)format.c_str();
210             }
211 
212 #if defined TECPLOTKERNEL
213 /* CORE SOURCE CODE REMOVED */
214 #ifdef MSWIN
215 #endif
216 #if defined UNIXX
217 #endif
218 #if defined MSWIN
219 #endif
220 #else /* !TECPLOTKERNEL */
221             {
222                 SendWarningToFile(stderr, message);
223             }
224 #endif
225 
226             if (cleanUp)
227                 FREE_ARRAY(message, "message");
228         }
229         InWarning = FALSE;
230 
231 #if defined TECPLOTKERNEL
232 /* CORE SOURCE CODE REMOVED */
233 #endif
234     }
235 }
236 
237 
SendErrToFile(FILE * File,const char * Msg)238 static void SendErrToFile(FILE       *File,
239                           const char *Msg)
240 {
241     char *formattedMsg;
242     REQUIRE(VALID_REF(File));
243     REQUIRE(VALID_REF(Msg));
244     if (WrapString(Msg, &formattedMsg))
245     {
246         fprintf(File, "Err: %s\n", formattedMsg);
247         FREE_ARRAY(formattedMsg, "temp error string");
248     }
249     else
250         fprintf(File, "Err: %s\n", Msg);
251 }
252 
253 
254 /* Fall-back ErrMsg procedure when nothing else works */
DefaultErrMsg(const char * Msg)255 static void DefaultErrMsg(const char *Msg)
256 {
257     REQUIRE(VALID_REF(Msg));
258 
259 #ifdef MSWIN
260 #ifdef TECPLOTKERNEL
261 /* CORE SOURCE CODE REMOVED */
262 #else
263     MessageBox(NULL, Msg, "Error", MB_OK | MB_ICONERROR);
264 #endif
265 #else
266     SendErrToFile(stderr, Msg);
267 #endif
268 }
269 
PostErrorMessage(TranslatedString format,va_list Arguments)270 static void PostErrorMessage(TranslatedString format,
271                              va_list          Arguments)
272 {
273     REQUIRE(!format.isNull());
274 
275     /*
276      * Attempt to format the string. Failing that simply use the original format
277      * string argument which, if we ran out of memory while formatting, is
278      * probably just an error message saying that we ran out of memory in some
279      * previous operation anyway.
280      */
281     Boolean_t cleanUp = TRUE;
282     char* messageString = vFormatString(format.c_str(), Arguments);
283     if (messageString == NULL)
284     {
285         cleanUp = FALSE; // ...this boolean allows us to "carefully" cast away the const'ness
286         messageString = (char*)format.c_str();
287     }
288 
289 #if defined TECPLOTKERNEL
290 /* CORE SOURCE CODE REMOVED */
291 #ifdef MSWIN
292 #endif
293 #if defined UNIXX
294 #if !defined ENGINE
295 #endif
296 #endif
297 #else /* !TECPLOTKERNEL */
298     {
299         DefaultErrMsg(messageString);
300     }
301 #endif
302 
303     /* cleanup if we allocated the string */
304     if (cleanUp)
305         FREE_ARRAY(messageString, "messageString");
306 }
307 
308 /*
309  * NOTES:
310  *   This function is thread safe in that it may be safely called by multiple
311  *   threads however when running interactively only the first error message is
312  *   queued for display on idle. In batch mode all messages are sent to the
313  *   batch log file.
314  */
vErrMsg(TranslatedString format,va_list Arguments)315 void vErrMsg(TranslatedString format,
316              va_list          Arguments)
317 {
318     REQUIRE(!format.isNull());
319 
320     static Boolean_t InErrMsg = FALSE; /* ...used to prevent recursive deadlock */
321     if (!InErrMsg)
322     {
323 #if defined TECPLOTKERNEL
324 /* CORE SOURCE CODE REMOVED */
325 #endif
326 
327         InErrMsg = TRUE;
328         {
329             PostErrorMessage(format, Arguments);
330         }
331         InErrMsg = FALSE;
332 
333 #if defined TECPLOTKERNEL
334 /* CORE SOURCE CODE REMOVED */
335 #endif
336     }
337 }
338 
339 /**
340  * Show the error message. Note that the format string can be the only
341  * argument, in which case it is essentially the error message itself.
342  *
343  * @param format
344  *   C format string or a simple message.
345  * @param ...
346  *   Zero or more variable arguments. The number of arguments must correspond
347  *   to the placeholders in the format string.
348  */
ErrMsg(TranslatedString format,...)349 void ErrMsg(TranslatedString format,
350             ...) /* zero or more arguments */
351 {
352     REQUIRE(!format.isNull());
353 
354     va_list Arguments;
355     va_start(Arguments, format);
356 #if defined TECPLOTKERNEL
357 /* CORE SOURCE CODE REMOVED */
358 #else
359     PostErrorMessage(format, Arguments);
360 #endif
361     va_end(Arguments);
362 }
363 
364 
365 #if defined TECPLOTKERNEL
366 /* CORE SOURCE CODE REMOVED */
367 #if !defined ENGINE
368 #endif
369 #if !defined ENGINE
370 #if defined MOTIF
371 #endif
372 #if defined MSWIN
373 #endif
374 #endif
375 #if !defined ENGINE
376 #if defined MOTIF
377 #endif
378 #if defined MSWIN
379 #endif
380 #endif
381 #if !defined ENGINE
382 #if defined MOTIF
383 #endif /* MOTIF */
384 #if defined MSWIN
385 #endif
386 #if defined MOTIF
387 #endif /* MOTIF */
388 #endif
389 #if !defined ENGINE
390 #endif
391 #endif /* TECPLOTKERNEL */
392 
393