led: map cursor position to terminal column number with led_pos()
[neatvi.git] / reset.c
blob157fdeabb33909971c3707807204a109a6b6f5a1
1 #include <regex.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include "vi.h"
7 struct reset {
8 regex_t regex; /* the combined regular expression */
9 int n; /* number of regular expressions in this set */
10 int *grp; /* the group assigned to each subgroup */
11 int *setgrpcnt; /* number of groups in each regular expression */
12 int grpcnt; /* group count */
15 static int re_groupcount(char *s)
17 int n = 0;
18 while (*s) {
19 if (s[0] == '(')
20 n++;
21 if (s[0] == '\\' && s[1])
22 s++;
23 s++;
25 return n;
28 struct reset *reset_make(int n, char **re)
30 struct reset *rs = malloc(sizeof(*rs));
31 struct sbuf *sb = sbuf_make();
32 int i;
33 memset(rs, 0, sizeof(*rs));
34 rs->grp = malloc((n + 1) * sizeof(rs->grp[0]));
35 rs->setgrpcnt = malloc((n + 1) * sizeof(rs->setgrpcnt[0]));
36 rs->grpcnt = 2;
37 rs->n = n;
38 sbuf_chr(sb, '(');
39 for (i = 0; i < n; i++) {
40 if (!re[i]) {
41 rs->grp[i] = -1;
42 rs->setgrpcnt[i] = 0;
43 continue;
45 if (sbuf_len(sb) > 1)
46 sbuf_chr(sb, '|');
47 sbuf_chr(sb, '(');
48 sbuf_str(sb, re[i]);
49 sbuf_chr(sb, ')');
50 rs->grp[i] = rs->grpcnt;
51 rs->setgrpcnt[i] = re_groupcount(re[i]);
52 rs->grpcnt += 1 + rs->setgrpcnt[i];
54 rs->grp[n] = rs->grpcnt;
55 sbuf_chr(sb, ')');
56 if (regcomp(&rs->regex, sbuf_buf(sb), REG_EXTENDED)) {
57 free(rs->grp);
58 free(rs->setgrpcnt);
59 free(rs);
60 sbuf_free(sb);
61 return NULL;
63 sbuf_free(sb);
64 return rs;
67 int reset_find(struct reset *rs, char *s, int n, int *grps, int flg)
69 regmatch_t *subs;
70 int found, i, set = -1;
71 if (rs->grpcnt <= 2)
72 return -1;
73 subs = malloc(rs->grpcnt * sizeof(subs[0]));
74 found = !regexec(&rs->regex, s, rs->grpcnt, subs, 0);
75 for (i = 0; found && i < rs->n; i++)
76 if (rs->grp[i] >= 0 && subs[rs->grp[i]].rm_so >= 0)
77 set = i;
78 if (found && set >= 0) {
79 for (i = 0; i < n; i++) {
80 int grp = rs->grp[set] + i;
81 if (i < rs->setgrpcnt[set] + 1) {
82 grps[i * 2] = subs[grp].rm_so;
83 grps[i * 2 + 1] = subs[grp].rm_eo;
84 } else {
85 grps[i * 2 + 0] = -1;
86 grps[i * 2 + 1] = -1;
90 free(subs);
91 return set;
94 void reset_free(struct reset *rs)
96 regfree(&rs->regex);
97 free(rs->setgrpcnt);
98 free(rs->grp);
99 free(rs);