case insensitive search

master
Allen Webster 2016-03-21 14:23:23 -04:00
parent 4a43a580c5
commit 6568de0e17
5 changed files with 127 additions and 2 deletions

View File

@ -357,6 +357,7 @@ struct Application_Links;
#define BUFFER_SEEK_DELIMITER_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, char delim, int seek_forward, int *out)
#define BUFFER_SEEK_STRING_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, char *str, int len, int seek_forward, int *out)
#define BUFFER_SEEK_STRING_INSENSITIVE_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, char *str, int len, int seek_forward, int *out)
#define REFRESH_BUFFER_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer)
#define BUFFER_READ_RANGE_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *out)
@ -438,6 +439,7 @@ extern "C"{
typedef BUFFER_SEEK_DELIMITER_SIG(Buffer_Seek_Delimiter_Function);
typedef BUFFER_SEEK_STRING_SIG(Buffer_Seek_String_Function);
typedef BUFFER_SEEK_STRING_INSENSITIVE_SIG(Buffer_Seek_String_Insensitive_Function);
typedef REFRESH_BUFFER_SIG(Refresh_Buffer_Function);
typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function);
@ -501,6 +503,7 @@ struct Application_Links{
Buffer_Seek_Delimiter_Function *buffer_seek_delimiter;
Buffer_Seek_String_Function *buffer_seek_string;
Buffer_Seek_String_Insensitive_Function *buffer_seek_string_insensitive;
Refresh_Buffer_Function *refresh_buffer;
Buffer_Read_Range_Function *buffer_read_range;

View File

@ -306,7 +306,8 @@ isearch(Application_Links *app, int start_reversed){
if (in.key.keycode != key_back){
int new_pos;
if (reverse){
app->buffer_seek_string(app, &buffer, start_pos - 1, bar.string.str, bar.string.size, 0, &new_pos);
// TODO(allen): Need a good way to allow users to implement seeks for themselves.
app->buffer_seek_string_insensitive(app, &buffer, start_pos - 1, bar.string.str, bar.string.size, 0, &new_pos);
if (new_pos >= 0){
if (step_backward){
pos = new_pos;
@ -319,7 +320,7 @@ isearch(Application_Links *app, int start_reversed){
}
}
else{
app->buffer_seek_string(app, &buffer, start_pos + 1, bar.string.str, bar.string.size, 1, &new_pos);
app->buffer_seek_string_insensitive(app, &buffer, start_pos + 1, bar.string.str, bar.string.size, 1, &new_pos);
if (new_pos < buffer.size){
if (step_forward){
pos = new_pos;

42
4ed.cpp
View File

@ -2199,7 +2199,48 @@ extern "C"{
return(result);
}
// TODO(allen): Reduce duplication between this and external_buffer_seek_string
BUFFER_SEEK_STRING_SIG(external_buffer_seek_string_insensitive){
Command_Data *cmd = (Command_Data*)app->cmd_context;
Models *models;
Editing_File *file;
Working_Set *working_set;
Partition *part;
Temp_Memory temp;
char *spare;
int result = 0;
int size;
if (buffer->exists){
models = cmd->models;
working_set = &models->working_set;
file = working_set_get_active_file(working_set, buffer->buffer_id);
if (file && file_is_ready(file)){
size = buffer_size(&file->state.buffer);
if (start < 0 && !seek_forward) *out = start;
else if (start >= size && seek_forward) *out = start;
else{
part = &models->mem.part;
temp = begin_temp_memory(part);
spare = push_array(part, char, len);
result = 1;
if (seek_forward){
*out = buffer_find_string_insensitive(&file->state.buffer, start, size, str, len, spare);
}
else{
*out = buffer_rfind_string_insensitive(&file->state.buffer, start, str, len, spare);
}
end_temp_memory(temp);
}
fill_buffer_summary(buffer, file, working_set);
}
}
return(result);
}
REFRESH_BUFFER_SIG(external_refresh_buffer){
int result;
*buffer = external_get_buffer(app, buffer->buffer_id);
@ -2615,6 +2656,7 @@ app_links_init(System_Functions *system, void *data, int size){
app_links.refresh_buffer = external_refresh_buffer;
app_links.buffer_seek_delimiter = external_buffer_seek_delimiter;
app_links.buffer_seek_string = external_buffer_seek_string;
app_links.buffer_seek_string_insensitive = external_buffer_seek_string_insensitive;
app_links.buffer_read_range = external_buffer_read_range;
app_links.buffer_replace_range = external_buffer_replace_range;

View File

@ -571,6 +571,66 @@ buffer_rfind_string_end:
return(pos);
}
internal_4tech int
buffer_find_string_insensitive(Buffer_Type *buffer, int start_pos, int end_pos, char *str, int len, char *spare){
Buffer_Stringify_Type loop;
char *data;
int end, pos;
pos = start_pos;
if (len > 0){
for (loop = buffer_stringify_loop(buffer, start_pos, end_pos - len + 1);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end; ++pos){
if (to_upper(*str) == to_upper(data[pos])){
buffer_stringify(buffer, pos, pos + len, spare);
if (is_match_insensitive(str, spare, len))
goto buffer_find_string_end;
}
}
}
}
buffer_find_string_end:
if (pos >= end_pos - len + 1) pos = end_pos;
return(pos);
}
internal_4tech int
buffer_rfind_string_insensitive(Buffer_Type *buffer, int start_pos, char *str, int len, char *spare){
Buffer_Backify_Type loop;
char *data;
int end, size;
int pos;
size = buffer_size(buffer);
pos = start_pos;
if (pos > size - len) pos = size - len;
if (len > 0){
for (loop = buffer_backify_loop(buffer, start_pos, 0);
buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos >= end; --pos){
if (to_upper(*str) == to_upper(data[pos])){
buffer_stringify(buffer, pos, pos + len, spare);
if (is_match_insensitive(str, spare, len))
goto buffer_rfind_string_end;
}
}
}
}
buffer_rfind_string_end:
return(pos);
}
#ifndef NON_ABSTRACT_4TECH
typedef struct Buffer_Measure_Starts{
int i;

View File

@ -408,6 +408,14 @@ is_lower(char c){
return (c >= 'a' && c <= 'z');
}
inline_4tech char
to_upper(char c){
if (is_lower(c)){
c += 'A' - 'a';
}
return(c);
}
internal_4tech int
is_match(char *a, char *b, int len){
int result;
@ -419,5 +427,16 @@ is_match(char *a, char *b, int len){
return(result);
}
internal_4tech int
is_match_insensitive(char *a, char *b, int len){
int result;
result = 1;
for (;len > 0; --len, ++a, ++b)
if (to_upper(*a) != to_upper(*b)) { result = 0; break; }
return(result);
}
// BOTTOM