tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: curses bug - incorrect curx at end of line



Looks good to me, go for it.
Thanks
(sorry for the top post... damn webmail) 

----- Original Message -----
From: "Simon Burge" 
To:
Cc:"Julian Coleman" 
Sent:Mon, 06 Aug 2018 18:07:38 +1000
Subject: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 
 #include 
 #include 

 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 = %dn", mx, x);
 printf("maxy = %d, getyx cury = %dn", my, y);
 printf("move(%d, %d) returns %dn", y, x, ret);

 exit(0);
 }



Home | Main Index | Thread Index | Old Index