aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKarl Heuer1994-10-19 04:51:45 +0000
committerKarl Heuer1994-10-19 04:51:45 +0000
commit487282dc64fdc27aeaaacad3180832607f5c3deb (patch)
tree6ca44ffea4727ba3949b74df5cb6ccc59d11c41f /src
parente50c66d349eb02a4a0367f4cd9227c0f227ea41b (diff)
downloademacs-487282dc64fdc27aeaaacad3180832607f5c3deb.tar.gz
emacs-487282dc64fdc27aeaaacad3180832607f5c3deb.zip
(searchbufs): New variable, replaces searchbuf and last_regexp and
search_fastmap. (syms_of_search): Initialize it. (searchbuf_head): New variable. (compile_pattern_1): Renamed from compile_pattern and made static. Copy the regexp string in case the caller modifies it in place later. (compile_pattern): New code, uses a cached entry if one is available. The pattern buffer is now a return value instead of an arg. (set_search_regs): Set num_regs directly, since there's no active pattern buffer to pass to re_set_registers. (Fstore_match_data): Likewise. (Flooking_at): Use the new calling convention for compile_pattern. (Fstring_match, fast_string_match, search_buffer): Likewise.
Diffstat (limited to 'src')
-rw-r--r--src/search.c142
1 files changed, 90 insertions, 52 deletions
diff --git a/src/search.c b/src/search.c
index c621e886d17..a0050190931 100644
--- a/src/search.c
+++ b/src/search.c
@@ -29,15 +29,23 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
29#include <sys/types.h> 29#include <sys/types.h>
30#include "regex.h" 30#include "regex.h"
31 31
32/* We compile regexps into this buffer and then use it for searching. */ 32#define REGEXP_CACHE_SIZE 5
33 33
34struct re_pattern_buffer searchbuf; 34/* If the regexp is non-nil, then the buffer contains the compiled form
35 of that regexp, suitable for searching. */
36struct regexp_cache {
37 struct regexp_cache *next;
38 Lisp_Object regexp;
39 struct re_pattern_buffer buf;
40 char fastmap[0400];
41};
35 42
36char search_fastmap[0400]; 43/* The instances of that struct. */
44struct regexp_cache searchbufs[REGEXP_CACHE_SIZE];
37 45
38/* Last regexp we compiled */ 46/* The head of the linked list; points to the most recently used buffer. */
47struct regexp_cache *searchbuf_head;
39 48
40Lisp_Object last_regexp;
41 49
42/* Every call to re_match, etc., must pass &search_regs as the regs 50/* Every call to re_match, etc., must pass &search_regs as the regs
43 argument unless you can show it is unnecessary (i.e., if re_match 51 argument unless you can show it is unnecessary (i.e., if re_match
@@ -49,8 +57,8 @@ Lisp_Object last_regexp;
49 been allocated by checking search_regs.num_regs. 57 been allocated by checking search_regs.num_regs.
50 58
51 The regex code keeps track of whether it has allocated the search 59 The regex code keeps track of whether it has allocated the search
52 buffer using bits in searchbuf. This means that whenever you 60 buffer using bits in the re_pattern_buffer. This means that whenever
53 compile a new pattern, it completely forgets whether it has 61 you compile a new pattern, it completely forgets whether it has
54 allocated any registers, and will allocate new registers the next 62 allocated any registers, and will allocate new registers the next
55 time you call a searching or matching function. Therefore, we need 63 time you call a searching or matching function. Therefore, we need
56 to call re_set_registers after compiling a new pattern or after 64 to call re_set_registers after compiling a new pattern or after
@@ -83,42 +91,68 @@ matcher_overflow ()
83 91
84/* Compile a regexp and signal a Lisp error if anything goes wrong. */ 92/* Compile a regexp and signal a Lisp error if anything goes wrong. */
85 93
86compile_pattern (pattern, bufp, regp, translate) 94static void
95compile_pattern_1 (cp, pattern, translate, regp)
96 struct regexp_cache *cp;
87 Lisp_Object pattern; 97 Lisp_Object pattern;
88 struct re_pattern_buffer *bufp;
89 struct re_registers *regp;
90 char *translate; 98 char *translate;
99 struct re_registers *regp;
91{ 100{
92 CONST char *val; 101 CONST char *val;
93 Lisp_Object dummy;
94 102
95 if (EQ (pattern, last_regexp) 103 cp->regexp = Qnil;
96 && translate == bufp->translate) 104 cp->buf.translate = translate;
97 return;
98
99 last_regexp = Qnil;
100 bufp->translate = translate;
101 BLOCK_INPUT; 105 BLOCK_INPUT;
102 val = (CONST char *) re_compile_pattern ((char *) XSTRING (pattern)->data, 106 val = (CONST char *) re_compile_pattern ((char *) XSTRING (pattern)->data,
103 XSTRING (pattern)->size, bufp); 107 XSTRING (pattern)->size, &cp->buf);
104 UNBLOCK_INPUT; 108 UNBLOCK_INPUT;
105 if (val) 109 if (val)
106 { 110 Fsignal (Qinvalid_regexp, Fcons (build_string (val), Qnil));
107 dummy = build_string (val);
108 while (1)
109 Fsignal (Qinvalid_regexp, Fcons (dummy, Qnil));
110 }
111 111
112 last_regexp = pattern; 112 cp->regexp = Fcopy_sequence (pattern);
113 113
114 /* Advise the searching functions about the space we have allocated 114 /* Advise the searching functions about the space we have allocated
115 for register data. */ 115 for register data. */
116 BLOCK_INPUT; 116 BLOCK_INPUT;
117 if (regp) 117 if (regp)
118 re_set_registers (bufp, regp, regp->num_regs, regp->start, regp->end); 118 re_set_registers (&cp->buf, regp, regp->num_regs, regp->start, regp->end);
119 UNBLOCK_INPUT; 119 UNBLOCK_INPUT;
120}
121
122/* Compile a regexp if necessary, but first check to see if there's one in
123 the cache. */
124
125struct re_pattern_buffer *
126compile_pattern (pattern, regp, translate)
127 Lisp_Object pattern;
128 struct re_registers *regp;
129 char *translate;
130{
131 struct regexp_cache *cp, **cpp;
132
133 for (cpp = &searchbuf_head; ; cpp = &cp->next)
134 {
135 cp = *cpp;
136 if (!NILP (Fstring_equal (cp->regexp, pattern))
137 && cp->buf.translate == translate)
138 break;
139
140 /* If we're at the end of the cache, compile into the last cell. */
141 if (cp->next == 0)
142 {
143 compile_pattern_1 (cp, pattern, translate, regp);
144 break;
145 }
146 }
147
148 /* When we get here, cp (aka *cpp) contains the compiled pattern,
149 either because we found it in the cache or because we just compiled it.
150 Move it to the front of the queue to mark it as most recently used. */
151 *cpp = cp->next;
152 cp->next = searchbuf_head;
153 searchbuf_head = cp;
120 154
121 return; 155 return &cp->buf;
122} 156}
123 157
124/* Error condition used for failing searches */ 158/* Error condition used for failing searches */
@@ -144,10 +178,12 @@ data if you want to preserve them.")
144 unsigned char *p1, *p2; 178 unsigned char *p1, *p2;
145 int s1, s2; 179 int s1, s2;
146 register int i; 180 register int i;
181 struct re_pattern_buffer *bufp;
147 182
148 CHECK_STRING (string, 0); 183 CHECK_STRING (string, 0);
149 compile_pattern (string, &searchbuf, &search_regs, 184 bufp = compile_pattern (string, &search_regs,
150 !NILP (current_buffer->case_fold_search) ? DOWNCASE_TABLE : 0); 185 (!NILP (current_buffer->case_fold_search)
186 ? DOWNCASE_TABLE : 0));
151 187
152 immediate_quit = 1; 188 immediate_quit = 1;
153 QUIT; /* Do a pending quit right away, to avoid paradoxical behavior */ 189 QUIT; /* Do a pending quit right away, to avoid paradoxical behavior */
@@ -171,7 +207,7 @@ data if you want to preserve them.")
171 s2 = 0; 207 s2 = 0;
172 } 208 }
173 209
174 i = re_match_2 (&searchbuf, (char *) p1, s1, (char *) p2, s2, 210 i = re_match_2 (bufp, (char *) p1, s1, (char *) p2, s2,
175 point - BEGV, &search_regs, 211 point - BEGV, &search_regs,
176 ZV - BEGV); 212 ZV - BEGV);
177 if (i == -2) 213 if (i == -2)
@@ -200,6 +236,7 @@ matched by parenthesis constructs in the pattern.")
200{ 236{
201 int val; 237 int val;
202 int s; 238 int s;
239 struct re_pattern_buffer *bufp;
203 240
204 CHECK_STRING (regexp, 0); 241 CHECK_STRING (regexp, 0);
205 CHECK_STRING (string, 1); 242 CHECK_STRING (string, 1);
@@ -218,10 +255,11 @@ matched by parenthesis constructs in the pattern.")
218 args_out_of_range (string, start); 255 args_out_of_range (string, start);
219 } 256 }
220 257
221 compile_pattern (regexp, &searchbuf, &search_regs, 258 bufp = compile_pattern (regexp, &search_regs,
222 !NILP (current_buffer->case_fold_search) ? DOWNCASE_TABLE : 0); 259 (!NILP (current_buffer->case_fold_search)
260 ? DOWNCASE_TABLE : 0));
223 immediate_quit = 1; 261 immediate_quit = 1;
224 val = re_search (&searchbuf, (char *) XSTRING (string)->data, 262 val = re_search (bufp, (char *) XSTRING (string)->data,
225 XSTRING (string)->size, s, XSTRING (string)->size - s, 263 XSTRING (string)->size, s, XSTRING (string)->size - s,
226 &search_regs); 264 &search_regs);
227 immediate_quit = 0; 265 immediate_quit = 0;
@@ -241,10 +279,11 @@ fast_string_match (regexp, string)
241 Lisp_Object regexp, string; 279 Lisp_Object regexp, string;
242{ 280{
243 int val; 281 int val;
282 struct re_pattern_buffer *bufp;
244 283
245 compile_pattern (regexp, &searchbuf, 0, 0); 284 bufp = compile_pattern (regexp, 0, 0);
246 immediate_quit = 1; 285 immediate_quit = 1;
247 val = re_search (&searchbuf, (char *) XSTRING (string)->data, 286 val = re_search (bufp, (char *) XSTRING (string)->data,
248 XSTRING (string)->size, 0, XSTRING (string)->size, 287 XSTRING (string)->size, 0, XSTRING (string)->size,
249 0); 288 0);
250 immediate_quit = 0; 289 immediate_quit = 0;
@@ -823,7 +862,9 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
823 862
824 if (RE && !trivial_regexp_p (string)) 863 if (RE && !trivial_regexp_p (string))
825 { 864 {
826 compile_pattern (string, &searchbuf, &search_regs, (char *) trt); 865 struct re_pattern_buffer *bufp;
866
867 bufp = compile_pattern (string, &search_regs, (char *) trt);
827 868
828 immediate_quit = 1; /* Quit immediately if user types ^G, 869 immediate_quit = 1; /* Quit immediately if user types ^G,
829 because letting this function finish 870 because letting this function finish
@@ -851,7 +892,7 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
851 while (n < 0) 892 while (n < 0)
852 { 893 {
853 int val; 894 int val;
854 val = re_search_2 (&searchbuf, (char *) p1, s1, (char *) p2, s2, 895 val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2,
855 pos - BEGV, lim - pos, &search_regs, 896 pos - BEGV, lim - pos, &search_regs,
856 /* Don't allow match past current point */ 897 /* Don't allow match past current point */
857 pos - BEGV); 898 pos - BEGV);
@@ -882,7 +923,7 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
882 while (n > 0) 923 while (n > 0)
883 { 924 {
884 int val; 925 int val;
885 val = re_search_2 (&searchbuf, (char *) p1, s1, (char *) p2, s2, 926 val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2,
886 pos - BEGV, lim - pos, &search_regs, 927 pos - BEGV, lim - pos, &search_regs,
887 lim - BEGV); 928 lim - BEGV);
888 if (val == -2) 929 if (val == -2)
@@ -1185,11 +1226,7 @@ set_search_regs (beg, len)
1185 1226
1186 starts = (regoff_t *) xmalloc (2 * sizeof (regoff_t)); 1227 starts = (regoff_t *) xmalloc (2 * sizeof (regoff_t));
1187 ends = (regoff_t *) xmalloc (2 * sizeof (regoff_t)); 1228 ends = (regoff_t *) xmalloc (2 * sizeof (regoff_t));
1188 BLOCK_INPUT; 1229 search_regs.num_regs = 2;
1189 re_set_registers (&searchbuf,
1190 &search_regs,
1191 2, starts, ends);
1192 UNBLOCK_INPUT;
1193 } 1230 }
1194 1231
1195 search_regs.start[0] = beg; 1232 search_regs.start[0] = beg;
@@ -1723,10 +1760,7 @@ LIST should have been created by calling `match-data' previously.")
1723 length * sizeof (regoff_t)); 1760 length * sizeof (regoff_t));
1724 } 1761 }
1725 1762
1726 BLOCK_INPUT; 1763 search_regs.num_regs = length;
1727 re_set_registers (&searchbuf, &search_regs, length,
1728 search_regs.start, search_regs.end);
1729 UNBLOCK_INPUT;
1730 } 1764 }
1731 } 1765 }
1732 1766
@@ -1802,9 +1836,16 @@ syms_of_search ()
1802{ 1836{
1803 register int i; 1837 register int i;
1804 1838
1805 searchbuf.allocated = 100; 1839 for (i = 0; i < REGEXP_CACHE_SIZE; ++i)
1806 searchbuf.buffer = (unsigned char *) malloc (searchbuf.allocated); 1840 {
1807 searchbuf.fastmap = search_fastmap; 1841 searchbufs[i].buf.allocated = 100;
1842 searchbufs[i].buf.buffer = (unsigned char *) malloc (100);
1843 searchbufs[i].buf.fastmap = searchbufs[i].fastmap;
1844 searchbufs[i].regexp = Qnil;
1845 staticpro (&searchbufs[i].regexp);
1846 searchbufs[i].next = (i == REGEXP_CACHE_SIZE-1 ? 0 : &searchbufs[i+1]);
1847 }
1848 searchbuf_head = &searchbufs[0];
1808 1849
1809 Qsearch_failed = intern ("search-failed"); 1850 Qsearch_failed = intern ("search-failed");
1810 staticpro (&Qsearch_failed); 1851 staticpro (&Qsearch_failed);
@@ -1821,9 +1862,6 @@ syms_of_search ()
1821 Fput (Qinvalid_regexp, Qerror_message, 1862 Fput (Qinvalid_regexp, Qerror_message,
1822 build_string ("Invalid regexp")); 1863 build_string ("Invalid regexp"));
1823 1864
1824 last_regexp = Qnil;
1825 staticpro (&last_regexp);
1826
1827 last_thing_searched = Qnil; 1865 last_thing_searched = Qnil;
1828 staticpro (&last_thing_searched); 1866 staticpro (&last_thing_searched);
1829 1867