- ceiling = BUFFER_CEILING_OF (start);
- ceiling = min (limit, ceiling);
- ceiling_addr = &FETCH_CHAR (ceiling) + 1;
- base = (cursor = &FETCH_CHAR (start));
- while (1)
- {
- while (*cursor != target && ++cursor != ceiling_addr)
- ;
- if (cursor != ceiling_addr)
- {
- if (--count == 0)
- {
- immediate_quit = 0;
- return (start + cursor - base + 1);
- }
- else
- if (++cursor == ceiling_addr)
- break;
- }
- else
- break;
- }
- start += cursor - base;
+ /* Our innermost scanning loop is very simple; it doesn't know
+ about gaps, buffer ends, or the newline cache. ceiling is
+ the position of the last character before the next such
+ obstacle --- the last character the dumb search loop should
+ examine. */
+ register int ceiling = end - 1;
+
+ /* If we're looking for a newline, consult the newline cache
+ to see where we can avoid some scanning. */
+ if (target == '\n' && newline_cache)
+ {
+ int next_change;
+ immediate_quit = 0;
+ while (region_cache_forward
+ (current_buffer, newline_cache, start, &next_change))
+ start = next_change;
+ immediate_quit = allow_quit;
+
+ /* start should never be after end. */
+ if (start >= end)
+ start = end - 1;
+
+ /* Now the text after start is an unknown region, and
+ next_change is the position of the next known region. */
+ ceiling = min (next_change - 1, ceiling);
+ }
+
+ /* The dumb loop can only scan text stored in contiguous
+ bytes. BUFFER_CEILING_OF returns the last character
+ position that is contiguous, so the ceiling is the
+ position after that. */
+ ceiling = min (BUFFER_CEILING_OF (start), ceiling);
+
+ {
+ /* The termination address of the dumb loop. */
+ register unsigned char *ceiling_addr = &FETCH_CHAR (ceiling) + 1;
+ register unsigned char *cursor = &FETCH_CHAR (start);
+ unsigned char *base = cursor;
+
+ while (cursor < ceiling_addr)
+ {
+ unsigned char *scan_start = cursor;
+
+ /* The dumb loop. */
+ while (*cursor != target && ++cursor < ceiling_addr)
+ ;
+
+ /* If we're looking for newlines, cache the fact that
+ the region from start to cursor is free of them. */
+ if (target == '\n' && newline_cache)
+ know_region_cache (current_buffer, newline_cache,
+ start + scan_start - base,
+ start + cursor - base);
+
+ /* Did we find the target character? */
+ if (cursor < ceiling_addr)
+ {
+ if (--count == 0)
+ {
+ immediate_quit = 0;
+ return (start + cursor - base + 1);
+ }
+ cursor++;
+ }
+ }
+
+ start += cursor - base;
+ }