tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
curses bug - incorrect curx at end of line
Hi folks,
Every now and then I've seen vi report something like
Error: move: l(39 + 0) c(90 + 0)
and I've tracked it down to the way that _cursesi_addwchar() and
_cursesi_waddbytes() interact in src/lib/libcurses/addbytes.c .
_cursesi_addwchar() checks to see if the current position is past
the end of the line after it adds a character with this:
if (*x == win->maxx) {
(*lnp)->flags |= __ISPASTEOL;
newx = win->maxx - 1 + win->ch_off;
if (newx > *(*lnp)->lastchp)
*(*lnp)->lastchp = newx;
__touchline(win, *y, sx, (int) win->maxx - 1);
>>> win->curx = sx;
} else {
The "*x" here is passed in from _cursesi_waddbytes(). If the current
position is past the end of the current line it sets win->curx to inside
the window (the >>> line), but leaves *x untouched. The problem is
that then _cursesi_waddbytes() has a SYNCH_OUT macro afer the call to
_cursesi_addwchar() which does this:
{win->cury = y; win->curx = x;}
which then sets win->curx back to the still invalid value of x that
_cursesi_addwchar() tried to adjust.
The other way of adding a character, _cursesi_addbyte(), doeasn't have
the same error as it checks for end of line differently.
This patch fixes the problem bu resetting x to a valid value and doesn't
seem to have had any side effects. Anyone see any problems with
committing this?
Index: addbytes.c
===================================================================
RCS file: /cvsroot/src/lib/libcurses/addbytes.c,v
retrieving revision 1.47
diff -d -p -u -r1.47 addbytes.c
--- addbytes.c 6 Jan 2017 14:25:41 -0000 1.47
+++ addbytes.c 6 Aug 2018 07:38:59 -0000
@@ -582,7 +582,7 @@ _cursesi_addwchar(WINDOW *win, __LINE **
if (newx > *(*lnp)->lastchp)
*(*lnp)->lastchp = newx;
__touchline(win, *y, sx, (int) win->maxx - 1);
- win->curx = sx;
+ *x = win->curx = sx;
} else {
win->curx = *x;
Below is a small test program that shows this failing and is essentially
what vi is doing when it gets the "Error: move" message.
Cheers,
Simon.
--
#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x, y, mx, my, ret;
WINDOW *w;
w = initscr();
mx = getmaxx(w);
my = getmaxy(w);
move(0, mx - 1);
addstr(".");
getyx(w, y, x);
ret = move(y, x);
endwin();
printf("maxx = %d, getyx curx = %d\n", mx, x);
printf("maxy = %d, getyx cury = %d\n", my, y);
printf("move(%d, %d) returns %d\n", y, x, ret);
exit(0);
}
Home |
Main Index |
Thread Index |
Old Index