aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiles Bader2004-12-25 02:00:25 +0000
committerMiles Bader2004-12-25 02:00:25 +0000
commit6a89b7e95a771e5141bb1718e8278dcf892359ea (patch)
tree189a864da85f49e73c6f9220b7231f0c54250e6e /src
parent054b6b53c3554c83ae02d24a772a74b63ebb08cd (diff)
parent70d16390a08dc9d94c961eb380be8e1b5b496963 (diff)
downloademacs-6a89b7e95a771e5141bb1718e8278dcf892359ea.tar.gz
emacs-6a89b7e95a771e5141bb1718e8278dcf892359ea.zip
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-79
Merge from emacs--cvs-trunk--0 Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-735 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-747 Update from CVS
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog116
-rw-r--r--src/alloc.c109
-rw-r--r--src/atimer.c2
-rw-r--r--src/data.c1
-rw-r--r--src/dispnew.c4
-rw-r--r--src/emacs.c21
-rw-r--r--src/eval.c1
-rw-r--r--src/fileio.c16
-rw-r--r--src/floatfns.c1
-rw-r--r--src/image.c6
-rw-r--r--src/keyboard.c56
-rw-r--r--src/lisp.h3
-rw-r--r--src/macterm.c102
-rw-r--r--src/process.c3
-rw-r--r--src/regex.c2
-rw-r--r--src/sysdep.c1
-rw-r--r--src/syssignal.h27
-rw-r--r--src/undo.c156
-rw-r--r--src/xdisp.c15
-rw-r--r--src/xselect.c2
-rw-r--r--src/xterm.c6
21 files changed, 491 insertions, 159 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index a2706547e77..9323304dc46 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,118 @@
12004-12-23 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
2
3 * keyboard.c (input_available_signal): Call SIGNAL_THREAD_CHECK
4 before touching input_available_clear_time, to avoid accessing it
5 from multiple threads.
6
72004-12-23 Jason Rumney <jasonr@gnu.org>
8
9 * image.c (__WIN32__) [HAVE_NTGUI]: Define for correct behaviour
10 of JPEG library.
11
122004-12-22 Richard M. Stallman <rms@gnu.org>
13
14 * emacs.c (main): If batch mode, set Vundo_outer_limit to nil.
15
16 * lisp.h (Vundo_outer_limit): Fix decl.
17
18 * undo.c (Vundo_outer_limit): Replaces undo_outer_limit.
19 Uses changed.
20 (syms_of_undo): Initialize appropriately.
21 (truncate_undo_list): If it's nil, there's no limit.
22
232004-12-22 Kenichi Handa <handa@m17n.org>
24
25 * xselect.c (Fx_get_cut_buffer_internal): Return a unibyte string.
26
272004-12-21 Richard M. Stallman <rms@gnu.org>
28
29 * eval.c (unwind_to_catch): Clear immediate_quit.
30
31 * xdisp.c (get_next_display_element): Display codes 8a0 and 8ad
32 specially as `\ ' and `\-'.
33
34 * keyboard.c (kbd_buffer_store_event_hold):
35 In the code for while-no-input, handle immediate_quit.
36
37 * alloc.c (Fgarbage_collect): Update call to truncate_undo_list.
38 Call that at the very start.
39 (undo_limit, undo_strong_limit, undo_outer_limit): Moved to undo.c.
40 (syms_of_alloc): Don't define undo-limit,
41 undo-strong-limit and undo-outer-limit here.
42
43 * undo.c (truncate_undo_list): Return void.
44 Take just one argument, the buffer.
45 Make it current, and inhibit recursive GC.
46 Access and update the undo list directly; return void.
47 Refer to the undo...limit variables directly.
48 Test undo_outer_limit only after counting the whole current command.
49 When it's exceeded, call the function in undo-outer-limit-function.
50 (undo_limit, undo_strong_limit, undo_outer_limit): From alloc.c.
51 (Vundo_outer_limit_function): New variable.
52 (syms_of_undo): Define undo-limit, undo-strong-limit
53 and undo-outer-limit here, and undo-outer-limit-function.
54 Doc fixes.
55
56 * lisp.h (truncate_undo_list): Update decl.
57
582004-12-21 Piet van Oostrum <piet@cs.uu.nl>
59
60 * fileio.c (Fread_file_name): Delete duplicates in
61 file-name-history when history_delete_duplicates is true.
62
632004-12-20 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
64
65 * macterm.c (mac_do_list_fonts): Fix memory leak
66
672004-12-20 Richard M. Stallman <rms@gnu.org>
68
69 * regex.c (re_match_2_internal) <symend, wordend>:
70 Fix calls to UPDATE_SYNTAX_TABLE_FORWARD.
71
722004-12-18 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
73
74 * macterm.c (endif, x_font_name_to_mac_font_name): Use
75 maccentraleurroman instead of maccentraleuropean
76 (mac_c_string_match, mac_do_list_fonts): Speed up font search by
77 quickly finding a specific font without needing regexps.
78
792004-12-15 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
80
81 * syssignal.h: Declare main_thread.
82 (SIGNAL_THREAD_CHECK): New macro.
83
84 * keyboard.c (input_available_signal): Move thread checking code
85 to macro SIGNAL_THREAD_CHECK and call that macro.
86 (interrupt_signal): Call SIGNAL_THREAD_CHECK.
87
88 * alloc.c (uninterrupt_malloc): Move main_thread to emacs.c.
89
90 * emacs.c: Define main_thread.
91 (main): Initialize main_thread.
92 (handle_USR1_signal, handle_USR2_signal, fatal_error_signal)
93 (memory_warning_signal): Call SIGNAL_THREAD_CHECK.
94
95 * floatfns.c (float_error): Call SIGNAL_THREAD_CHECK.
96
97 * dispnew.c (window_change_signal): Call SIGNAL_THREAD_CHECK.
98
99 * sysdep.c (select_alarm): Call SIGNAL_THREAD_CHECK.
100
101 * process.c (send_process_trap, sigchld_handler): Call
102 SIGNAL_THREAD_CHECK.
103
104 * data.c (arith_error): Call SIGNAL_THREAD_CHECK.
105
106 * atimer.c (alarm_signal_handler): Call SIGNAL_THREAD_CHECK.
107
108 * xterm.c (xg_scroll_callback): Update XG_LAST_SB_DATA before
109 returning when xg_ignore_gtk_scrollbar is true.
110
1112004-12-14 Kim F. Storm <storm@cua.dk>
112
113 * keyboard.c (read_char): Save and restore echo_string when
114 handling input method.
115
12004-12-13 Richard M. Stallman <rms@gnu.org> 1162004-12-13 Richard M. Stallman <rms@gnu.org>
2 117
3 * eval.c (syms_of_eval) <quit-flag>: Doc fix. 118 * eval.c (syms_of_eval) <quit-flag>: Doc fix.
@@ -143,6 +258,7 @@
143 * eval.c (Fcalled_interactively_p): Don't check INTERACTIVE. 258 * eval.c (Fcalled_interactively_p): Don't check INTERACTIVE.
144 (interactive_p): Skip Scalled_interactively_p frames 259 (interactive_p): Skip Scalled_interactively_p frames
145 like Sinteractive_p frames. 260 like Sinteractive_p frames.
261 (unwind_to_catch): Clear handling_signal.
146 262
147 * data.c (Fmake_variable_buffer_local): Doc fix. 263 * data.c (Fmake_variable_buffer_local): Doc fix.
148 (Fmake_local_variable): Doc fix. 264 (Fmake_local_variable): Doc fix.
diff --git a/src/alloc.c b/src/alloc.c
index 2a539920f22..9dd5e1abc05 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -99,7 +99,7 @@ extern __malloc_size_t __malloc_extra_blocks;
99 If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_* 99 If Emacs sets malloc hooks (! SYSTEM_MALLOC) and the emacs_blocked_*
100 functions below are called from malloc, there is a chance that one 100 functions below are called from malloc, there is a chance that one
101 of these threads preempts the Emacs main thread and the hook variables 101 of these threads preempts the Emacs main thread and the hook variables
102 end up in a inconsistent state. So we have a mutex to prevent that (note 102 end up in an inconsistent state. So we have a mutex to prevent that (note
103 that the backend handles concurrent access to malloc within its own threads 103 that the backend handles concurrent access to malloc within its own threads
104 but Emacs code running in the main thread is not included in that control). 104 but Emacs code running in the main thread is not included in that control).
105 105
@@ -109,7 +109,6 @@ extern __malloc_size_t __malloc_extra_blocks;
109 To prevent that, we only call BLOCK/UNBLOCK from the main thread. */ 109 To prevent that, we only call BLOCK/UNBLOCK from the main thread. */
110 110
111static pthread_mutex_t alloc_mutex; 111static pthread_mutex_t alloc_mutex;
112pthread_t main_thread;
113 112
114#define BLOCK_INPUT_ALLOC \ 113#define BLOCK_INPUT_ALLOC \
115 do \ 114 do \
@@ -201,12 +200,6 @@ extern
201#endif /* VIRT_ADDR_VARIES */ 200#endif /* VIRT_ADDR_VARIES */
202int malloc_sbrk_unused; 201int malloc_sbrk_unused;
203 202
204/* Two limits controlling how much undo information to keep. */
205
206EMACS_INT undo_limit;
207EMACS_INT undo_strong_limit;
208EMACS_INT undo_outer_limit;
209
210/* Number of live and free conses etc. */ 203/* Number of live and free conses etc. */
211 204
212static int total_conses, total_markers, total_symbols, total_vector_size; 205static int total_conses, total_markers, total_symbols, total_vector_size;
@@ -1310,8 +1303,6 @@ uninterrupt_malloc ()
1310 pthread_mutexattr_init (&attr); 1303 pthread_mutexattr_init (&attr);
1311 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); 1304 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
1312 pthread_mutex_init (&alloc_mutex, &attr); 1305 pthread_mutex_init (&alloc_mutex, &attr);
1313
1314 main_thread = pthread_self ();
1315#endif /* HAVE_GTK_AND_PTHREAD */ 1306#endif /* HAVE_GTK_AND_PTHREAD */
1316 1307
1317 if (__free_hook != emacs_blocked_free) 1308 if (__free_hook != emacs_blocked_free)
@@ -4604,13 +4595,48 @@ returns nil, because real GC can't be done. */)
4604 if (abort_on_gc) 4595 if (abort_on_gc)
4605 abort (); 4596 abort ();
4606 4597
4607 EMACS_GET_TIME (t1);
4608
4609 /* Can't GC if pure storage overflowed because we can't determine 4598 /* Can't GC if pure storage overflowed because we can't determine
4610 if something is a pure object or not. */ 4599 if something is a pure object or not. */
4611 if (pure_bytes_used_before_overflow) 4600 if (pure_bytes_used_before_overflow)
4612 return Qnil; 4601 return Qnil;
4613 4602
4603 /* Don't keep undo information around forever.
4604 Do this early on, so it is no problem if the user quits. */
4605 {
4606 register struct buffer *nextb = all_buffers;
4607
4608 while (nextb)
4609 {
4610 /* If a buffer's undo list is Qt, that means that undo is
4611 turned off in that buffer. Calling truncate_undo_list on
4612 Qt tends to return NULL, which effectively turns undo back on.
4613 So don't call truncate_undo_list if undo_list is Qt. */
4614 if (! EQ (nextb->undo_list, Qt))
4615 truncate_undo_list (nextb);
4616
4617 /* Shrink buffer gaps, but skip indirect and dead buffers. */
4618 if (nextb->base_buffer == 0 && !NILP (nextb->name))
4619 {
4620 /* If a buffer's gap size is more than 10% of the buffer
4621 size, or larger than 2000 bytes, then shrink it
4622 accordingly. Keep a minimum size of 20 bytes. */
4623 int size = min (2000, max (20, (nextb->text->z_byte / 10)));
4624
4625 if (nextb->text->gap_size > size)
4626 {
4627 struct buffer *save_current = current_buffer;
4628 current_buffer = nextb;
4629 make_gap (-(nextb->text->gap_size - size));
4630 current_buffer = save_current;
4631 }
4632 }
4633
4634 nextb = nextb->next;
4635 }
4636 }
4637
4638 EMACS_GET_TIME (t1);
4639
4614 /* In case user calls debug_print during GC, 4640 /* In case user calls debug_print during GC,
4615 don't let that cause a recursive GC. */ 4641 don't let that cause a recursive GC. */
4616 consing_since_gc = 0; 4642 consing_since_gc = 0;
@@ -4649,42 +4675,6 @@ returns nil, because real GC can't be done. */)
4649 4675
4650 shrink_regexp_cache (); 4676 shrink_regexp_cache ();
4651 4677
4652 /* Don't keep undo information around forever. */
4653 {
4654 register struct buffer *nextb = all_buffers;
4655
4656 while (nextb)
4657 {
4658 /* If a buffer's undo list is Qt, that means that undo is
4659 turned off in that buffer. Calling truncate_undo_list on
4660 Qt tends to return NULL, which effectively turns undo back on.
4661 So don't call truncate_undo_list if undo_list is Qt. */
4662 if (! EQ (nextb->undo_list, Qt))
4663 nextb->undo_list
4664 = truncate_undo_list (nextb->undo_list, undo_limit,
4665 undo_strong_limit, undo_outer_limit);
4666
4667 /* Shrink buffer gaps, but skip indirect and dead buffers. */
4668 if (nextb->base_buffer == 0 && !NILP (nextb->name))
4669 {
4670 /* If a buffer's gap size is more than 10% of the buffer
4671 size, or larger than 2000 bytes, then shrink it
4672 accordingly. Keep a minimum size of 20 bytes. */
4673 int size = min (2000, max (20, (nextb->text->z_byte / 10)));
4674
4675 if (nextb->text->gap_size > size)
4676 {
4677 struct buffer *save_current = current_buffer;
4678 current_buffer = nextb;
4679 make_gap (-(nextb->text->gap_size - size));
4680 current_buffer = save_current;
4681 }
4682 }
4683
4684 nextb = nextb->next;
4685 }
4686 }
4687
4688 gc_in_progress = 1; 4678 gc_in_progress = 1;
4689 4679
4690 /* clear_marks (); */ 4680 /* clear_marks (); */
@@ -5959,29 +5949,6 @@ prevent garbage collection during a part of the program. */);
5959 doc: /* Non-nil means loading Lisp code in order to dump an executable. 5949 doc: /* Non-nil means loading Lisp code in order to dump an executable.
5960This means that certain objects should be allocated in shared (pure) space. */); 5950This means that certain objects should be allocated in shared (pure) space. */);
5961 5951
5962 DEFVAR_INT ("undo-limit", &undo_limit,
5963 doc: /* Keep no more undo information once it exceeds this size.
5964This limit is applied when garbage collection happens.
5965The size is counted as the number of bytes occupied,
5966which includes both saved text and other data. */);
5967 undo_limit = 20000;
5968
5969 DEFVAR_INT ("undo-strong-limit", &undo_strong_limit,
5970 doc: /* Don't keep more than this much size of undo information.
5971A previous command which pushes the undo list past this size
5972is entirely forgotten when GC happens.
5973The size is counted as the number of bytes occupied,
5974which includes both saved text and other data. */);
5975 undo_strong_limit = 30000;
5976
5977 DEFVAR_INT ("undo-outer-limit", &undo_outer_limit,
5978 doc: /* Don't keep more than this much size of undo information.
5979If the current command has produced more than this much undo information,
5980GC discards it. This is a last-ditch limit to prevent memory overflow.
5981The size is counted as the number of bytes occupied,
5982which includes both saved text and other data. */);
5983 undo_outer_limit = 300000;
5984
5985 DEFVAR_BOOL ("garbage-collection-messages", &garbage_collection_messages, 5952 DEFVAR_BOOL ("garbage-collection-messages", &garbage_collection_messages,
5986 doc: /* Non-nil means display messages at start and end of garbage collection. */); 5953 doc: /* Non-nil means display messages at start and end of garbage collection. */);
5987 garbage_collection_messages = 0; 5954 garbage_collection_messages = 0;
diff --git a/src/atimer.c b/src/atimer.c
index 7410cad0244..ff5b8faaf36 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -364,6 +364,8 @@ alarm_signal_handler (signo)
364{ 364{
365 EMACS_TIME now; 365 EMACS_TIME now;
366 366
367 SIGNAL_THREAD_CHECK (signo);
368
367 EMACS_GET_TIME (now); 369 EMACS_GET_TIME (now);
368 pending_atimers = 0; 370 pending_atimers = 0;
369 371
diff --git a/src/data.c b/src/data.c
index 0439d5763bc..8fbc04489b9 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3262,6 +3262,7 @@ arith_error (signo)
3262 sigsetmask (SIGEMPTYMASK); 3262 sigsetmask (SIGEMPTYMASK);
3263#endif /* not BSD4_1 */ 3263#endif /* not BSD4_1 */
3264 3264
3265 SIGNAL_THREAD_CHECK (signo);
3265 Fsignal (Qarith_error, Qnil); 3266 Fsignal (Qarith_error, Qnil);
3266} 3267}
3267 3268
diff --git a/src/dispnew.c b/src/dispnew.c
index 814a3095ddf..f04e806b368 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -5980,6 +5980,9 @@ window_change_signal (signalnum) /* If we don't have an argument, */
5980#endif 5980#endif
5981 int old_errno = errno; 5981 int old_errno = errno;
5982 5982
5983 signal (SIGWINCH, window_change_signal);
5984 SIGNAL_THREAD_CHECK (signalnum);
5985
5983 get_frame_size (&width, &height); 5986 get_frame_size (&width, &height);
5984 5987
5985 /* The frame size change obviously applies to a termcap-controlled 5988 /* The frame size change obviously applies to a termcap-controlled
@@ -6002,7 +6005,6 @@ window_change_signal (signalnum) /* If we don't have an argument, */
6002 } 6005 }
6003 } 6006 }
6004 6007
6005 signal (SIGWINCH, window_change_signal);
6006 errno = old_errno; 6008 errno = old_errno;
6007} 6009}
6008#endif /* SIGWINCH */ 6010#endif /* SIGWINCH */
diff --git a/src/emacs.c b/src/emacs.c
index 02031fe9072..d84cc29fcfa 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -342,6 +342,14 @@ int fatal_error_in_progress;
342 342
343void (*fatal_error_signal_hook) P_ ((void)); 343void (*fatal_error_signal_hook) P_ ((void));
344 344
345#ifdef HAVE_GTK_AND_PTHREAD
346/* When compiled with GTK and running under Gnome, multiple threads meay be
347 created. Keep track of our main thread to make sure signals are delivered
348 to it (see syssignal.h). */
349
350pthread_t main_thread;
351#endif
352
345 353
346#ifdef SIGUSR1 354#ifdef SIGUSR1
347SIGTYPE 355SIGTYPE
@@ -350,6 +358,7 @@ handle_USR1_signal (sig)
350{ 358{
351 struct input_event buf; 359 struct input_event buf;
352 360
361 SIGNAL_THREAD_CHECK (sig);
353 bzero (&buf, sizeof buf); 362 bzero (&buf, sizeof buf);
354 buf.kind = USER_SIGNAL_EVENT; 363 buf.kind = USER_SIGNAL_EVENT;
355 buf.frame_or_window = selected_frame; 364 buf.frame_or_window = selected_frame;
@@ -365,6 +374,7 @@ handle_USR2_signal (sig)
365{ 374{
366 struct input_event buf; 375 struct input_event buf;
367 376
377 SIGNAL_THREAD_CHECK (sig);
368 bzero (&buf, sizeof buf); 378 bzero (&buf, sizeof buf);
369 buf.kind = USER_SIGNAL_EVENT; 379 buf.kind = USER_SIGNAL_EVENT;
370 buf.code = 1; 380 buf.code = 1;
@@ -379,6 +389,7 @@ SIGTYPE
379fatal_error_signal (sig) 389fatal_error_signal (sig)
380 int sig; 390 int sig;
381{ 391{
392 SIGNAL_THREAD_CHECK (sig);
382 fatal_error_code = sig; 393 fatal_error_code = sig;
383 signal (sig, SIG_DFL); 394 signal (sig, SIG_DFL);
384 395
@@ -418,6 +429,7 @@ memory_warning_signal (sig)
418 int sig; 429 int sig;
419{ 430{
420 signal (sig, memory_warning_signal); 431 signal (sig, memory_warning_signal);
432 SIGNAL_THREAD_CHECK (sig);
421 433
422 malloc_warning ("Operating system warns that virtual memory is running low.\n"); 434 malloc_warning ("Operating system warns that virtual memory is running low.\n");
423 435
@@ -1029,6 +1041,10 @@ main (argc, argv
1029# endif /* not SYNC_INPUT */ 1041# endif /* not SYNC_INPUT */
1030#endif /* not SYSTEM_MALLOC */ 1042#endif /* not SYSTEM_MALLOC */
1031 1043
1044#ifdef HAVE_GTK_AND_PTHREAD
1045 main_thread = pthread_self ();
1046#endif /* HAVE_GTK_AND_PTHREAD */
1047
1032#if defined (MSDOS) || defined (WINDOWSNT) 1048#if defined (MSDOS) || defined (WINDOWSNT)
1033 /* We do all file input/output as binary files. When we need to translate 1049 /* We do all file input/output as binary files. When we need to translate
1034 newlines, we do that manually. */ 1050 newlines, we do that manually. */
@@ -1117,7 +1133,10 @@ main (argc, argv
1117 /* Handle the -batch switch, which means don't do interactive display. */ 1133 /* Handle the -batch switch, which means don't do interactive display. */
1118 noninteractive = 0; 1134 noninteractive = 0;
1119 if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args)) 1135 if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args))
1120 noninteractive = 1; 1136 {
1137 noninteractive = 1;
1138 Vundo_outer_limit = Qnil;
1139 }
1121 if (argmatch (argv, argc, "-script", "--script", 3, &junk, &skip_args)) 1140 if (argmatch (argv, argc, "-script", "--script", 3, &junk, &skip_args))
1122 { 1141 {
1123 noninteractive = 1; /* Set batch mode. */ 1142 noninteractive = 1; /* Set batch mode. */
diff --git a/src/eval.c b/src/eval.c
index 879f916aa46..df528e3da80 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1178,6 +1178,7 @@ unwind_to_catch (catch, value)
1178 set_poll_suppress_count (catch->poll_suppress_count); 1178 set_poll_suppress_count (catch->poll_suppress_count);
1179 interrupt_input_blocked = catch->interrupt_input_blocked; 1179 interrupt_input_blocked = catch->interrupt_input_blocked;
1180 handling_signal = 0; 1180 handling_signal = 0;
1181 immediate_quit = 0;
1181 1182
1182 do 1183 do
1183 { 1184 {
diff --git a/src/fileio.c b/src/fileio.c
index 6f52f792a5b..3b43a06e7ea 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -228,6 +228,8 @@ extern int minibuf_level;
228 228
229extern int minibuffer_auto_raise; 229extern int minibuffer_auto_raise;
230 230
231extern int history_delete_duplicates;
232
231/* These variables describe handlers that have "already" had a chance 233/* These variables describe handlers that have "already" had a chance
232 to handle the current operation. 234 to handle the current operation.
233 235
@@ -6299,7 +6301,13 @@ and `read-file-name-function'. */)
6299 if (replace_in_history) 6301 if (replace_in_history)
6300 /* Replace what Fcompleting_read added to the history 6302 /* Replace what Fcompleting_read added to the history
6301 with what we will actually return. */ 6303 with what we will actually return. */
6302 XSETCAR (Fsymbol_value (Qfile_name_history), double_dollars (val)); 6304 {
6305 Lisp_Object val1 = double_dollars (val);
6306 tem = Fsymbol_value (Qfile_name_history);
6307 if (history_delete_duplicates)
6308 XSETCDR (tem, Fdelete (val1, XCDR(tem)));
6309 XSETCAR (tem, val1);
6310 }
6303 else if (add_to_history) 6311 else if (add_to_history)
6304 { 6312 {
6305 /* Add the value to the history--but not if it matches 6313 /* Add the value to the history--but not if it matches
@@ -6307,8 +6315,10 @@ and `read-file-name-function'. */)
6307 Lisp_Object val1 = double_dollars (val); 6315 Lisp_Object val1 = double_dollars (val);
6308 tem = Fsymbol_value (Qfile_name_history); 6316 tem = Fsymbol_value (Qfile_name_history);
6309 if (! CONSP (tem) || NILP (Fequal (XCAR (tem), val1))) 6317 if (! CONSP (tem) || NILP (Fequal (XCAR (tem), val1)))
6310 Fset (Qfile_name_history, 6318 {
6311 Fcons (val1, tem)); 6319 if (history_delete_duplicates) tem = Fdelete (val1, tem);
6320 Fset (Qfile_name_history, Fcons (val1, tem));
6321 }
6312 } 6322 }
6313 6323
6314 return val; 6324 return val;
diff --git a/src/floatfns.c b/src/floatfns.c
index 61879eabe39..8cd08106ef2 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -981,6 +981,7 @@ float_error (signo)
981 signal (SIGILL, float_error); 981 signal (SIGILL, float_error);
982#endif /* BSD_SYSTEM */ 982#endif /* BSD_SYSTEM */
983 983
984 SIGNAL_THREAD_CHECK (signo);
984 in_float = 0; 985 in_float = 0;
985 986
986 Fsignal (Qarith_error, Fcons (float_error_arg, Qnil)); 987 Fsignal (Qarith_error, Fcons (float_error_arg, Qnil));
diff --git a/src/image.c b/src/image.c
index 18ffc2db3a4..6a86708a9d7 100644
--- a/src/image.c
+++ b/src/image.c
@@ -6269,6 +6269,12 @@ jpeg_image_p (object)
6269#undef HAVE_STDLIB_H 6269#undef HAVE_STDLIB_H
6270#endif /* HAVE_STLIB_H */ 6270#endif /* HAVE_STLIB_H */
6271 6271
6272#if defined (HAVE_NTGUI) && !defined (__WIN32__)
6273/* jpeglib.h will define boolean differently depending on __WIN32__,
6274 so make sure it is defined. */
6275#define __WIN32__ 1
6276#endif
6277
6272#include <jpeglib.h> 6278#include <jpeglib.h>
6273#include <jerror.h> 6279#include <jerror.h>
6274#include <setjmp.h> 6280#include <setjmp.h>
diff --git a/src/keyboard.c b/src/keyboard.c
index 6ed15f232d1..29e65d3acda 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3043,6 +3043,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
3043 /* Save the echo status. */ 3043 /* Save the echo status. */
3044 int saved_immediate_echo = current_kboard->immediate_echo; 3044 int saved_immediate_echo = current_kboard->immediate_echo;
3045 struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause; 3045 struct kboard *saved_ok_to_echo = ok_to_echo_at_next_pause;
3046 Lisp_Object saved_echo_string = current_kboard->echo_string;
3046 int saved_echo_after_prompt = current_kboard->echo_after_prompt; 3047 int saved_echo_after_prompt = current_kboard->echo_after_prompt;
3047 3048
3048#if 0 3049#if 0
@@ -3097,6 +3098,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
3097 3098
3098 cancel_echoing (); 3099 cancel_echoing ();
3099 ok_to_echo_at_next_pause = saved_ok_to_echo; 3100 ok_to_echo_at_next_pause = saved_ok_to_echo;
3101 current_kboard->echo_string = saved_echo_string;
3100 current_kboard->echo_after_prompt = saved_echo_after_prompt; 3102 current_kboard->echo_after_prompt = saved_echo_after_prompt;
3101 if (saved_immediate_echo) 3103 if (saved_immediate_echo)
3102 echo_now (); 3104 echo_now ();
@@ -3579,6 +3581,9 @@ event_to_kboard (event)
3579} 3581}
3580#endif 3582#endif
3581 3583
3584
3585Lisp_Object Vthrow_on_input;
3586
3582/* Store an event obtained at interrupt level into kbd_buffer, fifo */ 3587/* Store an event obtained at interrupt level into kbd_buffer, fifo */
3583 3588
3584void 3589void
@@ -3704,6 +3709,24 @@ kbd_buffer_store_event_hold (event, hold_quit)
3704 *kbd_store_ptr = *event; 3709 *kbd_store_ptr = *event;
3705 ++kbd_store_ptr; 3710 ++kbd_store_ptr;
3706 } 3711 }
3712
3713 /* If we're inside while-no-input, and this event qualifies
3714 as input, set quit-flag to cause an interrupt. */
3715 if (!NILP (Vthrow_on_input)
3716 && event->kind != FOCUS_IN_EVENT
3717 && event->kind != HELP_EVENT
3718 && event->kind != DEICONIFY_EVENT)
3719 {
3720 Vquit_flag = Vthrow_on_input;
3721 /* If we're inside a function that wants immediate quits,
3722 do it now. */
3723 if (immediate_quit && NILP (Vinhibit_quit))
3724 {
3725 immediate_quit = 0;
3726 sigfree ();
3727 QUIT;
3728 }
3729 }
3707} 3730}
3708 3731
3709 3732
@@ -6817,30 +6840,16 @@ input_available_signal (signo)
6817 sigisheld (SIGIO); 6840 sigisheld (SIGIO);
6818#endif 6841#endif
6819 6842
6820 if (input_available_clear_time)
6821 EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
6822
6823#ifdef SYNC_INPUT 6843#ifdef SYNC_INPUT
6824 interrupt_input_pending = 1; 6844 interrupt_input_pending = 1;
6825#else 6845#else
6846 SIGNAL_THREAD_CHECK (signo);
6847#endif
6848
6849 if (input_available_clear_time)
6850 EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
6826 6851
6827# if !defined (SYSTEM_MALLOC) && defined (HAVE_GTK_AND_PTHREAD) 6852#ifndef SYNC_INPUT
6828 extern pthread_t main_thread;
6829 if (pthread_self () != main_thread)
6830 {
6831 /* POSIX says any thread can receive the signal. On GNU/Linux that is
6832 not true, but for other systems (FreeBSD at least) it is. So direct
6833 the signal to the correct thread and block it from this thread. */
6834 sigset_t new_mask;
6835
6836 sigemptyset (&new_mask);
6837 sigaddset (&new_mask, SIGIO);
6838 pthread_sigmask (SIG_BLOCK, &new_mask, 0);
6839 pthread_kill (main_thread, SIGIO);
6840 return;
6841 }
6842# endif /* HAVE_GTK_AND_PTHREAD */
6843
6844 handle_async_input (); 6853 handle_async_input ();
6845#endif 6854#endif
6846 6855
@@ -10255,6 +10264,7 @@ interrupt_signal (signalnum) /* If we don't have an argument, */
10255 } 10264 }
10256#endif /* USG */ 10265#endif /* USG */
10257 10266
10267 SIGNAL_THREAD_CHECK (signalnum);
10258 cancel_echoing (); 10268 cancel_echoing ();
10259 10269
10260 if (!NILP (Vquit_flag) 10270 if (!NILP (Vquit_flag)
@@ -11375,6 +11385,12 @@ Used during Emacs' startup. */);
11375 doc: /* *How long to display an echo-area message when the minibuffer is active. 11385 doc: /* *How long to display an echo-area message when the minibuffer is active.
11376If the value is not a number, such messages don't time out. */); 11386If the value is not a number, such messages don't time out. */);
11377 Vminibuffer_message_timeout = make_number (2); 11387 Vminibuffer_message_timeout = make_number (2);
11388
11389 DEFVAR_LISP ("throw-on-input", &Vthrow_on_input,
11390 doc: /* If non-nil, any keyboard input throws to this symbol.
11391The value of that variable is passed to `quit-flag' and later causes a
11392peculiar kind of quitting. */);
11393 Vthrow_on_input = Qnil;
11378} 11394}
11379 11395
11380void 11396void
diff --git a/src/lisp.h b/src/lisp.h
index 3f49ac546cc..a6ea85b00c1 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3090,7 +3090,7 @@ extern void syms_of_macros P_ ((void));
3090/* defined in undo.c */ 3090/* defined in undo.c */
3091extern Lisp_Object Qinhibit_read_only; 3091extern Lisp_Object Qinhibit_read_only;
3092EXFUN (Fundo_boundary, 0); 3092EXFUN (Fundo_boundary, 0);
3093extern Lisp_Object truncate_undo_list P_ ((Lisp_Object, int, int, int)); 3093extern void truncate_undo_list P_ ((struct buffer *));
3094extern void record_marker_adjustment P_ ((Lisp_Object, int)); 3094extern void record_marker_adjustment P_ ((Lisp_Object, int));
3095extern void record_insert P_ ((int, int)); 3095extern void record_insert P_ ((int, int));
3096extern void record_delete P_ ((int, Lisp_Object)); 3096extern void record_delete P_ ((int, Lisp_Object));
@@ -3099,6 +3099,7 @@ extern void record_change P_ ((int, int));
3099extern void record_property_change P_ ((int, int, Lisp_Object, Lisp_Object, 3099extern void record_property_change P_ ((int, int, Lisp_Object, Lisp_Object,
3100 Lisp_Object)); 3100 Lisp_Object));
3101extern void syms_of_undo P_ ((void)); 3101extern void syms_of_undo P_ ((void));
3102extern Lisp_Object Vundo_outer_limit;
3102 3103
3103/* defined in textprop.c */ 3104/* defined in textprop.c */
3104extern Lisp_Object Qfont, Qmouse_face; 3105extern Lisp_Object Qfont, Qmouse_face;
diff --git a/src/macterm.c b/src/macterm.c
index ba19e0fbc31..4e9981da8b8 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -5997,7 +5997,7 @@ mac_to_x_fontname (name, size, style, scriptcode, encoding_base)
5997 strcpy(cs, "mac-cyrillic"); 5997 strcpy(cs, "mac-cyrillic");
5998 break; 5998 break;
5999 case kTextEncodingMacCentralEurRoman: 5999 case kTextEncodingMacCentralEurRoman:
6000 strcpy(cs, "mac-centraleuropean"); 6000 strcpy(cs, "mac-centraleurroman");
6001 break; 6001 break;
6002 case kTextEncodingMacSymbol: 6002 case kTextEncodingMacSymbol:
6003 case kTextEncodingMacDingbats: 6003 case kTextEncodingMacDingbats:
@@ -6055,7 +6055,7 @@ x_font_name_to_mac_font_name (char *xf, char *mf)
6055 coding_system = Qeuc_kr; 6055 coding_system = Qeuc_kr;
6056 else if (strcmp (cs, "mac-roman") == 0 6056 else if (strcmp (cs, "mac-roman") == 0
6057 || strcmp (cs, "mac-cyrillic") == 0 6057 || strcmp (cs, "mac-cyrillic") == 0
6058 || strcmp (cs, "mac-centraleuropean") == 0 6058 || strcmp (cs, "mac-centraleurroman") == 0
6059 || strcmp (cs, "adobe-fontspecific") == 0) 6059 || strcmp (cs, "adobe-fontspecific") == 0)
6060 strcpy (mf, family); 6060 strcpy (mf, family);
6061 else 6061 else
@@ -6300,6 +6300,28 @@ static int xlfd_scalable_fields[] =
6300 }; 6300 };
6301 6301
6302static Lisp_Object 6302static Lisp_Object
6303mac_c_string_match (regexp, string, nonspecial, exact)
6304 Lisp_Object regexp;
6305 const char *string, *nonspecial;
6306 int exact;
6307{
6308 if (exact)
6309 {
6310 if (strcmp (string, nonspecial) == 0)
6311 return build_string (string);
6312 }
6313 else if (strstr (string, nonspecial))
6314 {
6315 Lisp_Object str = build_string (string);
6316
6317 if (fast_string_match (regexp, str) >= 0)
6318 return str;
6319 }
6320
6321 return Qnil;
6322}
6323
6324static Lisp_Object
6303mac_do_list_fonts (pattern, maxnames) 6325mac_do_list_fonts (pattern, maxnames)
6304 char *pattern; 6326 char *pattern;
6305 int maxnames; 6327 int maxnames;
@@ -6310,6 +6332,8 @@ mac_do_list_fonts (pattern, maxnames)
6310 char scaled[256]; 6332 char scaled[256];
6311 char *ptr; 6333 char *ptr;
6312 int scl_val[XLFD_SCL_LAST], *field, *val; 6334 int scl_val[XLFD_SCL_LAST], *field, *val;
6335 char *longest_start, *cur_start, *nonspecial;
6336 int longest_len, cur_len, exact;
6313 6337
6314 for (i = 0; i < XLFD_SCL_LAST; i++) 6338 for (i = 0; i < XLFD_SCL_LAST; i++)
6315 scl_val[i] = -1; 6339 scl_val[i] = -1;
@@ -6367,34 +6391,66 @@ mac_do_list_fonts (pattern, maxnames)
6367 ptr = regex; 6391 ptr = regex;
6368 *ptr++ = '^'; 6392 *ptr++ = '^';
6369 6393
6370 /* Turn pattern into a regexp and do a regexp match. */ 6394 longest_start = cur_start = ptr;
6395 longest_len = cur_len = 0;
6396 exact = 1;
6397
6398 /* Turn pattern into a regexp and do a regexp match. Also find the
6399 longest substring containing no special characters. */
6371 for (; *pattern; pattern++) 6400 for (; *pattern; pattern++)
6372 { 6401 {
6373 if (*pattern == '?') 6402 if (*pattern == '?' || *pattern == '*')
6374 *ptr++ = '.'; 6403 {
6375 else if (*pattern == '*') 6404 if (cur_len > longest_len)
6376 { 6405 {
6377 *ptr++ = '.'; 6406 longest_start = cur_start;
6378 *ptr++ = '*'; 6407 longest_len = cur_len;
6379 } 6408 }
6409 cur_len = 0;
6410 exact = 0;
6411
6412 if (*pattern == '?')
6413 *ptr++ = '.';
6414 else /* if (*pattern == '*') */
6415 {
6416 *ptr++ = '.';
6417 *ptr++ = '*';
6418 }
6419 }
6380 else 6420 else
6381 *ptr++ = tolower (*pattern); 6421 {
6422 if (cur_len == 0)
6423 cur_start = ptr;
6424 cur_len++;
6425
6426 *ptr++ = tolower (*pattern);
6427 }
6382 } 6428 }
6429
6430 if (cur_len > longest_len)
6431 {
6432 longest_start = cur_start;
6433 longest_len = cur_len;
6434 }
6435
6383 *ptr = '$'; 6436 *ptr = '$';
6384 *(ptr + 1) = '\0'; 6437 *(ptr + 1) = '\0';
6385 6438
6439 nonspecial = xmalloc (longest_len + 1);
6440 strncpy (nonspecial, longest_start, longest_len);
6441 nonspecial[longest_len] = '\0';
6442
6386 pattern_regex = build_string (regex); 6443 pattern_regex = build_string (regex);
6387 6444
6388 for (i = 0; i < font_name_count; i++) 6445 for (i = 0; i < font_name_count; i++)
6389 { 6446 {
6390 fontname = build_string (font_name_table[i]); 6447 fontname = mac_c_string_match (pattern_regex, font_name_table[i],
6391 if (fast_string_match (pattern_regex, fontname) >= 0) 6448 nonspecial, exact);
6449 if (!NILP (fontname))
6392 { 6450 {
6393 font_list = Fcons (fontname, font_list); 6451 font_list = Fcons (fontname, font_list);
6394 6452 if (exact || maxnames > 0 && ++n_fonts >= maxnames)
6395 n_fonts++; 6453 break;
6396 if (maxnames > 0 && n_fonts >= maxnames)
6397 break;
6398 } 6454 }
6399 else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0 6455 else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0
6400 && (ptr = strstr (font_name_table[i], "-0-0-75-75-m-0-"))) 6456 && (ptr = strstr (font_name_table[i], "-0-0-75-75-m-0-")))
@@ -6408,17 +6464,19 @@ mac_do_list_fonts (pattern, maxnames)
6408 scl_val[XLFD_SCL_POINT_SIZE], 6464 scl_val[XLFD_SCL_POINT_SIZE],
6409 scl_val[XLFD_SCL_AVGWIDTH], 6465 scl_val[XLFD_SCL_AVGWIDTH],
6410 ptr + sizeof ("-0-0-75-75-m-0-") - 1); 6466 ptr + sizeof ("-0-0-75-75-m-0-") - 1);
6411 fontname = build_string (scaled); 6467 fontname = mac_c_string_match (pattern_regex, scaled,
6412 if (fast_string_match (pattern_regex, fontname) >= 0) 6468 nonspecial, exact);
6469 if (!NILP (fontname))
6413 { 6470 {
6414 font_list = Fcons (fontname, font_list); 6471 font_list = Fcons (fontname, font_list);
6415 6472 if (exact || maxnames > 0 && ++n_fonts >= maxnames)
6416 n_fonts++;
6417 if (maxnames > 0 && n_fonts >= maxnames)
6418 break; 6473 break;
6419 } 6474 }
6420 } 6475 }
6421 } 6476 }
6477
6478 xfree (nonspecial);
6479
6422 return font_list; 6480 return font_list;
6423} 6481}
6424 6482
diff --git a/src/process.c b/src/process.c
index 699c99cdcb8..6da7d73594d 100644
--- a/src/process.c
+++ b/src/process.c
@@ -5109,6 +5109,7 @@ Lisp_Object process_sent_to;
5109SIGTYPE 5109SIGTYPE
5110send_process_trap () 5110send_process_trap ()
5111{ 5111{
5112 SIGNAL_THREAD_CHECK (SIGPIPE);
5112#ifdef BSD4_1 5113#ifdef BSD4_1
5113 sigrelse (SIGPIPE); 5114 sigrelse (SIGPIPE);
5114 sigrelse (SIGALRM); 5115 sigrelse (SIGALRM);
@@ -6144,6 +6145,8 @@ sigchld_handler (signo)
6144 register struct Lisp_Process *p; 6145 register struct Lisp_Process *p;
6145 extern EMACS_TIME *input_available_clear_time; 6146 extern EMACS_TIME *input_available_clear_time;
6146 6147
6148 SIGNAL_THREAD_CHECK (signo);
6149
6147#ifdef BSD4_1 6150#ifdef BSD4_1
6148 extern int sigheld; 6151 extern int sigheld;
6149 sigheld |= sigbit (SIGCHLD); 6152 sigheld |= sigbit (SIGCHLD);
diff --git a/src/regex.c b/src/regex.c
index f21955a3c0e..e43fc2dc0aa 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -6096,7 +6096,7 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
6096 PREFETCH_NOLIMIT (); 6096 PREFETCH_NOLIMIT ();
6097 c2 = RE_STRING_CHAR (d, dend - d); 6097 c2 = RE_STRING_CHAR (d, dend - d);
6098#ifdef emacs 6098#ifdef emacs
6099 UPDATE_SYNTAX_TABLE_FORWARD (charpos); 6099 UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1);
6100#endif 6100#endif
6101 s2 = SYNTAX (c2); 6101 s2 = SYNTAX (c2);
6102 6102
diff --git a/src/sysdep.c b/src/sysdep.c
index 6284774d092..1884c0ccffa 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -2472,6 +2472,7 @@ select_alarm ()
2472#else /* not BSD4_1 */ 2472#else /* not BSD4_1 */
2473 signal (SIGALRM, SIG_IGN); 2473 signal (SIGALRM, SIG_IGN);
2474#endif /* not BSD4_1 */ 2474#endif /* not BSD4_1 */
2475 SIGNAL_THREAD_CHECK (SIGALRM);
2475 if (read_alarm_should_throw) 2476 if (read_alarm_should_throw)
2476 longjmp (read_alarm_throw, 1); 2477 longjmp (read_alarm_throw, 1);
2477} 2478}
diff --git a/src/syssignal.h b/src/syssignal.h
index cef71f7459a..04e84df1a3a 100644
--- a/src/syssignal.h
+++ b/src/syssignal.h
@@ -20,6 +20,11 @@ Boston, MA 02111-1307, USA. */
20 20
21extern void init_signals P_ ((void)); 21extern void init_signals P_ ((void));
22 22
23#ifdef HAVE_GTK_AND_PTHREAD
24#include <pthread.h>
25extern pthread_t main_thread;
26#endif
27
23#ifdef POSIX_SIGNALS 28#ifdef POSIX_SIGNALS
24 29
25/* Don't #include <signal.h>. That header should always be #included 30/* Don't #include <signal.h>. That header should always be #included
@@ -198,5 +203,27 @@ extern SIGMASKTYPE sigprocmask_set;
198char *strsignal (); 203char *strsignal ();
199#endif 204#endif
200 205
206#ifdef HAVE_GTK_AND_PTHREAD
207#define SIGNAL_THREAD_CHECK(signo) \
208 do { \
209 if (pthread_self () != main_thread) \
210 { \
211 /* POSIX says any thread can receive the signal. On GNU/Linux \
212 that is not true, but for other systems (FreeBSD at least) \
213 it is. So direct the signal to the correct thread and block \
214 it from this thread. */ \
215 sigset_t new_mask; \
216 \
217 sigemptyset (&new_mask); \
218 sigaddset (&new_mask, signo); \
219 pthread_sigmask (SIG_BLOCK, &new_mask, 0); \
220 pthread_kill (main_thread, signo); \
221 return; \
222 } \
223 } while (0)
224
225#else /* not HAVE_GTK_AND_PTHREAD */
226#define SIGNAL_THREAD_CHECK(signo)
227#endif /* not HAVE_GTK_AND_PTHREAD */
201/* arch-tag: 4580e86a-340d-4574-9e11-a742b6e1a152 228/* arch-tag: 4580e86a-340d-4574-9e11-a742b6e1a152
202 (do not change this comment) */ 229 (do not change this comment) */
diff --git a/src/undo.c b/src/undo.c
index 9fdc46a3b13..df4b8d08cd6 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -24,6 +24,17 @@ Boston, MA 02111-1307, USA. */
24#include "buffer.h" 24#include "buffer.h"
25#include "commands.h" 25#include "commands.h"
26 26
27/* Limits controlling how much undo information to keep. */
28
29EMACS_INT undo_limit;
30EMACS_INT undo_strong_limit;
31
32Lisp_Object Vundo_outer_limit;
33
34/* Function to call when undo_outer_limit is exceeded. */
35
36Lisp_Object Vundo_outer_limit_function;
37
27/* Last buffer for which undo information was recorded. */ 38/* Last buffer for which undo information was recorded. */
28Lisp_Object last_undo_buffer; 39Lisp_Object last_undo_buffer;
29 40
@@ -291,31 +302,35 @@ but another undo command will undo to the previous boundary. */)
291} 302}
292 303
293/* At garbage collection time, make an undo list shorter at the end, 304/* At garbage collection time, make an undo list shorter at the end,
294 returning the truncated list. 305 returning the truncated list. How this is done depends on the
295 MINSIZE, MAXSIZE and LIMITSIZE are the limits on size allowed, 306 variables undo-limit, undo-strong-limit and undo-outer-limit.
296 as described below. 307 In some cases this works by calling undo-outer-limit-function. */
297 In practice, these are the values of undo-limit, 308
298 undo-strong-limit, and undo-outer-limit. */ 309void
299 310truncate_undo_list (b)
300Lisp_Object 311 struct buffer *b;
301truncate_undo_list (list, minsize, maxsize, limitsize)
302 Lisp_Object list;
303 int minsize, maxsize, limitsize;
304{ 312{
313 Lisp_Object list;
305 Lisp_Object prev, next, last_boundary; 314 Lisp_Object prev, next, last_boundary;
306 int size_so_far = 0; 315 int size_so_far = 0;
307 316
317 /* Make sure that calling undo-outer-limit-function
318 won't cause another GC. */
319 int count = inhibit_garbage_collection ();
320
321 /* Make the buffer current to get its local values of variables such
322 as undo_limit. Also so that Vundo_outer_limit_function can
323 tell which buffer to operate on. */
324 record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ());
325 set_buffer_internal (b);
326
327 list = b->undo_list;
328
308 prev = Qnil; 329 prev = Qnil;
309 next = list; 330 next = list;
310 last_boundary = Qnil; 331 last_boundary = Qnil;
311 332
312 /* Always preserve at least the most recent undo record 333 /* If the first element is an undo boundary, skip past it. */
313 unless it is really horribly big.
314 If the first element is an undo boundary, skip past it.
315
316 Skip, skip, skip the undo, skip, skip, skip the undo,
317 Skip, skip, skip the undo, skip to the undo bound'ry.
318 (Get it? "Skip to my Loo?") */
319 if (CONSP (next) && NILP (XCAR (next))) 334 if (CONSP (next) && NILP (XCAR (next)))
320 { 335 {
321 /* Add in the space occupied by this element and its chain link. */ 336 /* Add in the space occupied by this element and its chain link. */
@@ -326,6 +341,12 @@ truncate_undo_list (list, minsize, maxsize, limitsize)
326 next = XCDR (next); 341 next = XCDR (next);
327 } 342 }
328 343
344 /* Always preserve at least the most recent undo record
345 unless it is really horribly big.
346
347 Skip, skip, skip the undo, skip, skip, skip the undo,
348 Skip, skip, skip the undo, skip to the undo bound'ry. */
349
329 while (CONSP (next) && ! NILP (XCAR (next))) 350 while (CONSP (next) && ! NILP (XCAR (next)))
330 { 351 {
331 Lisp_Object elt; 352 Lisp_Object elt;
@@ -341,35 +362,53 @@ truncate_undo_list (list, minsize, maxsize, limitsize)
341 + SCHARS (XCAR (elt))); 362 + SCHARS (XCAR (elt)));
342 } 363 }
343 364
344 /* If we reach LIMITSIZE before the first boundary,
345 we're heading for memory full, so truncate the list to nothing. */
346 if (size_so_far > limitsize)
347 return Qnil;
348
349 /* Advance to next element. */ 365 /* Advance to next element. */
350 prev = next; 366 prev = next;
351 next = XCDR (next); 367 next = XCDR (next);
352 } 368 }
353 369
370 /* If by the first boundary we have already passed undo_outer_limit,
371 we're heading for memory full, so offer to clear out the list. */
372 if (INTEGERP (Vundo_outer_limit)
373 && size_so_far > XINT (Vundo_outer_limit)
374 && !NILP (Vundo_outer_limit_function))
375 {
376 Lisp_Object temp = last_undo_buffer;
377
378 /* Normally the function this calls is undo-outer-limit-truncate. */
379 if (! NILP (call1 (Vundo_outer_limit_function,
380 make_number (size_so_far))))
381 {
382 /* The function is responsible for making
383 any desired changes in buffer-undo-list. */
384 unbind_to (count, Qnil);
385 return;
386 }
387 /* That function probably used the minibuffer, and if so, that
388 changed last_undo_buffer. Change it back so that we don't
389 force next change to make an undo boundary here. */
390 last_undo_buffer = temp;
391 }
392
354 if (CONSP (next)) 393 if (CONSP (next))
355 last_boundary = prev; 394 last_boundary = prev;
356 395
357 /* Keep more if it fits. */ 396 /* Keep additional undo data, if it fits in the limits. */
358 while (CONSP (next)) 397 while (CONSP (next))
359 { 398 {
360 Lisp_Object elt; 399 Lisp_Object elt;
361 elt = XCAR (next); 400 elt = XCAR (next);
362 401
363 /* When we get to a boundary, decide whether to truncate 402 /* When we get to a boundary, decide whether to truncate
364 either before or after it. The lower threshold, MINSIZE, 403 either before or after it. The lower threshold, undo_limit,
365 tells us to truncate after it. If its size pushes past 404 tells us to truncate after it. If its size pushes past
366 the higher threshold MAXSIZE as well, we truncate before it. */ 405 the higher threshold undo_strong_limit, we truncate before it. */
367 if (NILP (elt)) 406 if (NILP (elt))
368 { 407 {
369 if (size_so_far > maxsize) 408 if (size_so_far > undo_strong_limit)
370 break; 409 break;
371 last_boundary = prev; 410 last_boundary = prev;
372 if (size_so_far > minsize) 411 if (size_so_far > undo_limit)
373 break; 412 break;
374 } 413 }
375 414
@@ -390,16 +429,15 @@ truncate_undo_list (list, minsize, maxsize, limitsize)
390 429
391 /* If we scanned the whole list, it is short enough; don't change it. */ 430 /* If we scanned the whole list, it is short enough; don't change it. */
392 if (NILP (next)) 431 if (NILP (next))
393 return list; 432 ;
394
395 /* Truncate at the boundary where we decided to truncate. */ 433 /* Truncate at the boundary where we decided to truncate. */
396 if (!NILP (last_boundary)) 434 else if (!NILP (last_boundary))
397 { 435 XSETCDR (last_boundary, Qnil);
398 XSETCDR (last_boundary, Qnil); 436 /* There's nothing we decided to keep, so clear it out. */
399 return list;
400 }
401 else 437 else
402 return Qnil; 438 b->undo_list = Qnil;
439
440 unbind_to (count, Qnil);
403} 441}
404 442
405DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0, 443DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0,
@@ -563,6 +601,54 @@ syms_of_undo ()
563 601
564 defsubr (&Sprimitive_undo); 602 defsubr (&Sprimitive_undo);
565 defsubr (&Sundo_boundary); 603 defsubr (&Sundo_boundary);
604
605 DEFVAR_INT ("undo-limit", &undo_limit,
606 doc: /* Keep no more undo information once it exceeds this size.
607This limit is applied when garbage collection happens.
608When a previous command increases the total undo list size past this
609value, the earlier commands that came before it are forgotten.
610
611The size is counted as the number of bytes occupied,
612which includes both saved text and other data. */);
613 undo_limit = 20000;
614
615 DEFVAR_INT ("undo-strong-limit", &undo_strong_limit,
616 doc: /* Don't keep more than this much size of undo information.
617This limit is applied when garbage collection happens.
618When a previous command increases the total undo list size past this
619value, that command and the earlier commands that came before it are forgotten.
620However, the most recent buffer-modifying command's undo info
621is never discarded for this reason.
622
623The size is counted as the number of bytes occupied,
624which includes both saved text and other data. */);
625 undo_strong_limit = 30000;
626
627 DEFVAR_LISP ("undo-outer-limit", &Vundo_outer_limit,
628 doc: /* Outer limit on size of undo information for one command.
629At garbage collection time, if the current command has produced
630more than this much undo information, it asks you whether to delete
631the information. This is a last-ditch limit to prevent memory overflow.
632
633The size is counted as the number of bytes occupied,
634which includes both saved text and other data.
635
636In fact, this calls the function which is the value of
637`undo-outer-limit-function' with one argument, the size.
638The text above describes the behavior of the function
639that variable usually specifies. */);
640 Vundo_outer_limit = make_number (300000);
641
642 DEFVAR_LISP ("undo-outer-limit-function", &Vundo_outer_limit_function,
643 doc: /* Function to call when an undo list exceeds `undo-outer-limit'.
644This function is called with one argument, the current undo list size
645for the most recent command (since the last undo boundary).
646If the function returns t, that means truncation has been fully handled.
647If it returns nil, the other forms of truncation are done.
648
649Garbage collection is inhibited around the call to this function,
650so it must make sure not to do a lot of consing. */);
651 Vundo_outer_limit_function = Qnil;
566} 652}
567 653
568/* arch-tag: d546ee01-4aed-4ffb-bb8b-eefaae50d38a 654/* arch-tag: d546ee01-4aed-4ffb-bb8b-eefaae50d38a
diff --git a/src/xdisp.c b/src/xdisp.c
index ba6ee253d79..62efd4cac6c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -5050,6 +5050,21 @@ get_next_display_element (it)
5050 XSETINT (it->ctl_chars[1], g); 5050 XSETINT (it->ctl_chars[1], g);
5051 ctl_len = 2; 5051 ctl_len = 2;
5052 } 5052 }
5053 else if (it->c == 0x8a0 || it->c == 0x8ad)
5054 {
5055 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5056 if (it->dp
5057 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5058 && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (it->dp))))
5059 g = XINT (DISP_ESCAPE_GLYPH (it->dp));
5060 else
5061 g = FAST_MAKE_GLYPH ('\\', face_id);
5062 XSETINT (it->ctl_chars[0], g);
5063
5064 g = FAST_MAKE_GLYPH (it->c == 0x8ad ? '-' : ' ', face_id);
5065 XSETINT (it->ctl_chars[1], g);
5066 ctl_len = 2;
5067 }
5053 else 5068 else
5054 { 5069 {
5055 unsigned char str[MAX_MULTIBYTE_LENGTH]; 5070 unsigned char str[MAX_MULTIBYTE_LENGTH];
diff --git a/src/xselect.c b/src/xselect.c
index c89347be2cd..38547ea6bbf 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -2324,7 +2324,7 @@ DEFUN ("x-get-cut-buffer-internal", Fx_get_cut_buffer_internal,
2324 Fcons (x_atom_to_symbol (display, type), 2324 Fcons (x_atom_to_symbol (display, type),
2325 Fcons (make_number (format), Qnil)))); 2325 Fcons (make_number (format), Qnil))));
2326 2326
2327 ret = (bytes ? make_string ((char *) data, bytes) : Qnil); 2327 ret = (bytes ? make_unibyte_string ((char *) data, bytes) : Qnil);
2328 /* Use xfree, not XFree, because x_get_window_property 2328 /* Use xfree, not XFree, because x_get_window_property
2329 calls xmalloc itself. */ 2329 calls xmalloc itself. */
2330 xfree (data); 2330 xfree (data);
diff --git a/src/xterm.c b/src/xterm.c
index 2ffe7668516..05148608961 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -4289,8 +4289,6 @@ xg_scroll_callback (widget, data)
4289 int part = -1, whole = 0, portion = 0; 4289 int part = -1, whole = 0, portion = 0;
4290 GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (widget)); 4290 GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (widget));
4291 4291
4292 if (xg_ignore_gtk_scrollbar) return;
4293
4294 position = gtk_adjustment_get_value (adj); 4292 position = gtk_adjustment_get_value (adj);
4295 4293
4296 p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA); 4294 p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA);
@@ -4304,6 +4302,8 @@ xg_scroll_callback (widget, data)
4304 previous = *p; 4302 previous = *p;
4305 *p = position; 4303 *p = position;
4306 4304
4305 if (xg_ignore_gtk_scrollbar) return;
4306
4307 diff = (int) (position - previous); 4307 diff = (int) (position - previous);
4308 4308
4309 if (diff == (int) adj->step_increment) 4309 if (diff == (int) adj->step_increment)
@@ -4335,7 +4335,7 @@ xg_scroll_callback (widget, data)
4335 } 4335 }
4336 4336
4337 if (part >= 0) 4337 if (part >= 0)
4338 { 4338 {
4339 window_being_scrolled = bar->window; 4339 window_being_scrolled = bar->window;
4340 last_scroll_bar_part = part; 4340 last_scroll_bar_part = part;
4341 x_send_scroll_bar_event (bar->window, part, portion, whole); 4341 x_send_scroll_bar_event (bar->window, part, portion, whole);