*/
static void resizeline(Terminal *term, termline *line, int cols)
{
- int i, oldlen;
+ int i, oldcols;
if (line->cols != cols) {
+
+ oldcols = line->cols;
+
/*
* This line is the wrong length, which probably means it
* hasn't been accessed since a resize. Resize it now.
* out in the resize (if we're shrinking the line) and
* return their cc lists to the cc free list.
*/
- for (i = cols; i < line->cols; i++)
+ for (i = cols; i < oldcols; i++)
clear_cc(line, i);
/*
+ * If we're shrinking the line, we now bodily move the
+ * entire cc section from where it started to where it now
+ * needs to be. (We have to do this before the resize, so
+ * that the data we're copying is still there. However, if
+ * we're expanding, we have to wait until _after_ the
+ * resize so that the space we're copying into is there.)
+ */
+ if (cols < oldcols)
+ memmove(line->chars + cols, line->chars + oldcols,
+ (line->size - line->cols) * TSIZE);
+
+ /*
* Now do the actual resize, leaving the _same_ amount of
* cc space as there was to begin with.
*/
- oldlen = line->cols;
- line->size += cols - oldlen;
+ line->size += cols - oldcols;
line->chars = sresize(line->chars, line->size, TTYPE);
line->cols = cols;
/*
- * Bodily move the entire cc section from where it started
- * to where it now needs to be.
+ * If we're expanding the line, _now_ we move the cc
+ * section.
*/
- memmove(line->chars + line->cols, line->chars + oldlen,
- (line->size - line->cols) * TSIZE);
+ if (cols > oldcols)
+ memmove(line->chars + cols, line->chars + oldcols,
+ (line->size - line->cols) * TSIZE);
/*
* Go through what's left of the original line, and adjust
* relative offsets within the cc block.) Also do the same
* to the head of the cc_free list.
*/
- for (i = 0; i < oldlen && i < line->cols; i++)
+ for (i = 0; i < oldcols && i < cols; i++)
if (line->chars[i].cc_next)
- line->chars[i].cc_next += cols - oldlen;
+ line->chars[i].cc_next += cols - oldcols;
if (line->cc_free)
- line->cc_free += cols - oldlen;
+ line->cc_free += cols - oldcols;
/*
* And finally fill in the new space with erase chars. (We
* don't have to worry about cc lists here, because we
* _know_ the erase char doesn't have one.)
*/
- for (i = oldlen; i < cols; i++)
+ for (i = oldcols; i < cols; i++)
line->chars[i] = term->basic_erase_char;
cc_check(line); /* XXX-REMOVE-BEFORE-RELEASE */