@@ -38,7 +38,11 @@ fn regex_compilation_result(
3838
3939// TODO: the implementation is copied from awk, maybe we should consider putting it in a shared crate
4040pub struct Regex {
41- raw_regex : libc:: regex_t ,
41+ /// if the regex was initialized with an empty string,
42+ /// `raw_regex` will be empty. This is to allow
43+ /// empty string regexes on MacOS, which otherwise
44+ /// would return a REG_EMPTY on compilation.
45+ raw_regex : Option < libc:: regex_t > ,
4246 regex_string : CString ,
4347}
4448
@@ -57,6 +61,9 @@ pub struct MatchIter<'a> {
5761impl Iterator for MatchIter < ' _ > {
5862 type Item = RegexMatch ;
5963 fn next ( & mut self ) -> Option < Self :: Item > {
64+ if self . regex . raw_regex . is_none ( ) {
65+ return None ;
66+ }
6067 if self . next_start >= self . string . to_bytes ( ) . len ( ) {
6168 return None ;
6269 }
@@ -66,7 +73,7 @@ impl Iterator for MatchIter<'_> {
6673 } ;
6774 let exec_status = unsafe {
6875 libc:: regexec (
69- ptr:: from_ref ( & self . regex . raw_regex ) ,
76+ ptr:: from_ref ( & self . regex . raw_regex . unwrap ( ) ) ,
7077 self . string . as_ptr ( ) . add ( self . next_start ) ,
7178 1 ,
7279 ptr:: from_mut ( & mut match_range) ,
@@ -87,13 +94,19 @@ impl Iterator for MatchIter<'_> {
8794
8895impl Regex {
8996 pub fn new ( regex : CString ) -> Result < Self , String > {
97+ if regex. is_empty ( ) {
98+ return Ok ( Self {
99+ raw_regex : None ,
100+ regex_string : regex,
101+ } ) ;
102+ }
90103 let mut raw = unsafe { std:: mem:: zeroed :: < libc:: regex_t > ( ) } ;
91104 // difference from awk implementation: use 0 instead of REG_EXTENDED
92105 let compilation_status =
93106 unsafe { libc:: regcomp ( ptr:: from_mut ( & mut raw) , regex. as_ptr ( ) , 0 ) } ;
94107 regex_compilation_result ( compilation_status, & raw ) ?;
95108 Ok ( Self {
96- raw_regex : raw,
109+ raw_regex : Some ( raw) ,
97110 regex_string : regex,
98111 } )
99112 }
@@ -113,8 +126,10 @@ impl Regex {
113126
114127impl Drop for Regex {
115128 fn drop ( & mut self ) {
116- unsafe {
117- libc:: regfree ( ptr:: from_mut ( & mut self . raw_regex ) ) ;
129+ if let Some ( regex) = & mut self . raw_regex {
130+ unsafe {
131+ libc:: regfree ( ptr:: from_mut ( regex) ) ;
132+ }
118133 }
119134 }
120135}
0 commit comments