From 7074fde6640c88db886be0fcc4182e3790936d7d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Francesco=20Potort=C3=AC?= Date: Mon, 21 Nov 1994 12:50:27 +0000 Subject: [PATCH] Added code for automatically saving and restoring the match data when a filter or sentinel tries to modify it. --- src/emacs.c | 5 +++++ src/lisp.h | 3 +++ src/process.c | 9 ++++++++- src/search.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/emacs.c b/src/emacs.c index bfc83b87087..ae13412fc80 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -98,6 +98,10 @@ int inhibit_window_system; priority; Those functions have their own extern declaration. */ int emacs_priority; +/* If non-zero a filter or a sentinel is running. Tested to save the match + data on the first attempt to change it inside asynchronous code. */ +int running_asynch_code; + #ifdef BSD_PGRPS /* See sysdep.c. */ extern int inherited_pgroup; @@ -697,6 +701,7 @@ Usage: %s [-t term] [--terminal term] [-nw] [--no-windows] [--batch]\n\ init_alloc (); init_eval (); init_data (); + running_asynch_code = 0; #ifdef MSDOS /* Call early 'cause init_environment needs it. */ diff --git a/src/lisp.h b/src/lisp.h index 1b773b2fa65..f946da5e5f4 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1404,6 +1404,7 @@ extern Lisp_Object Vfundamental_mode_abbrev_table; /* defined in search.c */ extern Lisp_Object Fstring_match (); extern Lisp_Object Fscan_buffer (); +extern void restore_match_data (); /* defined in minibuf.c */ @@ -1499,6 +1500,8 @@ void shut_down_emacs ( /* int signal, int no_x, Lisp_Object stuff */ ); extern int noninteractive; /* Nonzero means don't do use window-system-specific display code */ extern int inhibit_window_system; +/* Nonzero means that a filter or a sentinel is running. */ +extern int running_asynch_code; /* defined in process.c */ extern Lisp_Object Fget_process (), Fget_buffer_process (), Fprocessp (); diff --git a/src/process.c b/src/process.c index db4b31ad57c..526f46f0db2 100644 --- a/src/process.c +++ b/src/process.c @@ -2350,13 +2350,17 @@ read_process_output (proc, channel) specbind (Qinhibit_quit, Qt); specbind (Qlast_nonmenu_event, Qt); + running_asynch_code = 1; internal_condition_case_1 (read_process_output_call, Fcons (outstream, Fcons (proc, - Fcons (make_string (chars, nchars), + Fcons (make_string (chars, + nchars), Qnil))), !NILP (Vdebug_on_error) ? Qnil : Qerror, read_process_output_error_handler); + running_asynch_code = 0; + restore_match_data (); /* Handling the process output should not deactivate the mark. */ Vdeactivate_mark = odeactivate; @@ -3233,11 +3237,14 @@ exec_sentinel (proc, reason) specbind (Qinhibit_quit, Qt); specbind (Qlast_nonmenu_event, Qt); + running_asynch_code = 1; internal_condition_case_1 (read_process_output_call, Fcons (sentinel, Fcons (proc, Fcons (reason, Qnil))), !NILP (Vdebug_on_error) ? Qnil : Qerror, exec_sentinel_error_handler); + running_asynch_code = 0; + restore_match_data (); Vdeactivate_mark = odeactivate; if (! EQ (Fcurrent_buffer (), obuffer)) diff --git a/src/search.c b/src/search.c index 622df821c70..2aa645047c6 100644 --- a/src/search.c +++ b/src/search.c @@ -206,6 +206,9 @@ looking_at_1 (string, posix) register int i; struct re_pattern_buffer *bufp; + if (running_asynch_code) + save_search_regs (); + CHECK_STRING (string, 0); bufp = compile_pattern (string, &search_regs, (!NILP (current_buffer->case_fold_search) @@ -284,6 +287,9 @@ string_match_1 (regexp, string, start, posix) int s; struct re_pattern_buffer *bufp; + if (running_asynch_code) + save_search_regs (); + CHECK_STRING (regexp, 0); CHECK_STRING (string, 1); @@ -928,6 +934,9 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt, posix) unsigned char *p1, *p2; int s1, s2; + if (running_asynch_code) + save_search_regs (); + /* Null string is found at starting position. */ if (len == 0) { @@ -1845,6 +1854,9 @@ LIST should have been created by calling `match-data' previously.") register int i; register Lisp_Object marker; + if (running_asynch_code) + save_search_regs (); + if (!CONSP (list) && !NILP (list)) list = wrong_type_argument (Qconsp, list); @@ -1914,6 +1926,46 @@ LIST should have been created by calling `match-data' previously.") return Qnil; } +/* If non-zero the match data have been saved in saved_search_regs + during the execution of a sentinel or filter. */ +static int search_regs_saved = 0; +static struct re_registers saved_search_regs; + +/* Called from Flooking_at, Fstring_match, search_buffer, Fstore_match_data + if asynchronous code (filter or sentinel) is running. */ +static void +save_search_regs () +{ + if (!search_regs_saved) + { + saved_search_regs.num_regs = search_regs.num_regs; + saved_search_regs.start = search_regs.start; + saved_search_regs.end = search_regs.end; + search_regs.num_regs = 0; + + search_regs_saved = 1; + } +} + +/* Called upon exit from filters and sentinels. */ +void +restore_match_data () +{ + if (search_regs_saved) + { + if (search_regs.num_regs > 0) + { + xfree (search_regs.start); + xfree (search_regs.end); + } + search_regs.num_regs = saved_search_regs.num_regs; + search_regs.start = saved_search_regs.start; + search_regs.end = saved_search_regs.end; + + search_regs_saved = 0; + } +} + /* Quote a string to inactivate reg-expr chars */ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0, -- 2.39.5