version 1.259, 2020/03/31 16:53:23 |
version 1.260, 2020/04/01 07:35:10 |
|
|
u_int, u_int, u_int, int); |
u_int, u_int, u_int, int); |
static int window_copy_search_rl(struct grid *, struct grid *, u_int *, |
static int window_copy_search_rl(struct grid *, struct grid *, u_int *, |
u_int, u_int, u_int, int); |
u_int, u_int, u_int, int); |
static int window_copy_search_lr_regex(struct grid *, struct grid *, |
|
u_int *, u_int *, u_int, u_int, u_int, int); |
|
static int window_copy_search_rl_regex(struct grid *, struct grid *, |
|
u_int *, u_int *, u_int, u_int, u_int, int); |
|
static int window_copy_last_regex(struct grid *gd, u_int py, u_int first, |
static int window_copy_last_regex(struct grid *gd, u_int py, u_int first, |
u_int last, u_int len, u_int *ppx, u_int *psx, |
u_int last, u_int len, u_int *ppx, u_int *psx, |
const char *buf, const regex_t *preg, int eflags); |
const char *buf, const regex_t *preg, int eflags); |
|
|
} |
} |
|
|
static int |
static int |
window_copy_search_lr_regex(struct grid *gd, struct grid *sgd, |
window_copy_search_lr_regex(struct grid *gd, u_int *ppx, u_int *psx, u_int py, |
u_int *ppx, u_int *psx, u_int py, u_int first, u_int last, int cis) |
u_int first, u_int last, regex_t *reg) |
{ |
{ |
int cflags = REG_EXTENDED, eflags = 0; |
int eflags = 0; |
u_int endline, foundx, foundy, len, pywrap, size = 1; |
u_int endline, foundx, foundy, len, pywrap, size = 1; |
u_int ssize = 1; |
char *buf; |
char *buf, *sbuf; |
|
regex_t reg; |
|
regmatch_t regmatch; |
regmatch_t regmatch; |
struct grid_line *gl; |
struct grid_line *gl; |
|
|
|
|
if (first >= last) |
if (first >= last) |
return (0); |
return (0); |
|
|
sbuf = xmalloc(ssize); |
|
sbuf[0] = '\0'; |
|
sbuf = window_copy_stringify(sgd, 0, 0, sgd->sx, sbuf, &ssize); |
|
if (sbuf == NULL) |
|
return (0); |
|
|
|
/* Set flags for regex search. */ |
/* Set flags for regex search. */ |
if (cis) |
|
cflags |= REG_ICASE; |
|
if (regcomp(®, sbuf, cflags) != 0) { |
|
free(sbuf); |
|
return (0); |
|
} |
|
if (first != 0) |
if (first != 0) |
eflags |= REG_NOTBOL; |
eflags |= REG_NOTBOL; |
|
|
|
|
len += gd->sx; |
len += gd->sx; |
} |
} |
|
|
if (regexec(®, buf, 1, ®match, eflags) == 0) { |
if (regexec(reg, buf, 1, ®match, eflags) == 0) { |
foundx = first; |
foundx = first; |
foundy = py; |
foundy = py; |
window_copy_cstrtocellpos(gd, len, &foundx, &foundy, |
window_copy_cstrtocellpos(gd, len, &foundx, &foundy, |
|
|
foundy--; |
foundy--; |
} |
} |
*psx -= *ppx; |
*psx -= *ppx; |
regfree(®); |
|
free(sbuf); |
|
free(buf); |
free(buf); |
return (1); |
return (1); |
} |
} |
} |
} |
|
|
regfree(®); |
|
free(sbuf); |
|
free(buf); |
free(buf); |
*ppx = 0; |
*ppx = 0; |
*psx = 0; |
*psx = 0; |
|
|
} |
} |
|
|
static int |
static int |
window_copy_search_rl_regex(struct grid *gd, struct grid *sgd, |
window_copy_search_rl_regex(struct grid *gd, u_int *ppx, u_int *psx, u_int py, |
u_int *ppx, u_int *psx, u_int py, u_int first, u_int last, int cis) |
u_int first, u_int last, regex_t *reg) |
{ |
{ |
int cflags = REG_EXTENDED, eflags = 0; |
int eflags = 0; |
u_int endline, len, pywrap, size = 1, ssize = 1; |
u_int endline, len, pywrap, size = 1; |
char *buf, *sbuf; |
char *buf; |
regex_t reg; |
|
struct grid_line *gl; |
struct grid_line *gl; |
|
|
sbuf = xmalloc(ssize); |
|
sbuf[0] = '\0'; |
|
sbuf = window_copy_stringify(sgd, 0, 0, sgd->sx, sbuf, &ssize); |
|
if (sbuf == NULL) |
|
return (0); |
|
|
|
/* Set flags for regex search. */ |
/* Set flags for regex search. */ |
if (cis) |
|
cflags |= REG_ICASE; |
|
if (regcomp(®, sbuf, cflags) != 0) { |
|
free(sbuf); |
|
return (0); |
|
} |
|
if (first != 0) |
if (first != 0) |
eflags |= REG_NOTBOL; |
eflags |= REG_NOTBOL; |
|
|
|
|
} |
} |
|
|
if (window_copy_last_regex(gd, py, first, last, len, ppx, psx, buf, |
if (window_copy_last_regex(gd, py, first, last, len, ppx, psx, buf, |
®, eflags)) |
reg, eflags)) |
{ |
{ |
regfree(®); |
|
free(sbuf); |
|
free(buf); |
free(buf); |
return (1); |
return (1); |
} |
} |
|
|
regfree(®); |
|
free(sbuf); |
|
free(buf); |
free(buf); |
*ppx = 0; |
*ppx = 0; |
*psx = 0; |
*psx = 0; |
return (0); |
return (0); |
} |
} |
|
|
|
static const char * |
|
window_copy_cellstring(const struct grid_line *gl, u_int px, size_t *size) |
|
{ |
|
struct grid_cell_entry *gce; |
|
|
|
if (px >= gl->cellsize) { |
|
*size = 1; |
|
return (" "); |
|
} |
|
|
|
gce = &gl->celldata[px]; |
|
if (~gce->flags & GRID_FLAG_EXTENDED) { |
|
*size = 1; |
|
return (&gce->data.data); |
|
} |
|
|
|
*size = gl->extddata[gce->offset].data.size; |
|
return (gl->extddata[gce->offset].data.data); |
|
} |
|
|
/* Find last match in given range. */ |
/* Find last match in given range. */ |
static int |
static int |
window_copy_last_regex(struct grid *gd, u_int py, u_int first, u_int last, |
window_copy_last_regex(struct grid *gd, u_int py, u_int first, u_int last, |
|
|
window_copy_stringify(struct grid *gd, u_int py, u_int first, u_int last, |
window_copy_stringify(struct grid *gd, u_int py, u_int first, u_int last, |
char *buf, u_int *size) |
char *buf, u_int *size) |
{ |
{ |
u_int ax, bx, newsize; |
u_int ax, bx, newsize = *size; |
struct grid_cell gc; |
const struct grid_line *gl; |
|
const char *d; |
|
size_t bufsize = 1024, dlen; |
|
|
|
while (bufsize < newsize) |
|
bufsize *= 2; |
|
buf = xrealloc(buf, bufsize); |
|
|
|
gl = grid_peek_line(gd, py); |
bx = *size - 1; |
bx = *size - 1; |
newsize = *size; |
|
for (ax = first; ax < last; ax++) { |
for (ax = first; ax < last; ax++) { |
grid_get_cell(gd, ax, py, &gc); |
d = window_copy_cellstring(gl, ax, &dlen); |
newsize += gc.data.size; |
newsize += dlen; |
buf = xrealloc(buf, newsize); |
while (bufsize < newsize) { |
memcpy(buf + bx, gc.data.data, gc.data.size); |
bufsize *= 2; |
bx += gc.data.size; |
buf = xrealloc(buf, bufsize); |
|
} |
|
if (dlen == 1) |
|
buf[bx++] = *d; |
|
else { |
|
memcpy(buf + bx, d, dlen); |
|
bx += dlen; |
|
} |
} |
} |
|
|
buf[newsize - 1] = '\0'; |
buf[newsize - 1] = '\0'; |
|
|
*size = newsize; |
*size = newsize; |
return (buf); |
return (buf); |
} |
} |
|
|
window_copy_cstrtocellpos(struct grid *gd, u_int ncells, u_int *ppx, u_int *ppy, |
window_copy_cstrtocellpos(struct grid *gd, u_int ncells, u_int *ppx, u_int *ppy, |
const char *str) |
const char *str) |
{ |
{ |
u_int cell, ccell, px, pywrap; |
u_int cell, ccell, px, pywrap, pos, len; |
int match; |
int match; |
const char *cstr; |
const struct grid_line *gl; |
char *celldata, **cells; |
const char *d; |
struct grid_cell gc; |
size_t dlen; |
|
struct { |
|
const char *d; |
|
size_t dlen; |
|
} *cells; |
|
|
/* Set up staggered array of cell contents. This speeds up search. */ |
|
cells = xreallocarray(NULL, ncells, sizeof cells[0]); |
|
|
|
/* Populate the array of cell data. */ |
/* Populate the array of cell data. */ |
|
cells = xreallocarray(NULL, ncells, sizeof cells[0]); |
cell = 0; |
cell = 0; |
px = *ppx; |
px = *ppx; |
pywrap = *ppy; |
pywrap = *ppy; |
|
gl = grid_peek_line(gd, pywrap); |
while (cell < ncells) { |
while (cell < ncells) { |
grid_get_cell(gd, px, pywrap, &gc); |
cells[cell].d = window_copy_cellstring(gl, px, |
celldata = xmalloc(gc.data.size + 1); |
&cells[cell].dlen); |
memcpy(celldata, gc.data.data, gc.data.size); |
|
celldata[gc.data.size] = '\0'; |
|
cells[cell] = celldata; |
|
cell++; |
cell++; |
px = (px + 1) % gd->sx; |
px = (px + 1) % gd->sx; |
if (px == 0) |
if (px == 0) { |
pywrap++; |
pywrap++; |
|
gl = grid_peek_line(gd, pywrap); |
|
} |
} |
} |
|
|
/* Locate starting cell. */ |
/* Locate starting cell. */ |
cell = 0; |
cell = 0; |
|
len = strlen(str); |
while (cell < ncells) { |
while (cell < ncells) { |
ccell = cell; |
ccell = cell; |
cstr = str; |
pos = 0; |
match = 1; |
match = 1; |
while (ccell < ncells) { |
while (ccell < ncells) { |
/* Anchor found to the end. */ |
if (str[pos] == '\0') { |
if (*cstr == '\0') { |
|
match = 0; |
match = 0; |
break; |
break; |
} |
} |
|
d = cells[ccell].d; |
celldata = cells[ccell]; |
dlen = cells[ccell].dlen; |
while (*celldata != '\0' && *cstr != '\0') { |
if (dlen == 1) { |
if (*celldata++ != *cstr++) { |
if (str[pos] != *d) { |
match = 0; |
match = 0; |
break; |
break; |
} |
} |
|
pos++; |
|
} else { |
|
if (dlen > len - pos) |
|
dlen = len - pos; |
|
if (memcmp(str + pos, d, dlen) != 0) { |
|
match = 0; |
|
break; |
|
} |
|
pos += dlen; |
} |
} |
|
|
if (!match) |
|
break; |
|
ccell++; |
ccell++; |
} |
} |
|
|
if (match) |
if (match) |
break; |
break; |
cell++; |
cell++; |
|
|
*ppy = pywrap; |
*ppy = pywrap; |
|
|
/* Free cell data. */ |
/* Free cell data. */ |
for (cell = 0; cell < ncells; cell++) |
|
free(cells[cell]); |
|
free(cells); |
free(cells); |
} |
} |
|
|
|
|
struct grid *sgd, u_int fx, u_int fy, u_int endline, int cis, int wrap, |
struct grid *sgd, u_int fx, u_int fy, u_int endline, int cis, int wrap, |
int direction, int regex) |
int direction, int regex) |
{ |
{ |
u_int i, px, sx; |
u_int i, px, sx, ssize = 1; |
int found = 0; |
int found = 0, cflags = REG_EXTENDED; |
|
char *sbuf; |
|
regex_t reg; |
|
|
|
if (regex) { |
|
sbuf = xmalloc(ssize); |
|
sbuf[0] = '\0'; |
|
sbuf = window_copy_stringify(sgd, 0, 0, sgd->sx, sbuf, &ssize); |
|
if (cis) |
|
cflags |= REG_ICASE; |
|
if (regcomp(®, sbuf, cflags) != 0) { |
|
free(sbuf); |
|
return (0); |
|
} |
|
} |
|
|
if (direction) { |
if (direction) { |
for (i = fy; i <= endline; i++) { |
for (i = fy; i <= endline; i++) { |
if (regex) |
if (regex) { |
found = window_copy_search_lr_regex(gd, sgd, |
found = window_copy_search_lr_regex(gd, |
&px, &sx, i, fx, gd->sx, cis); |
&px, &sx, i, fx, gd->sx, ®); |
else |
} else { |
found = window_copy_search_lr(gd, sgd, |
found = window_copy_search_lr(gd, sgd, |
&px, i, fx, gd->sx, cis); |
&px, i, fx, gd->sx, cis); |
|
} |
if (found) |
if (found) |
break; |
break; |
fx = 0; |
fx = 0; |
} |
} |
} else { |
} else { |
for (i = fy + 1; endline < i; i--) { |
for (i = fy + 1; endline < i; i--) { |
if (regex) |
if (regex) { |
found = window_copy_search_rl_regex(gd, sgd, |
found = window_copy_search_rl_regex(gd, |
&px, &sx, i - 1, 0, fx + 1, cis); |
&px, &sx, i - 1, 0, fx + 1, ®); |
else |
} else { |
found = window_copy_search_rl(gd, sgd, |
found = window_copy_search_rl(gd, sgd, |
&px, i - 1, 0, fx + 1, cis); |
&px, i - 1, 0, fx + 1, cis); |
|
} |
if (found) { |
if (found) { |
i--; |
i--; |
break; |
break; |
|
|
fx = gd->sx - 1; |
fx = gd->sx - 1; |
} |
} |
} |
} |
|
if (regex) { |
|
free(sbuf); |
|
regfree(®); |
|
} |
|
|
if (found) { |
if (found) { |
window_copy_scroll_to(wme, px, i); |
window_copy_scroll_to(wme, px, i); |
|
|
struct screen_write_ctx ctx; |
struct screen_write_ctx ctx; |
struct grid *gd = s->grid; |
struct grid *gd = s->grid; |
int found, cis, which = -1; |
int found, cis, which = -1; |
|
int cflags = REG_EXTENDED; |
u_int px, py, b, nfound = 0, width; |
u_int px, py, b, nfound = 0, width; |
|
u_int ssize = 1; |
|
char *sbuf; |
|
regex_t reg; |
|
|
if (ssp == NULL) { |
if (ssp == NULL) { |
width = screen_write_strlen("%s", data->searchstr); |
width = screen_write_strlen("%s", data->searchstr); |
|
|
free(data->searchmark); |
free(data->searchmark); |
data->searchmark = bit_alloc((gd->hsize + gd->sy) * gd->sx); |
data->searchmark = bit_alloc((gd->hsize + gd->sy) * gd->sx); |
|
|
|
if (regex) { |
|
sbuf = xmalloc(ssize); |
|
sbuf[0] = '\0'; |
|
sbuf = window_copy_stringify(ssp->grid, 0, 0, ssp->grid->sx, |
|
sbuf, &ssize); |
|
if (cis) |
|
cflags |= REG_ICASE; |
|
if (regcomp(®, sbuf, cflags) != 0) { |
|
free(sbuf); |
|
return (0); |
|
} |
|
} |
for (py = 0; py < gd->hsize + gd->sy; py++) { |
for (py = 0; py < gd->hsize + gd->sy; py++) { |
px = 0; |
px = 0; |
for (;;) { |
for (;;) { |
if (regex) { |
if (regex) { |
found = window_copy_search_lr_regex(gd, |
found = window_copy_search_lr_regex(gd, |
ssp->grid, &px, &width, py, px, |
&px, &width, py, px, gd->sx, ®); |
gd->sx, cis); |
|
if (!found) |
if (!found) |
break; |
break; |
} |
} else { |
else { |
|
found = window_copy_search_lr(gd, ssp->grid, |
found = window_copy_search_lr(gd, ssp->grid, |
&px, py, px, gd->sx, cis); |
&px, py, px, gd->sx, cis); |
if (!found) |
if (!found) |
break; |
break; |
} |
} |
|
|
nfound++; |
nfound++; |
if (px == data->cx && py == gd->hsize + data->cy - data->oy) |
if (px == data->cx && |
|
py == gd->hsize + data->cy - data->oy) |
which = nfound; |
which = nfound; |
|
|
b = (py * gd->sx) + px; |
b = (py * gd->sx) + px; |
|
|
|
|
px++; |
px++; |
} |
} |
|
} |
|
if (regex) { |
|
free(sbuf); |
|
regfree(®); |
} |
} |
|
|
if (which != -1) |
if (which != -1) |