summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-08-16 15:45:58 -0400
committerJune McEnroe <june@causal.agency>2019-08-16 15:45:58 -0400
commit4aa35a930fde62d605e5c751d49b9f0ae11dd60e (patch)
treec1ea05ddb325a5777ac390d0d689c18feb541cbc
parentBehave like ICH in IRM (diff)
downloadstream-4aa35a930fde62d605e5c751d49b9f0ae11dd60e.tar.gz
stream-4aa35a930fde62d605e5c751d49b9f0ae11dd60e.zip
Make everything 0-based and exclusive
Also allow both forms of cell pointer to one past the end.
-rw-r--r--term.c67
1 files changed, 33 insertions, 34 deletions
diff --git a/term.c b/term.c
index a7e53bf..54dcef0 100644
--- a/term.c
+++ b/term.c
@@ -39,15 +39,16 @@ static void unhandled(const char *format, ...) {
 }
 
 static struct Cell *cell(struct Term *term, uint y, uint x) {
-	assert(y < term->rows);
+	assert(y <= term->rows);
 	assert(x <= term->cols);
+	assert(y * term->cols + x <= term->rows * term->cols);
 	return &term->cells[y * term->cols + x];
 }
 
-static void erase(struct Style style, struct Cell *a, struct Cell *b) {
-	for (; a <= b; ++a) {
-		a->style = style;
-		a->ch = L' ';
+static void erase(struct Term *term, struct Cell *at, struct Cell *to) {
+	for (; at < to; ++at) {
+		at->style = term->style;
+		at->ch = L' ';
 	}
 }
 
@@ -56,30 +57,30 @@ static void move(struct Cell *dst, struct Cell *src, uint len) {
 }
 
 static void scrollUp(struct Term *term, uint top, uint n) {
-	if (!n || top >= term->scroll.bot) return;
+	n = MIN(n, term->scroll.bot - top);
 	move(
 		cell(term, top, 0),
 		cell(term, top + n, 0),
-		term->cols * (1 + term->scroll.bot - top - n)
+		term->cols * (term->scroll.bot - top - n)
 	);
 	erase(
-		term->style,
-		cell(term, 1 + term->scroll.bot - n, 0),
-		cell(term, term->scroll.bot, term->cols - 1)
+		term,
+		cell(term, term->scroll.bot - n, 0),
+		cell(term, term->scroll.bot - 1, term->cols)
 	);
 }
 
 static void scrollDown(struct Term *term, uint top, uint n) {
-	if (!n || top >= term->scroll.bot) return;
+	n = MIN(n, term->scroll.bot - top);
 	move(
 		cell(term, top + n, 0),
 		cell(term, top, 0),
-		term->cols * (1 + term->scroll.bot - top - n)
+		term->cols * (term->scroll.bot - top - n)
 	);
 	erase(
-		term->style,
+		term,
 		cell(term, top, 0),
-		cell(term, top + n - 1, term->cols - 1)
+		cell(term, top + n, 0)
 	);
 }
 
@@ -135,38 +136,38 @@ ACTION(decrc) {
 
 ACTION(ed) {
 	erase(
-		t->style,
+		t,
 		(P(0, 0) == 0 ? C(Y, X) : C(0, 0)),
-		(P(0, 0) == 1 ? C(Y, X) : C(B, R))
+		(P(0, 0) == 1 ? C(Y, X) : C(B, t->cols))
 	);
 }
 ACTION(el) {
 	erase(
-		t->style,
+		t,
 		(P(0, 0) == 0 ? C(Y, X) : C(Y, 0)),
-		(P(0, 0) == 1 ? C(Y, X) : C(Y, R))
+		(P(0, 0) == 1 ? C(Y, X) : C(Y, t->cols))
 	);
 }
 ACTION(ech) {
-	erase(t->style, C(Y, X), C(Y, MIN(X + P(0, 1) - 1, R)));
+	erase(t, C(Y, X), C(Y, MIN(X + P(0, 1), t->cols)));
 }
 
 ACTION(dch) {
 	uint n = MIN(P(0, 1), t->cols - X);
 	move(C(Y, X), C(Y, X + n), t->cols - X - n);
-	erase(t->style, C(Y, t->cols - n), C(Y, R));
+	erase(t, C(Y, t->cols - n), C(Y, t->cols));
 }
 ACTION(ich) {
 	uint n = MIN(P(0, 1), t->cols - X);
 	move(C(Y, X + n), C(Y, X), t->cols - X - n);
-	erase(t->style, C(Y, X), C(Y, X + n) - 1);
+	erase(t, C(Y, X), C(Y, X + n));
 }
 
-ACTION(dl) { scrollUp(t, Y, MIN(P(0, 1), t->scroll.bot - Y)); }
-ACTION(il) { scrollDown(t, Y, MIN(P(0, 1), t->scroll.bot - Y)); }
+ACTION(dl) { scrollUp(t, MIN(Y, t->scroll.bot), P(0, 1)); }
+ACTION(il) { scrollDown(t, MIN(Y, t->scroll.bot), P(0, 1)); }
 
 ACTION(nl) {
-	if (Y == t->scroll.bot) {
+	if (Y + 1 == t->scroll.bot) {
 		scrollUp(t, t->scroll.top, 1);
 	} else {
 		Y = MIN(Y + 1, B);
@@ -179,14 +180,12 @@ ACTION(ri) {
 		if (Y) Y--;
 	}
 }
-ACTION(su) {
-	scrollUp(t, t->scroll.top, MIN(P(0, 1), t->scroll.bot - t->scroll.top));
-}
-ACTION(sd) {
-	scrollDown(t, t->scroll.top, MIN(P(0, 1), t->scroll.bot - t->scroll.top));
-}
+
+ACTION(su) { scrollUp(t, t->scroll.top, P(0, 1)); }
+ACTION(sd) { scrollDown(t, t->scroll.top, P(0, 1)); }
+
 ACTION(decstbm) {
-	t->scroll.bot = MIN(P(1, t->rows) - 1, B);
+	t->scroll.bot = MIN(P(1, t->rows), t->rows);
 	t->scroll.top = MIN(P(0, 1) - 1, t->scroll.bot);
 }
 
@@ -495,9 +494,9 @@ struct Term *termAlloc(uint rows, uint cols) {
 	term->rows = rows;
 	term->cols = cols;
 	term->mode = Wrap | Cursor;
-	term->scroll.bot = rows - 1;
+	term->scroll.bot = rows;
 	term->style = Default;
-	erase(Default, cell(term, 0, 0), cell(term, rows - 1, cols - 1));
+	erase(term, cell(term, 0, 0), cell(term, rows - 1, cols - 1));
 
 	return term;
 }
@@ -598,7 +597,7 @@ int termSnapshot(struct Term *term, int _fd) {
 		IRM, (term->mode & Insert ? 'h' : 'l'),
 		DECAWM, (term->mode & Wrap ? 'h' : 'l'),
 		DECTCEM, (term->mode & Cursor ? 'h' : 'l'),
-		1 + term->scroll.top, 1 + term->scroll.bot,
+		1 + term->scroll.top, term->scroll.bot,
 		1 + term->y, 1 + term->x
 	);
 	if (n < 0) goto fail;