| 130 | } |
| 131 | |
| 132 | fn exec_( |
| 133 | &mut self, |
| 134 | mut clist: &mut Threads, |
| 135 | mut nlist: &mut Threads, |
| 136 | matches: &mut [bool], |
| 137 | slots: &mut [Slot], |
| 138 | quit_after_match: bool, |
| 139 | mut at: InputAt, |
| 140 | end: usize, |
| 141 | ) -> bool { |
| 142 | let mut matched = false; |
| 143 | let mut all_matched = false; |
| 144 | clist.set.clear(); |
| 145 | nlist.set.clear(); |
| 146 | 'LOOP: loop { |
| 147 | if clist.set.is_empty() { |
| 148 | // Three ways to bail out when our current set of threads is |
| 149 | // empty. |
| 150 | // |
| 151 | // 1. We have a match---so we're done exploring any possible |
| 152 | // alternatives. Time to quit. (We can't do this if we're |
| 153 | // looking for matches for multiple regexes, unless we know |
| 154 | // they all matched.) |
| 155 | // |
| 156 | // 2. If the expression starts with a '^' we can terminate as |
| 157 | // soon as the last thread dies. |
| 158 | if (matched && matches.len() <= 1) |
| 159 | || all_matched |
| 160 | || (!at.is_start() && self.prog.is_anchored_start) { |
| 161 | break; |
| 162 | } |
| 163 | |
| 164 | // 3. If there's a literal prefix for the program, try to |
| 165 | // jump ahead quickly. If it can't be found, then we can |
| 166 | // bail out early. |
| 167 | if !self.prog.prefixes.is_empty() { |
| 168 | at = match self.input.prefix_at(&self.prog.prefixes, at) { |
| 169 | None => break, |
| 170 | Some(at) => at, |
| 171 | }; |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | // This simulates a preceding '.*?' for every regex by adding |
| 176 | // a state starting at the current position in the input for the |
| 177 | // beginning of the program only if we don't already have a match. |
| 178 | if clist.set.is_empty() |
| 179 | || (!self.prog.is_anchored_start && !all_matched) { |
| 180 | self.add(&mut clist, slots, 0, at); |
| 181 | } |
| 182 | // The previous call to "add" actually inspects the position just |
| 183 | // before the current character. For stepping through the machine, |
| 184 | // we can to look at the current character, so we advance the |
| 185 | // input. |
| 186 | let at_next = self.input.at(at.next_pos()); |
| 187 | for i in 0..clist.set.len() { |
| 188 | let ip = clist.set[i]; |
| 189 | if self.step( |