Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 641 lines (576 sloc) 15.656 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
7 char id_message[] = "$Id: message.c,v 2.52 2003/10/18 04:47:18 steve Exp $";
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 */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
291 if (*verbose || (msghiding && (imp == MSG_ERROR || imp == MSG_WARNING)))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
292 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
293 if (imp == MSG_FATAL)
294 {
295 fprintf(fperr, "%s\n", terse);
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
296 o_tempsession = ElvFalse;
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
297 sesclose();
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
298 if (gui)
299 (*gui->term)();
300 else if (chosengui)
301 (*chosengui->term)();
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
302 #ifdef NDEBUG
303 exit(1);
304 #else
305 abort();
306 #endif
307 }
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
308 return;
309 }
310
311 /* Convert any arguments to CHAR strings */
312 if (*terse == '[')
313 {
314 #if USE_PROTOTYPES
315 va_start(argptr, terse);
316 #else
317 va_start(argptr);
318 #endif
319 for (i = 0, terse++; *terse != ']'; i++, terse++)
320 {
321 assert(i < QTY(arg));
322
323 /* convert argument to a CHAR string */
324 switch (*terse)
325 {
326 case 'd':
327 sprintf(text, "%ld", va_arg(argptr, long));
328 arg[i] = toCHAR(text);
329 break;
330
331 case 'S':
332 arg[i] = va_arg(argptr, CHAR *);
333 if (!arg[i])
334 arg[i] = toCHAR("NULL");
335 break;
336
337 case 's':
338 str = va_arg(argptr, char *);
339 if (!str)
340 str = "NULL";
341 arg[i] = toCHAR(str);
342 break;
343
344 case 'c':
345 text[0] = va_arg(argptr, _char_);
346 text[1] = '\0';
347 arg[i] = toCHAR(text);
348 break;
349
350 case 'C':
351 text[0] = va_arg(argptr, _CHAR_);
352 text[1] = '\0';
353 arg[i] = toCHAR(text);
354 break;
355
356 default:
357 /* elvis source code should never have a
358 * bad format code.
359 */
360 abort();
361 }
362
363 /* dynamically allocate a copy of that string. This
364 * is done because some parameter types use the text[]
365 * buffer, and a later argument may need to reuse that
366 * buffer.
367 */
368 arg[i] = CHARdup(arg[i]);
369 }
370 va_end(argptr);
371 arg[i] = NULL;
372
373 /* move the terse pointer past the closing ']' character */
374 assert(*terse == ']');
375 terse++;
376 }
377 else /* no bracketted list at start of terse string */
378 {
379 /* no extra arguments */
380 arg[0] = NULL;
381 }
382
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
383 if (imp == MSG_FATAL && !arg[0])
384 {
385 /* set "scan" to the message text */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
386 scan = toCHAR(terse);
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
387 }
388 else
389 {
390 /* translate the terse message via "Elvis messages" buffer */
391 translate(terse);
392
393 /* expand any arguments or option names */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
394 scan = calculate(verbose, arg, CALC_MSG);
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
395 if (!scan)
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
396 scan = calculate(toCHAR(terse), arg, CALC_MSG);
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
397 if (!scan)
398 scan = toCHAR(terse);
399 }
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
400
401 /* If it starts with a ^G character, then ring the bell. Also
402 * ring the bell if errorbells or warningbells is set
403 */
404 switch (imp)
405 {
406 case MSG_ERROR: ding = o_errorbells; break;
407 case MSG_WARNING: ding = o_warningbells; break;
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
408 default: ding = ElvFalse;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
409 }
410 if (*scan == ELVCTRL('G'))
411 {
412 scan++;
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
413 ding = ElvTrue;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
414 }
415
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
416 /* 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
417 * start of the message.
418 */
419 if (scan != verbose
420 && (o_verbose >= 1 && scriptnamedup)
421 && (o_verbose >= 8
422 || ((imp == MSG_WARNING || imp == MSG_ERROR || imp == MSG_FATAL)
423 && (strlen(scriptnamedup) != strlen(EX_BUF) + 2 || strncmp(scriptnamedup + 1, EX_BUF, strlen(EX_BUF))))))
424 {
425 sprintf(tochar8(verbose), "%s, line %ld%s: ",
426 scriptnamedup, scriptline, scriptknown ? "" : "?");
427 }
428 else
429 *verbose = '\0';
430
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
431 /* copy the string into verbose[] */
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
432 CHARncat(verbose, scan, QTY(verbose) - 1 - CHARlen(verbose));
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
433 verbose[QTY(verbose) - 1] = '\0';
434
435 /* free the arg[] strings */
436 for (i = 0; arg[i]; i++)
437 {
438 safefree(arg[i]);
439 }
440
441 /* Status and fatal messages are shown immediately, without flushing
442 * the message buffer. During the initialization phase, other messages
443 * may also be output immediately.
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
444 *
445 * Also, since scan & change operations can't be done simultaneously,
446 * if there is currently a scan operation in progress then output the
447 * message immediately.
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
448 */
449 if (!verbose[0] && imp != MSG_FATAL)
450 {
451 /* ignore it. No output */
452 }
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
453 else if ((o_verbose >= 1 && !windefault)
454 || !gui
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
455 #ifndef GUI_WIN32
456 || (eventcounter <= 1 && imp == MSG_ERROR)
457 #endif
3a9bb55 @mbert Import Elvis 2.1_3 (written by Steve Kirkendall)
authored
458 || imp == MSG_STATUS
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
459 || imp == MSG_FATAL
460 || scan__top != NULL)
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
461 {
462 /* show the message */
463 if (gui && windefault)
464 {
465 /* Either the GUI will show it, or we will */
466 if (!gui->msg || !(*gui->msg)(windefault->gw, imp, verbose, (int)(scan - verbose)))
467 {
468 /* we have to show it... on bottom of window? */
469 drawmsg(windefault, imp, verbose, (int)CHARlen(verbose));
470 }
471
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
472 /* For fatal error messages, also write it to fperr */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
473 if (imp == MSG_FATAL)
474 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
475 fprintf(fperr, "%s\n", verbose);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
476 }
477 }
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
478 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
479 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
480 /* no GUI yet, so just write it to fpinfo/fperr */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
481 if (imp == MSG_FATAL || imp == MSG_ERROR)
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
482 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
483 fprintf(fperr, "%s\n", verbose);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
484 }
485 else
486 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
487 fprintf(fpinfo, "%s\r\n", verbose);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
488 }
489 }
490
491 /* clean up & exit */
492 if (imp == MSG_FATAL)
493 {
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
494 o_tempsession = ElvFalse;
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
495 sesclose();
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
496 if (gui)
497 (*gui->term)();
498 else if (chosengui)
499 (*chosengui->term)();
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
500 #ifdef NDEBUG
501 exit(1);
502 #else
503 abort();
504 #endif
505 }
506 }
507 else
508 {
509 /* append the message to the message buffer */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
510 buf = bufalloc(toCHAR(MSGQUEUE_BUF), 0, ElvTrue);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
511 (void)marktmp(mark, buf, o_bufchars(buf));
512 bufreplace(&mark, &mark, toCHAR("\n"), 1L);
513 bufreplace(&mark, &mark, verbose, (long)CHARlen(verbose));
514 bufreplace(&mark, &mark, toCHAR(imp>=MSG_ERROR ? "n" : " "), 1L);
515 }
516
517 /* if error, then alert the terminal */
518 if (imp >= MSG_ERROR)
519 {
520 mapalert();
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
521 if ((optflags(o_exitcode) & OPT_SET) == 0 && eventcounter <= 1)
522 {
523 o_exitcode = 1;
524 }
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
525 }
526
527 /* if we're supposed to ring the bell, and this GUI has a bell,
528 * then ring it.
529 */
530 if (ding && gui && gui->beep && windefault)
531 {
532 guibeep(windefault);
533 }
534
535 /* Zero the first byte of verbose[], so we can tell that we aren't
536 * in the middle of a message anymore.
537 */
538 *verbose = '\0';
539 }
540
541
542 /* This function flushes messages from the message queue to the current
543 * window. This function should be called before outputting ex text,
544 * before reading keystrokes, and when exiting elvis, after the GUI has
545 * been shut down but before the session file has been closed.
546 */
547 void msgflush()
548 {
549 BUFFER buf;
550 MARK mark, end;
551 CHAR *cp;
552 int len;
553 MSGIMP imp;
554
555 /* if we have a GUI but no windows yet, then delay output */
556 if (gui && !windefault)
557 {
558 return;
559 }
560
561 /* locate the message queue buffer, if any. If it doesn't exist,
562 * or is empty, then we're done!
563 */
564 buf = buffind(toCHAR(MSGQUEUE_BUF));
565 if (!buf || o_bufchars(buf) == 0)
566 {
567 return;
568 }
569
570 /* Copy each line into the "verbose" buffer. For each one, display
571 * the message as either info or an error.
572 */
573 mark = markalloc(buf, 0);
574 for (scanalloc(&cp, mark), len = 0; cp; scannext(&cp))
575 {
576 if (*cp == '\n')
577 {
578 verbose[len] = '\0';
579 imp = (verbose[0]=='*' ? MSG_ERROR : MSG_INFO);
580
581 /* show the message */
582 if (gui && windefault)
583 {
584 /* Either the GUI will show it, or we will */
585 if (!gui->msg || !(*gui->msg)(windefault->gw, imp, verbose + 1, len - 1))
586 {
587 /* we have to show it... on bottom of window? */
588 drawmsg(windefault, imp, verbose + 1, len - 1);
589 }
590 }
591 else
592 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
593 /* no GUI yet, so just write it to fpinfo/fperr */
594 fprintf(imp >= MSG_ERROR ? fperr : fpinfo,
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
595 "%s\n", verbose + 1);
596 }
597 len = 0;
598 }
599 else if (len < QTY(verbose) - 2)
600 {
601 verbose[len++] = *cp;
602 }
603 }
604 scanfree(&cp);
605
606 /* cleanup */
607 end = markalloc(buf, o_bufchars(buf));
608 bufreplace(mark, end, NULL, 0);
609 markfree(mark);
610 markfree(end);
611 *verbose = '\0';
612 }
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
613
614
615 /* Translate a simple word or phrase, and return a dynamically-allocated
616 * copy of the result. This also has the side-effect of converting a
617 * (char *) to a (CHAR *).
618 *
619 * This is used mostly for setting some options to locale-sensitive defaults
620 */
621 CHAR *msgtranslate(word)
622 char *word;
623 {
624 CHAR *ret;
625
626 /* Translate it */
627 translate(word);
628
629 /* Make a dynamic copy of it */
630 ret = CHARkdup(verbose);
631
632 /* Zero the first byte of verbose[] so msg() doesn't think we're
633 * doing a message. That's important because msg() skips translation
634 * if an error message occurs while evaluating another message.
635 */
636 verbose[0] = '\0';
637
638 /* return the dynamically-allocated copy */
639 return ret;
640 }
Something went wrong with that request. Please try again.