Compare commits

...

3 Commits

Author SHA1 Message Date
Renaud 81d6f76c78 Test maze scripts using subroutines instead of stored procedures. (Avoid leftover buffers after execution). 2021-09-08 11:05:51 +08:00
Renaud 296f0af96c !gosub
Use generic list deletion API.
Remove lines at parsing time.
2021-09-08 10:58:53 +08:00
Renaud 2674d40d4c Introduce generic list deletion API. 2021-09-08 10:54:07 +08:00
8 changed files with 260 additions and 245 deletions

View File

@ -4,13 +4,14 @@
# either maze.cmd, sharpmaz.cmd or floodmaz.cmd # either maze.cmd, sharpmaz.cmd or floodmaz.cmd
execute-file floodmaz.cmd execute-file floodmaz.cmd
set %meml $curline # save entrance location set %dotc &asc "" # alternatively use "."
set %memc $curcol set $curchar %dotc
set %x &add %memc 1 set %x &add $curcol 1
set %y %meml set %y $curline
end-of-line end-of-line
set %stopcol &sub $curcol 1 set %stopcol &sub $curcol 1
# X-Y offset for absolute direction: east, south, west, north
set %DX0 1 set %DX0 1
set %DY0 0 set %DY0 0
set %DX1 0 set %DX1 0
@ -20,53 +21,41 @@ set %DY2 0
set %DX3 0 set %DX3 0
set %DY3 -1 set %DY3 -1
set %dotc &asc "" # alternatively use "." set %absD 0 # absolute direction: looking EAST
!store peep
set %OX &ind &cat "%DX" %nD
set %OY &ind &cat "%DY" %nD
set %nx &add %x %OX
set %ny &add %y %OY
set $curline %ny
set $curcol %nx
!if &or &equ $curchar 32 &equ $curchar %dotc
!if &equ $curchar 32
set %C %dotc
!else
set %C &asc " " # erase when backtracking (or highlight)
!endif
set %D %nD
set $curchar %C
set $curline %y
set $curcol %x
set $curchar %C
set %x &add %nx %OX
set %y &add %ny %OY
set $curline %y
set $curcol %x
set %res TRUE
!else
set %res FALSE
!endif
update-screen
!endm
set %D 0 # looking EAST
!while &les %x %stopcol !while &les %x %stopcol
set %nD &mod &add %D 3 4 # Can go left? # try move on left, right or front
run peep set %relD 3 # 3, 0, 1, 2 == left, front, right, back
!if &not %res !while &not &equ %relD 2
set %nD %D # Can go straight? set %newD &mod &add %absD %relD 4
run peep set %offX &ind &cat "%DX" %newD
!if &not %res set %offY &ind &cat "%DY" %newD
set %nD &mod &add %D 1 4 # Can go right? set %nx &add %x %offX
run peep set %ny &add %y %offY
!if &not %res set $curline %ny
set %D &mod &add %D 2 4 # Go back! set $curcol %nx
!if &or &equ $curchar 32 &equ $curchar %dotc
!if &equ $curchar 32
set %C %dotc
!else
set %C &asc " " # erase (or highlight) when backtracking
!endif !endif
set %absD %newD
set $curchar %C
set $curline %y
set $curcol %x
set $curchar %C
set %x &add %nx %offX
set %y &add %ny %offY
update-screen
!goto moveon
!endif !endif
!endif set %relD &mod &add %relD 1 4
!endwhile
# else turn around
set %absD &mod &add %absD 2 4 # face back!
:moveon
!endwhile !endwhile
set $curline %meml
set $curcol %memc set $curline %y
set $curcol %x
unmark-buffer unmark-buffer

View File

@ -14,6 +14,7 @@
#include "defines.h" #include "defines.h"
#include "file.h" #include "file.h"
#include "input.h" #include "input.h"
#include "list.h"
#include "mlout.h" #include "mlout.h"
#include "utf8.h" #include "utf8.h"
#include "util.h" #include "util.h"
@ -326,13 +327,12 @@ static unsigned int utf8_disp_len( const char *s) {
static int makelist( int iflag) { static int makelist( int iflag) {
buffer_p bp;
int s;
char line[ FNAMSTART + sizeof( fname_t)] ; char line[ FNAMSTART + sizeof( fname_t)] ;
blistp->b_flag &= ~BFCHG; /* Don't complain! Mute bclear() */ blistp->b_flag &= ~BFCHG; /* Don't complain! Mute bclear() */
if ((s = bclear(blistp)) != TRUE) /* Blow old text away */ int s = bclear( blistp) ; /* Blow old text away */
return s; if( s != TRUE)
return s ;
blistp->b_fname[ 0] = 0 ; /* in case of user override */ blistp->b_fname[ 0] = 0 ; /* in case of user override */
@ -346,19 +346,15 @@ static int makelist( int iflag) {
return FALSE ; return FALSE ;
/* output the list of buffers */ /* output the list of buffers */
for( bp = bheadp ; bp != NULL ; bp = bp->b_bufp) { /* For all buffers */ for( buffer_p bp = bheadp ; bp != NULL ; bp = bp->b_bufp) {
char *cp1, *cp2 ;
int c ; 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 */ /* skip invisible buffers if iflag is false */
if (((bp->b_flag & BFINVS) != 0) && (iflag != TRUE)) if (((bp->b_flag & BFINVS) != 0) && (iflag != TRUE))
continue; continue;
do_layout( line, bp->b_mode) ; 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) */ /* output status of ACTIVE flag ('@' when the file has been read in) */
*cp1++ = (bp->b_active == TRUE) ? '@' : ' ' ; *cp1++ = (bp->b_active == TRUE) ? '@' : ' ' ;
@ -370,9 +366,10 @@ static int makelist( int iflag) {
*cp1 = ((bp->b_flag & BFCHG) != 0) ? '*' : ' ' ; *cp1 = ((bp->b_flag & BFCHG) != 0) ? '*' : ' ' ;
/* Buffer size */ /* Buffer size */
nbytes = 0L; /* Count bytes in buf. */ long nbytes = 0L; /* Count bytes in buf. */
nlines = 0 ; long nlines = 0 ;
for( lp = lforw( bp->b_linep) ; lp != bp->b_linep ; lp = lforw( lp)) { for( line_p lp = lforw( bp->b_linep) ; lp != bp->b_linep ;
lp = lforw( lp)) {
nbytes += (long) llength(lp) + 1L; nbytes += (long) llength(lp) + 1L;
nlines += 1 ; nlines += 1 ;
} }
@ -385,8 +382,8 @@ static int makelist( int iflag) {
*cp1++ = ' ' ; *cp1++ = ' ' ;
/* Display buffer name */ /* Display buffer name */
cp2 = &bp->b_bname[ 0] ; char *cp2 = &bp->b_bname[ 0] ;
while ((c = *cp2++) != 0) while( (c = *cp2++) != 0)
*cp1++ = c; *cp1++ = c;
/* Pad with spaces to max buffer name length */ /* 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. updates that are required. Return TRUE if everything looks good.
*/ */
int bclear( buffer_p bp) { int bclear( buffer_p bp) {
line_p lp ;
int s ; int s ;
if( (bp->b_flag & (BFINVS | BFCHG)) == BFCHG /* regular and changed */ if( (bp->b_flag & (BFINVS | BFCHG)) == BFCHG /* regular and changed */
@ -536,13 +532,28 @@ int bclear( buffer_p bp) {
return s ; return s ;
bp->b_flag &= ~BFCHG ; /* Not changed */ bp->b_flag &= ~BFCHG ; /* Not changed */
while( (lp = lforw( bp->b_linep)) != bp->b_linep) line_p lp = bp->b_linep ;
lfree( lp) ; 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 ; return TRUE ;
} }

160
exec.c
View File

@ -19,6 +19,7 @@
#include "flook.h" #include "flook.h"
#include "input.h" #include "input.h"
#include "line.h" #include "line.h"
#include "list.h"
#include "mlout.h" #include "mlout.h"
#include "random.h" #include "random.h"
#include "util.h" #include "util.h"
@ -39,18 +40,24 @@ boolean clexec = FALSE ; /* command line execution flag */
#define DENDWHILE 7 #define DENDWHILE 7
#define DBREAK 8 #define DBREAK 8
#define DFORCE 9 #define DFORCE 9
#define DGOSUB 10
typedef struct caller {
struct caller *next ;
line_p caller ;
} *caller_p ;
/* The !WHILE directive in the execution language needs to /* The !WHILE directive in the execution language needs to
* stack references to pending whiles. These are stored linked * stack references to pending whiles. These are stored linked
* to each currently open procedure via a linked list of * to each currently open procedure via a linked list of
* the following structure. * the following structure.
*/ */
typedef struct while_block { typedef struct while_block {
struct while_block *w_next ; /* next while */
line_p w_begin ; /* ptr to !while statement */ line_p w_begin ; /* ptr to !while statement */
line_p w_end ; /* ptr to the !endwhile statement */ line_p w_end ; /* ptr to the !endwhile statement */
int w_type ; /* block type */ int w_type ; /* block type */
struct while_block *w_next ; /* next while */
} *while_p ; } *while_p ;
#define BTWHILE 1 #define BTWHILE 1
@ -60,7 +67,8 @@ typedef struct while_block {
static const char *dname[] = { static const char *dname[] = {
"if", "else", "endif", "goto", "return", "if", "else", "endif", "goto", "return",
"endm", "while", "endwhile", "break", "force" "endm", "while", "endwhile", "break", "force",
"gosub"
} ; } ;
#define NUMDIRS ARRAY_SIZE( dname) #define NUMDIRS ARRAY_SIZE( dname)
@ -185,8 +193,8 @@ static int docmd( char *cline) {
return status ; return status ;
} }
/*
* new token: /* new token:
* chop a token off a string * chop a token off a string
* return a pointer past the token * return a pointer past the token
* *
@ -203,52 +211,45 @@ static char *newtoken( char *src, char **tokref) {
++src ; ++src ;
/* scan through the source string */ /* scan through the source string */
boolean quotef = FALSE ; /* is the current string quoted? */ boolean quote_f = FALSE ; /* is the current string quoted? */
while( *src) { for( char c = *src ; c ; c = *++src) {
char c ; /* temporary character */ /* process special characters */
if( c == '~') {
c = *++src ;
if( c == 0)
break ;
/* process special characters */ switch( c) {
if( *src == '~') {
++src;
if (*src == 0)
break;
switch (*src++) {
case 'r': case 'r':
c = 13; c = 13 ;
break; break ;
case 'n': case 'n':
c = 10; c = 10 ;
break; break ;
case 't': case 't':
c = 9; c = 9 ;
break; break ;
case 'b': case 'b':
c = 8; c = 8 ;
break; break ;
case 'f': case 'f':
c = 12; c = 12 ;
break; break ;
default:
c = *(src - 1);
} }
} else { } else {
/* check for the end of the token */ /* check for the end of the token: end of string or space separator */
if (quotef) { if( quote_f) {
if (*src == '"') if( c == '"')
break; break ;
} else { } else if( c == ' ' || c == '\t')
if (*src == ' ' || *src == '\t') break ;
break;
}
/* set quote mode if quote found */ /* set quote mode if quote found */
if (*src == '"') if( c == '"')
quotef = TRUE; quote_f = TRUE ;
/* record the character */
c = *src++;
} }
/* record the character */
if( idx < size - 1) if( idx < size - 1)
tok[ idx++] = c ; tok[ idx++] = c ;
else if( size > 1) { else if( size > 1) {
@ -256,7 +257,7 @@ static char *newtoken( char *src, char **tokref) {
tmptok = malloc( size + 32) ; tmptok = malloc( size + 32) ;
if( tmptok == NULL) if( tmptok == NULL)
size = 0 ; size = 0 ; /* can't store more */
else { else {
memcpy( tmptok, tok, idx) ; memcpy( tmptok, tok, idx) ;
free( tok) ; free( tok) ;
@ -267,15 +268,11 @@ static char *newtoken( char *src, char **tokref) {
} }
} }
/* terminate the token and exit */
if (*src)
++src;
if( tok != NULL) if( tok != NULL)
tok[ idx] = 0 ; tok[ idx] = 0 ;
*tokref = tok ; *tokref = tok ;
return src; return src + (*src != 0) ;
} }
static char *token( char *srcstr, char *tok, int maxtoksize) { static char *token( char *srcstr, char *tok, int maxtoksize) {
@ -488,19 +485,6 @@ BINDABLE( execbuf) {
} }
/* free a list of while block pointers
*
* while_p wp; head of structure to free
*/
static void freewhile( while_p wp) {
while( wp != NULL) {
while_p next = wp->w_next ;
free( wp) ;
wp = next ;
}
}
static boolean storeline( char *eline, int linlen) { static boolean storeline( char *eline, int linlen) {
/* allocate the space for the line */ /* allocate the space for the line */
line_p mp = lalloc( linlen) ; line_p mp = lalloc( linlen) ;
@ -564,19 +548,10 @@ static int dobuf( buffer_p bp) {
if( *eline != ' ' && *eline != '\t') if( *eline != ' ' && *eline != '\t')
break ; break ;
/* empty blank and comment lines */ /* delete blank and comment lines */
if( eline == eol || *eline == '#' || *eline == ';') { if( eline == eol || *eline == '#' || *eline == ';') {
if( bp->b_nwnd != 0) lp = lp->l_bp ;
lp->l_used = 0 ; lfree( lp->l_fp) ;
else {
/* delete line if buffer is not displayed */
line_p curlp = lp ;
lp = lp->l_bp ;
lp->l_fp = curlp->l_fp ;
curlp->l_fp->l_bp = lp ;
free( curlp) ;
}
continue ; continue ;
} }
@ -598,7 +573,9 @@ static int dobuf( buffer_p bp) {
} else if( !storeline( lp->l_text, lp->l_used)) } else if( !storeline( lp->l_text, lp->l_used))
goto failexit ; goto failexit ;
lp->l_used = 0 ; /* remove line */
lp = lp->l_bp ;
lfree( lp->l_fp) ;
continue ; continue ;
} }
@ -618,8 +595,7 @@ static int dobuf( buffer_p bp) {
if( !strncmp( eline, "!store", 6)) { if( !strncmp( eline, "!store", 6)) {
if( lp->l_used < lp->l_size) { if( lp->l_used < lp->l_size) {
eline[ lp->l_used] = 0 ; eline[ lp->l_used] = 0 ;
execstr = &eline[ 6] ; token( &eline[ 6], &tkn[ 1], sizeof tkn - 1) ;
gettoken( &tkn[ 1], sizeof tkn - 1) ;
char c = tkn[ 1] ; char c = tkn[ 1] ;
if( c >= '1' && c <= '9') { /* number >= 1 */ if( c >= '1' && c <= '9') { /* number >= 1 */
if( !storemac( TRUE, atoi( &tkn[ 1]))) if( !storemac( TRUE, atoi( &tkn[ 1])))
@ -632,7 +608,9 @@ static int dobuf( buffer_p bp) {
} }
} }
lp->l_used = 0 ; /* remove line */
lp = lp->l_bp ;
lfree( lp->l_fp) ;
continue ; continue ;
} else if( !strncmp( eline, "!while", 6)) { } else if( !strncmp( eline, "!while", 6)) {
/* if it is a while directive, make a block... */ /* if it is a while directive, make a block... */
@ -693,8 +671,8 @@ static int dobuf( buffer_p bp) {
/* while and endwhile should match! */ /* while and endwhile should match! */
mloutfmt( "%%!WHILE with no matching !ENDWHILE in '%s'", bp->b_bname) ; mloutfmt( "%%!WHILE with no matching !ENDWHILE in '%s'", bp->b_bname) ;
failexit: failexit:
freewhile( scanner) ; freelist( (list_p) scanner) ;
freewhile( whlist) ; freelist( (list_p) whlist) ;
return FALSE ; return FALSE ;
} }
@ -707,6 +685,7 @@ static int dobuf( buffer_p bp) {
int status = TRUE ; /* status of command execution */ int status = TRUE ; /* status of command execution */
boolean done = FALSE ; boolean done = FALSE ;
int execlevel = 0 ; /* execution IF level */ int execlevel = 0 ; /* execution IF level */
caller_p returnto = NULL ;
line_p lp = hlp->l_fp ; line_p lp = hlp->l_fp ;
for( ; lp != hlp ; lp = lp->l_fp) { for( ; lp != hlp ; lp = lp->l_fp) {
if( einit) { if( einit) {
@ -847,9 +826,10 @@ static int dobuf( buffer_p bp) {
break ; break ;
case DENDIF: /* ENDIF directive */ case DENDIF: /* ENDIF directive */
if( execlevel) if( execlevel)
--execlevel; --execlevel ;
break ; break ;
case DGOSUB: /* GOSUB directive */
case DGOTO: /* GOTO directive */ case DGOTO: /* GOTO directive */
/* .....only if we are currently executing */ /* .....only if we are currently executing */
if( execlevel != 0) if( execlevel != 0)
@ -865,6 +845,18 @@ static int dobuf( buffer_p bp) {
char c = *glp->l_text ; char c = *glp->l_text ;
if( (c == '*' || c == ':') if( (c == '*' || c == ':')
&& !strncmp( &glp->l_text[ 1], golabel, linlen)) { && !strncmp( &glp->l_text[ 1], golabel, linlen)) {
if( dirnum == DGOSUB) {
caller_p cp = malloc( sizeof *cp) ;
if( cp == NULL) {
status = mloutfail( "OoM on !gosub") ;
break ;
} else {
cp->caller = lp ;
cp->next = returnto ;
returnto = cp ;
}
}
lp = glp ; lp = glp ;
break ; break ;
} }
@ -879,8 +871,15 @@ static int dobuf( buffer_p bp) {
break ; break ;
case DRETURN: /* RETURN directive */ case DRETURN: /* RETURN directive */
if( execlevel == 0) if( execlevel == 0) {
done = TRUE ; if( returnto != NULL) {
caller_p cp = returnto ;
lp = returnto->caller ;
returnto = returnto->next ;
free( cp) ;
} else
done = TRUE ;
}
break ; break ;
case DENDWHILE: /* ENDWHILE directive */ case DENDWHILE: /* ENDWHILE directive */
@ -929,7 +928,8 @@ static int dobuf( buffer_p bp) {
bp->b_doto = 0 ; bp->b_doto = 0 ;
} }
freewhile( whlist) ; freelist( (list_p) returnto) ;
freelist( (list_p) whlist) ;
if( einit) if( einit)
free( einit) ; free( einit) ;

View File

@ -1,4 +1,4 @@
## floodmaz.cmd -- solve maze by painting right wall ## floodmaz.cmd -- solve maze by painting wall on the right
# 6 set $seed # 6 set $seed
# either maze.cmd or sharpmaz.cmd # either maze.cmd or sharpmaz.cmd
@ -8,39 +8,9 @@ set %thisbuf $cbufname
set %meml $curline set %meml $curline
set %memc $curcol set %memc $curcol
!store pushxy # push x y
set %x $curcol
set %y $curline
select-buffer stack
beginning-of-file
insert-string %x
newline
insert-string %y
newline
select-buffer %thisbuf
!endm
!store popxy # pop x y
select-buffer stack
beginning-of-file
set %x $line
1 kill-to-end-of-line
set %y $line
1 kill-to-end-of-line
select-buffer %thisbuf
set $curline %y
set $curcol %x
!endm
!store probe
!if &not &or &equ $curchar %NC &equ $curchar 32
run pushxy
!endif
!endm
set $curline 1 set $curline 1
set $curcol 0 set $curcol 0
run pushxy #push stop position !gosub pushxy #push stop position
set %x 1 set %x 1
set $curline 4 set $curline 4
set $curcol %x set $curcol %x
@ -51,16 +21,25 @@ set %NC &asc "█"
set %cc $curcol set %cc $curcol
set %ll $curline set %ll $curline
set $curcol &add %cc 1 set $curcol &add %cc 1
run probe !gosub probe
set $curcol &add %cc -1 set $curcol &add %cc -1
run probe !gosub probe
set $curline &add %ll 1 set $curline &add %ll 1
set $curcol %cc set $curcol %cc
run probe !gosub probe
set $curline &add %ll -1 set $curline &add %ll -1
set $curcol %cc set $curcol %cc
run probe !gosub probe
run popxy # pop x y
select-buffer stack
beginning-of-file
set %x $line
1 kill-to-end-of-line
set %y $line
1 kill-to-end-of-line
select-buffer %thisbuf
set $curline %y
set $curcol %x
!endwhile !endwhile
set $curline %meml set $curline %meml
@ -70,3 +49,19 @@ unmark-buffer
select-buffer %thisbuf select-buffer %thisbuf
unmark-buffer unmark-buffer
delete-buffer stack delete-buffer stack
!return
:probe
!if &not &or &equ $curchar %NC &equ $curchar 32
:pushxy # push x y
set %x $curcol
set %y $curline
select-buffer stack
beginning-of-file
insert-string %x
newline
insert-string %y
newline
select-buffer %thisbuf
!endif
!return

82
line.c
View File

@ -21,6 +21,7 @@
#include "buffer.h" #include "buffer.h"
#include "defines.h" #include "defines.h"
#include "list.h"
#include "mlout.h" #include "mlout.h"
#include "utf8.h" #include "utf8.h"
#include "window.h" #include "window.h"
@ -198,47 +199,45 @@ line_p lalloc( int used) {
return lp ; 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 * 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 * might be in. Release the memory. The buffers are updated too; the magic
* conditions described in the above comments don't hold here. * conditions described in the above comments don't hold here.
*/ */
void lfree( line_p lp) { void lfree( line_p lp) {
buffer_p bp; for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) {
struct window *wp; if( wp->w_linep == lp)
wp->w_linep = lp->l_fp ;
wp = wheadp; if( wp->w_dotp == lp) {
while (wp != NULL) { wp->w_dotp = lp->l_fp ;
if (wp->w_linep == lp) wp->w_doto = 0 ;
wp->w_linep = lp->l_fp;
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; if( wp->w_markp == lp) {
wp->w_marko = 0; wp->w_markp = lp->l_fp ;
wp->w_marko = 0 ;
} }
wp = wp->w_wndp;
} }
bp = bheadp;
while (bp != NULL) { for( buffer_p bp = bheadp ; bp != NULL ; bp = bp->b_bufp) {
if (bp->b_nwnd == 0) { if( bp->b_nwnd == 0) {
if (bp->b_dotp == lp) { if( bp->b_dotp == lp) {
bp->b_dotp = lp->l_fp; bp->b_dotp = lp->l_fp ;
bp->b_doto = 0; bp->b_doto = 0 ;
} }
if (bp->b_markp == lp) {
bp->b_markp = lp->l_fp; if( bp->b_markp == lp) {
bp->b_marko = 0; 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; lp->l_bp->l_fp = lp->l_fp ;
free((char *) lp); lp->l_fp->l_bp = lp->l_bp ;
free( lp) ;
} }
/* /*
@ -747,28 +746,19 @@ static int ldelnewline( void) {
return TRUE; 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 * new kill context is being created. The kill buffer array is released, just
* in case the buffer has grown to immense size. No errors. * in case the buffer has grown to immense size. No errors.
*/ */
void kdelete(void) void kdelete( void) {
{ if( kbufh != NULL) {
kill_p kp; /* ptr to scan kill buffer chunk list */ /* first, delete all the chunks */
freelist( (list_p) kbufh) ;
if (kbufh != NULL) { /* and reset all the kill buffer pointers */
kbufh = kbufp = NULL ;
/* first, delete all the chunks */ kused = KBLOCK ;
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;
klen = 0 ; klen = 0 ;
if( value != NULL) { if( value != NULL) {
free( value) ; free( value) ;

16
list.c Normal file
View File

@ -0,0 +1,16 @@
/* list.c -- implements list.h */
/* Copyright © 2021 Renaud Fivet */
#include "list.h"
#include <stdlib.h> /* free() */
/* free a list */
void freelist( list_p lp) {
while( lp) {
list_p next = lp->next ;
free( lp) ;
lp = next ;
}
}
/* end of list.c */

13
list.h Normal file
View File

@ -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 */

View File

@ -15,13 +15,6 @@ set %old $line
set $line %spaces set $line %spaces
next-line next-line
!store check
!if &not &equ $curchar 32
set %v &add %v %inc
!endif
set %inc &tim %inc 2
!endm
!while &less $curline %el !while &less $curline %el
set $curcol 1 set $curcol 1
!while &less $curcol %ec !while &less $curcol %ec
@ -29,15 +22,15 @@ next-line
set %v 0 set %v 0
set %inc 1 set %inc 1
previous-line previous-line
run check !gosub check
next-line next-line
backward-character backward-character
run check !gosub check
2 forward-character 2 forward-character
run check !gosub check
next-line next-line
backward-character backward-character
run check !gosub check
previous-line previous-line
# alternatively use single width "╳╵╴┘╶└─┴╷│┐┤┌├┬┼" # alternatively use single width "╳╵╴┘╶└─┴╷│┐┤┌├┬┼"
set $curchar &asc &mid "╳╹╸┛╺┗━┻╻┃┓┫┏┣┳╋" &add %v 1 1 set $curchar &asc &mid "╳╹╸┛╺┗━┻╻┃┓┫┏┣┳╋" &add %v 1 1
@ -51,3 +44,11 @@ beginning-of-file
set $line %old set $line %old
set $curline %meml set $curline %meml
set $curcol %memc set $curcol %memc
!return
:check
!if &not &equ $curchar 32
set %v &add %v %inc
!endif
set %inc &tim %inc 2
!return