From 0c584e5490ee642c4623d27793a1d2bda113808b Mon Sep 17 00:00:00 2001 From: Renaud Fivet Date: Wed, 15 Sep 2021 13:15:31 +0800 Subject: [PATCH] Revise window flagging on line change. Evaluation of Value of kill buffer and current line. --- eval.c | 32 ++++- line.c | 435 ++++++++++++++++++++++++++------------------------------- line.h | 8 +- 3 files changed, 232 insertions(+), 243 deletions(-) diff --git a/eval.c b/eval.c index 7412fd2..ced8549 100644 --- a/eval.c +++ b/eval.c @@ -259,7 +259,7 @@ typedef struct { static void findvar( char *var, variable_description *vd, int size) ; static int svar( variable_description *var, char *value) ; -static char *i_to_a( int i) ; +static const char *i_to_a( int i) ; /* * putctext: @@ -616,11 +616,37 @@ static char *gtusr( char *vname) { } +/* getctext: grab and return a string with the text of the current line */ +static const char *getctext( void) { + static int rsize = 0 ; + static char *rline = NULL ; /* line to return */ + +/* find the contents of the current line and its length */ + line_p lp = curwp->w_dotp ; /* line to copy */ + int size = lp->l_used ; /* length of line to return */ + if( size >= rsize) { + /* extend storage */ + int newsize = size + 1 ; + char *newstr = realloc( rline, newsize) ; + if( newstr == NULL) + return "" ; + + rline = newstr ; + rsize = newsize ; + } + + /* copy it across */ + memcpy( rline, lp->l_text, size) ; + rline[ size] = 0 ; + return rline ; +} + + /* gtenv() * * char *vname; name of environment variable to retrieve */ -static char *gtenv( char *vname) { +static const char *gtenv( char *vname) { unsigned vnum ; /* ordinal number of var referenced */ /* scan the list, looking for the referenced name */ @@ -1085,7 +1111,7 @@ static int svar( variable_description *var, char *value) * * int i; integer to translate to a string */ -static char *i_to_a( int i) { +static const char *i_to_a( int i) { unsigned u ; int sign ; /* sign of resulting number */ /* returns result string: sign digits null */ diff --git a/line.c b/line.c index 30e29dc..593a87b 100644 --- a/line.c +++ b/line.c @@ -54,35 +54,23 @@ static char *value = NULL ; /* temp buffer for value */ /* * return some of the contents of the kill buffer */ -char *getkill( void) { - kill_p kp ; - char *cp ; - - if (kbufh == NULL) - /* no kill buffer....just a null string */ +const char *getkill( void) { +/* no kill buffer or no memory .... just return a null string */ + if( kbufh == NULL + || (value = realloc( value, klen + 1)) == NULL) return "" ; - if( value != NULL) - free( value) ; - - value = (char *) malloc( klen + 1) ; - cp = value ; - for( kp = kbufh ; kp != NULL ; kp = kp->d_next) { - int size ; - - if( kp->d_next != NULL) - size = KBLOCK ; - else - size = kused ; - + char *cp = value ; + for( kill_p kp = kbufh ; kp != NULL ; kp = kp->d_next) { + int size = (kp->d_next != NULL) ? KBLOCK : kused ; memcpy( cp, kp->d_chunk, size) ; cp += size ; } *cp = 0 ; - /* and return the constructed value */ - return value; +/* and return the constructed value */ + return value ; } @@ -240,29 +228,25 @@ void lfree( line_p lp) { free( lp) ; } -/* - * This routine gets called when a character is changed in place in the current + +/* This routine gets called when a character is changed in place in the current * buffer. It updates all of the required flags in the buffer and window * system. The flag used is passed as an argument; if the buffer is being - * displayed in more than 1 window we change EDIT t HARD. Set MODE if the + * displayed in more than 1 window we change EDIT to HARD. Set MODE if the * mode line needs to be updated (the "*" has to be set). */ -void lchange(int flag) -{ - struct window *wp; +void lchange( int flag) { + if( curbp->b_nwnd != 1) /* Ensure hard. */ + flag = WFHARD ; - if (curbp->b_nwnd != 1) /* Ensure hard. */ - flag = WFHARD; - if ((curbp->b_flag & BFCHG) == 0) { /* First change, so */ - flag |= WFMODE; /* update mode lines. */ - curbp->b_flag |= BFCHG; - } - wp = wheadp; - while (wp != NULL) { - if (wp->w_bufp == curbp) - wp->w_flag |= flag; - wp = wp->w_wndp; + if( (curbp->b_flag & BFCHG) == 0) { /* First change, so */ + flag |= WFMODE ; /* update mode lines. */ + curbp->b_flag |= BFCHG ; } + + for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) + if( wp->w_bufp == curbp) + wp->w_flag |= flag ; } @@ -309,81 +293,85 @@ boolean linstr( char *instr) { boolean linsert_byte( int n, int c) { char *cp1; char *cp2; - line_p lp1, lp2, lp3 ; - int doto; - int i; - struct window *wp; + line_p lp2, lp3 ; + int i ; assert( (curbp->b_mode & MDVIEW) == 0) ; - lchange(WFEDIT); - lp1 = curwp->w_dotp; /* Current line */ - if (lp1 == curbp->b_linep) { /* At the end: special */ - if (curwp->w_doto != 0) { - mloutstr( "bug: linsert") ; - return FALSE; - } + lchange( WFEDIT) ; + line_p lp1 = curwp->w_dotp ; /* Current line */ + if( lp1 == curbp->b_linep) { /* At the end: special */ + if( curwp->w_doto != 0) + return mloutfail( "bug: linsert") ; lp2 = lalloc( n) ; /* Allocate new line */ if( lp2 == NULL) return FALSE ; - lp3 = lp1->l_bp; /* Previous line */ - lp3->l_fp = lp2; /* Link in */ - lp2->l_fp = lp1; - lp1->l_bp = lp2; - lp2->l_bp = lp3; - for (i = 0; i < n; ++i) - lp2->l_text[i] = c; - curwp->w_dotp = lp2; - curwp->w_doto = n; - return TRUE; + lp3 = lp1->l_bp ; /* Previous line */ + lp3->l_fp = lp2 ; /* Link in */ + lp2->l_fp = lp1 ; + lp1->l_bp = lp2 ; + lp2->l_bp = lp3 ; + for( i = 0 ; i < n ; ++i) + lp2->l_text[ i] = c ; + + curwp->w_dotp = lp2 ; + curwp->w_doto = n ; + return TRUE ; } - doto = curwp->w_doto; /* Save for later. */ - if (lp1->l_used + n > lp1->l_size) { /* Hard: reallocate */ + + int doto = curwp->w_doto ; /* Save for later. */ + if( lp1->l_used + n > lp1->l_size) { /* Hard: reallocate */ lp2 = lalloc( lp1->l_used + n) ; if( lp2 == NULL) return FALSE ; - cp1 = &lp1->l_text[0]; - cp2 = &lp2->l_text[0]; - while (cp1 != &lp1->l_text[doto]) - *cp2++ = *cp1++; - cp2 += n; - while (cp1 != &lp1->l_text[lp1->l_used]) - *cp2++ = *cp1++; - lp1->l_bp->l_fp = lp2; - lp2->l_fp = lp1->l_fp; - lp1->l_fp->l_bp = lp2; - lp2->l_bp = lp1->l_bp; - free((char *) lp1); + cp1 = &lp1->l_text[ 0] ; + cp2 = &lp2->l_text[ 0] ; + while( cp1 != &lp1->l_text[ doto]) + *cp2++ = *cp1++ ; + + cp2 += n ; + while( cp1 != &lp1->l_text[ lp1->l_used]) + *cp2++ = *cp1++ ; + + lp1->l_bp->l_fp = lp2 ; + lp2->l_fp = lp1->l_fp ; + lp1->l_fp->l_bp = lp2 ; + lp2->l_bp = lp1->l_bp ; + free( lp1) ; } else { /* Easy: in place */ - lp2 = lp1; /* Pretend new line */ - lp2->l_used += n; - cp2 = &lp1->l_text[lp1->l_used]; - cp1 = cp2 - n; - while (cp1 != &lp1->l_text[doto]) - *--cp2 = *--cp1; + lp2 = lp1 ; /* Pretend new line */ + lp2->l_used += n ; + cp2 = &lp1->l_text[ lp1->l_used] ; + cp1 = cp2 - n ; + while( cp1 != &lp1->l_text[ doto]) + *--cp2 = *--cp1 ; } - for (i = 0; i < n; ++i) /* Add the characters */ - lp2->l_text[doto + i] = c; - wp = wheadp; /* Update windows */ - while (wp != NULL) { - if (wp->w_linep == lp1) - wp->w_linep = lp2; - if (wp->w_dotp == lp1) { - wp->w_dotp = lp2; - if (wp == curwp || wp->w_doto > doto) - wp->w_doto += n; + + for( i = 0 ; i < n ; ++i) /* Add the characters */ + lp2->l_text[ doto + i] = c ; + +/* Update windows */ + for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) { + if( wp->w_linep == lp1) + wp->w_linep = lp2 ; + + if( wp->w_dotp == lp1) { + wp->w_dotp = lp2 ; + if( wp == curwp || wp->w_doto > doto) + wp->w_doto += n ; } - if (wp->w_markp == lp1) { - wp->w_markp = lp2; - if (wp->w_marko > doto) - wp->w_marko += n; + + if( wp->w_markp == lp1) { + wp->w_markp = lp2 ; + if( wp->w_marko > doto) + wp->w_marko += n ; } - wp = wp->w_wndp; } - return TRUE; + + return TRUE ; } boolean linsert( int n, unicode_t c) { @@ -565,101 +553,72 @@ boolean ldelchar( long n, boolean kill_f) { * int kflag; put killed text in kill buffer flag */ boolean ldelete( long n, boolean kflag) { - char *cp1; - char *cp2; - line_p dotp; - int doto; - int chunk; - struct window *wp; - assert( !(curbp->b_mode & MDVIEW)) ; while( n > 0) { - dotp = curwp->w_dotp; - doto = curwp->w_doto; - if (dotp == curbp->b_linep) /* Hit end of buffer. */ - return FALSE; - chunk = dotp->l_used - doto; /* Size of chunk. */ - if (chunk > n) - chunk = n; - if (chunk == 0) { /* End of line, merge. */ + line_p dotp = curwp->w_dotp ; + if( dotp == curbp->b_linep) /* Hit end of buffer. */ + return FALSE ; + + int doto = curwp->w_doto ; + int chunk = dotp->l_used - doto ; /* Size of chunk. */ + if( chunk == 0) { /* End of line, merge. */ #if SCROLLCODE - lchange(WFHARD | WFKILLS); + lchange( WFHARD | WFKILLS) ; #else - lchange(WFHARD); + lchange( WFHARD) ; #endif - if (ldelnewline() == FALSE - || (kflag != FALSE && kinsert('\n') == FALSE)) - return FALSE; - --n; - continue; - } - lchange(WFEDIT); - cp1 = &dotp->l_text[doto]; /* Scrunch text. */ - cp2 = cp1 + chunk; - if (kflag != FALSE) { /* Kill? */ - while (cp1 != cp2) { - if (kinsert(*cp1) == FALSE) - return FALSE; - ++cp1; - } - cp1 = &dotp->l_text[doto]; - } - while (cp2 != &dotp->l_text[dotp->l_used]) - *cp1++ = *cp2++; - dotp->l_used -= chunk; - wp = wheadp; /* Fix windows */ - while (wp != NULL) { - if (wp->w_dotp == dotp && wp->w_doto >= doto) { - wp->w_doto -= chunk; - if (wp->w_doto < doto) - wp->w_doto = doto; - } - if (wp->w_markp == dotp && wp->w_marko >= doto) { - wp->w_marko -= chunk; - if (wp->w_marko < doto) - wp->w_marko = doto; - } - wp = wp->w_wndp; - } - n -= chunk; - } - return TRUE; -} + if( ldelnewline() == FALSE + || (kflag != FALSE && kinsert( '\n') == FALSE)) + return FALSE ; -/* - * getctext: grab and return a string with the text of - * the current line - */ -char *getctext( void) { - line_p lp ; /* line to copy */ - int size; /* length of line to return */ - static int rsize = 0 ; - static char *rline ; /* line to return */ + --n ; + continue ; + } else if( chunk > n) + chunk = n ; - /* find the contents of the current line and its length */ - lp = curwp->w_dotp; - size = lp->l_used; - if( size >= rsize) { - if( rsize) - free( rline) ; + lchange( WFEDIT) ; + char *cp1 = &dotp->l_text[ doto] ; /* Scrunch text. */ + char *cp2 = cp1 + chunk ; + if( kflag != FALSE) { /* Kill? */ + while( cp1 != cp2) { + if( kinsert( *cp1) == FALSE) + return FALSE ; + + ++cp1 ; + } - rsize = size + 1 ; - rline = malloc( rsize) ; - if( rline == NULL) { - rsize = 0 ; - return "" ; + cp1 = &dotp->l_text[ doto] ; } + + while( cp2 != &dotp->l_text[ dotp->l_used]) + *cp1++ = *cp2++ ; + + dotp->l_used -= chunk ; + + /* Fix windows */ + for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) { + if( wp->w_dotp == dotp && wp->w_doto >= doto) { + wp->w_doto -= chunk ; + if( wp->w_doto < doto) + wp->w_doto = doto ; + } + + if( wp->w_markp == dotp && wp->w_marko >= doto) { + wp->w_marko -= chunk ; + if( wp->w_marko < doto) + wp->w_marko = doto ; + } + } + + n -= chunk ; } - /* copy it across */ - memcpy( rline, lp->l_text, size) ; - rline[ size] = 0 ; - return rline ; + return TRUE ; } -/* - * Delete a newline. Join the current line with the next line. If the next line + +/* Delete a newline. Join the current line with the next line. If the next line * is the magic header line always return TRUE; merging the last line with the * header line can be thought of as always being a successful operation, even * if nothing is done, and this makes the kill buffer work "right". Easy cases @@ -670,80 +629,86 @@ char *getctext( void) { static int ldelnewline( void) { char *cp1; char *cp2; - line_p lp1, lp2, lp3 ; - struct window *wp; + window_p wp ; assert( (curbp->b_mode & MDVIEW) == 0) ; - lp1 = curwp->w_dotp; - lp2 = lp1->l_fp; - if (lp2 == curbp->b_linep) { /* At the buffer end. */ - if (lp1->l_used == 0) /* Blank line. */ - lfree(lp1); - return TRUE; + line_p lp1 = curwp->w_dotp ; + line_p lp2 = lp1->l_fp ; + if( lp2 == curbp->b_linep) { /* At the buffer end. */ + if( lp1->l_used == 0) /* Blank line. */ + lfree( lp1) ; + + return TRUE ; } - if (lp2->l_used <= lp1->l_size - lp1->l_used) { - cp1 = &lp1->l_text[lp1->l_used]; - cp2 = &lp2->l_text[0]; - while (cp2 != &lp2->l_text[lp2->l_used]) - *cp1++ = *cp2++; - wp = wheadp; - while (wp != NULL) { - if (wp->w_linep == lp2) - wp->w_linep = lp1; - if (wp->w_dotp == lp2) { - wp->w_dotp = lp1; - wp->w_doto += lp1->l_used; + + if( lp2->l_used <= lp1->l_size - lp1->l_used) { + cp1 = &lp1->l_text[ lp1->l_used] ; + cp2 = lp2->l_text ; + while( cp2 != &lp2->l_text[ lp2->l_used]) + *cp1++ = *cp2++ ; + + for( wp = wheadp ; wp != NULL ; wp = wp->w_wndp) { + if( wp->w_linep == lp2) + wp->w_linep = lp1 ; + + if( wp->w_dotp == lp2) { + wp->w_dotp = lp1 ; + wp->w_doto += lp1->l_used ; } - if (wp->w_markp == lp2) { - wp->w_markp = lp1; - wp->w_marko += lp1->l_used; + + if( wp->w_markp == lp2) { + wp->w_markp = lp1 ; + wp->w_marko += lp1->l_used ; } - wp = wp->w_wndp; } - lp1->l_used += lp2->l_used; - lp1->l_fp = lp2->l_fp; - lp2->l_fp->l_bp = lp1; - free((char *) lp2); - return TRUE; + + lp1->l_used += lp2->l_used ; + lp1->l_fp = lp2->l_fp ; + lp2->l_fp->l_bp = lp1 ; + free( lp2) ; + return TRUE ; } - lp3 = lalloc( lp1->l_used + lp2->l_used) ; + line_p lp3 = lalloc( lp1->l_used + lp2->l_used) ; if( lp3 == NULL) return FALSE ; - cp1 = &lp1->l_text[0]; - cp2 = &lp3->l_text[0]; - while (cp1 != &lp1->l_text[lp1->l_used]) - *cp2++ = *cp1++; - cp1 = &lp2->l_text[0]; - while (cp1 != &lp2->l_text[lp2->l_used]) - *cp2++ = *cp1++; - lp1->l_bp->l_fp = lp3; - lp3->l_fp = lp2->l_fp; - lp2->l_fp->l_bp = lp3; - lp3->l_bp = lp1->l_bp; - wp = wheadp; - while (wp != NULL) { - if (wp->w_linep == lp1 || wp->w_linep == lp2) - wp->w_linep = lp3; - if (wp->w_dotp == lp1) - wp->w_dotp = lp3; - else if (wp->w_dotp == lp2) { - wp->w_dotp = lp3; - wp->w_doto += lp1->l_used; + cp1 = lp1->l_text ; + cp2 = lp3->l_text ; + while( cp1 != &lp1->l_text[ lp1->l_used]) + *cp2++ = *cp1++ ; + + cp1 = lp2->l_text ; + while( cp1 != &lp2->l_text[ lp2->l_used]) + *cp2++ = *cp1++ ; + + lp1->l_bp->l_fp = lp3 ; + lp3->l_fp = lp2->l_fp ; + lp2->l_fp->l_bp = lp3 ; + lp3->l_bp = lp1->l_bp ; + for( wp = wheadp ; wp != NULL ; wp = wp->w_wndp) { + if( wp->w_linep == lp1 || wp->w_linep == lp2) + wp->w_linep = lp3 ; + + if( wp->w_dotp == lp1) + wp->w_dotp = lp3 ; + else if( wp->w_dotp == lp2) { + wp->w_dotp = lp3 ; + wp->w_doto += lp1->l_used ; } - if (wp->w_markp == lp1) - wp->w_markp = lp3; - else if (wp->w_markp == lp2) { - wp->w_markp = lp3; - wp->w_marko += lp1->l_used; + + if( wp->w_markp == lp1) + wp->w_markp = lp3 ; + else if( wp->w_markp == lp2) { + wp->w_markp = lp3 ; + wp->w_marko += lp1->l_used ; } - wp = wp->w_wndp; } - free((char *) lp1); - free((char *) lp2); - return TRUE; + + free( lp1) ; + free( lp2) ; + return TRUE ; } diff --git a/line.h b/line.h index 5260386..4434f49 100644 --- a/line.h +++ b/line.h @@ -29,15 +29,12 @@ typedef struct line { extern int tabwidth ; /* Map to $tab, default to 8, can be set to [1, .. */ -char *getkill( void) ; - /* Bindable functions */ BBINDABLE( backchar) ; BBINDABLE( forwchar) ; BINDABLE( insspace) ; BINDABLE( yank) ; -void lfree( line_p lp) ; void lchange( int flag) ; boolean linstr( char *instr) ; boolean linsert( int n, unicode_t c) ; @@ -47,10 +44,11 @@ boolean lnewline( void) ; boolean ldelete( long n, boolean kflag) ; boolean ldelchar( long n, boolean kflag) ; int lgetchar( unicode_t *cref) ; -char *getctext( void) ; void kdelete( void) ; int kinsert( int c) ; -line_p lalloc( int minsize) ; /* Allocate a line of at least minsize chars. */ +line_p lalloc( int minsize) ; /* Allocate a line of at least minsize chars. */ +void lfree( line_p lp) ; /* free a line, updating buffers and windows */ +const char *getkill( void) ; /* get value of $kill */ boolean rdonly( void) ; /* Read Only error message */