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
)
22 if (s
[0] == '\\' && s
[1])
29 struct rset
*rset_make(int n
, char **re
, int flg
)
31 struct rset
*rs
= malloc(sizeof(*rs
));
32 struct sbuf
*sb
= sbuf_make();
33 int regex_flg
= REG_EXTENDED
| (flg
& RE_ICASE
? REG_ICASE
: 0);
35 memset(rs
, 0, sizeof(*rs
));
36 rs
->grp
= malloc((n
+ 1) * sizeof(rs
->grp
[0]));
37 rs
->setgrpcnt
= malloc((n
+ 1) * sizeof(rs
->setgrpcnt
[0]));
41 for (i
= 0; i
< n
; i
++) {
52 rs
->grp
[i
] = rs
->grpcnt
;
53 rs
->setgrpcnt
[i
] = re_groupcount(re
[i
]);
54 rs
->grpcnt
+= 1 + rs
->setgrpcnt
[i
];
56 rs
->grp
[n
] = rs
->grpcnt
;
58 if (regcomp(&rs
->regex
, sbuf_buf(sb
), regex_flg
)) {
69 /* return the index of the matching regular expression or -1 if none matches */
70 int rset_find(struct rset
*rs
, char *s
, int n
, int *grps
, int flg
)
73 int found
, i
, set
= -1;
78 regex_flg
|= REG_NOTBOL
;
80 regex_flg
|= REG_NOTEOL
;
81 subs
= malloc(rs
->grpcnt
* sizeof(subs
[0]));
82 found
= !regexec(&rs
->regex
, s
, rs
->grpcnt
, subs
, regex_flg
);
83 for (i
= 0; found
&& i
< rs
->n
; i
++)
84 if (rs
->grp
[i
] >= 0 && subs
[rs
->grp
[i
]].rm_so
>= 0)
86 if (found
&& set
>= 0) {
87 for (i
= 0; i
< n
; i
++) {
88 int grp
= rs
->grp
[set
] + i
;
89 if (i
< rs
->setgrpcnt
[set
] + 1) {
90 grps
[i
* 2] = subs
[grp
].rm_so
;
91 grps
[i
* 2 + 1] = subs
[grp
].rm_eo
;
102 void rset_free(struct rset
*rs
)