* anchor.c (reAnchorPos): rewrite (reAnchorWord): delete reseq_anchor() (reAnchorAny): use l->size delete reseq_anchor() * backend.c (internal_get): pass TRUE to saveBuffer * buffer.c (newBuffer): delete n->linelen (reshapeBuffer): rewrite * display.c (displayBuffer): FoldLine (redrawLine): l->bpos (cursorUp0): added (cursorUp): rewrite (cursorDown0): added (cursowDown): rewrite (cursorRight): check l->next l->bwidth (cursorLeft): l->prev && l->bpos l->bwidth (arrangeCursor): buf->currentLine->bwidth buf->cursorX * etc.c (checkType): **oporp rewrite (calcPosition): realColumn allocated by New_reuse * file.c (addnewline): add nlines arg (propBuffer): deleted (colorBuffer): deleted (readHeader): propBuffer FOLD_BUFFER_WIDTH (HTMLlineproc2body): rewrite (addnewline2): added (addnewline): rewrite (loadBuffer): propBuffer, colorBuffer (saveBuffer): cont arg (getNextPage): rewrite * fm.h (LINELEN): 256 (FNLEN): deleted (Line): add size, bpos, bwidth (Buffer): delete linelen (INIT_BUFFER_WIDTH): check showLineNum (FOLD_BUFFER_WIDTH): added (FoldLine): added * funcname.tab (RESHAPE): added * main.c (do_dump): pass FALSE to saveBuffer (nscroll): rewrite (clear_mark): l->size (shiftvisualpos): rewrite (pipeBuf): pass TRUE to saveBuffer (linebeg): check line->prev && line->bpos (linend): check line->next, line->next->bpos (editScr): pass TRUE to saveBuffer (svBuf): pass TRUE to saveBuffer (vmSrc): pass TRUE to saveBuffer (reshape): added (curlno): rewrite * mimehead.c (LINELEN): deleted * proto.h (reshape): added (saveBuffer): add cont arg (cursorUp0): added (cursorDown0): added (checkType): change type oprop, ocolor, delete check_color, len * rc.c (CMT_FOLD_LINE): added (params1): add fold_line (sync_with_option): check PagerMax * search.c (set_mark): l->size (forwardSearch): rewrite (backwardSearch): rewrite * doc/README.func (RESHAPE): added * doc-jp/README.func (RESHAPE): added * scripts/w3mhelp.cgi.in (Buffer operation): add reshape From: Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
300 lines
6.0 KiB
C
300 lines
6.0 KiB
C
/* $Id: search.c,v 1.26 2003/01/23 18:37:21 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", str);
|
|
again:
|
|
if (fflush(migemow) != 0) {
|
|
switch (errno) {
|
|
case EINTR:
|
|
goto again;
|
|
default:
|
|
goto err;
|
|
}
|
|
}
|
|
tmp = Strfgets(migemor);
|
|
Strchop(tmp);
|
|
if (tmp->length == 0)
|
|
goto err;
|
|
return tmp->ptr;
|
|
err:
|
|
/* XXX: backend migemo is not working? */
|
|
init_migemo();
|
|
migemo_active = migemo_running = 0;
|
|
return str;
|
|
}
|
|
#endif /* USE_MIGEMO */
|
|
|
|
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 + 1;
|
|
if (l->bpos) {
|
|
pos += l->bpos;
|
|
while (l->bpos && l->prev)
|
|
l = l->prev;
|
|
}
|
|
begin = l;
|
|
#ifdef JP_CHARSET
|
|
if (l->propBuf[pos] & PC_KANJI2)
|
|
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) {
|
|
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);
|
|
if (wrapped && l == begin && buf->pos == first - l->lineBuf)
|
|
/* exactly same match */
|
|
break;
|
|
pos = first - l->lineBuf;
|
|
while (pos >= l->len) {
|
|
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 JP_CHARSET
|
|
if (l->propBuf[pos] & PC_KANJI2)
|
|
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;
|
|
}
|
|
#ifdef JP_CHARSET
|
|
if (l->propBuf[q - l->lineBuf] & PC_KANJI1)
|
|
q += 2;
|
|
else
|
|
#endif
|
|
q++;
|
|
if (q > p)
|
|
break;
|
|
}
|
|
if (found) {
|
|
pos = found - l->lineBuf;
|
|
while (pos >= l->len) {
|
|
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);
|
|
if (wrapped && l == begin && buf->pos == first - l->lineBuf)
|
|
/* exactly same match */
|
|
;
|
|
else {
|
|
found = first;
|
|
found_last = last;
|
|
}
|
|
#ifdef JP_CHARSET
|
|
if (l->propBuf[q - l->lineBuf] & PC_KANJI1)
|
|
q += 2;
|
|
else
|
|
#endif
|
|
q++;
|
|
}
|
|
if (found) {
|
|
pos = found - l->lineBuf;
|
|
while (pos >= l->len) {
|
|
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;
|
|
}
|