4 From: Bram Moolenaar <Bram@moolenaar.net>
6 Content-Type: text/plain; charset=ISO-8859-1
7 Content-Transfer-Encoding: 8bit
11 Problem: When in debug mode, receiving a message from a remote client
12 causes a crash. Evaluating an expression causes Vim to wait for
13 "cont" to be typed, without a prompt. (Hari Krishna Dara)
14 Solution: Disable debugging when evaluating an expression for a client.
15 (Michael Geddes) Don't try reading into the typehead buffer when
16 it may have been filled in another way.
17 Files: src/ex_getln.c, src/getchar.c, src/if_xcmdsrv.c, src/main.c,
18 src/misc1.c, src/proto/getchar.pro, src/proto/main.pro,
19 src/proto/os_unix.pro, src/proto/ui.pro, src/structs.h,
20 src/os_unix.c, src/ui.c
23 *** ../vim-6.2.294/src/ex_getln.c Tue Feb 24 15:23:58 2004
24 --- src/ex_getln.c Sat Feb 28 16:33:29 2004
27 p = (char_u *)line_ga.ga_data + line_ga.ga_len;
29 /* Get one character (inchar gets a third of maxlen characters!) */
30 ! len = inchar(p + off, 3, -1L);
32 continue; /* end of input script reached */
33 /* for a special character, we need at least three characters */
35 p = (char_u *)line_ga.ga_data + line_ga.ga_len;
37 /* Get one character (inchar gets a third of maxlen characters!) */
38 ! len = inchar(p + off, 3, -1L, 0);
40 continue; /* end of input script reached */
41 /* for a special character, we need at least three characters */
42 *** ../vim-6.2.294/src/getchar.c Tue Feb 17 21:46:46 2004
43 --- src/getchar.c Sun Feb 29 14:24:23 2004
46 * of an escape sequence.
47 * In an xterm we get one char at a time and we have to get them all.
49 ! while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L) != 0)
51 typebuf.tb_off = MAXMAPLEN;
54 * of an escape sequence.
55 * In an xterm we get one char at a time and we have to get them all.
57 ! while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L,
58 ! typebuf.tb_change_cnt) != 0)
60 typebuf.tb_off = MAXMAPLEN;
66 * Initialize typebuf.tb_buf to point to typebuf_init.
67 ! * Alloc() cannot be used here: In out-of-memory situations it would
68 * be impossible to type anything.
74 * Initialize typebuf.tb_buf to point to typebuf_init.
75 ! * alloc() cannot be used here: In out-of-memory situations it would
76 * be impossible to type anything.
82 typebuf.tb_buflen = TYPELEN_INIT;
85 + typebuf.tb_change_cnt = 1;
95 + if (++typebuf.tb_change_cnt == 0)
96 + typebuf.tb_change_cnt = 1;
98 addlen = (int)STRLEN(str);
106 + * Return TRUE if the typeahead buffer was changed (while waiting for a
107 + * character to arrive). Happens when a message was received from a client.
108 + * But check in a more generic way to avoid trouble: When "typebuf.tb_buf"
109 + * changed it was reallocated and the old pointer can no longer be used.
110 + * Or "typebuf.tb_off" may have been changed and we would overwrite characters
111 + * that was just added.
114 + typebuf_changed(tb_change_cnt)
115 + int tb_change_cnt; /* old value of typebuf.tb_change_cnt */
117 + return (tb_change_cnt != 0 && (typebuf.tb_change_cnt != tb_change_cnt
118 + #ifdef FEAT_CLIENTSERVER
119 + || received_from_client
125 * Return TRUE if there are no characters in the typeahead buffer that have
126 * not been typed (result from a mapping or come from ":normal").
131 * typeahead buffer. */
132 received_from_client = FALSE;
134 + if (++typebuf.tb_change_cnt == 0)
135 + typebuf.tb_change_cnt = 1;
142 typebuf.tb_maplen = 0;
143 typebuf.tb_silent = 0;
144 typebuf.tb_no_abbr_cnt = 0;
145 + if (++typebuf.tb_change_cnt == 0)
146 + typebuf.tb_change_cnt = 1;
154 /* flush all input */
155 ! c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L);
157 ! * If inchar returns TRUE (script file was active) or we
158 * are inside a mapping, get out of insert mode.
159 * Otherwise we behave like having gotten a CTRL-C.
160 * As a result typing CTRL-C in insert mode will
164 /* flush all input */
165 ! c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L,
166 ! typebuf.tb_change_cnt);
168 ! * If inchar() returns TRUE (script file was active) or we
169 * are inside a mapping, get out of insert mode.
170 * Otherwise we behave like having gotten a CTRL-C.
171 * As a result typing CTRL-C in insert mode will
175 && (p_timeout || (keylen == KL_PART_KEY && p_ttimeout))
176 && (c = inchar(typebuf.tb_buf + typebuf.tb_off
177 ! + typebuf.tb_len, 3, 25L))
180 colnr_T col = 0, vcol;
184 && (p_timeout || (keylen == KL_PART_KEY && p_ttimeout))
185 && (c = inchar(typebuf.tb_buf + typebuf.tb_off
186 ! + typebuf.tb_len, 3, 25L,
187 ! typebuf.tb_change_cnt)) == 0)
189 colnr_T col = 0, vcol;
194 : ((keylen == KL_PART_KEY && p_ttm >= 0)
198 #ifdef FEAT_CMDL_INFO
202 : ((keylen == KL_PART_KEY && p_ttm >= 0)
204 ! : p_tm)), typebuf.tb_change_cnt);
206 #ifdef FEAT_CMDL_INFO
213 ! * As much characters as we can get (upto 'maxlen') are put in buf and
214 * NUL terminated (buffer length must be 'maxlen' + 1).
215 ! * Minimum for 'maxlen' is 3!!!!
217 * If we got an interrupt all input is read until none is available.
223 ! * As much characters as we can get (upto 'maxlen') are put in "buf" and
224 * NUL terminated (buffer length must be 'maxlen' + 1).
225 ! * Minimum for "maxlen" is 3!!!!
227 ! * "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
228 ! * it. When typebuf.tb_change_cnt changes (e.g., when a message is received
229 ! * from a remote client) "buf" can no longer be used. "tb_change_cnt" is 0
232 * If we got an interrupt all input is read until none is available.
236 * Return the number of obtained characters.
237 * Return -1 when end of input script reached.
241 ! inchar(buf, maxlen, wait_time)
244 long wait_time; /* milli seconds */
246 int len = 0; /* init for GCC */
247 int retesc = FALSE; /* return ESC with gotint */
249 * Return the number of obtained characters.
250 * Return -1 when end of input script reached.
253 ! inchar(buf, maxlen, wait_time, tb_change_cnt)
256 long wait_time; /* milli seconds */
259 int len = 0; /* init for GCC */
260 int retesc = FALSE; /* return ESC with gotint */
266 ! len = ui_inchar(dum, DUM_LEN, 0L);
267 if (len == 0 || (len == 1 && dum[0] == 3))
274 ! len = ui_inchar(dum, DUM_LEN, 0L, 0);
275 if (len == 0 || (len == 1 && dum[0] == 3))
280 * Fill up to a third of the buffer, because each character may be
283 ! len = ui_inchar(buf, maxlen / 3, wait_time);
286 return fix_input_buffer(buf, len, script_char >= 0);
289 * Fill up to a third of the buffer, because each character may be
292 ! len = ui_inchar(buf, maxlen / 3, wait_time, tb_change_cnt);
295 + if (typebuf_changed(tb_change_cnt))
298 return fix_input_buffer(buf, len, script_char >= 0);
300 *** ../vim-6.2.294/src/if_xcmdsrv.c Thu Jul 24 21:52:31 2003
301 --- src/if_xcmdsrv.c Fri Feb 27 17:33:19 2004
308 ! ret = eval_to_string(cmd, NULL);
317 ! ret = eval_client_expr_to_string(cmd);
324 server_to_input_buf(script);
328 ! res = eval_to_string(script, NULL);
332 if (resWindow != None)
336 server_to_input_buf(script);
338 ! res = eval_client_expr_to_string(script);
340 if (resWindow != None)
342 *** ../vim-6.2.294/src/main.c Thu Feb 19 14:43:37 2004
343 --- src/main.c Fri Feb 27 17:29:56 2004
347 /* Let input_available() know we inserted text in the typeahead buffer. */
348 received_from_client = TRUE;
352 + * Evaluate an expression that the client sent to a string.
353 + * Handles disabling error messages and disables debugging, otherwise Vim
354 + * hangs, waiting for "cont" to be typed.
357 + eval_client_expr_to_string(expr)
361 + int save_dbl = debug_break_level;
362 + int save_ro = redir_off;
364 + debug_break_level = -1;
368 + res = eval_to_string(expr, NULL);
370 + debug_break_level = save_dbl;
371 + redir_off = save_ro;
379 * Make our basic server name: use the specified "arg" if given, otherwise use
380 *** ../vim-6.2.294/src/misc1.c Sun Feb 15 13:44:45 2004
381 --- src/misc1.c Sat Feb 28 16:38:02 2004
384 * insert a key code into (max 5 chars plus NUL). And
385 * fix_input_buffer() can triple the number of bytes. */
386 n = ui_inchar(buf + len, (CBUFLEN - 6 - len) / 3,
387 ! len == 0 ? -1L : 100L);
390 /* Replace zero and CSI by a special key code. */
392 * insert a key code into (max 5 chars plus NUL). And
393 * fix_input_buffer() can triple the number of bytes. */
394 n = ui_inchar(buf + len, (CBUFLEN - 6 - len) / 3,
395 ! len == 0 ? -1L : 100L, 0);
398 /* Replace zero and CSI by a special key code. */
399 *** ../vim-6.2.294/src/proto/getchar.pro Sun Jun 1 12:26:10 2003
400 --- src/proto/getchar.pro Sat Feb 28 16:40:34 2004
404 int start_redo_ins __ARGS((void));
405 void stop_redo_ins __ARGS((void));
406 int ins_typebuf __ARGS((char_u *str, int noremap, int offset, int nottyped, int silent));
407 + int typebuf_changed __ARGS((int tb_change_cnt));
408 int typebuf_typed __ARGS((void));
409 int typebuf_maplen __ARGS((void));
410 void del_typebuf __ARGS((int len, int offset));
413 int vpeekc_any __ARGS((void));
414 int char_avail __ARGS((void));
415 void vungetc __ARGS((int c));
416 ! int inchar __ARGS((char_u *buf, int maxlen, long wait_time));
417 int fix_input_buffer __ARGS((char_u *buf, int len, int script));
418 int input_available __ARGS((void));
419 int do_map __ARGS((int maptype, char_u *arg, int mode, int abbrev));
421 int vpeekc_any __ARGS((void));
422 int char_avail __ARGS((void));
423 void vungetc __ARGS((int c));
424 ! int inchar __ARGS((char_u *buf, int maxlen, long wait_time, int tb_change_cnt));
425 int fix_input_buffer __ARGS((char_u *buf, int len, int script));
426 int input_available __ARGS((void));
427 int do_map __ARGS((int maptype, char_u *arg, int mode, int abbrev));
428 *** ../vim-6.2.294/src/proto/main.pro Sun Jun 1 12:26:13 2003
429 --- src/proto/main.pro Sat Feb 28 16:40:40 2004
433 void time_pop __ARGS((void *tp));
434 void time_msg __ARGS((char *msg, void *tv_start));
435 void server_to_input_buf __ARGS((char_u *str));
436 + char_u *eval_client_expr_to_string __ARGS((char_u *expr));
437 int toF_TyA __ARGS((int c));
438 int fkmap __ARGS((int c));
439 void conv_to_pvim __ARGS((void));
440 *** ../vim-6.2.294/src/proto/os_unix.pro Sun Jun 1 12:26:18 2003
441 --- src/proto/os_unix.pro Sat Feb 28 16:40:46 2004
445 void mch_write __ARGS((char_u *s, int len));
446 ! int mch_inchar __ARGS((char_u *buf, int maxlen, long wtime));
447 int mch_char_avail __ARGS((void));
448 long_u mch_total_mem __ARGS((int special));
449 void mch_delay __ARGS((long msec, int ignoreinput));
452 void mch_write __ARGS((char_u *s, int len));
453 ! int mch_inchar __ARGS((char_u *buf, int maxlen, long wtime, int tb_change_cnt));
454 int mch_char_avail __ARGS((void));
455 long_u mch_total_mem __ARGS((int special));
456 void mch_delay __ARGS((long msec, int ignoreinput));
457 *** ../vim-6.2.294/src/proto/ui.pro Sun Jun 1 12:26:21 2003
458 --- src/proto/ui.pro Sat Feb 28 16:40:50 2004
462 void ui_write __ARGS((char_u *s, int len));
463 void ui_inchar_undo __ARGS((char_u *s, int len));
464 ! int ui_inchar __ARGS((char_u *buf, int maxlen, long wtime));
465 int ui_char_avail __ARGS((void));
466 void ui_delay __ARGS((long msec, int ignoreinput));
467 void ui_suspend __ARGS((void));
470 void ui_write __ARGS((char_u *s, int len));
471 void ui_inchar_undo __ARGS((char_u *s, int len));
472 ! int ui_inchar __ARGS((char_u *buf, int maxlen, long wtime, int tb_change_cnt));
473 int ui_char_avail __ARGS((void));
474 void ui_delay __ARGS((long msec, int ignoreinput));
475 void ui_suspend __ARGS((void));
476 *** ../vim-6.2.294/src/structs.h Thu Feb 5 12:09:25 2004
477 --- src/structs.h Sun Feb 29 14:25:58 2004
480 char_u *tb_noremap; /* mapping flags for characters in tb_buf[] */
481 int tb_buflen; /* size of tb_buf[] */
482 int tb_off; /* current position in tb_buf[] */
483 ! int tb_len; /* number of valid chars in tb_buf[] */
484 ! int tb_maplen; /* nr of mapped characters in tb_buf[] */
485 ! int tb_silent; /* nr of silently mapped chars in tb_buf[] */
486 ! int tb_no_abbr_cnt; /* nr of chars without abbrev. in tb_buf[] */
489 /* Struct to hold the saved typeahead for save_typeahead(). */
491 char_u *tb_noremap; /* mapping flags for characters in tb_buf[] */
492 int tb_buflen; /* size of tb_buf[] */
493 int tb_off; /* current position in tb_buf[] */
494 ! int tb_len; /* number of valid bytes in tb_buf[] */
495 ! int tb_maplen; /* nr of mapped bytes in tb_buf[] */
496 ! int tb_silent; /* nr of silently mapped bytes in tb_buf[] */
497 ! int tb_no_abbr_cnt; /* nr of bytes without abbrev. in tb_buf[] */
498 ! int tb_change_cnt; /* nr of time tb_buf was changed; never zero */
501 /* Struct to hold the saved typeahead for save_typeahead(). */
502 *** ../vim-6.2.294/src/os_unix.c Sun Feb 1 20:06:29 2004
503 --- src/os_unix.c Sat Feb 28 16:38:11 2004
506 * If wtime == -1 wait forever for characters.
509 ! mch_inchar(buf, maxlen, wtime)
512 long wtime; /* don't use "time", MIPS cannot handle it */
517 * If wtime == -1 wait forever for characters.
520 ! mch_inchar(buf, maxlen, wtime, tb_change_cnt)
523 long wtime; /* don't use "time", MIPS cannot handle it */
530 if (do_resize) /* interrupted by SIGWINCH signal */
533 ! #ifdef FEAT_CLIENTSERVER
534 ! if (received_from_client)
535 ! return 0; /* Input was put directly in typeahead buffer */
539 * For some terminals we only get one character at a time.
541 if (do_resize) /* interrupted by SIGWINCH signal */
544 ! /* If input was put directly in typeahead buffer bail out here. */
545 ! if (typebuf_changed(tb_change_cnt))
549 * For some terminals we only get one character at a time.
553 if (!(options & SHELL_EXPAND)
555 ! || (len = ui_inchar(ta_buf, BUFLEN, 10L)) > 0))
561 if (!(options & SHELL_EXPAND)
563 ! || (len = ui_inchar(ta_buf, BUFLEN, 10L,
568 *** ../vim-6.2.294/src/ui.c Sun Jan 18 20:58:01 2004
569 --- src/ui.c Sat Feb 28 16:36:51 2004
572 * If "wtime" == 0 do not wait for characters.
573 * If "wtime" == -1 wait forever for characters.
574 * If "wtime" > 0 wait "wtime" milliseconds for a character.
577 ! ui_inchar(buf, maxlen, wtime)
580 long wtime; /* don't use "time", MIPS cannot handle it */
585 * If "wtime" == 0 do not wait for characters.
586 * If "wtime" == -1 wait forever for characters.
587 * If "wtime" > 0 wait "wtime" milliseconds for a character.
589 + * "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
590 + * it. When typebuf.tb_change_cnt changes (e.g., when a message is received
591 + * from a remote client) "buf" can no longer be used. "tb_change_cnt" is NULL
595 ! ui_inchar(buf, maxlen, wtime, tb_change_cnt)
598 long wtime; /* don't use "time", MIPS cannot handle it */
605 static int count = 0;
608 ! retval = mch_inchar(buf, maxlen, 10L);
612 if (wtime == -1 && ++count == 1000)
614 static int count = 0;
617 ! retval = mch_inchar(buf, maxlen, 10L, tb_change_cnt);
618 ! if (retval > 0 || typebuf_changed(tb_change_cnt))
621 if (wtime == -1 && ++count == 1000)
627 ! if (gui_wait_for_chars(wtime))
628 retval = read_from_input_buf(buf, (long)maxlen);
635 ! if (gui_wait_for_chars(wtime) && !typebuf_changed(tb_change_cnt))
636 retval = read_from_input_buf(buf, (long)maxlen);
644 ! retval = mch_inchar(buf, maxlen, wtime);
647 ctrl_c_interrupts = TRUE;
652 ! retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
655 ctrl_c_interrupts = TRUE;
656 *** ../vim-6.2.294/src/version.c Sat Feb 28 15:30:58 2004
657 --- src/version.c Sun Feb 29 14:42:27 2004
661 { /* Add new patch number below this line */
667 Not too long ago, a program was something you watched on TV...
669 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
670 /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
671 \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
672 \\\ Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html ///