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
)
31 struct rset
*rs
= malloc(sizeof(*rs
));
32 struct sbuf
*sb
= sbuf_make();
34 memset(rs
, 0, sizeof(*rs
));
35 rs
->grp
= malloc((n
+ 1) * sizeof(rs
->grp
[0]));
36 rs
->setgrpcnt
= malloc((n
+ 1) * sizeof(rs
->setgrpcnt
[0]));
40 for (i
= 0; i
< n
; i
++) {
51 rs
->grp
[i
] = rs
->grpcnt
;
52 rs
->setgrpcnt
[i
] = re_groupcount(re
[i
]);
53 rs
->grpcnt
+= 1 + rs
->setgrpcnt
[i
];
55 rs
->grp
[n
] = rs
->grpcnt
;
57 if (regcomp(&rs
->regex
, sbuf_buf(sb
), REG_EXTENDED
)) {
68 /* return the index of the matching regular expression or -1 if none matches */
69 int rset_find(struct rset
*rs
, char *s
, int n
, int *grps
, int flg
)
72 int found
, i
, set
= -1;
75 subs
= malloc(rs
->grpcnt
* sizeof(subs
[0]));
76 found
= !regexec(&rs
->regex
, s
, rs
->grpcnt
, subs
, 0);
77 for (i
= 0; found
&& i
< rs
->n
; i
++)
78 if (rs
->grp
[i
] >= 0 && subs
[rs
->grp
[i
]].rm_so
>= 0)
80 if (found
&& set
>= 0) {
81 for (i
= 0; i
< n
; i
++) {
82 int grp
= rs
->grp
[set
] + i
;
83 if (i
< rs
->setgrpcnt
[set
] + 1) {
84 grps
[i
* 2] = subs
[grp
].rm_so
;
85 grps
[i
* 2 + 1] = subs
[grp
].rm_eo
;
96 void rset_free(struct rset
*rs
)