diff --git a/buffer.c b/buffer.c index 40aa32d..8810ce8 100644 --- a/buffer.c +++ b/buffer.c @@ -14,6 +14,7 @@ #include "defines.h" #include "file.h" #include "input.h" +#include "list.h" #include "mlout.h" #include "utf8.h" #include "util.h" @@ -326,13 +327,12 @@ static unsigned int utf8_disp_len( const char *s) { static int makelist( int iflag) { - buffer_p bp; - int s; char line[ FNAMSTART + sizeof( fname_t)] ; blistp->b_flag &= ~BFCHG; /* Don't complain! Mute bclear() */ - if ((s = bclear(blistp)) != TRUE) /* Blow old text away */ - return s; + int s = bclear( blistp) ; /* Blow old text away */ + if( s != TRUE) + return s ; blistp->b_fname[ 0] = 0 ; /* in case of user override */ @@ -346,19 +346,15 @@ static int makelist( int iflag) { return FALSE ; /* output the list of buffers */ - for( bp = bheadp ; bp != NULL ; bp = bp->b_bufp) { /* For all buffers */ - char *cp1, *cp2 ; + for( buffer_p bp = bheadp ; bp != NULL ; bp = bp->b_bufp) { int c ; - line_p lp ; - long nbytes ; /* # of bytes in current buffer */ - long nlines ; /* # of lines in current buffer */ /* skip invisible buffers if iflag is false */ if (((bp->b_flag & BFINVS) != 0) && (iflag != TRUE)) continue; do_layout( line, bp->b_mode) ; - cp1 = line ; /* Start at left edge */ + char *cp1 = line ; /* Start at left edge */ /* output status of ACTIVE flag ('@' when the file has been read in) */ *cp1++ = (bp->b_active == TRUE) ? '@' : ' ' ; @@ -370,9 +366,10 @@ static int makelist( int iflag) { *cp1 = ((bp->b_flag & BFCHG) != 0) ? '*' : ' ' ; /* Buffer size */ - nbytes = 0L; /* Count bytes in buf. */ - nlines = 0 ; - for( lp = lforw( bp->b_linep) ; lp != bp->b_linep ; lp = lforw( lp)) { + long nbytes = 0L; /* Count bytes in buf. */ + long nlines = 0 ; + for( line_p lp = lforw( bp->b_linep) ; lp != bp->b_linep ; + lp = lforw( lp)) { nbytes += (long) llength(lp) + 1L; nlines += 1 ; } @@ -385,8 +382,8 @@ static int makelist( int iflag) { *cp1++ = ' ' ; /* Display buffer name */ - cp2 = &bp->b_bname[ 0] ; - while ((c = *cp2++) != 0) + char *cp2 = &bp->b_bname[ 0] ; + while( (c = *cp2++) != 0) *cp1++ = c; /* Pad with spaces to max buffer name length */ @@ -528,7 +525,6 @@ buffer_p bfind( const char *bname, boolean create_f, int flags) { updates that are required. Return TRUE if everything looks good. */ int bclear( buffer_p bp) { - line_p lp ; int s ; if( (bp->b_flag & (BFINVS | BFCHG)) == BFCHG /* regular and changed */ @@ -536,13 +532,28 @@ int bclear( buffer_p bp) { return s ; bp->b_flag &= ~BFCHG ; /* Not changed */ - while( (lp = lforw( bp->b_linep)) != bp->b_linep) - lfree( lp) ; + line_p lp = bp->b_linep ; + if( lp->l_fp != lp) { /* non empty buffer */ + /* turn line ring into a list and delete it */ + lp->l_bp->l_fp = NULL ; + freelist( (list_p) lp->l_fp) ; + lp->l_fp = lp->l_bp = lp ; + + /* Fix dots and marks */ + bp->b_dotp = bp->b_linep ; /* Fix "." */ + bp->b_doto = 0 ; + bp->b_markp = NULL ; /* Invalidate "mark" */ + bp->b_marko = 0 ; + if( bp->b_nwnd) /* buffer is displayed */ + for( window_p wp = wheadp ; wp ; wp = wp->w_wndp) + if( wp->w_bufp == bp) { + wp->w_linep = wp->w_dotp = lp ; + wp->w_doto = 0 ; + wp->w_markp = NULL ; + wp->w_marko = 0 ; + } + } - bp->b_dotp = bp->b_linep ; /* Fix "." */ - bp->b_doto = 0 ; - bp->b_markp = NULL ; /* Invalidate "mark" */ - bp->b_marko = 0 ; return TRUE ; } diff --git a/line.c b/line.c index 1e94d16..30e29dc 100644 --- a/line.c +++ b/line.c @@ -21,6 +21,7 @@ #include "buffer.h" #include "defines.h" +#include "list.h" #include "mlout.h" #include "utf8.h" #include "window.h" @@ -198,47 +199,45 @@ line_p lalloc( int used) { return lp ; } -/* - * Delete line "lp". Fix all of the links that might point at it (they are + +/* Delete line "lp". Fix all of the links that might point at it (they are * moved to offset 0 of the next line. Unlink the line from whatever buffer it * might be in. Release the memory. The buffers are updated too; the magic * conditions described in the above comments don't hold here. */ void lfree( line_p lp) { - buffer_p bp; - struct window *wp; + for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) { + if( wp->w_linep == lp) + wp->w_linep = lp->l_fp ; - wp = wheadp; - while (wp != NULL) { - if (wp->w_linep == lp) - wp->w_linep = lp->l_fp; - if (wp->w_dotp == lp) { - wp->w_dotp = lp->l_fp; - wp->w_doto = 0; + if( wp->w_dotp == lp) { + wp->w_dotp = lp->l_fp ; + wp->w_doto = 0 ; } - if (wp->w_markp == lp) { - wp->w_markp = lp->l_fp; - wp->w_marko = 0; + + if( wp->w_markp == lp) { + wp->w_markp = lp->l_fp ; + wp->w_marko = 0 ; } - wp = wp->w_wndp; } - bp = bheadp; - while (bp != NULL) { - if (bp->b_nwnd == 0) { - if (bp->b_dotp == lp) { - bp->b_dotp = lp->l_fp; - bp->b_doto = 0; + + for( buffer_p bp = bheadp ; bp != NULL ; bp = bp->b_bufp) { + if( bp->b_nwnd == 0) { + if( bp->b_dotp == lp) { + bp->b_dotp = lp->l_fp ; + bp->b_doto = 0 ; } - if (bp->b_markp == lp) { - bp->b_markp = lp->l_fp; - bp->b_marko = 0; + + if( bp->b_markp == lp) { + bp->b_markp = lp->l_fp ; + bp->b_marko = 0 ; } } - bp = bp->b_bufp; } - lp->l_bp->l_fp = lp->l_fp; - lp->l_fp->l_bp = lp->l_bp; - free((char *) lp); + + lp->l_bp->l_fp = lp->l_fp ; + lp->l_fp->l_bp = lp->l_bp ; + free( lp) ; } /* @@ -747,28 +746,19 @@ static int ldelnewline( void) { return TRUE; } -/* - * Delete all of the text saved in the kill buffer. Called by commands when a + +/* Delete all of the text saved in the kill buffer. Called by commands when a * new kill context is being created. The kill buffer array is released, just * in case the buffer has grown to immense size. No errors. */ -void kdelete(void) -{ - kill_p kp; /* ptr to scan kill buffer chunk list */ +void kdelete( void) { + if( kbufh != NULL) { + /* first, delete all the chunks */ + freelist( (list_p) kbufh) ; - if (kbufh != NULL) { - - /* first, delete all the chunks */ - kbufp = kbufh; - while (kbufp != NULL) { - kp = kbufp->d_next; - free(kbufp); - kbufp = kp; - } - - /* and reset all the kill buffer pointers */ - kbufh = kbufp = NULL; - kused = KBLOCK; + /* and reset all the kill buffer pointers */ + kbufh = kbufp = NULL ; + kused = KBLOCK ; klen = 0 ; if( value != NULL) { free( value) ; diff --git a/list.c b/list.c new file mode 100644 index 0000000..bee2b11 --- /dev/null +++ b/list.c @@ -0,0 +1,16 @@ +/* list.c -- implements list.h */ +/* Copyright © 2021 Renaud Fivet */ +#include "list.h" + +#include /* free() */ + +/* free a list */ +void freelist( list_p lp) { + while( lp) { + list_p next = lp->next ; + free( lp) ; + lp = next ; + } +} + +/* end of list.c */ diff --git a/list.h b/list.h new file mode 100644 index 0000000..718fa47 --- /dev/null +++ b/list.h @@ -0,0 +1,13 @@ +/* list.h -- generic list deletion */ +/* Copyright © 2021 Renaud Fivet */ +#ifndef _LIST_H_ +#define _LIST_H_ + +typedef struct list { + struct list *next ; +} *list_p ; + +void freelist( list_p lp) ; + +#endif +/* end of list.h */