X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/9ac6d28ab8c29547d9f9365dc8f7cea13c32ef7a..d703a4dce564ede122f5c307889e4bd0e3f3e75c:/src/search.c diff --git a/src/search.c b/src/search.c index ecfb235214..0252542a36 100644 --- a/src/search.c +++ b/src/search.c @@ -1,6 +1,6 @@ /* String search routines for GNU Emacs. -Copyright (C) 1985-1987, 1993-1994, 1997-1999, 2001-2014 Free Software +Copyright (C) 1985-1987, 1993-1994, 1997-1999, 2001-2015 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -84,12 +84,6 @@ static struct re_registers search_regs; Qnil if no searching has been done yet. */ static Lisp_Object last_thing_searched; -/* Error condition signaled when regexp compile_pattern fails. */ -static Lisp_Object Qinvalid_regexp; - -/* Error condition used for failing searches. */ -static Lisp_Object Qsearch_failed; - static void set_search_regs (ptrdiff_t, ptrdiff_t); static void save_search_regs (void); static EMACS_INT simple_search (EMACS_INT, unsigned char *, ptrdiff_t, @@ -985,6 +979,24 @@ scan_newline (ptrdiff_t start, ptrdiff_t start_byte, return shortage; } +/* Like above, but always scan from point and report the + resulting position in *CHARPOS and *BYTEPOS. */ + +ptrdiff_t +scan_newline_from_point (ptrdiff_t count, ptrdiff_t *charpos, + ptrdiff_t *bytepos) +{ + ptrdiff_t shortage; + + if (count <= 0) + *charpos = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, count - 1, + &shortage, bytepos, 1); + else + *charpos = find_newline (PT, PT_BYTE, ZV, ZV_BYTE, count, + &shortage, bytepos, 1); + return shortage; +} + /* Like find_newline, but doesn't allow QUITting and doesn't return SHORTAGE. */ ptrdiff_t @@ -1318,6 +1330,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, translation. Otherwise set to zero later. */ int char_base = -1; bool boyer_moore_ok = 1; + USE_SAFE_ALLOCA; /* MULTIBYTE says whether the text to be searched is multibyte. We must convert PATTERN to match that, or we will not really @@ -1335,7 +1348,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, raw_pattern_size_byte = count_size_as_multibyte (SDATA (string), raw_pattern_size); - raw_pattern = alloca (raw_pattern_size_byte + 1); + raw_pattern = SAFE_ALLOCA (raw_pattern_size_byte + 1); copy_text (SDATA (string), raw_pattern, SCHARS (string), 0, 1); } @@ -1349,7 +1362,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, the chosen single-byte character set can possibly match. */ raw_pattern_size = SCHARS (string); raw_pattern_size_byte = SCHARS (string); - raw_pattern = alloca (raw_pattern_size + 1); + raw_pattern = SAFE_ALLOCA (raw_pattern_size + 1); copy_text (SDATA (string), raw_pattern, SBYTES (string), 1, 0); } @@ -1357,7 +1370,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, /* Copy and optionally translate the pattern. */ len = raw_pattern_size; len_byte = raw_pattern_size_byte; - patbuf = alloca (len * MAX_MULTIBYTE_LENGTH); + SAFE_NALLOCA (patbuf, MAX_MULTIBYTE_LENGTH, len); pat = patbuf; base_pat = raw_pattern; if (multibyte) @@ -1497,13 +1510,15 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, len_byte = pat - patbuf; pat = base_pat = patbuf; - if (boyer_moore_ok) - return boyer_moore (n, pat, len_byte, trt, inverse_trt, - pos_byte, lim_byte, - char_base); - else - return simple_search (n, pat, raw_pattern_size, len_byte, trt, - pos, pos_byte, lim, lim_byte); + EMACS_INT result + = (boyer_moore_ok + ? boyer_moore (n, pat, len_byte, trt, inverse_trt, + pos_byte, lim_byte, + char_base) + : simple_search (n, pat, raw_pattern_size, len_byte, trt, + pos, pos_byte, lim, lim_byte)); + SAFE_FREE (); + return result; } } @@ -2809,7 +2824,8 @@ Return value is undefined if the last search failed. */) prev = Qnil; - data = alloca ((2 * search_regs.num_regs + 1) * sizeof *data); + USE_SAFE_ALLOCA; + SAFE_NALLOCA (data, 1, 2 * search_regs.num_regs + 1); len = 0; for (i = 0; i < search_regs.num_regs; i++) @@ -2852,25 +2868,28 @@ Return value is undefined if the last search failed. */) /* If REUSE is not usable, cons up the values and return them. */ if (! CONSP (reuse)) - return Flist (len, data); - - /* If REUSE is a list, store as many value elements as will fit - into the elements of REUSE. */ - for (i = 0, tail = reuse; CONSP (tail); - i++, tail = XCDR (tail)) + reuse = Flist (len, data); + else { + /* If REUSE is a list, store as many value elements as will fit + into the elements of REUSE. */ + for (i = 0, tail = reuse; CONSP (tail); + i++, tail = XCDR (tail)) + { + if (i < len) + XSETCAR (tail, data[i]); + else + XSETCAR (tail, Qnil); + prev = tail; + } + + /* If we couldn't fit all value elements into REUSE, + cons up the rest of them and add them to the end of REUSE. */ if (i < len) - XSETCAR (tail, data[i]); - else - XSETCAR (tail, Qnil); - prev = tail; + XSETCDR (prev, Flist (len - i, data + i)); } - /* If we couldn't fit all value elements into REUSE, - cons up the rest of them and add them to the end of REUSE. */ - if (i < len) - XSETCDR (prev, Flist (len - i, data + i)); - + SAFE_FREE (); return reuse; } @@ -3075,7 +3094,8 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0, CHECK_STRING (string); - temp = alloca (SBYTES (string) * 2); + USE_SAFE_ALLOCA; + SAFE_NALLOCA (temp, 2, SBYTES (string)); /* Now copy the data into the new string, inserting escapes. */ @@ -3093,10 +3113,13 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0, *out++ = *in; } - return make_specified_string (temp, - SCHARS (string) + backslashes_added, - out - temp, - STRING_MULTIBYTE (string)); + Lisp_Object result + = make_specified_string (temp, + SCHARS (string) + backslashes_added, + out - temp, + STRING_MULTIBYTE (string)); + SAFE_FREE (); + return result; } /* Like find_newline, but doesn't use the cache, and only searches forward. */ @@ -3300,7 +3323,10 @@ syms_of_search (void) } searchbuf_head = &searchbufs[0]; + /* Error condition used for failing searches. */ DEFSYM (Qsearch_failed, "search-failed"); + + /* Error condition signaled when regexp compile_pattern fails. */ DEFSYM (Qinvalid_regexp, "invalid-regexp"); Fput (Qsearch_failed, Qerror_conditions,