8 struct rset
*rs
; /* only for regex patterns */
9 char *str
; /* for simple, non-regex patterns */
10 int icase
; /* ignore case */
11 int lbeg
, lend
; /* match line beg/end */
12 int wbeg
, wend
; /* match word beg/end */
15 /* return zero if a simple pattern is given */
16 static int rstr_simple(struct rstr
*rs
, char *re
)
20 rs
->lbeg
= re
[0] == '^';
23 rs
->wbeg
= re
[0] == '\\' && re
[1] == '<';
27 while (re
[0] && !strchr("\\.*+?[]{}()$", (unsigned char) re
[0]))
30 rs
->wend
= re
[0] == '\\' && re
[1] == '>';
33 rs
->lend
= re
[0] == '$';
38 rs
->str
= malloc(len
+ 1);
39 memcpy(rs
->str
, beg
, len
);
46 struct rstr
*rstr_make(char *re
, int flg
)
48 struct rstr
*rs
= malloc(sizeof(*rs
));
49 memset(rs
, 0, sizeof(*rs
));
50 rs
->icase
= flg
& RE_ICASE
;
51 if (rstr_simple(rs
, re
))
52 rs
->rs
= rset_make(1, &re
, flg
);
53 if (!rs
->rs
&& !rs
->str
) {
60 static int isword(char *s
)
62 int c
= (unsigned char) s
[0];
63 return isalnum(c
) || c
== '_' || c
> 127;
66 static int match_case(char *s
, char *r
, int icase
)
68 for (; *r
&& *s
; s
++, r
++) {
69 if (!icase
&& *s
!= *r
)
71 if (icase
&& tolower((unsigned char) *s
) != tolower((unsigned char) *r
))
77 /* return zero if an occurrence is found */
78 int rstr_find(struct rstr
*rs
, char *s
, int n
, int *grps
, int flg
)
84 return rset_find(rs
->rs
, s
, n
, grps
, flg
);
85 if ((rs
->lbeg
&& (flg
& RE_NOTBOL
)) || (rs
->lend
&& (flg
& RE_NOTEOL
)))
87 len
= strlen(rs
->str
);
89 end
= s
+ strlen(s
) - len
- 1;
96 for (r
= beg
; r
<= end
; r
++) {
97 if (rs
->wbeg
&& r
> s
&& (isword(r
- 1) || !isword(r
)))
99 if (rs
->wend
&& r
[len
] && (!isword(r
+ len
- 1) || isword(r
+ len
)))
101 if (!match_case(r
, rs
->str
, rs
->icase
)) {
104 grps
[1] = r
- s
+ len
;
112 void rstr_free(struct rstr
*rs
)