| trset: use rset struct instead of regex.h - neatvi - [fork] simple vi-type editor with UTF-8 support |
| git clone git://src.adamsgaard.dk/neatvi |
| Log |
| Files |
| Refs |
| README |
| --- |
| commit 4b67186ed7bb5e6e255f78c351151bf72e51919d |
| parent 3efb0c5dc5d7be165d3a80ecdd144e895fed6aa6 |
| Author: Ali Gholami Rudi |
| Date: Thu, 14 May 2015 11:12:15 +0430
rset: use rset struct instead of regex.h
Diffstat:
M dir.c | 25 +++++++++----------------
M ex.c | 35 +++++++++++++++++--------------
M rset.c | 12 +++++++++---
M uc.c | 10 ++++++++++
M vi.c | 26 +++++++++++++-------------
M vi.h | 7 ++++++-
6 files changed, 66 insertions(+), 49 deletions(-)
--- |
| diff --git a/dir.c b/dir.c |
| t@@ -1,7 +1,6 @@
#include
#include
#include
-#include
#include "vi.h"
#define CR2L "ءآأؤإئابةتثجحخدذرزسشصضطظعغـفقكلمنهوىييپچژکگی؛،»«؟"
t@@ -33,32 +32,26 @@ static struct rset *dir_rslr; /* pattern of marks for left-to-right strings */
static struct rset *dir_rsrl; /* pattern of marks for right-to-left strings */
static struct rset *dir_rsctx; /* direction context patterns */
-static int uc_off(char *s, int off)
-{
- char *e = s + off;
- int i;
- for (i = 0; s < e && *s; i++)
- s = uc_next(s);
- return i;
-}
-
static int dir_match(char **chrs, int beg, int end, int ctx, int *rec,
int *r_beg, int *r_end, int *c_beg, int *c_end, int *dir)
{
int subs[16 * 2];
struct rset *rs = ctx < 0 ? dir_rsrl : dir_rslr;
struct sbuf *str = sbuf_make();
+ int flg = (beg ? RE_NOTBOL : 0) | (chrs[end][0] ? RE_NOTEOL : 0);
int found;
sbuf_mem(str, chrs[beg], chrs[end] - chrs[beg]);
- found = rset_find(rs, sbuf_buf(str), LEN(subs) / 2, subs, 0);
+ found = rset_find(rs, sbuf_buf(str), LEN(subs) / 2, subs, flg);
if (found >= 0 && r_beg && r_end && c_beg && c_end) {
struct dmark *dm = &dmarks[found];
char *s = sbuf_buf(str);
int grp = dm->grp;
*r_beg = beg + uc_off(s, subs[0]);
*r_end = beg + uc_off(s, subs[1]);
- *c_beg = subs[grp * 2 + 0] >= 0 ? beg + uc_off(s, subs[grp * 2 + 0]) : *r_beg;
- *c_end = subs[grp * 2 + 1] >= 0 ? beg + uc_off(s, subs[grp * 2 + 1]) : *r_end;
+ *c_beg = subs[grp * 2 + 0] >= 0 ?
+ beg + uc_off(s, subs[grp * 2 + 0]) : *r_beg;
+ *c_end = subs[grp * 2 + 1] >= 0 ?
+ beg + uc_off(s, subs[grp * 2 + 1]) : *r_end;
*dir = dm->dir;
*rec = grp > 0;
}
t@@ -134,11 +127,11 @@ void dir_init(void)
relr[i] = dmarks[i].ctx >= 0 ? dmarks[i].pat : NULL;
rerl[i] = dmarks[i].ctx <= 0 ? dmarks[i].pat : NULL;
}
- dir_rslr = rset_make(LEN(dmarks), relr);
- dir_rsrl = rset_make(LEN(dmarks), rerl);
+ dir_rslr = rset_make(LEN(dmarks), relr, 0);
+ dir_rsrl = rset_make(LEN(dmarks), rerl, 0);
for (i = 0; i < LEN(dcontexts); i++)
ctx[i] = dcontexts[i].pat;
- dir_rsctx = rset_make(LEN(dcontexts), ctx);
+ dir_rsctx = rset_make(LEN(dcontexts), ctx, 0);
}
void dir_done(void) |
| diff --git a/ex.c b/ex.c |
| t@@ -1,6 +1,5 @@
#include
#include
-#include
#include
#include
#include
t@@ -96,28 +95,32 @@ static char *ex_arg(char *s, char *arg)
static int ex_search(char *pat)
{
- struct sbuf *kwd;
+ struct sbuf *kw;
int dir = *pat == '/' ? 1 : -1;
char *b = pat;
char *e = b;
+ char *re_kw[1];
int i = xrow;
- regex_t re;
- kwd = sbuf_make();
+ struct rset *re;
+ kw = sbuf_make();
while (*++e) {
if (*e == *pat)
break;
- sbuf_chr(kwd, (unsigned char) *e);
+ sbuf_chr(kw, (unsigned char) *e);
if (*e == '\\' && e[1])
e++;
}
- regcomp(&re, sbuf_buf(kwd), 0);
+ re_kw[0] = sbuf_buf(kw);
+ re = rset_make(1, re_kw, 0);
+ sbuf_free(kw);
+ if (!re)
+ return i;
while (i >= 0 && i < lbuf_len(xb)) {
- if (!regexec(&re, lbuf_get(xb, i), 0, NULL, 0))
+ if (rset_find(re, lbuf_get(xb, i), 0, NULL, 0) >= 0)
break;
i += dir;
}
- regfree(&re);
- sbuf_free(kwd);
+ rset_free(re);
return i;
}
t@@ -388,8 +391,8 @@ static char *readuntil(char **src, int delim)
static void ec_substitute(char *ec)
{
char loc[EXLEN], arg[EXLEN];
- regmatch_t subs[16];
- regex_t re;
+ struct rset *re;
+ int offs[32];
int beg, end;
char *pat, *rep;
char *s = arg;
t@@ -402,20 +405,20 @@ static void ec_substitute(char *ec)
delim = (unsigned char) *s++;
pat = readuntil(&s, delim);
rep = readuntil(&s, delim);
- regcomp(&re, pat, 0);
+ re = rset_make(1, &pat, 0);
for (i = beg; i < end; i++) {
char *ln = lbuf_get(xb, i);
- if (!regexec(&re, ln, LEN(subs), subs, 0)) {
+ if (rset_find(re, ln, LEN(offs) / 2, offs, 0)) {
struct sbuf *r = sbuf_make();
- sbuf_mem(r, ln, subs[0].rm_so);
+ sbuf_mem(r, ln, offs[0]);
sbuf_str(r, rep);
- sbuf_str(r, ln + subs[0].rm_eo);
+ sbuf_str(r, ln + offs[1]);
lbuf_put(xb, i, sbuf_buf(r));
lbuf_rm(xb, i + 1, i + 2);
sbuf_free(r);
}
}
- regfree(&re);
+ rset_free(re);
free(pat);
free(rep);
} |
| diff --git a/rset.c b/rset.c |
| t@@ -26,10 +26,11 @@ static int re_groupcount(char *s)
return n;
}
-struct rset *rset_make(int n, char **re)
+struct rset *rset_make(int n, char **re, int flg)
{
struct rset *rs = malloc(sizeof(*rs));
struct sbuf *sb = sbuf_make();
+ int regex_flg = REG_EXTENDED | (flg & RE_ICASE ? REG_ICASE : 0);
int i;
memset(rs, 0, sizeof(*rs));
rs->grp = malloc((n + 1) * sizeof(rs->grp[0]));
t@@ -54,7 +55,7 @@ struct rset *rset_make(int n, char **re)
}
rs->grp[n] = rs->grpcnt;
sbuf_chr(sb, ')');
- if (regcomp(&rs->regex, sbuf_buf(sb), REG_EXTENDED)) {
+ if (regcomp(&rs->regex, sbuf_buf(sb), regex_flg)) {
free(rs->grp);
free(rs->setgrpcnt);
free(rs);
t@@ -70,10 +71,15 @@ int rset_find(struct rset *rs, char *s, int n, int *grps, int flg)
{
regmatch_t *subs;
int found, i, set = -1;
+ int regex_flg = 0;
if (rs->grpcnt <= 2)
return -1;
+ if (flg & RE_NOTBOL)
+ regex_flg |= REG_NOTBOL;
+ if (flg & RE_NOTEOL)
+ regex_flg |= REG_NOTEOL;
subs = malloc(rs->grpcnt * sizeof(subs[0]));
- found = !regexec(&rs->regex, s, rs->grpcnt, subs, 0);
+ found = !regexec(&rs->regex, s, rs->grpcnt, subs, regex_flg);
for (i = 0; found && i < rs->n; i++)
if (rs->grp[i] >= 0 && subs[rs->grp[i]].rm_so >= 0)
set = i; |
| diff --git a/uc.c b/uc.c |
| t@@ -105,6 +105,16 @@ char *uc_chr(char *s, int off)
return s && (off < 0 || i == off) ? s : "";
}
+/* the number of characters between s and s + off*/
+int uc_off(char *s, int off)
+{
+ char *e = s + off;
+ int i;
+ for (i = 0; s < e && *s; i++)
+ s = uc_next(s);
+ return i;
+}
+
char *uc_sub(char *s, int beg, int end)
{
char *sbeg = uc_chr(s, beg); |
| diff --git a/vi.c b/vi.c |
| t@@ -7,7 +7,6 @@
*/
#include
#include
-#include
#include
#include
#include
t@@ -146,29 +145,30 @@ static void lbuf_findchar(struct lbuf *lb, int *row, int *col, char *cs, int cmd
static int lbuf_search(struct lbuf *lb, char *kw, int dir, int *r, int *c, int *len)
{
- regmatch_t subs[1];
- regex_t re;
+ int offs[2];
int found = 0;
int row = *r, col = *c;
int i;
- if (regcomp(&re, kw, REG_EXTENDED))
+ struct rset *re = rset_make(1, &kw, 0);
+ if (!re)
return 1;
for (i = row; !found && i >= 0 && i < lbuf_len(lb); i += dir) {
char *s = lbuf_get(lb, i);
- int off = dir > 0 && row == i ? col + 1 : 0;
- while (!regexec(&re, s + off, LEN(subs), subs, 0)) {
- if (dir < 0 && row == i && off + subs[0].rm_so >= col)
+ int off = dir > 0 && row == i ? uc_chr(s, col + 1) - s : 0;
+ int flg = off ? RE_NOTBOL : 0;
+ while (rset_find(re, s + off, 1, offs, flg) >= 0) {
+ if (dir < 0 && row == i && off + offs[0] >= col)
break;
found = 1;
- *c = off + subs[0].rm_so;
+ *c = uc_off(s, off + offs[0]);
*r = i;
- *len = subs[0].rm_eo - subs[0].rm_so;
- off += subs[0].rm_eo;
+ *len = offs[1] - offs[0];
+ off += offs[1];
if (dir > 0)
break;
}
}
- regfree(&re);
+ rset_free(re);
return !found;
}
t@@ -177,8 +177,8 @@ static int vi_search(int cmd, int cnt, int *row, int *col)
int r = *row;
int c = *col;
int failed = 0;
- int i, len;
- int dir;
+ int len = 0;
+ int i, dir;
if (cmd == '/' || cmd == '?') {
char sign[4] = {cmd};
char *kw; |
| diff --git a/vi.h b/vi.h |
| t@@ -37,7 +37,11 @@ int sbuf_len(struct sbuf *sb);
void sbuf_cut(struct sbuf *s, int len);
/* regular expression sets */
-struct rset *rset_make(int n, char **pat);
+#define RE_ICASE 1
+#define RE_NOTBOL 2
+#define RE_NOTEOL 4
+
+struct rset *rset_make(int n, char **pat, int flg);
int rset_find(struct rset *re, char *s, int n, int *grps, int flg);
void rset_free(struct rset *re);
t@@ -69,6 +73,7 @@ int uc_wid(char *s);
int uc_slen(char *s);
int uc_code(char *s);
char *uc_chr(char *s, int off);
+int uc_off(char *s, int off);
char *uc_sub(char *s, int beg, int end);
char *uc_dup(char *s);
int uc_isspace(char *s); |