diff options
author | Tatsuya Kinoshita <tats@vega.ocn.ne.jp> | 2011-05-04 07:05:14 +0000 |
---|---|---|
committer | Tatsuya Kinoshita <tats@vega.ocn.ne.jp> | 2011-05-04 07:05:14 +0000 |
commit | 72f72d64a422d6628c4796f5c0bf2e508f134214 (patch) | |
tree | 0c9ea90cc53310832c977265521fb44db24a515e /search.c | |
parent | Adding upstream version 0.3 (diff) | |
download | w3m-upstream/0.5.1.tar.gz w3m-upstream/0.5.1.zip |
Adding upstream version 0.5.1upstream/0.5.1
Diffstat (limited to 'search.c')
-rw-r--r-- | search.c | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/search.c b/search.c new file mode 100644 index 0000000..4182020 --- /dev/null +++ b/search.c @@ -0,0 +1,307 @@ +/* $Id: search.c,v 1.31 2004/03/23 16:44:02 ukai Exp $ */ +#include "fm.h" +#include "regex.h" +#include <signal.h> +#include <errno.h> +#include <unistd.h> + +static void +set_mark(Line *l, int pos, int epos) +{ + for (; pos < epos && pos < l->size; pos++) + l->propBuf[pos] |= PE_MARK; +} + +#ifdef USE_MIGEMO +/* Migemo: romaji --> kana+kanji in regexp */ +static FILE *migemor = NULL, *migemow = NULL; +static int migemo_running; +static int migemo_pid = 0; + +void +init_migemo() +{ + migemo_active = migemo_running = use_migemo; + if (migemor != NULL) + fclose(migemor); + if (migemow != NULL) + fclose(migemow); + migemor = migemow = NULL; + if (migemo_pid) + kill(migemo_pid, SIGKILL); + migemo_pid = 0; +} + +static int +open_migemo(char *migemo_command) +{ + migemo_pid = open_pipe_rw(&migemor, &migemow); + if (migemo_pid < 0) + goto err0; + if (migemo_pid == 0) { + /* child */ + setup_child(FALSE, 2, -1); + myExec(migemo_command); + /* XXX: ifdef __EMX__, use start /f ? */ + } + return 1; + err0: + migemo_pid = 0; + migemo_active = migemo_running = 0; + return 0; +} + +static char * +migemostr(char *str) +{ + Str tmp = NULL; + if (migemor == NULL || migemow == NULL) + if (open_migemo(migemo_command) == 0) + return str; + fprintf(migemow, "%s\n", conv_to_system(str)); + again: + if (fflush(migemow) != 0) { + switch (errno) { + case EINTR: + goto again; + default: + goto err; + } + } + tmp = Str_conv_from_system(Strfgets(migemor)); + Strchop(tmp); + if (tmp->length == 0) + goto err; + return conv_search_string(tmp->ptr, SystemCharset); + err: + /* XXX: backend migemo is not working? */ + init_migemo(); + migemo_active = migemo_running = 0; + return str; +} +#endif /* USE_MIGEMO */ + +#ifdef USE_M17N +/* normalize search string */ +char * +conv_search_string(char *str, wc_ces f_ces) +{ + if (SearchConv && !WcOption.pre_conv && + Currentbuf->document_charset != f_ces) + str = wtf_conv_fit(str, Currentbuf->document_charset); + return str; +} +#endif + +int +forwardSearch(Buffer *buf, char *str) +{ + char *p, *first, *last; + Line *l, *begin; + int wrapped = FALSE; + int pos; + +#ifdef USE_MIGEMO + if (migemo_active > 0) { + if (((p = regexCompile(migemostr(str), IgnoreCase)) != NULL) + && ((p = regexCompile(str, IgnoreCase)) != NULL)) { + message(p, 0, 0); + return SR_NOTFOUND; + } + } + else +#endif + if ((p = regexCompile(str, IgnoreCase)) != NULL) { + message(p, 0, 0); + return SR_NOTFOUND; + } + l = buf->currentLine; + if (l == NULL) { + return SR_NOTFOUND; + } + pos = buf->pos; + if (l->bpos) { + pos += l->bpos; + while (l->bpos && l->prev) + l = l->prev; + } + begin = l; +#ifdef USE_M17N + while (pos < l->size && l->propBuf[pos] & PC_WCHAR2) + pos++; +#endif + if (pos < l->size && regexMatch(&l->lineBuf[pos], l->size - pos, 0) == 1) { + matchedPosition(&first, &last); + pos = first - l->lineBuf; + while (pos >= l->len && l->next && l->next->bpos) { + pos -= l->len; + l = l->next; + } + buf->pos = pos; + if (l != buf->currentLine) + gotoLine(buf, l->linenumber); + arrangeCursor(buf); + set_mark(l, pos, pos + last - first); + return SR_FOUND; + } + for (l = l->next;; l = l->next) { + if (l == NULL) { + if (buf->pagerSource) { + l = getNextPage(buf, 1); + if (l == NULL) { + if (WrapSearch && !wrapped) { + l = buf->firstLine; + wrapped = TRUE; + } + else { + break; + } + } + } + else if (WrapSearch) { + l = buf->firstLine; + wrapped = TRUE; + } + else { + break; + } + } + if (l->bpos) + continue; + if (regexMatch(l->lineBuf, l->size, 1) == 1) { + matchedPosition(&first, &last); + pos = first - l->lineBuf; + while (pos >= l->len && l->next && l->next->bpos) { + pos -= l->len; + l = l->next; + } + buf->pos = pos; + buf->currentLine = l; + gotoLine(buf, l->linenumber); + arrangeCursor(buf); + set_mark(l, pos, pos + last - first); + return SR_FOUND | (wrapped ? SR_WRAPPED : 0); + } + if (wrapped && l == begin) /* no match */ + break; + } + return SR_NOTFOUND; +} + +int +backwardSearch(Buffer *buf, char *str) +{ + char *p, *q, *found, *found_last, *first, *last; + Line *l, *begin; + int wrapped = FALSE; + int pos; + +#ifdef USE_MIGEMO + if (migemo_active > 0) { + if (((p = regexCompile(migemostr(str), IgnoreCase)) != NULL) + && ((p = regexCompile(str, IgnoreCase)) != NULL)) { + message(p, 0, 0); + return SR_NOTFOUND; + } + } + else +#endif + if ((p = regexCompile(str, IgnoreCase)) != NULL) { + message(p, 0, 0); + return SR_NOTFOUND; + } + l = buf->currentLine; + if (l == NULL) { + return SR_NOTFOUND; + } + pos = buf->pos; + if (l->bpos) { + pos += l->bpos; + while (l->bpos && l->prev) + l = l->prev; + } + begin = l; + if (pos > 0) { + pos--; +#ifdef USE_M17N + while (pos > 0 && l->propBuf[pos] & PC_WCHAR2) + pos--; +#endif + p = &l->lineBuf[pos]; + found = NULL; + found_last = NULL; + q = l->lineBuf; + while (regexMatch(q, &l->lineBuf[l->size] - q, q == l->lineBuf) == 1) { + matchedPosition(&first, &last); + if (first <= p) { + found = first; + found_last = last; + } + if (q - l->lineBuf >= l->size) + break; + q++; +#ifdef USE_M17N + while (q - l->lineBuf < l->size + && l->propBuf[q - l->lineBuf] & PC_WCHAR2) + q++; +#endif + if (q > p) + break; + } + if (found) { + pos = found - l->lineBuf; + while (pos >= l->len && l->next && l->next->bpos) { + pos -= l->len; + l = l->next; + } + buf->pos = pos; + if (l != buf->currentLine) + gotoLine(buf, l->linenumber); + arrangeCursor(buf); + set_mark(l, pos, pos + found_last - found); + return SR_FOUND; + } + } + for (l = l->prev;; l = l->prev) { + if (l == NULL) { + if (WrapSearch) { + l = buf->lastLine; + wrapped = TRUE; + } + else { + break; + } + } + found = NULL; + found_last = NULL; + q = l->lineBuf; + while (regexMatch(q, &l->lineBuf[l->size] - q, q == l->lineBuf) == 1) { + matchedPosition(&first, &last); + found = first; + found_last = last; + if (q - l->lineBuf >= l->size) + break; + q++; +#ifdef USE_M17N + while (q - l->lineBuf < l->size + && l->propBuf[q - l->lineBuf] & PC_WCHAR2) + q++; +#endif + } + if (found) { + pos = found - l->lineBuf; + while (pos >= l->len && l->next && l->next->bpos) { + pos -= l->len; + l = l->next; + } + buf->pos = pos; + gotoLine(buf, l->linenumber); + arrangeCursor(buf); + set_mark(l, pos, pos + found_last - found); + return SR_FOUND | (wrapped ? SR_WRAPPED : 0); + } + if (wrapped && l == begin) /* no match */ + break; + } + return SR_NOTFOUND; +} |