- /* If there aren't any tabs then there's nothing to do. */
- first_tab = memchr (ext->line, '\t', ext->len);
- if (first_tab == NULL)
- return;
- orig_len = ext->len;
-
- /* If there's just one tab then expand it inline. Otherwise do a
- full string copy to another buffer. */
- second_tab = memchr (first_tab + 1, '\t',
- ext->len - (first_tab - ext->line + 1));
- if (second_tab == NULL)
- {
- int n_spaces = 8 - (first_tab - ext->line) % 8;
-
- ext->len += n_spaces - 1;
-
- /* Expand the line if necessary, keeping the first_tab pointer
- valid. */
- {
- size_t ofs = first_tab - ext->line;
- force_line_buffer_expansion ();
- first_tab = ext->line + ofs;
- }
-
- memmove (first_tab + n_spaces, first_tab + 1,
- orig_len - (first_tab - ext->line + 1));
- memset (first_tab, ' ', n_spaces);
- } else {
- /* Make a local copy of original text. */
- char *orig_line = local_alloc (ext->len + 1);
- memcpy (orig_line, ext->line, ext->len);
-
- /* Allocate memory assuming we need to add 8 spaces for every tab. */
- ext->len += 2 + count_tabs (second_tab + 1,
- ext->len - (second_tab - ext->line + 1));
-
- /* Expand the line if necessary, keeping the first_tab pointer
- valid. */
- {
- size_t ofs = first_tab - ext->line;
- force_line_buffer_expansion ();
- first_tab = ext->line + ofs;
- }
-
- /* Walk through orig_line, expanding tabs into ext->line. */
- {
- char *src_p = orig_line + (first_tab - ext->line);
- char *dest_p = first_tab;
-
- for (; src_p < orig_line + orig_len; src_p++)
- {
- /* Most characters simply pass through untouched. */
- if (*src_p != '\t')
- {
- *dest_p++ = *src_p;
- continue;
- }
-
- /* Tabs are expanded into an equivalent number of
- spaces. */
- {
- int n_spaces = 8 - (dest_p - ext->line) % 8;
-
- memset (dest_p, ' ', n_spaces);
- dest_p += n_spaces;
- }
- }
-
- /* Supply null terminator and actual string length. */
- *dest_p = 0;
- ext->len = dest_p - ext->line;
- }
-
- local_free (orig_line);
- }