diff --git a/src/expand-common.c b/src/expand-common.c index 7c0ea2ea7..e3f9ea84e 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -271,44 +271,54 @@ finalize_tab_stops (void) } +/* Return number of first tab stop after COLUMN. TAB_INDEX specifies + amny multiple tab-sizes. Set *LAST_TAB depending on whether we are + returning COLUMN + 1 merely because we're past the last tab. + If the number would overflow, diagnose this and exit. */ extern colno -get_next_tab_column (const colno column, idx_t *tab_index, - bool *last_tab) +get_next_tab_column (colno column, idx_t *tab_index, bool *last_tab) { *last_tab = false; + colno tab_distance; /* single tab-size - return multiples of it */ if (tab_size) - return column + (tab_size - column % tab_size); - - /* multiple tab-sizes - iterate them until the tab position is beyond - the current input column. */ - for ( ; *tab_index < first_free_tab ; (*tab_index)++ ) + tab_distance = tab_size - column % tab_size; + else { - colno tab = tab_list[*tab_index]; - if (column < tab) + /* multiple tab-sizes - iterate them until the tab position is beyond + the current input column. */ + for ( ; *tab_index < first_free_tab ; (*tab_index)++ ) + { + colno tab = tab_list[*tab_index]; + if (column < tab) return tab; + } + + /* relative last tab - return multiples of it */ + if (extend_size) + tab_distance = extend_size - column % extend_size; + else if (increment_size) + { + /* incremental last tab - add increment_size to the previous + tab stop */ + colno end_tab = tab_list[first_free_tab - 1]; + tab_distance = increment_size - ((column - end_tab) % increment_size); + } + else + { + *last_tab = true; + tab_distance = 1; + } } - /* relative last tab - return multiples of it */ - if (extend_size) - return column + (extend_size - column % extend_size); - - /* incremental last tab - add increment_size to the previous tab stop */ - if (increment_size) - { - colno end_tab = tab_list[first_free_tab - 1]; - - return column + (increment_size - ((column - end_tab) % increment_size)); - } - - *last_tab = true; - return 0; + colno tab_stop; + if (ckd_add (&tab_stop, column, tab_distance)) + error (EXIT_FAILURE, 0, _("input line is too long")); + return tab_stop; } - - /* Sets new file-list */ extern void set_file_list (char **list) diff --git a/src/expand.c b/src/expand.c index 419cf19df..9f950ecd4 100644 --- a/src/expand.c +++ b/src/expand.c @@ -113,7 +113,7 @@ expand (void) is true: */ /* Column of next input character. */ - uintmax_t column = 0; + colno column = 0; /* Index in TAB_LIST of next tab stop to examine. */ idx_t tab_index = 0; @@ -131,17 +131,9 @@ expand (void) if (c == '\t') { /* Column the next input tab stop is on. */ - uintmax_t next_tab_column; bool last_tab; - - next_tab_column = get_next_tab_column (column, &tab_index, - &last_tab); - - if (last_tab) - next_tab_column = column + 1; - - if (next_tab_column < column) - error (EXIT_FAILURE, 0, _("input line is too long")); + colno next_tab_column + = get_next_tab_column (column, &tab_index, &last_tab); while (++column < next_tab_column) if (putchar (' ') < 0) @@ -158,8 +150,7 @@ expand (void) } else { - column++; - if (!column) + if (ckd_add (&column, column, 1)) error (EXIT_FAILURE, 0, _("input line is too long")); } diff --git a/src/unexpand.c b/src/unexpand.c index 9e621929a..0d10ffe39 100644 --- a/src/unexpand.c +++ b/src/unexpand.c @@ -175,9 +175,6 @@ unexpand (void) if (convert) { - if (next_tab_column < column) - error (EXIT_FAILURE, 0, _("input line is too long")); - if (c == '\t') { column = next_tab_column;