diff --git a/src/viewer/text/search.c b/src/viewer/text/search.c index e916b7ba..6f70cb57 100644 --- a/src/viewer/text/search.c +++ b/src/viewer/text/search.c @@ -454,14 +454,23 @@ is_in_range_regex(struct document *document, int y, int height, #endif /* HAVE_REGEX_H */ static UCHAR * -memacpy_u(unsigned char *text, int textlen) +memacpy_u(unsigned char *text, int textlen, int utf8) { #ifdef CONFIG_UTF_8 UCHAR *mem = mem_alloc((textlen + 1) * sizeof(UCHAR)); - int i; if (!mem) return NULL; - for (i = 0; i < textlen; i++) mem[i] = utf_8_to_unicode(&text, text + 7); + if (utf8) { + int i; + + for (i = 0; i < textlen; i++) + mem[i] = utf_8_to_unicode(&text, text + 7); + } else { + int i; + + for (i = 0; i < textlen; i++) + mem[i] = text[i]; + } mem[textlen] = 0; return mem; #else @@ -470,28 +479,29 @@ memacpy_u(unsigned char *text, int textlen) } static int -strlen_u(unsigned char *text) +strlen_u(unsigned char *text, int utf8) { #ifdef CONFIG_UTF_8 - return strlen_utf8(&text); -#else - return strlen(text); + if (utf8) + return strlen_utf8(&text); #endif + return strlen(text); + } /* Returns an allocated string which is a lowered copy of passed one. */ static UCHAR * -lowered_string(unsigned char *text, int textlen) +lowered_string(unsigned char *text, int textlen, int utf8) { UCHAR *ret; - if (textlen < 0) textlen = strlen_u(text); + if (textlen < 0) textlen = strlen_u(text, utf8); - ret = memacpy_u(text, textlen); + ret = memacpy_u(text, textlen, utf8); if (ret && textlen) { do { #if defined(CONFIG_UTF_8) && defined(HAVE_WCTYPE_H) - ret[textlen] = towlower(ret[textlen]); + ret[textlen] = utf8 ? towlower(ret[textlen]) : tolower(ret[textlen]); #else ret[textlen] = tolower(ret[textlen]); #endif @@ -505,14 +515,14 @@ static int is_in_range_plain(struct document *document, int y, int height, unsigned char *text, int textlen, int *min, int *max, - struct search *s1, struct search *s2) + struct search *s1, struct search *s2, int utf8) { int yy = y + height; UCHAR *txt; int found = 0; int case_sensitive = get_opt_bool("document.browse.search.case"); - txt = case_sensitive ? memacpy_u(text, textlen) : lowered_string(text, textlen); + txt = case_sensitive ? memacpy_u(text, textlen, utf8) : lowered_string(text, textlen, utf8); if (!txt) return -1; /* TODO: This is a great candidate for nice optimizations. Fresh CS @@ -521,7 +531,7 @@ is_in_range_plain(struct document *document, int y, int height, * maybe some other Boyer-Moore variant, I don't feel that strong in * this area), hmm? >:) --pasky */ #if defined(CONFIG_UTF_8) && defined(HAVE_WCTYPE_H) -#define maybe_tolower(c) (case_sensitive ? (c) : towlower(c)) +#define maybe_tolower(c) (case_sensitive ? (c) : utf8 ? towlower(c) : tolower(c)) #else #define maybe_tolower(c) (case_sensitive ? (c) : tolower(c)) #endif @@ -564,12 +574,16 @@ is_in_range(struct document *document, int y, int height, { struct search *s1, *s2; int textlen; + int utf8 = 0; assert(document && text && min && max); if_assert_failed return -1; +#ifdef CONFIG_UTF_8 + utf8 = is_cp_special(document->options.cp); +#endif *min = INT_MAX, *max = 0; - textlen = strlen_u(text); + textlen = strlen_u(text, utf8); if (get_range(document, y, height, textlen, &s1, &s2)) return 0; @@ -580,7 +594,7 @@ is_in_range(struct document *document, int y, int height, min, max, s1, s2); #endif return is_in_range_plain(document, y, height, text, textlen, - min, max, s1, s2); + min, max, s1, s2, utf8); } #define realloc_points(pts, size) \ @@ -588,7 +602,7 @@ is_in_range(struct document *document, int y, int height, static void get_searched_plain(struct document_view *doc_view, struct point **pt, int *pl, - int l, struct search *s1, struct search *s2) + int l, struct search *s1, struct search *s2, int utf8) { UCHAR *txt; struct point *points = NULL; @@ -597,8 +611,8 @@ get_searched_plain(struct document_view *doc_view, struct point **pt, int *pl, int len = 0; int case_sensitive = get_opt_bool("document.browse.search.case"); - txt = case_sensitive ? memacpy_u(*doc_view->search_word, l) - : lowered_string(*doc_view->search_word, l); + txt = case_sensitive ? memacpy_u(*doc_view->search_word, l, utf8) + : lowered_string(*doc_view->search_word, l, utf8); if (!txt) return; box = &doc_view->box; @@ -606,7 +620,7 @@ get_searched_plain(struct document_view *doc_view, struct point **pt, int *pl, yoffset = box->y - doc_view->vs->y; #if defined(CONFIG_UTF_8) && defined(HAVE_WCTYPE_H) -#define maybe_tolower(c) (case_sensitive ? (c) : towlower(c)) +#define maybe_tolower(c) (case_sensitive ? (c) : utf8 ? towlower(c) : tolower(c)) #else #define maybe_tolower(c) (case_sensitive ? (c) : tolower(c)) #endif @@ -720,7 +734,7 @@ get_searched_regex(struct document_view *doc_view, struct point **pt, int *pl, #endif /* HAVE_REGEX_H */ static void -get_searched(struct document_view *doc_view, struct point **pt, int *pl) +get_searched(struct document_view *doc_view, struct point **pt, int *pl, int utf8) { struct search *s1, *s2; int l; @@ -732,7 +746,7 @@ get_searched(struct document_view *doc_view, struct point **pt, int *pl) return; get_search_data(doc_view->document); - l = strlen_u(*doc_view->search_word); + l = strlen_u(*doc_view->search_word, utf8); if (get_range(doc_view->document, doc_view->vs->y, doc_view->box.height, l, &s1, &s2)) { *pt = NULL; @@ -746,7 +760,7 @@ get_searched(struct document_view *doc_view, struct point **pt, int *pl) get_searched_regex(doc_view, pt, pl, l, s1, s2); else #endif - get_searched_plain(doc_view, pt, pl, l, s1, s2); + get_searched_plain(doc_view, pt, pl, l, s1, s2, utf8); } /* Highlighting of searched strings. */ @@ -755,6 +769,7 @@ draw_searched(struct terminal *term, struct document_view *doc_view) { struct point *pt = NULL; int len = 0; + int utf8 = 0; assert(term && doc_view); if_assert_failed return; @@ -762,7 +777,10 @@ draw_searched(struct terminal *term, struct document_view *doc_view) if (!has_search_word(doc_view)) return; - get_searched(doc_view, &pt, &len); +#ifdef CONFIG_UTF_8 + utf8 = is_cp_special(doc_view->document->options.cp); +#endif + get_searched(doc_view, &pt, &len, utf8); if (len) { int i; struct color_pair *color = get_bfu_color(term, "searched"); @@ -925,10 +943,14 @@ find_next_link_in_search(struct document_view *doc_view, int direction) struct point *pt = NULL; struct link *link; int len; + int utf8 = 0; +#ifdef CONFIG_UTF_8 + utf8 = is_cp_special(doc_view->document->options.cp); +#endif nt: link = &doc_view->document->links[doc_view->vs->current_link]; - get_searched(doc_view, &pt, &len); + get_searched(doc_view, &pt, &len, utf8); if (point_intersect(pt, len, link->points, link->npoints)) { mem_free(pt); return 0;