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); }