From 6568de0e1719f8269d83a697b403ab8972ae27dd Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 21 Mar 2016 14:23:23 -0400 Subject: [PATCH] case insensitive search --- 4coder_custom.h | 3 ++ 4coder_default.cpp | 5 +-- 4ed.cpp | 42 ++++++++++++++++++++++ buffer/4coder_buffer_abstract.cpp | 60 +++++++++++++++++++++++++++++++ buffer/4coder_shared.cpp | 19 ++++++++++ 5 files changed, 127 insertions(+), 2 deletions(-) diff --git a/4coder_custom.h b/4coder_custom.h index 807fbf2a..79d9f37e 100644 --- a/4coder_custom.h +++ b/4coder_custom.h @@ -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; diff --git a/4coder_default.cpp b/4coder_default.cpp index 6f0ffbfe..134316ab 100644 --- a/4coder_default.cpp +++ b/4coder_default.cpp @@ -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; diff --git a/4ed.cpp b/4ed.cpp index 1be71c17..1e53c8c7 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -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; diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index ffd085e7..37b95932 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -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; diff --git a/buffer/4coder_shared.cpp b/buffer/4coder_shared.cpp index 8238a7b3..afb630be 100644 --- a/buffer/4coder_shared.cpp +++ b/buffer/4coder_shared.cpp @@ -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