- if (many_times_ok)
- { /* More than one repetition is allowed, so put in at the
- end a backward relative jump from `b' to before the next
- jump we're going to put in below (which jumps from
- laststart to after this jump).
-
- But if we are at the `*' in the exact sequence `.*\n',
- insert an unconditional jump backwards to the .,
- instead of the beginning of the loop. This way we only
- push a failure point once, instead of every time
- through the loop. */
- assert (p - 1 > pattern);
-
- /* Allocate the space for the jump. */
- GET_BUFFER_SPACE (3);
-
- /* We know we are not at the first character of the pattern,
- because laststart was nonzero. And we've already
- incremented `p', by the way, to be the character after
- the `*'. Do we have to do something analogous here
- for null bytes, because of RE_DOT_NOT_NULL? */
- if (TRANSLATE ((unsigned char)*(p - 2)) == TRANSLATE ('.')
- && zero_times_ok
- && p < pend
- && TRANSLATE ((unsigned char)*p) == TRANSLATE ('\n')
- && !(syntax & RE_DOT_NEWLINE))
- { /* We have .*\n. */
- STORE_JUMP (jump, b, laststart);
- keep_string_p = true;
+ if (many_times_ok)
+ {
+ boolean simple = skip_one_char (laststart) == b;
+ unsigned int startoffset = 0;
+ assert (skip_one_char (laststart) <= b);
+
+ if (!zero_times_ok && simple)
+ { /* Since simple * loops can be made faster by using
+ on_failure_keep_string_jump, we turn simple P+
+ into PP* if P is simple. */
+ unsigned char *p1, *p2;
+ startoffset = b - laststart;
+ GET_BUFFER_SPACE (startoffset);
+ p1 = b; p2 = laststart;
+ while (p2 < p1)
+ *b++ = *p2++;
+ zero_times_ok = 1;
+ }
+
+ GET_BUFFER_SPACE (6);
+ if (!zero_times_ok)
+ /* A + loop. */
+ STORE_JUMP (on_failure_jump_loop, b, b + 6);
+ else
+ /* Simple * loops can use on_failure_keep_string_jump
+ depending on what follows. But since we don't know
+ that yet, we leave the decision up to
+ on_failure_jump_smart. */
+ INSERT_JUMP (simple ? on_failure_jump_smart
+ : on_failure_jump_loop,
+ laststart + startoffset, b + 6);
+ b += 3;
+ STORE_JUMP (jump, b, laststart + startoffset);
+ b += 3;