7 /* regular expression set */
9 regex_t regex
; /* the combined regular expression */
10 int n
; /* number of regular expressions in this set */
11 int *grp
; /* the group assigned to each subgroup */
12 int *setgrpcnt
; /* number of groups in each regular expression */
13 int grpcnt
; /* group count */
16 static int re_groupcount(char *s
)
24 s
+= s
[1] == '^' ? 3 : 2;
25 while (s
[0] && (s
[0] != ']' || dep
)) {
33 if (s
[0] == '\\' && s
[1])
40 struct rset
*rset_make(int n
, char **re
, int flg
)
42 struct rset
*rs
= malloc(sizeof(*rs
));
43 struct sbuf
*sb
= sbuf_make();
44 int regex_flg
= REG_EXTENDED
| (flg
& RE_ICASE
? REG_ICASE
: 0);
46 memset(rs
, 0, sizeof(*rs
));
47 rs
->grp
= malloc((n
+ 1) * sizeof(rs
->grp
[0]));
48 rs
->setgrpcnt
= malloc((n
+ 1) * sizeof(rs
->setgrpcnt
[0]));
52 for (i
= 0; i
< n
; i
++) {
63 rs
->grp
[i
] = rs
->grpcnt
;
64 rs
->setgrpcnt
[i
] = re_groupcount(re
[i
]);
65 rs
->grpcnt
+= 1 + rs
->setgrpcnt
[i
];
67 rs
->grp
[n
] = rs
->grpcnt
;
69 if (regcomp(&rs
->regex
, sbuf_buf(sb
), regex_flg
)) {
80 /* return the index of the matching regular expression or -1 if none matches */
81 int rset_find(struct rset
*rs
, char *s
, int n
, int *grps
, int flg
)
84 int found
, i
, set
= -1;
89 regex_flg
|= REG_NOTBOL
;
91 regex_flg
|= REG_NOTEOL
;
92 subs
= malloc(rs
->grpcnt
* sizeof(subs
[0]));
93 found
= !regexec(&rs
->regex
, s
, rs
->grpcnt
, subs
, regex_flg
);
94 for (i
= 0; found
&& i
< rs
->n
; i
++)
95 if (rs
->grp
[i
] >= 0 && subs
[rs
->grp
[i
]].rm_so
>= 0)
97 if (found
&& set
>= 0) {
98 for (i
= 0; i
< n
; i
++) {
99 int grp
= rs
->grp
[set
] + i
;
100 if (i
< rs
->setgrpcnt
[set
] + 1) {
101 grps
[i
* 2] = subs
[grp
].rm_so
;
102 grps
[i
* 2 + 1] = subs
[grp
].rm_eo
;
104 grps
[i
* 2 + 0] = -1;
105 grps
[i
* 2 + 1] = -1;
113 void rset_free(struct rset
*rs
)