Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 645 lines (580 sloc) 15.703 kb
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
1 /* message.c */
2 /* Copyright 1995 by Steve Kirkendall */
3
4
5 #include "elvis.h"
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
6 #ifdef FEATURE_RCSID
2fe6e17 @mbert Import Elvis 2.2_1 (written by Steve Kirkendall)
authored
7 char id_message[] = "$Id: message.c,v 2.53 2004/03/19 23:04:10 steve Exp $";
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
8 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
9 #if USE_PROTOTYPES
10 # include <stdarg.h>
11 #else
12 # include <varargs.h>
13 #endif
14
15 #if USE_PROTOTYPES
16 static void translate(char *terse);
17 #endif
18
19 static CHAR verbose[200];
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
20 static FILE *fperr, *fpinfo;
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
21 static ELVBOOL msghiding;
22
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
23
24 /* redirect messages to a log file. If "filename" is NULL then revert to
25 * the normal reporting (stdout and stderr)
26 */
27 void msglog(filename)
28 char *filename;
29 {
30 /* if previously redirected, then stop redirection now */
31 if (fperr != NULL && fperr != stderr)
32 fclose(fperr);
33
34 /* open the log file, if any */
35 fperr = fpinfo = filename ? fopen(filename, "w") : NULL;
36 }
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
37
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
38 /* These are used for generating an error message which includes a file name
39 * and line number, whenever possible.
40 */
41 static char *scriptnamedup;
42 static long scriptline;
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
43 static ELVBOOL scriptknown;
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
44
45 /* This is called by other code to inform the message module of the location
46 * of the current command. This allows the message module to report the file
47 * name (or some other name, if not from a file) and line number (usually)
48 * as part of an error message. When executing commands from a buffer or
49 * scanned string, "mark" is the value returned by scanmark() for the scanning
50 * pointer; otherwise, "mark" should be NULL. For strings, the "name" value
51 * should describe the origin of the string: an alias name, or something else
52 * for other strings.
53 */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
54 void msgscriptline(mark, name)
55 MARK mark;
56 char *name;
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
57 {
58 char newname[300];
59
60 if (!mark || !markbuffer(mark))
61 {
62 if (name)
63 {
64 if (!scriptnamedup || strcmp(scriptnamedup, name))
65 {
66 free(scriptnamedup);
67 sprintf(newname, "\"%s\"", name);
68 scriptnamedup = strdup(newname);
69 if (!mark || mark->offset == 0)
70 scriptline = 1;
71 else
72 scriptline++;
73 }
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
74 scriptknown = ElvTrue;
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
75 return;
76 }
77 else if (!scriptnamedup)
78 scriptnamedup = strdup("unknown script");
79 scriptline++;
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
80 scriptknown = ElvFalse;
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
81 return;
82 }
83 if (o_filename(markbuffer(mark)))
84 strcpy(newname, tochar8(o_filename(markbuffer(mark))));
85 else
86 sprintf(newname, "(%s)", tochar8(o_bufname(markbuffer(mark))));
87 if (!scriptnamedup || strcmp(newname, scriptnamedup))
88 {
89 free(scriptnamedup);
90 scriptnamedup = strdup(newname);
91 }
92 scriptline = markline(mark);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
93 scriptknown = ElvTrue;
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
94 }
95
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
96 /* Copy a message into static verbose[] buffer, declared at the top of this
97 * file. If a buffer named "Elvis messages" exists, translate the message via
98 * that buffer along the way.
99 */
100 static void translate(terse)
101 char *terse; /* terse form of error message */
102 {
103 BUFFER buf; /* the "Elvis messages" buffer */
104 MARKBUF mark; /* the start of the buffer */
105 CHAR *scan; /* used for scanning the buffer */
106 CHAR *build; /* used for copying chars into the verbose[] buffer */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
107 ELVBOOL bol; /* are we at the start of a line? */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
108 int match; /* used for counting characters that match */
109
110 /* Copy the terse string into the verbose buffer, as a default */
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
111 for (build = verbose, match = 0;
112 build < &verbose[QTY(verbose) - 1] && terse[match];
113 )
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
114 {
115 *build++ = terse[match++];
116 }
117 *build = '\0';
118
119 /* if the "terse" option is on, then we're done */
120 if (o_terse)
121 {
122 return;
123 }
124
125 /* Find the "Elvis messages" buffer. If it doesn't exist, then
126 * no more translation is necessary.
127 */
128 buf = buffind(toCHAR(MSG_BUF));
129 if (!buf)
130 {
131 return;
132 }
133
134 /* Scan the buffer for a line which starts with the terse message
135 * followed by a colon. If there is no such line, then we're done.
136 */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
137 for (scanalloc(&scan, marktmp(mark, buf, 0L)), match = 0, bol = ElvTrue;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
138 scan;
139 scannext(&scan))
140 {
141 /* if this is a newline, then set "bol" and zero "match" */
142 if (*scan == '\n')
143 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
144 bol = ElvTrue;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
145 match = 0;
146 continue;
147 }
148
149 /* if we're in the middle of a match, then check to see if
150 * this position in "Elvis messages" matches the terse message.
151 */
152 if (match >= 0)
153 {
154 if (*scan != (terse[match] ? terse[match] : ':'))
155 {
156 match = -1;
157 continue;
158 }
159 if (!terse[match])
160 {
161 break;
162 }
163 match++;
164 }
165 }
166
167 /* if we get here and "scan" isn't NULL, then we've found the line
168 * that translates this terse message and "scan" is pointing at the
169 * ':' that marks the end of the terse text. Copy the verbose text
170 * after the ':' into the verbose[] variable.
171 */
172 if (scan)
173 {
174 /* skip the ':' */
175 scannext(&scan);
176
177 /* at this point, the previous character was not a newline */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
178 bol = ElvFalse;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
179
180 /* copy the verbose message from the buffer */
181 for (build = verbose; build < &verbose[QTY(verbose) - 1]; )
182 {
183 /* if non-whitespace, then copy the character */
184 if (*scan != ' ' && *scan != '\t' && *scan != '\n')
185 {
186 *build++ = *scan;
187 scannext(&scan);
188 continue;
189 }
190
191 /* skip whitespace */
192 while (scan && (*scan == ' ' || *scan == '\t' || *scan == '\n'))
193 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
194 bol = (*scan == '\n') ? ElvTrue : ElvFalse;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
195 scannext(&scan);
196 }
197
198 /* if this non-whitespace character appeared right after
199 * a newline, then we're done. This is because an
200 * unindented line in this file always marks the start
201 * of the next terse message. We're also done if we
202 * hit the end of the buffer.
203 */
204 if (!scan || bol)
205 {
206 break;
207 }
208
209 /* whitespace is converted into a single blank
210 * character, except at the very beginning of the
211 * message where it is deleted completely.
212 */
213 if (build != verbose)
214 {
215 *build++ = ' ';
216 }
217 }
218 *build = '\0';
219 }
220
221 /* clean up */
222 scanfree(&scan);
223 }
224
225
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
226 /* Set the message hiding flag to a given value & return its previous value */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
227 ELVBOOL msghide(hide)
228 ELVBOOL hide; /* should we hide messages? (else reveal them) */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
229 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
230 ELVBOOL previous = msghiding;
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
231
232 msghiding = hide;
233 return previous;
234 }
235
236
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
237 /* output a message via the GUI. Before calling the GUI, it subjects
238 * the terse message to a series of transformations. First, the
239 * buffer "Elvis messages" is scanned to perform a user-configurable
240 * transformation, such as translating it into a native language.
241 * Then the message is evaluated via the calculate() function with
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
242 * its "asmsg" parameter set to ElvTrue.
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
243 *
244 * The arg[] array passed into calculate() is built from the extra arguments
245 * supplied to msg. The beginning of the terse string can begin with a list
246 * of characters enclosed in square brackets to indicate how the arguments
247 * are to be converted to text strings. The conversion letters are:
248 * d The argument is a (long int), to be shown as a decimal number
249 * s The argument is a (char *)
250 * S The argument is a (CHAR *)
251 * c The argument is a (char), to be shown as a string of length 1
252 * C The argument is a (CHAR), to be shown as a string of length 1
253 * If no bracketted list appears at the start of the string, then it is assumed
254 * that the message has no extra arguments.
255 *
256 * For example, msg(MSG_info, "[s]\$1=$1, list=(list)", "foo") will output
257 * "$1=foo, list=false"
258 */
259 #if USE_PROTOTYPES
260 void msg(MSGIMP imp, char *terse, ...)
261 {
262 #else
263 void msg(imp, terse, va_alist)
264 MSGIMP imp; /* message type */
265 char *terse; /* terse form of message (may contain %s or %d) */
266 va_dcl
267 {
268 #endif
269 va_list argptr;
270 CHAR *scan;
271 CHAR *arg[10];
272 char text[12], *str;
273 int i;
274 BUFFER buf;
275 MARKBUF mark;
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
276 ELVBOOL ding;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
277
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
278 /* if fperr and fpinfo are NULL, then use stderr and stdout */
279 if (!fperr)
280 {
281 fperr = stderr;
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
282 #ifdef FEATURE_STDIN
283 if (stdin_not_kbd)
284 fpinfo = stderr;
285 else
286 #endif
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
287 fpinfo = stdout;
288 }
289
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
290 /* can't nest msg() calls. If another call is in progress, exit now */
2fe6e17 @mbert Import Elvis 2.2_1 (written by Steve Kirkendall)
authored
291 #if 0
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
292 if (*verbose || (msghiding && (imp == MSG_ERROR || imp == MSG_WARNING)))
2fe6e17 @mbert Import Elvis 2.2_1 (written by Steve Kirkendall)
authored
293 #else
294 if (*verbose || msghiding)
295 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
296 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
297 if (imp == MSG_FATAL)
298 {
299 fprintf(fperr, "%s\n", terse);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
300 o_tempsession = ElvFalse;
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
301 sesclose();
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
302 if (gui)
303 (*gui->term)();
304 else if (chosengui)
305 (*chosengui->term)();
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
306 #ifdef NDEBUG
307 exit(1);
308 #else
309 abort();
310 #endif
311 }
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
312 return;
313 }
314
315 /* Convert any arguments to CHAR strings */
316 if (*terse == '[')
317 {
318 #if USE_PROTOTYPES
319 va_start(argptr, terse);
320 #else
321 va_start(argptr);
322 #endif
323 for (i = 0, terse++; *terse != ']'; i++, terse++)
324 {
325 assert(i < QTY(arg));
326
327 /* convert argument to a CHAR string */
328 switch (*terse)
329 {
330 case 'd':
331 sprintf(text, "%ld", va_arg(argptr, long));
332 arg[i] = toCHAR(text);
333 break;
334
335 case 'S':
336 arg[i] = va_arg(argptr, CHAR *);
337 if (!arg[i])
338 arg[i] = toCHAR("NULL");
339 break;
340
341 case 's':
342 str = va_arg(argptr, char *);
343 if (!str)
344 str = "NULL";
345 arg[i] = toCHAR(str);
346 break;
347
348 case 'c':
349 text[0] = va_arg(argptr, _char_);
350 text[1] = '\0';
351 arg[i] = toCHAR(text);
352 break;
353
354 case 'C':
355 text[0] = va_arg(argptr, _CHAR_);
356 text[1] = '\0';
357 arg[i] = toCHAR(text);
358 break;
359
360 default:
361 /* elvis source code should never have a
362 * bad format code.
363 */
364 abort();
365 }
366
367 /* dynamically allocate a copy of that string. This
368 * is done because some parameter types use the text[]
369 * buffer, and a later argument may need to reuse that
370 * buffer.
371 */
372 arg[i] = CHARdup(arg[i]);
373 }
374 va_end(argptr);
375 arg[i] = NULL;
376
377 /* move the terse pointer past the closing ']' character */
378 assert(*terse == ']');
379 terse++;
380 }
381 else /* no bracketted list at start of terse string */
382 {
383 /* no extra arguments */
384 arg[0] = NULL;
385 }
386
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
387 if (imp == MSG_FATAL && !arg[0])
388 {
389 /* set "scan" to the message text */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
390 scan = toCHAR(terse);
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
391 }
392 else
393 {
394 /* translate the terse message via "Elvis messages" buffer */
395 translate(terse);
396
397 /* expand any arguments or option names */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
398 scan = calculate(verbose, arg, CALC_MSG);
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
399 if (!scan)
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
400 scan = calculate(toCHAR(terse), arg, CALC_MSG);
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
401 if (!scan)
402 scan = toCHAR(terse);
403 }
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
404
405 /* If it starts with a ^G character, then ring the bell. Also
406 * ring the bell if errorbells or warningbells is set
407 */
408 switch (imp)
409 {
410 case MSG_ERROR: ding = o_errorbells; break;
411 case MSG_WARNING: ding = o_warningbells; break;
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
412 default: ding = ElvFalse;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
413 }
414 if (*scan == ELVCTRL('G'))
415 {
416 scan++;
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
417 ding = ElvTrue;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
418 }
419
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
420 /* if warning or error from a script, then put a line number at the
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
421 * start of the message.
422 */
423 if (scan != verbose
424 && (o_verbose >= 1 && scriptnamedup)
425 && (o_verbose >= 8
426 || ((imp == MSG_WARNING || imp == MSG_ERROR || imp == MSG_FATAL)
427 && (strlen(scriptnamedup) != strlen(EX_BUF) + 2 || strncmp(scriptnamedup + 1, EX_BUF, strlen(EX_BUF))))))
428 {
429 sprintf(tochar8(verbose), "%s, line %ld%s: ",
430 scriptnamedup, scriptline, scriptknown ? "" : "?");
431 }
432 else
433 *verbose = '\0';
434
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
435 /* copy the string into verbose[] */
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
436 CHARncat(verbose, scan, QTY(verbose) - 1 - CHARlen(verbose));
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
437 verbose[QTY(verbose) - 1] = '\0';
438
439 /* free the arg[] strings */
440 for (i = 0; arg[i]; i++)
441 {
442 safefree(arg[i]);
443 }
444
445 /* Status and fatal messages are shown immediately, without flushing
446 * the message buffer. During the initialization phase, other messages
447 * may also be output immediately.
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
448 *
449 * Also, since scan & change operations can't be done simultaneously,
450 * if there is currently a scan operation in progress then output the
451 * message immediately.
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
452 */
453 if (!verbose[0] && imp != MSG_FATAL)
454 {
455 /* ignore it. No output */
456 }
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
457 else if ((o_verbose >= 1 && !windefault)
458 || !gui
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
459 #ifndef GUI_WIN32
460 || (eventcounter <= 1 && imp == MSG_ERROR)
461 #endif
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
462 || imp == MSG_STATUS
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
463 || imp == MSG_FATAL
464 || scan__top != NULL)
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
465 {
466 /* show the message */
467 if (gui && windefault)
468 {
469 /* Either the GUI will show it, or we will */
470 if (!gui->msg || !(*gui->msg)(windefault->gw, imp, verbose, (int)(scan - verbose)))
471 {
472 /* we have to show it... on bottom of window? */
473 drawmsg(windefault, imp, verbose, (int)CHARlen(verbose));
474 }
475
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
476 /* For fatal error messages, also write it to fperr */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
477 if (imp == MSG_FATAL)
478 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
479 fprintf(fperr, "%s\n", verbose);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
480 }
481 }
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
482 else if (!gui || !gui->msg || !gui->exonly || !(*gui->msg)(0, imp, verbose, (int)(scan - verbose)))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
483 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
484 /* no GUI yet, so just write it to fpinfo/fperr */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
485 if (imp == MSG_FATAL || imp == MSG_ERROR)
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
486 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
487 fprintf(fperr, "%s\n", verbose);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
488 }
489 else
490 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
491 fprintf(fpinfo, "%s\r\n", verbose);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
492 }
493 }
494
495 /* clean up & exit */
496 if (imp == MSG_FATAL)
497 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
498 o_tempsession = ElvFalse;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
499 sesclose();
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
500 if (gui)
501 (*gui->term)();
502 else if (chosengui)
503 (*chosengui->term)();
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
504 #ifdef NDEBUG
505 exit(1);
506 #else
507 abort();
508 #endif
509 }
510 }
511 else
512 {
513 /* append the message to the message buffer */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
514 buf = bufalloc(toCHAR(MSGQUEUE_BUF), 0, ElvTrue);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
515 (void)marktmp(mark, buf, o_bufchars(buf));
516 bufreplace(&mark, &mark, toCHAR("\n"), 1L);
517 bufreplace(&mark, &mark, verbose, (long)CHARlen(verbose));
518 bufreplace(&mark, &mark, toCHAR(imp>=MSG_ERROR ? "n" : " "), 1L);
519 }
520
521 /* if error, then alert the terminal */
522 if (imp >= MSG_ERROR)
523 {
524 mapalert();
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
525 if ((optflags(o_exitcode) & OPT_SET) == 0 && eventcounter <= 1)
526 {
527 o_exitcode = 1;
528 }
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
529 }
530
531 /* if we're supposed to ring the bell, and this GUI has a bell,
532 * then ring it.
533 */
534 if (ding && gui && gui->beep && windefault)
535 {
536 guibeep(windefault);
537 }
538
539 /* Zero the first byte of verbose[], so we can tell that we aren't
540 * in the middle of a message anymore.
541 */
542 *verbose = '\0';
543 }
544
545
546 /* This function flushes messages from the message queue to the current
547 * window. This function should be called before outputting ex text,
548 * before reading keystrokes, and when exiting elvis, after the GUI has
549 * been shut down but before the session file has been closed.
550 */
551 void msgflush()
552 {
553 BUFFER buf;
554 MARK mark, end;
555 CHAR *cp;
556 int len;
557 MSGIMP imp;
558
559 /* if we have a GUI but no windows yet, then delay output */
560 if (gui && !windefault)
561 {
562 return;
563 }
564
565 /* locate the message queue buffer, if any. If it doesn't exist,
566 * or is empty, then we're done!
567 */
568 buf = buffind(toCHAR(MSGQUEUE_BUF));
569 if (!buf || o_bufchars(buf) == 0)
570 {
571 return;
572 }
573
574 /* Copy each line into the "verbose" buffer. For each one, display
575 * the message as either info or an error.
576 */
577 mark = markalloc(buf, 0);
578 for (scanalloc(&cp, mark), len = 0; cp; scannext(&cp))
579 {
580 if (*cp == '\n')
581 {
582 verbose[len] = '\0';
583 imp = (verbose[0]=='*' ? MSG_ERROR : MSG_INFO);
584
585 /* show the message */
586 if (gui && windefault)
587 {
588 /* Either the GUI will show it, or we will */
589 if (!gui->msg || !(*gui->msg)(windefault->gw, imp, verbose + 1, len - 1))
590 {
591 /* we have to show it... on bottom of window? */
592 drawmsg(windefault, imp, verbose + 1, len - 1);
593 }
594 }
595 else
596 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
597 /* no GUI yet, so just write it to fpinfo/fperr */
598 fprintf(imp >= MSG_ERROR ? fperr : fpinfo,
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
599 "%s\n", verbose + 1);
600 }
601 len = 0;
602 }
603 else if (len < QTY(verbose) - 2)
604 {
605 verbose[len++] = *cp;
606 }
607 }
608 scanfree(&cp);
609
610 /* cleanup */
611 end = markalloc(buf, o_bufchars(buf));
612 bufreplace(mark, end, NULL, 0);
613 markfree(mark);
614 markfree(end);
615 *verbose = '\0';
616 }
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
617
618
619 /* Translate a simple word or phrase, and return a dynamically-allocated
620 * copy of the result. This also has the side-effect of converting a
621 * (char *) to a (CHAR *).
622 *
623 * This is used mostly for setting some options to locale-sensitive defaults
624 */
625 CHAR *msgtranslate(word)
626 char *word;
627 {
628 CHAR *ret;
629
630 /* Translate it */
631 translate(word);
632
633 /* Make a dynamic copy of it */
634 ret = CHARkdup(verbose);
635
636 /* Zero the first byte of verbose[] so msg() doesn't think we're
637 * doing a message. That's important because msg() skips translation
638 * if an error message occurs while evaluating another message.
639 */
640 verbose[0] = '\0';
641
642 /* return the dynamically-allocated copy */
643 return ret;
644 }
Something went wrong with that request. Please try again.