vi: fix backward search with GNU regex
With FEATURE_VI_REGEX_SEARCH enabled backward searches don't work. This is problematic on distros that enable regexes, such as Tiny Core Linux and Fedora. When calling GNU re_search() with a negative range parameter (indicating a backward search) the start offset must be set to the end of the area being searched. The return value of re_search() is the offset of the matched pattern from the start of the area being searched. For a successful search (positive return value) char_search() can return the pointer to the start of the area plus the offset. FEATURE_VI_REGEX_SEARCH isn't enabled by default but when it is: function old new delta char_search 256 247 -9 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-9) Total: -9 bytes Signed-off-by: Andrey Dobrovolsky <andrey.dobrovolsky.odessa@gmail.com> Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
		
				
					committed by
					
						 Denys Vlasenko
						Denys Vlasenko
					
				
			
			
				
	
			
			
			
						parent
						
							ac4786ba00
						
					
				
				
					commit
					51358757c7
				
			
							
								
								
									
										33
									
								
								editors/vi.c
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								editors/vi.c
									
									
									
									
									
								
							| @@ -2376,9 +2376,7 @@ static char *char_search(char *p, const char *pat, int dir_and_range) | ||||
| 	struct re_pattern_buffer preg; | ||||
| 	const char *err; | ||||
| 	char *q; | ||||
| 	int i; | ||||
| 	int size; | ||||
| 	int range; | ||||
| 	int i, size, range, start; | ||||
|  | ||||
| 	re_syntax_options = RE_SYNTAX_POSIX_EXTENDED; | ||||
| 	if (ignorecase) | ||||
| @@ -2403,31 +2401,26 @@ static char *char_search(char *p, const char *pat, int dir_and_range) | ||||
|  | ||||
| 	// RANGE could be negative if we are searching backwards | ||||
| 	range = q - p; | ||||
| 	q = p; | ||||
| 	size = range; | ||||
| 	if (range < 0) { | ||||
| 		size = -size; | ||||
| 		q = p - size; | ||||
| 		if (q < text) | ||||
| 			q = text; | ||||
| 		size = -range; | ||||
| 		start = size; | ||||
| 	} else { | ||||
| 		size = range; | ||||
| 		start = 0; | ||||
| 	} | ||||
| 	q = p - start; | ||||
| 	if (q < text) | ||||
| 		q = text; | ||||
| 	// search for the compiled pattern, preg, in p[] | ||||
| 	// range < 0: search backward | ||||
| 	// range > 0: search forward | ||||
| 	// 0 < start < size | ||||
| 	// range < 0, start == size: search backward | ||||
| 	// range > 0, start == 0: search forward | ||||
| 	// re_search() < 0: not found or error | ||||
| 	// re_search() >= 0: index of found pattern | ||||
| 	//           struct pattern   char     int   int    int    struct reg | ||||
| 	// re_search(*pattern_buffer, *string, size, start, range, *regs) | ||||
| 	i = re_search(&preg, q, size, /*start:*/ 0, range, /*struct re_registers*:*/ NULL); | ||||
| 	i = re_search(&preg, q, size, start, range, /*struct re_registers*:*/ NULL); | ||||
| 	regfree(&preg); | ||||
| 	if (i < 0) | ||||
| 		return NULL; | ||||
| 	if (dir_and_range > 0) // FORWARD? | ||||
| 		p = p + i; | ||||
| 	else | ||||
| 		p = p - i; | ||||
| 	return p; | ||||
| 	return i < 0 ? NULL : q + i; | ||||
| } | ||||
| # else | ||||
| #  if ENABLE_FEATURE_VI_SETOPTS | ||||
|   | ||||
		Reference in New Issue
	
	Block a user