#include <sys/types.h>
#include "config.h"
#include "screen.h"
#include "mark.h"
#include "extern.h"
#define INPUTLINE (flayer->l_height - 1)
extern struct layer *flayer;
extern struct win *fore;
#ifdef COPY_PASTE
int search_ic;
static int matchword __P((char *, int, int, int));
static void searchend __P((char *, int, char *));
static void backsearchend __P((char *, int, char *));
void
Search(dir)
int dir;
{
struct markdata *markdata;
if (dir == 0)
{
markdata = (struct markdata *)flayer->l_data;
if (markdata->isdir > 0)
searchend(0, 0, NULL);
else if (markdata->isdir < 0)
backsearchend(0, 0, NULL);
else
LMsg(0, "No previous pattern");
}
else
Input((dir > 0 ? "/" : "?"), sizeof(markdata->isstr)-1, INP_COOKED,
(dir > 0 ? searchend : backsearchend), NULL);
}
static void
searchend(buf, len, data)
char *buf;
int len;
char *data;
{
int x = 0, sx, ex, y;
struct markdata *markdata;
struct win *p;
markdata = (struct markdata *)flayer->l_data;
p = markdata->md_window;
markdata->isdir = 1;
if (len)
strcpy(markdata->isstr, buf);
sx = markdata->cx + 1;
ex = flayer->l_width - 1;
for (y = markdata->cy; y < p->w_histheight + flayer->l_height; y++, sx = 0)
{
if ((x = matchword(markdata->isstr, y, sx, ex)) >= 0)
break;
}
if (y >= p->w_histheight + flayer->l_height)
{
LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
LMsg(0, "Pattern not found");
}
else
revto(x, y);
}
static void
backsearchend(buf, len, data)
char *buf;
int len;
char *data;
{
int sx, ex, x = -1, y;
struct markdata *markdata;
markdata = (struct markdata *)flayer->l_data;
markdata->isdir = -1;
if (len)
strcpy(markdata->isstr, buf);
ex = markdata->cx - 1;
for (y = markdata->cy; y >= 0; y--, ex = flayer->l_width - 1)
{
sx = 0;
while ((sx = matchword(markdata->isstr, y, sx, ex)) >= 0)
x = sx++;
if (x >= 0)
break;
}
if (y < 0)
{
LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
LMsg(0, "Pattern not found");
}
else
revto(x, y);
}
static int
matchword(pattern, y, sx, ex)
char *pattern;
int y, sx, ex;
{
unsigned char *ip, *ipe, *cp, *pp;
struct mline *ml;
fore = ((struct markdata *)flayer->l_data)->md_window;
ml = WIN(y);
ip = ml->image + sx;
ipe = ml->image + flayer->l_width;
for (;sx <= ex; sx++)
{
cp = ip++;
pp = (unsigned char *)pattern;
for (;;)
{
if (*cp != *pp)
if (!search_ic || ((*cp ^ *pp) & 0xdf) || (*cp | 0x20) < 'a' || (*cp | 0x20) > 'z')
break;
cp++;
pp++;
if (*pp == 0)
return sx;
if (cp == ipe)
break;
}
}
return -1;
}
static char *isprompts[] = {
"I-search backward: ", "failing I-search backward: ",
"I-search: ", "failing I-search: "
};
static int is_redo __P((struct markdata *));
static void is_process __P((char *, int, char *));
static int is_bm __P((char *, int, int, int, int));
static int
is_bm(str, l, p, end, dir)
char *str;
int l, p, end, dir;
{
int tab[256];
int i, q;
unsigned char *s, c;
int w = flayer->l_width;
fore = ((struct markdata *)flayer->l_next->l_data)->md_window;
debug2("is_bm: searching for %s len %d\n", str, l);
debug3("start at %d end %d dir %d\n", p, end, dir);
if (p < 0 || p + l > end)
return -1;
if (l == 0)
return p;
if (dir < 0)
str += l - 1;
for (i = 0; i < 256; i++)
tab[i] = l * dir;
for (i = 0; i < l - 1; i++, str += dir)
{
q = *(unsigned char *)str;
tab[q] = (l - 1 - i) * dir;
if (search_ic && (q | 0x20) >= 'a' && ((q | 0x20) <= 'z'))
tab[q ^ 0x20] = (l - 1 - i) * dir;
}
if (dir > 0)
p += l - 1;
debug1("first char to match: %c\n", *str);
while (p >= 0 && p < end)
{
q = p;
s = (unsigned char *)str;
for (i = 0;;)
{
c = (WIN(q / w))->image[q % w];
if (i == 0)
p += tab[(int)(unsigned char) c];
if (c != *s)
if (!search_ic || ((c ^ *s) & 0xdf) || (c | 0x20) < 'a' || (c | 0x20) > 'z')
break;
q -= dir;
s -= dir;
if (++i == l)
return q + (dir > 0 ? 1 : -l);
}
}
return -1;
}
static void
is_process(p, n, data)
char *p;
int n;
char *data;
{
int pos, x, y, dir;
struct markdata *markdata;
if (n == 0)
return;
ASSERT(p);
markdata = (struct markdata *)flayer->l_next->l_data;
pos = markdata->cx + markdata->cy * flayer->l_width;
LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
switch (*p)
{
case '\007':
pos = markdata->isstartpos;
case '\033':
*p = 0;
break;
case '\013':
case '\027':
markdata->isistrl = 1;
case '\b':
case '\177':
if (markdata->isistrl == 0)
return;
markdata->isistrl--;
pos = is_redo(markdata);
*p = '\b';
break;
case '\023':
case '\022':
if (markdata->isistrl >= (int)sizeof(markdata->isistr))
return;
dir = (*p == '\023') ? 1 : -1;
pos += dir;
if (markdata->isdir == dir && markdata->isistrl == 0)
{
strcpy(markdata->isistr, markdata->isstr);
markdata->isistrl = markdata->isstrl = strlen(markdata->isstr);
break;
}
markdata->isdir = dir;
markdata->isistr[markdata->isistrl++] = *p;
break;
default:
if (*p < ' ' || markdata->isistrl >= (int)sizeof(markdata->isistr)
|| markdata->isstrl >= (int)sizeof(markdata->isstr) - 1)
return;
markdata->isstr[markdata->isstrl++] = *p;
markdata->isistr[markdata->isistrl++] = *p;
markdata->isstr[markdata->isstrl] = 0;
debug2("New char: %c - left %d\n", *p, (int)sizeof(markdata->isistr) - markdata->isistrl);
}
if (*p && *p != '\b')
pos = is_bm(markdata->isstr, markdata->isstrl, pos, flayer->l_width * (markdata->md_window->w_histheight + flayer->l_height), markdata->isdir);
if (pos >= 0)
{
x = pos % flayer->l_width;
y = pos / flayer->l_width;
LAY_CALL_UP
(
LayRedisplayLine(INPUTLINE, 0, flayer->l_width - 1, 0);
revto(x, y);
if (W2D(markdata->cy) == INPUTLINE)
revto_line(markdata->cx, markdata->cy, INPUTLINE > 0 ? INPUTLINE - 1 : 1);
);
}
if (*p)
inp_setprompt(isprompts[markdata->isdir + (pos < 0) + 1], markdata->isstrl ? markdata->isstr : "");
flayer->l_x = markdata->cx;
flayer->l_y = W2D(markdata->cy);
LGotoPos(flayer, flayer->l_x, flayer->l_y);
if (!*p)
{
flayer->l_next->l_x = markdata->cx;
flayer->l_next->l_y = W2D(markdata->cy);
}
}
static int
is_redo(markdata)
struct markdata *markdata;
{
int i, pos, npos, dir;
char c;
npos = pos = markdata->isstartpos;
dir = markdata->isstartdir;
markdata->isstrl = 0;
for (i = 0; i < markdata->isistrl; i++)
{
c = markdata->isistr[i];
if (c == '\022')
pos += (dir = -1);
else if (c == '\023')
pos += (dir = 1);
else
markdata->isstr[markdata->isstrl++] = c;
if (pos >= 0)
{
npos = is_bm(markdata->isstr, markdata->isstrl, pos, flayer->l_width * (markdata->md_window->w_histheight + flayer->l_height), dir);
if (npos >= 0)
pos = npos;
}
}
markdata->isstr[markdata->isstrl] = 0;
markdata->isdir = dir;
return npos;
}
void
ISearch(dir)
int dir;
{
struct markdata *markdata;
markdata = (struct markdata *)flayer->l_data;
markdata->isdir = markdata->isstartdir = dir;
markdata->isstartpos = markdata->cx + markdata->cy * flayer->l_width;
markdata->isistrl = markdata->isstrl = 0;
if (W2D(markdata->cy) == INPUTLINE)
revto_line(markdata->cx, markdata->cy, INPUTLINE > 0 ? INPUTLINE - 1 : 1);
Input(isprompts[dir + 1], sizeof(markdata->isstr) - 1, INP_RAW,
is_process, NULL);
LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
flayer->l_x = markdata->cx;
flayer->l_y = W2D(markdata->cy);
}
#endif