From 8379eac6b7471da50cc449901b7255246b011d85 Mon Sep 17 00:00:00 2001 From: Marco Kirchner Date: Sat, 10 Sep 2016 13:28:25 +0200 Subject: [PATCH] texteditor: make search case insensitive --- Makefile | 2 +- bm.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ bm.h | 6 +++++ text.c | 17 ++++++++++---- utils.c | 6 +++++ utils.h | 2 ++ 6 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 bm.c create mode 100644 bm.h diff --git a/Makefile b/Makefile index 02992fa..add4d5d 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ TITLE_ID = VITASHELL TARGET = VitaShell OBJS = main.o init.o io_process.o package_installer.o network_update.o context_menu.o archive.o photo.o file.o text.o hex.o sfo.o \ uncommon_dialog.o message_dialog.o ime_dialog.o config.o theme.o language.o utils.o sha1.o \ - audioplayer.o minizip/unzip.o minizip/ioapi.o + audioplayer.o minizip/unzip.o minizip/ioapi.o bm.o RESOURCES_PNG = resources/folder_icon.png resources/file_icon.png resources/archive_icon.png resources/image_icon.png \ resources/audio_icon.png resources/sfo_icon.png resources/text_icon.png\ diff --git a/bm.c b/bm.c new file mode 100644 index 0000000..1362ec7 --- /dev/null +++ b/bm.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include + +const char * boyer_moore(const char *haystack, const char *needle) { + size_t plen = strlen(needle), slen = strlen(haystack); + + if (plen > slen) { + return NULL; + } + + int skip[UCHAR_MAX+1]; + int i, j, k, * next; + + /* calc skip table („bad rule“) */ + for (i = 0; i <= UCHAR_MAX; i++) { + skip[i] = plen; + } + + for (i = 0; i < plen; i++) { + skip[tolower((unsigned char)needle[i])] = plen - i - 1; + } + + + /* calc next table („good rule“) */ + next = (int*)malloc((plen+1) * sizeof(int)); + + for (j = 0; j <= plen; j++) { + for (i = plen - 1; i >= 1; i--) { + for (k = 1; k <= j; k++) { + if (i - k < 0) { + break; + } + if (tolower((unsigned char)needle[plen - k]) != tolower((unsigned char)needle[i - k])) { + goto nexttry; + } + } + goto matched; +nexttry: + ; + } +matched: + next[j] = plen - i; + } + + plen--; + i = plen; /* position of last p letter in s */ + + while (i < slen) { + j = 0; /* matched letter count */ + while (j <= plen) { + if (tolower((unsigned char)haystack[i - j]) == tolower((unsigned char)needle[plen - j])) { + j++; + } else { + i += skip[tolower((unsigned char)haystack[i - j])] > next[j] ? skip[tolower((unsigned char)haystack[i - j])] - j : next[j]; + goto newi; + } + } + free(next); + return haystack + i - plen; +newi: + ; + } + free(next); + return NULL; +} \ No newline at end of file diff --git a/bm.h b/bm.h new file mode 100644 index 0000000..0567b26 --- /dev/null +++ b/bm.h @@ -0,0 +1,6 @@ +#ifndef __BM_H__ +#define __BM_H__ + +char * boyer_moore(const char *haystack, const char *needle); + +#endif \ No newline at end of file diff --git a/text.c b/text.c index 9064852..7af6eb8 100644 --- a/text.c +++ b/text.c @@ -490,7 +490,7 @@ static int search_thread(SceSize args, SearchParams *argp) { char *r; while (state->search_running && offset < state->size && state->n_search_results < MAX_SEARCH_RESULTS) { - r = strstr(state->buffer + offset, search_term); + r = strcasestr(state->buffer + offset, search_term); if (r == NULL) { state->search_running = 0; @@ -981,10 +981,12 @@ int textViewer(char *file) { char *search_highlight = NULL; if (search_result_on_line) { - search_highlight = strstr(line, s->search_term); + search_highlight = strcasestr(line, s->search_term); } + char tmp = '\0'; if (search_highlight) { + tmp = *search_highlight; *search_highlight = '\0'; } @@ -999,9 +1001,16 @@ int textViewer(char *file) { } if (search_highlight) { - *search_highlight = s->search_term[0]; + *search_highlight = tmp; + + int search_term_length = strlen(s->search_term); + tmp = search_highlight[search_term_length]; + search_highlight[search_term_length] = '\0'; + x += width; - x += pgf_draw_text(x, START_Y + (i * FONT_Y_SPACE), TEXT_HIGHLIGHT_COLOR, FONT_SIZE, s->search_term); + x += pgf_draw_text(x, START_Y + (i * FONT_Y_SPACE), TEXT_HIGHLIGHT_COLOR, FONT_SIZE, line); + + search_highlight[search_term_length] = tmp; line += strlen(s->search_term); } } diff --git a/utils.c b/utils.c index 7e145b4..17aecfb 100644 --- a/utils.c +++ b/utils.c @@ -23,6 +23,7 @@ #include "theme.h" #include "language.h" #include "utils.h" +#include "bm.h" SceCtrlData pad; uint32_t old_buttons, current_buttons, pressed_buttons, hold_buttons, hold2_buttons, released_buttons; @@ -319,4 +320,9 @@ int launchAppByUriExit(char *titleid) { sceKernelExitProcess(0); return 0; +} + + +char *strcasestr(const char *haystack, const char *needle) { + return boyer_moore(haystack, needle); } \ No newline at end of file diff --git a/utils.h b/utils.h index d1e51ac..6de952b 100644 --- a/utils.h +++ b/utils.h @@ -74,4 +74,6 @@ int debugPrintf(char *text, ...); int launchAppByUriExit(char *titleid); +char *strcasestr(const char *haystack, const char *needle); + #endif