mirror of
https://github.com/rfivet/uemacs.git
synced 2025-01-03 06:56:29 -05:00
Merge branch 'unicode'
This commit is contained in:
commit
2befa53c3a
18
Makefile
18
Makefile
@ -13,11 +13,6 @@ else
|
||||
endif
|
||||
export E Q
|
||||
|
||||
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
|
||||
# for windows based target, insure we strip the variant part
|
||||
# CYGWIN_NT-6.1, CYGWIN_NT-6.1-WOW, CYGWIN_NT-6.1-WOW64, MSYS_NT-10.0-19042
|
||||
uname_S := $(shell sh -c 'echo $(uname_S) | sed s/_.*$$//')
|
||||
|
||||
PROGRAM=ue
|
||||
|
||||
CC=gcc
|
||||
@ -25,18 +20,7 @@ WARNINGS=-pedantic -Wall -Wextra -Wstrict-prototypes -Wno-unused-parameter
|
||||
CFLAGS=-O2 $(WARNINGS)
|
||||
LDFLAGS=-s
|
||||
LIBS=-lcurses
|
||||
DEFINES=-DAUTOCONF -DPROGRAM=$(PROGRAM) # -DNDEBUG
|
||||
ifeq ($(uname_S),Linux)
|
||||
DEFINES += -DPOSIX -DUSG
|
||||
else ifeq ($(uname_S),CYGWIN)
|
||||
DEFINES += -DCYGWIN -DSYSV
|
||||
else ifeq ($(uname_S),MSYS)
|
||||
DEFINES += -DCYGWIN -DSYSV
|
||||
else ifeq ($(uname_S),NetBSD)
|
||||
DEFINES += -DPOSIX -DBSD=1
|
||||
else
|
||||
$(error $(uname_S) needs configuration)
|
||||
endif
|
||||
DEFINES=-DPROGRAM=$(PROGRAM) -D_GNU_SOURCE # -DNDEBUG
|
||||
|
||||
BINDIR=/usr/bin
|
||||
LIBDIR=/usr/lib
|
||||
|
14
README.md
14
README.md
@ -1,6 +1,6 @@
|
||||
# README #
|
||||
|
||||
µEMACS (ue) on Cygwin/Linux, based on uEmacs/PK (em) from [kernel.org](
|
||||
µEMACS (ue) on Cygwin/Linux/NetBSD, based on uEmacs/PK (em) from [kernel.org](
|
||||
https://git.kernel.org/pub/scm/editors/uemacs/uemacs.git/).
|
||||
|
||||
### Changes compare to uEmacs/PK ###
|
||||
@ -18,14 +18,14 @@ https://git.kernel.org/pub/scm/editors/uemacs/uemacs.git/).
|
||||
* Some defaults changed due to 'finger habits': ue instead of em, ^S in
|
||||
commands mapping...
|
||||
|
||||
### Unicode (UTF-8) support ###
|
||||
|
||||
* gcc limitation on Windows (__WCHAR_WIDTH__ 16).
|
||||
|
||||
* Display of double and zero width characters ongoing.
|
||||
|
||||
### How to build ###
|
||||
|
||||
* dependencies: gcc, gmake, ncurses-devel.
|
||||
|
||||
* make
|
||||
|
||||
### Badges ###
|
||||
|
||||
[![Coverity Status](
|
||||
https://scan.coverity.com/projects/4449/badge.svg)](
|
||||
https://scan.coverity.com/projects/4449)
|
||||
|
66
blindmaz.cmd
66
blindmaz.cmd
@ -1,13 +1,17 @@
|
||||
## blindmaz.cmd -- solve maze by walking a left-handed blind mouse
|
||||
|
||||
#7 set $seed
|
||||
#execute-file maze.cmd
|
||||
# either maze.cmd, sharpmaz.cmd or floodmaz.cmd
|
||||
execute-file floodmaz.cmd
|
||||
set %x 2
|
||||
|
||||
set %dotc &asc "•" # alternatively use "."
|
||||
set $curchar %dotc
|
||||
set %x &add $curcol 1
|
||||
set %y $curline
|
||||
end-of-line
|
||||
set %stopcol &sub $curcol 1
|
||||
|
||||
# X-Y offset for absolute direction: east, south, west, north
|
||||
set %DX0 1
|
||||
set %DY0 0
|
||||
set %DX1 0
|
||||
@ -17,54 +21,40 @@ set %DY2 0
|
||||
set %DX3 0
|
||||
set %DY3 -1
|
||||
|
||||
set %dotc &asc "."
|
||||
|
||||
store-procedure probe
|
||||
set %OX &ind &cat "%DX" %nD
|
||||
set %OY &ind &cat "%DY" %nD
|
||||
set %nx &add %x %OX
|
||||
set %ny &add %y %OY
|
||||
set %absD 0 # absolute direction: looking EAST
|
||||
!while &les %x %stopcol
|
||||
# try move on left, right or front
|
||||
set %relD 3 # 3, 0, 1, 2 == left, front, right, back
|
||||
!while ¬ &equ %relD 2
|
||||
set %newD &mod &add %absD %relD 4
|
||||
set %offX &ind &cat "%DX" %newD
|
||||
set %offY &ind &cat "%DY" %newD
|
||||
set %nx &add %x %offX
|
||||
set %ny &add %y %offY
|
||||
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)
|
||||
set %C &asc " " # erase (or highlight) when backtracking
|
||||
!endif
|
||||
set %D %nD
|
||||
set %absD %newD
|
||||
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
|
||||
set %x &add %nx %offX
|
||||
set %y &add %ny %offY
|
||||
update-screen
|
||||
!endm
|
||||
|
||||
set %D 0 # looking EAST
|
||||
!while &les %x %stopcol
|
||||
set %nD &mod &add %D 3 4 # Can go left?
|
||||
run probe
|
||||
!if &seq %res FALSE
|
||||
set %nD %D # Can go straight?
|
||||
run probe
|
||||
!if &seq %res FALSE
|
||||
set %nD &mod &add %D 1 4 # Can go right?
|
||||
run probe
|
||||
!if &seq %res FALSE
|
||||
set %D &mod &add %D 2 4 # Go back!
|
||||
!endif
|
||||
!endif
|
||||
!goto moveon
|
||||
!endif
|
||||
set %relD &mod &add %relD 1 4
|
||||
!endwhile
|
||||
# else turn around
|
||||
set %absD &mod &add %absD 2 4 # face back!
|
||||
:moveon
|
||||
!endwhile
|
||||
beginning-of-file
|
||||
set $curline 3
|
||||
set $curcol 1
|
||||
|
||||
set $curcol &add %x -1
|
||||
unmark-buffer
|
||||
|
53
buffer.c
53
buffer.c
@ -1,8 +1,9 @@
|
||||
/* buffer.c -- implements buffer.h */
|
||||
#include "buffer.h"
|
||||
|
||||
/* Buffer management. Some of the functions are internal, and some are actually attached to
|
||||
user keys. Like everyone else, they set hints for the display system.
|
||||
/* Buffer management. Some of the functions are internal, and some are
|
||||
actually attached to user keys. Like everyone else, they set hints for
|
||||
the display system.
|
||||
|
||||
modified by Petri Kutvonen
|
||||
*/
|
||||
@ -11,9 +12,9 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "estruct.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 ;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
66
defines.h
66
defines.h
@ -1,17 +1,63 @@
|
||||
/* defines.h -- */
|
||||
/* defines.h -- customization based on gcc predefined macroes */
|
||||
#ifndef __DEFINES_H__
|
||||
#define __DEFINES_H__
|
||||
|
||||
/* Must define one of
|
||||
USG | BSD
|
||||
*/
|
||||
#define USG 1
|
||||
|
||||
#define PKCODE 1
|
||||
#define SCROLLCODE 1 /* scrolling code P.K. */
|
||||
#define ENVFUNC 1
|
||||
#if __unix__
|
||||
# define UNIX 1
|
||||
# if __NetBSD__
|
||||
# define BSD 1
|
||||
# define POSIX 1
|
||||
# elif __linux__
|
||||
# define USG 1
|
||||
# define SVR4 1 /* locks */
|
||||
# define POSIX 1
|
||||
# else /* __CYGWIN__ */
|
||||
# define USG 1
|
||||
//# define POSIX 1
|
||||
# endif
|
||||
#else
|
||||
# error Missing gcc predefined __unix__
|
||||
#endif
|
||||
|
||||
#define NSTRING 128 /* # of bytes, string buffers */
|
||||
|
||||
#define TERMCAP 1 /* UNIX */
|
||||
#define XONXOFF 1 /* UNIX */
|
||||
|
||||
#define VISMAC 0 /* update display during keyboard macros */
|
||||
|
||||
#define MSDOS 0
|
||||
#define IBMPC MSDOS
|
||||
#define COLOR MSDOS
|
||||
|
||||
|
||||
#define FILOCK (SVR4 | BSD)
|
||||
#define ENVFUNC 1 /* only two types so far (USG | BSD) */
|
||||
|
||||
#define PKCODE 1 /* include P.K. extensions, define always */
|
||||
#define SCROLLCODE 1 /* scrolling code P.K. */
|
||||
|
||||
/* Dynamic RAM tracking and reporting redefinitions */
|
||||
#define RAMSIZE 0 /* dynamic RAM memory usage tracking */
|
||||
#if RAMSIZE
|
||||
# define RAMSHOW 1 /* auto dynamic RAM reporting */
|
||||
# include <stdlib.h> /* size_t */
|
||||
void *allocate( size_t size) ;
|
||||
void release( void *ptr) ;
|
||||
|
||||
# define malloc( sz) allocate(sz)
|
||||
# define free( ptr) release( ptr)
|
||||
#endif
|
||||
/* end of defines.h */
|
||||
|
||||
/* De-allocate memory always on exit (if the operating system or main
|
||||
program can not)
|
||||
*/
|
||||
#define CLEAN 0 /* de-alloc memory on exit */
|
||||
#if CLEAN
|
||||
# define exit(a) cexit(a)
|
||||
|
||||
void cexit( int status) ;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* end of predefs.h */
|
||||
|
542
display.c
542
display.c
@ -1,8 +1,6 @@
|
||||
/* display.c -- implements display.h */
|
||||
#include "display.h"
|
||||
|
||||
#define REVSTA 1 /* Status line appears in reverse video */
|
||||
|
||||
/* The functions in this file handle redisplay. There are two halves, the
|
||||
ones that update the virtual display screen, and the ones that make the
|
||||
physical display screen the same as the virtual display screen. These
|
||||
@ -11,19 +9,22 @@
|
||||
Modified by Petri Kutvonen
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "estruct.h"
|
||||
#include "defines.h"
|
||||
#include "input.h"
|
||||
#include "line.h"
|
||||
#include "termio.h"
|
||||
#include "terminal.h"
|
||||
#include "version.h"
|
||||
#include "wrapper.h"
|
||||
#include "utf8.h"
|
||||
#include "window.h"
|
||||
|
||||
@ -45,33 +46,31 @@ typedef struct {
|
||||
#define VFCOL 0x0010 /* color change requested */
|
||||
|
||||
static video_p *vscreen ; /* Virtual screen. */
|
||||
#if MEMMAP == 0 || SCROLLCODE
|
||||
static video_p *pscreen ; /* Physical screen. */
|
||||
#endif
|
||||
|
||||
static int displaying = TRUE ;
|
||||
#if UNIX
|
||||
# include <signal.h>
|
||||
#endif
|
||||
|
||||
#ifdef SIGWINCH
|
||||
# include <sys/ioctl.h>
|
||||
/* for window size changes */
|
||||
int chg_width, chg_height ;
|
||||
static int displaying = TRUE ;
|
||||
|
||||
static void sizesignal( int signr) ;
|
||||
#endif
|
||||
|
||||
|
||||
static int currow ; /* Cursor row */
|
||||
static int curcol ; /* Cursor column */
|
||||
static int vtrow = 0 ; /* Row location of SW cursor */
|
||||
static int vtcol = 0 ; /* Column location of SW cursor */
|
||||
static int lbound = 0 ; /* leftmost column of current line being displayed */
|
||||
static int taboff = 0 ; /* tab offset for display */
|
||||
|
||||
int mpresf = FALSE ; /* TRUE if message in last line */
|
||||
int scrollcount = 1 ; /* number of lines to scroll */
|
||||
int discmd = TRUE ; /* display command flag */
|
||||
int disinp = TRUE ; /* display input characters (echo) */
|
||||
|
||||
/* global variables */
|
||||
boolean viewtab = FALSE ; /* $viewtab = TRUE to visualize hardcoded tab */
|
||||
|
||||
static int reframe( window_p wp) ;
|
||||
static void updone( window_p wp) ;
|
||||
@ -84,65 +83,95 @@ static void upddex( void) ;
|
||||
static void updext( void) ;
|
||||
static void updgar( void) ;
|
||||
static void updpos( void) ;
|
||||
static int updateline( int row, video_p vp1, video_p vp2) ;
|
||||
static boolean updupd( boolean force_f) ;
|
||||
static void updateline( int row) ;
|
||||
static void updupd( boolean force_f) ;
|
||||
static void modeline( window_p wp) ;
|
||||
static void mlputi( int i, int r) ;
|
||||
static void mlputli( long l, int r) ;
|
||||
static void mlputf( int s) ;
|
||||
static void mlputs( const char *s) ;
|
||||
#if SIGWINCH
|
||||
static int newscreensize( int h, int w) ;
|
||||
static void newscreensize( int h, int w) ;
|
||||
#endif
|
||||
|
||||
|
||||
/* xmalloc is used at early initialization before memory usage tracking is
|
||||
enabled so it bypass the memory tracking macroes.
|
||||
*/
|
||||
static void *xmalloc( size_t size) {
|
||||
void *ret = (malloc)( size) ;
|
||||
if( !ret) {
|
||||
fprintf( stderr, "fatal: Out of memory\n") ;
|
||||
exit( EXIT_FAILURE) ;
|
||||
}
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
/* Initialize the data structures used by the display code. The edge
|
||||
vectors used to access the screens are set up. The operating system's
|
||||
terminal I/O channel is set up. All the other things get initialized at
|
||||
compile time. The original window has "WFCHG" set, so that it will get
|
||||
completely redrawn on the first call to "update".
|
||||
*/
|
||||
void vtinit( void) {
|
||||
TTopen() ; /* open the screen */
|
||||
TTkopen() ; /* open the keyboard */
|
||||
TTrev( FALSE) ;
|
||||
vscreen = xmalloc( term.t_maxrow * sizeof( video_p )) ;
|
||||
|
||||
#if MEMMAP == 0 || SCROLLCODE
|
||||
pscreen = xmalloc( term.t_maxrow * sizeof( video_p )) ;
|
||||
#endif
|
||||
for( int i = 0 ; i < term.t_maxrow ; ++i) {
|
||||
video_p vp = xmalloc( sizeof *vp + term.t_maxcol * sizeof( unicode_t)) ;
|
||||
static int lastmrow ; /* remember mrow for later free */
|
||||
|
||||
static void vtalloc( int maxrow, int maxcol) {
|
||||
lastmrow = maxrow ; /* remember mrow for later free */
|
||||
vscreen = xmalloc( maxrow * sizeof( video_p )) ;
|
||||
pscreen = xmalloc( maxrow * sizeof( video_p )) ;
|
||||
for( int i = 0 ; i < maxrow ; ++i) {
|
||||
video_p vp = xmalloc( sizeof *vp + maxcol * sizeof( unicode_t)) ;
|
||||
vp->v_flag = 0 ;
|
||||
#if COLOR
|
||||
vp->v_rfcolor = 7 ;
|
||||
vp->v_rbcolor = 0 ;
|
||||
#endif
|
||||
vscreen[ i] = vp ;
|
||||
#if MEMMAP == 0 || SCROLLCODE
|
||||
vp = xmalloc( sizeof *vp + term.t_maxcol * sizeof( unicode_t)) ;
|
||||
vp = xmalloc( sizeof *vp + maxcol * sizeof( unicode_t)) ;
|
||||
vp->v_flag = 0 ;
|
||||
pscreen[ i] = vp ;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if CLEAN
|
||||
/* free up all the dynamically allocated video structures */
|
||||
void updmargin( void) {
|
||||
#define MINMARGIN 3 /* MINMARGIN - 1 enough for $ + prev before current */
|
||||
#if MINCOLS < 2 * MINMARGIN + 1
|
||||
# error "MINCOLS and MINMARGIN are not consistent"
|
||||
#endif
|
||||
term.t_margin = term.t_ncol / 10 ;
|
||||
if( term.t_margin < MINMARGIN)
|
||||
term.t_margin = MINMARGIN ;
|
||||
|
||||
term.t_scrsiz = term.t_ncol - 2 * term.t_margin ;
|
||||
}
|
||||
|
||||
void vtinit( void) {
|
||||
#ifdef SIGWINCH
|
||||
signal( SIGWINCH, sizesignal) ;
|
||||
#endif
|
||||
|
||||
setlocale( LC_CTYPE, "") ; /* expects $LANG like en_GB.UTF-8 */
|
||||
TTopen() ; /* open the screen */
|
||||
updmargin() ;
|
||||
TTkopen() ; /* open the keyboard */
|
||||
TTrev( FALSE) ;
|
||||
vtalloc( term.t_mrow, term.t_mcol) ;
|
||||
}
|
||||
|
||||
|
||||
/* free up all the dynamically video structures allocated by vtalloc */
|
||||
void vtfree( void) {
|
||||
for( int i = 0 ; i < term.t_maxrow ; ++i ) {
|
||||
free( vscreen[ i]) ;
|
||||
#if MEMMAP == 0 || SCROLLCODE
|
||||
free( pscreen[ i]) ;
|
||||
#endif
|
||||
/* as xmalloc bypass the malloc macro, we need bypass the free macro too */
|
||||
for( int i = 0 ; i < lastmrow ; ++i ) {
|
||||
(free)( vscreen[ i]) ;
|
||||
(free)( pscreen[ i]) ;
|
||||
}
|
||||
|
||||
free( vscreen) ;
|
||||
#if MEMMAP == 0 || SCROLLCODE
|
||||
free( pscreen) ;
|
||||
#endif
|
||||
(free)( vscreen) ;
|
||||
(free)( pscreen) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Clean up the virtual terminal system, in anticipation for a return to
|
||||
@ -193,16 +222,17 @@ static void sane_vtputc( unicode_t c) {
|
||||
vtcol += 1 ;
|
||||
}
|
||||
|
||||
static void vtputc( unicode_t c) {
|
||||
static void vtputuc( unicode_t c) {
|
||||
/* In case somebody passes us a signed char.. */
|
||||
if( c > 0x10FFFF) /* Let's assume this is due to sign extension */
|
||||
c &= 0xFF ;
|
||||
// if( c > 0x10FFFF) /* Let's assume this is due to sign extension */
|
||||
// c &= 0xFF ;
|
||||
assert( c <= 0x10FFFF) ;
|
||||
|
||||
if( c == '\t')
|
||||
do {
|
||||
if( c == '\t') {
|
||||
sane_vtputc( viewtab ? 0xBB : ' ') ; /* 0xBB: '»' */
|
||||
while( ((vtcol + lbound) % tabwidth) != 0)
|
||||
sane_vtputc( ' ') ;
|
||||
} while( ((vtcol + taboff) % tabwidth) != 0) ;
|
||||
else if( c < 0x20 || c == 0x7F) {
|
||||
} else if( c < 0x20 || c == 0x7F) {
|
||||
sane_vtputc( '^') ;
|
||||
sane_vtputc( c ^ 0x40) ;
|
||||
} else if( c >= 0x80 && c <= 0xA0) {
|
||||
@ -224,7 +254,7 @@ static int vtputs( const char *s) {
|
||||
unicode_t c ;
|
||||
|
||||
s += utf8_to_unicode( s, 0, 4, &c) ;
|
||||
vtputc( c) ;
|
||||
vtputuc( c) ;
|
||||
n += utf8_width( c) ;
|
||||
}
|
||||
|
||||
@ -242,11 +272,11 @@ static void vteeol( void) {
|
||||
vcp[ vtcol++] = ' ' ;
|
||||
}
|
||||
|
||||
/* upscreen:
|
||||
/* upscreen():
|
||||
* user routine to force a screen update
|
||||
* always finishes complete update
|
||||
*/
|
||||
BINDABLE( upscreen) {
|
||||
TBINDABLE( upscreen) {
|
||||
update( TRUE) ;
|
||||
return TRUE ;
|
||||
}
|
||||
@ -264,23 +294,27 @@ static int scrflags ;
|
||||
|
||||
boolean force_f ; force update past type ahead?
|
||||
*/
|
||||
boolean update( boolean force_f) {
|
||||
void update( boolean force_f) {
|
||||
window_p wp ;
|
||||
|
||||
#if TYPEAH && ! PKCODE
|
||||
if( force_f == FALSE && typahead())
|
||||
return TRUE ;
|
||||
return ;
|
||||
#endif
|
||||
#if VISMAC == 0
|
||||
if( force_f == FALSE && kbdmode == PLAY)
|
||||
return TRUE ;
|
||||
return ;
|
||||
#endif
|
||||
|
||||
#if SIGWINCH
|
||||
displaying = TRUE ;
|
||||
resize:
|
||||
#endif
|
||||
|
||||
#if SCROLLCODE
|
||||
|
||||
/* first, propagate mode line changes to all instances of a buffer displayed
|
||||
* in more than one window */
|
||||
window_p wp ;
|
||||
for( wp = wheadp ; wp != NULL ; wp = wp->w_wndp)
|
||||
if( wp->w_flag & WFMODE
|
||||
&& wp->w_bufp->b_nwnd > 1)
|
||||
@ -318,11 +352,6 @@ boolean update( boolean force_f) {
|
||||
/* recalc the current hardware cursor location */
|
||||
updpos() ;
|
||||
|
||||
#if MEMMAP && ! SCROLLCODE
|
||||
/* update the cursor and flush the buffers */
|
||||
movecursor( currow, curcol - lbound) ;
|
||||
#endif
|
||||
|
||||
/* check for lines to de-extend */
|
||||
upddex() ;
|
||||
|
||||
@ -336,12 +365,15 @@ boolean update( boolean force_f) {
|
||||
/* update the cursor and flush the buffers */
|
||||
movecursor( currow, curcol - lbound) ;
|
||||
TTflush() ;
|
||||
displaying = FALSE ;
|
||||
#if SIGWINCH
|
||||
while( chg_width || chg_height)
|
||||
if( chg_width || chg_height) {
|
||||
newscreensize( chg_height, chg_width) ;
|
||||
force_f = TRUE ;
|
||||
goto resize ;
|
||||
}
|
||||
|
||||
displaying = FALSE ;
|
||||
#endif
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
@ -438,8 +470,10 @@ static void show_line( line_p lp) {
|
||||
while( i < len) {
|
||||
unicode_t c ;
|
||||
i += utf8_to_unicode( lp->l_text, i, len, &c) ;
|
||||
vtputc( c) ;
|
||||
vtputuc( c) ;
|
||||
}
|
||||
|
||||
vteeol() ;
|
||||
}
|
||||
|
||||
|
||||
@ -449,9 +483,10 @@ static void show_line( line_p lp) {
|
||||
* window_p wp; window to update current line in
|
||||
*/
|
||||
static void updone( window_p wp) {
|
||||
line_p lp ;
|
||||
|
||||
/* search down the line we want */
|
||||
int sline = wp->w_toprow ; /* physical screen line to update */
|
||||
line_p lp ;
|
||||
for( lp = wp->w_linep ; lp != wp->w_dotp ; lp = lforw( lp))
|
||||
++sline ;
|
||||
|
||||
@ -464,7 +499,6 @@ static void updone( window_p wp) {
|
||||
vscreen[ sline]->v_rfcolor = wp->w_fcolor ;
|
||||
vscreen[ sline]->v_rbcolor = wp->w_bcolor ;
|
||||
#endif
|
||||
vteeol() ;
|
||||
}
|
||||
|
||||
|
||||
@ -486,14 +520,14 @@ static void updall( window_p wp) {
|
||||
/* if we are not at the end */
|
||||
show_line( lp) ;
|
||||
lp = lforw( lp) ;
|
||||
}
|
||||
} else
|
||||
vteeol() ;
|
||||
|
||||
/* on to the next one */
|
||||
#if COLOR
|
||||
vscreen[ sline]->v_rfcolor = wp->w_fcolor ;
|
||||
vscreen[ sline]->v_rbcolor = wp->w_bcolor ;
|
||||
#endif
|
||||
vteeol() ;
|
||||
++sline ;
|
||||
}
|
||||
}
|
||||
@ -504,13 +538,12 @@ static void updall( window_p wp) {
|
||||
This is the only update for simple moves.
|
||||
*/
|
||||
static void updpos( void) {
|
||||
line_p lp ;
|
||||
|
||||
/* find the current row */
|
||||
line_p lp = curwp->w_linep ;
|
||||
currow = curwp->w_toprow ;
|
||||
while( lp != curwp->w_dotp) {
|
||||
for( lp = curwp->w_linep ; lp != curwp->w_dotp ; lp = lforw( lp))
|
||||
++currow ;
|
||||
lp = lforw( lp) ;
|
||||
}
|
||||
|
||||
/* find the current column */
|
||||
curcol = 0 ;
|
||||
@ -551,7 +584,6 @@ static void upddex( void) {
|
||||
|| (curcol < term.t_ncol - 1)) {
|
||||
vtmove( i, 0) ;
|
||||
show_line( lp) ;
|
||||
vteeol() ;
|
||||
|
||||
/* this line no longer is extended */
|
||||
vscreen[ i]->v_flag &= ~VFEXT ;
|
||||
@ -572,18 +604,14 @@ static void upddex( void) {
|
||||
static void updgar( void) {
|
||||
for( int i = 0 ; i < term.t_nrow ; ++i) {
|
||||
vscreen[ i]->v_flag |= VFCHG ;
|
||||
#if REVSTA
|
||||
vscreen[ i]->v_flag &= ~VFREV ;
|
||||
#endif
|
||||
#if COLOR
|
||||
vscreen[ i]->v_fcolor = gfcolor ;
|
||||
vscreen[ i]->v_bcolor = gbcolor ;
|
||||
#endif
|
||||
#if MEMMAP == 0 || SCROLLCODE
|
||||
unicode_t *txt = pscreen[ i]->v_text ;
|
||||
for( int j = 0 ; j < term.t_ncol ; ++j)
|
||||
txt[ j] = ' ' ;
|
||||
#endif
|
||||
}
|
||||
|
||||
movecursor( 0, 0) ; /* Erase the screen. */
|
||||
@ -601,7 +629,7 @@ static void updgar( void) {
|
||||
*
|
||||
* int force; forced update flag
|
||||
*/
|
||||
static boolean updupd( boolean force_f) {
|
||||
static void updupd( boolean force_f) {
|
||||
#if SCROLLCODE
|
||||
if( scrflags & WFKILLS)
|
||||
scrolls( FALSE) ;
|
||||
@ -613,23 +641,15 @@ static boolean updupd( boolean force_f) {
|
||||
#endif
|
||||
|
||||
for( int i = 0 ; i < term.t_nrow ; ++i) {
|
||||
video_p vp1 = vscreen[ i] ;
|
||||
|
||||
/* for each line that needs to be updated */
|
||||
if( (vp1->v_flag & VFCHG) != 0) {
|
||||
if( (vscreen[ i]->v_flag & VFCHG) != 0) {
|
||||
#if TYPEAH && ! PKCODE
|
||||
if( force_f == FALSE && typahead())
|
||||
return TRUE ;
|
||||
#endif
|
||||
#if MEMMAP && ! SCROLLCODE
|
||||
updateline( i, vp1) ;
|
||||
#else
|
||||
updateline( i, vp1, pscreen[ i]) ;
|
||||
#endif
|
||||
updateline( i) ;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
#if SCROLLCODE
|
||||
@ -731,12 +751,10 @@ static int scrolls( int inserts) {
|
||||
vpp->v_flag = vpv->v_flag ; /* XXX */
|
||||
if( vpp->v_flag & VFREV) {
|
||||
vpp->v_flag &= ~VFREV ;
|
||||
vpp->v_flag |= ~VFREQ ;
|
||||
vpp->v_flag |= VFREQ ;
|
||||
}
|
||||
#if MEMMAP
|
||||
vscreen[ to + i]->v_flag &= ~VFCHG ;
|
||||
#endif
|
||||
}
|
||||
|
||||
if( inserts) {
|
||||
from = target ;
|
||||
to = match ;
|
||||
@ -744,7 +762,7 @@ static int scrolls( int inserts) {
|
||||
from = target + count ;
|
||||
to = match + count ;
|
||||
}
|
||||
#if MEMMAP == 0
|
||||
|
||||
for( i = from ; i < to ; i++) {
|
||||
unicode_t *txt ;
|
||||
txt = pscreen[ i]->v_text ;
|
||||
@ -752,9 +770,10 @@ static int scrolls( int inserts) {
|
||||
txt[ j] = ' ' ;
|
||||
vscreen[ i]->v_flag |= VFCHG ;
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
@ -791,30 +810,20 @@ static int endofline( unicode_t *s, int n) {
|
||||
|
||||
|
||||
/* updext:
|
||||
* update the extended line which the cursor is currently
|
||||
* on at a column greater than the terminal width. The line
|
||||
* will be scrolled right or left to let the user see where
|
||||
* the cursor is
|
||||
update the extended line which the cursor is currently on at a column
|
||||
greater than the terminal width. The line will be scrolled right or
|
||||
left to let the user see where the cursor is.
|
||||
*/
|
||||
static void updext( void) {
|
||||
int rcursor ; /* real cursor location */
|
||||
line_p lp ; /* pointer to current line */
|
||||
|
||||
/* calculate what column the real cursor will end up in */
|
||||
rcursor = ((curcol - term.t_ncol) % term.t_scrsiz) + term.t_margin ;
|
||||
taboff = lbound = curcol - rcursor + 1 ;
|
||||
lbound = curcol - ((curcol - term.t_ncol) % term.t_scrsiz + term.t_margin) ;
|
||||
|
||||
/* scan through the line outputing characters to the virtual screen */
|
||||
/* once we reach the left edge */
|
||||
vtmove( currow, -lbound) ; /* start scanning offscreen */
|
||||
lp = curwp->w_dotp ; /* line to output */
|
||||
show_line( lp) ;
|
||||
show_line( curwp->w_dotp) ;
|
||||
|
||||
/* truncate the virtual line, restore tab offset */
|
||||
vteeol() ;
|
||||
taboff = 0 ;
|
||||
|
||||
/* and put a '$' in column 1 */
|
||||
/* put a '$' in column 1 */
|
||||
vscreen[ currow]->v_text[ 0] = '$' ;
|
||||
}
|
||||
|
||||
@ -823,114 +832,62 @@ static void updext( void) {
|
||||
* character sequences; we are using VT52 functionality. Update the physical
|
||||
* row and column variables. It does try an exploit erase to end of line.
|
||||
*/
|
||||
#if MEMMAP
|
||||
/* UPDATELINE specific code for the IBM-PC and other compatables */
|
||||
|
||||
static int updateline( int row, video_p vp1, video_p vp2) {
|
||||
#if SCROLLCODE
|
||||
unicode_t *cp1 ;
|
||||
unicode_t *cp2 ;
|
||||
int nch ;
|
||||
|
||||
cp1 = &vp1->v_text[ 0] ;
|
||||
cp2 = &vp2->v_text[ 0] ;
|
||||
nch = term.t_ncol ;
|
||||
do {
|
||||
*cp2 = *cp1 ;
|
||||
++cp2 ;
|
||||
++cp1 ;
|
||||
}
|
||||
while( --nch) ;
|
||||
#endif
|
||||
#if COLOR
|
||||
scwrite( row, vp1->v_text, vp1->v_rfcolor, vp1->v_rbcolor) ;
|
||||
vp1->v_fcolor = vp1->v_rfcolor ;
|
||||
vp1->v_bcolor = vp1->v_rbcolor ;
|
||||
#else
|
||||
if( vp1->v_flag & VFREQ)
|
||||
scwrite( row, vp1->v_text, 0, 7) ;
|
||||
else
|
||||
scwrite( row, vp1->v_text, 7, 0) ;
|
||||
#endif
|
||||
vp1->v_flag &= ~(VFCHG | VFCOL) ; /* flag this line as changed */
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* updateline()
|
||||
*
|
||||
* int row ; row of screen to update
|
||||
* video_p vp1 ; virtual screen image
|
||||
* video_p vp2 ; physical screen image
|
||||
*/
|
||||
static int updateline( int row, video_p vp1, video_p vp2) {
|
||||
/* UPDATELINE code for all other versions */
|
||||
|
||||
unicode_t *cp1 ;
|
||||
unicode_t *cp2 ;
|
||||
unicode_t *cp3 ;
|
||||
unicode_t *cp4 ;
|
||||
unicode_t *cp5 ;
|
||||
int nbflag ; /* non-blanks to the right flag? */
|
||||
#if REVSTA
|
||||
int rev ; /* reverse video flag */
|
||||
#endif
|
||||
int req = FALSE ; /* reverse video request flag */
|
||||
|
||||
static void updateline( int row) {
|
||||
video_p vp1 = vscreen[ row] ;
|
||||
vp1->v_flag &= ~VFCHG ; /* flag this line as updated */
|
||||
|
||||
/* set up pointers to virtual and physical lines */
|
||||
cp1 = &vp1->v_text[ 0] ;
|
||||
cp2 = &vp2->v_text[ 0] ;
|
||||
unicode_t *inp = vp1->v_text ;
|
||||
unicode_t *out = pscreen[ row]->v_text ;
|
||||
|
||||
#if COLOR
|
||||
TTforg( vp1->v_rfcolor) ;
|
||||
TTbacg( vp1->v_rbcolor) ;
|
||||
#endif
|
||||
|
||||
#if REVSTA | COLOR
|
||||
/* do a re-write of the entire line if it is reverse or there
|
||||
** is a request to change the reverse status */
|
||||
rev = (vp1->v_flag & VFREV) == VFREV ;
|
||||
req = (vp1->v_flag & VFREQ) == VFREQ ;
|
||||
if( req || (req != rev)
|
||||
/* do a re-write of the entire line if there is a request to toggle the
|
||||
* reverse status */
|
||||
int rev = (vp1->v_flag & VFREV) == VFREV ;
|
||||
if( rev != ((vp1->v_flag & VFREQ) == VFREQ)
|
||||
#if COLOR
|
||||
|| (vp1->v_fcolor != vp1->v_rfcolor)
|
||||
|| (vp1->v_bcolor != vp1->v_rbcolor)
|
||||
#endif
|
||||
) {
|
||||
movecursor( row, 0) ; /* Go to start of line. */
|
||||
TTrev( req) ; /* set needed rev video state */
|
||||
TTrev( !rev) ; /* set needed rev video state */
|
||||
|
||||
/* scan through the line and dump it to the screen and
|
||||
the virtual screen array */
|
||||
while( ttcol < term.t_ncol) {
|
||||
/* TODO: handle double width unicode char at last screen col */
|
||||
unicode_t c = *cp1++ ;
|
||||
unicode_t c = *out++ = *inp++ ;
|
||||
TTputc( c) ;
|
||||
ttcol += utf8_width( c) ;
|
||||
*cp2++ = c ;
|
||||
ttcol += _utf8_width( c) ; /* filtered by vtputuc */
|
||||
}
|
||||
|
||||
TTrev( FALSE) ; /* turn rev video off */
|
||||
|
||||
/* update the needed flags */
|
||||
vp1->v_flag &= ~VFCHG ;
|
||||
if( req)
|
||||
vp1->v_flag |= VFREV ;
|
||||
else
|
||||
vp1->v_flag &= ~VFREV ;
|
||||
vp1->v_flag ^= VFREV ;
|
||||
#if COLOR
|
||||
vp1->v_fcolor = vp1->v_rfcolor ;
|
||||
vp1->v_bcolor = vp1->v_rbcolor ;
|
||||
#endif
|
||||
return TRUE ;
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* advance past any common chars at the left */
|
||||
while( cp1 != &vp1->v_text[ term.t_ncol] && cp1[ 0] == cp2[ 0]) {
|
||||
++cp1 ;
|
||||
++cp2 ;
|
||||
unicode_t *end = &vp1->v_text[ term.t_ncol] ;
|
||||
int startcol = 0 ;
|
||||
while( inp != end && *inp == *out) {
|
||||
startcol += _utf8_width( *inp++) ; /* filtered by vtputuc */
|
||||
++out ;
|
||||
}
|
||||
|
||||
/* This can still happen, even though we only call this routine on changed
|
||||
@ -940,97 +897,72 @@ static int updateline( int row, video_p vp1, video_p vp2) {
|
||||
* be hard operations that do a lot of update, so I don't really care.
|
||||
*/
|
||||
/* if both lines are the same, no update needs to be done */
|
||||
if( cp1 == &vp1->v_text[ term.t_ncol]) {
|
||||
vp1->v_flag &= ~VFCHG ; /* flag this line is changed */
|
||||
return TRUE ;
|
||||
}
|
||||
if( inp == end)
|
||||
return ;
|
||||
|
||||
/* find out if there is a match on the right */
|
||||
nbflag = FALSE ;
|
||||
cp3 = &vp1->v_text[ term.t_ncol] ;
|
||||
cp4 = &vp2->v_text[ term.t_ncol] ;
|
||||
int nbflag = FALSE ; /* non-blanks to the right flag? */
|
||||
|
||||
while( cp3[ -1] == cp4[ -1]) {
|
||||
--cp3 ;
|
||||
--cp4 ;
|
||||
if( cp3[ 0] != ' ') /* Note if any nonblank */
|
||||
unicode_t *nbp = &pscreen[ row]->v_text[ term.t_ncol] ;
|
||||
while( end[ -1] == nbp[ -1]) {
|
||||
--end ;
|
||||
--nbp ;
|
||||
if( *end != ' ') /* Note if any nonblank */
|
||||
nbflag = TRUE ; /* in right match. */
|
||||
}
|
||||
|
||||
cp5 = cp3 ;
|
||||
nbp = end ;
|
||||
|
||||
/* Erase to EOL ? */
|
||||
if( nbflag == FALSE && eolexist == TRUE && (req != TRUE)) {
|
||||
while( cp5 != cp1 && cp5[ -1] == ' ')
|
||||
--cp5 ;
|
||||
if( nbflag == FALSE && eolexist == TRUE && (rev != TRUE)) {
|
||||
while( nbp != inp && nbp[ -1] == ' ')
|
||||
--nbp ;
|
||||
|
||||
if( cp3 - cp5 <= 3) /* Use only if erase is */
|
||||
cp5 = cp3 ; /* fewer characters. */
|
||||
if( end - nbp <= 3) /* Use only if erase is */
|
||||
nbp = end ; /* fewer characters. */
|
||||
}
|
||||
|
||||
movecursor( row, cp1 - &vp1->v_text[ 0]) ; /* Go to start of line. */
|
||||
#if REVSTA
|
||||
movecursor( row, startcol) ; /* Go to start of line change */
|
||||
TTrev( rev) ;
|
||||
#endif
|
||||
|
||||
while( cp1 != cp5) { /* Ordinary. */
|
||||
unicode_t c = *cp1++ ;
|
||||
while( inp != nbp) { /* Copy */
|
||||
unicode_t c = *out++ = *inp++ ;
|
||||
TTputc( c) ;
|
||||
ttcol += utf8_width( c) ;
|
||||
*cp2++ = c ;
|
||||
}
|
||||
|
||||
if( cp5 != cp3) { /* Erase. */
|
||||
if( inp != end) { /* Erase */
|
||||
TTeeol() ;
|
||||
while( cp1 != cp3)
|
||||
*cp2++ = *cp1++ ;
|
||||
do
|
||||
*out++ = ' ' ;
|
||||
while( ++inp != end) ;
|
||||
}
|
||||
#if REVSTA
|
||||
|
||||
TTrev( FALSE) ;
|
||||
#endif
|
||||
vp1->v_flag &= ~VFCHG ; /* flag this line as updated */
|
||||
return TRUE ;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Redisplay the mode line for the window pointed to by the "wp". This is the
|
||||
* only routine that has any idea of how the modeline is formatted. You can
|
||||
* change the modeline format by hacking at this routine. Called by "update"
|
||||
* any time there is a dirty window.
|
||||
/* Redisplay the mode line for the window pointed to by the "wp". This is
|
||||
the only routine that has any idea of how the modeline is formatted.
|
||||
You can change the modeline format by hacking at this routine. Called
|
||||
by "update" any time there is a dirty window.
|
||||
*/
|
||||
static void modeline( window_p wp) {
|
||||
int n ; /* cursor position count */
|
||||
buffer_p bp ;
|
||||
int i ; /* loop index */
|
||||
int lchar ; /* character to draw line in buffer with */
|
||||
int firstm ; /* is this the first mode? */
|
||||
char tline[] = " % " ; /* formatting buffer for percentage */
|
||||
|
||||
n = wp->w_toprow + wp->w_ntrows ; /* Location. */
|
||||
int n = wp->w_toprow + wp->w_ntrows ; /* Location. */
|
||||
vscreen[ n]->v_flag |= VFCHG | VFREQ | VFCOL ; /* Redraw next time. */
|
||||
#if COLOR
|
||||
vscreen[ n]->v_rfcolor = 0 ; /* black on */
|
||||
vscreen[ n]->v_rbcolor = 7 ; /* white..... */
|
||||
#endif
|
||||
vtmove( n, 0) ; /* Seek to right line. */
|
||||
if( wp == curwp) /* mark the current buffer */
|
||||
#if PKCODE && REVSTA
|
||||
lchar = '-' ;
|
||||
#else
|
||||
lchar = '=' ;
|
||||
#endif
|
||||
else
|
||||
#if REVSTA
|
||||
if( revexist)
|
||||
lchar = ' ' ;
|
||||
else
|
||||
#endif
|
||||
lchar = '-' ;
|
||||
int lchar = "-= -"[ 2 * revexist + (wp == curwp)] ; /* pick bg character */
|
||||
|
||||
bp = wp->w_bufp ;
|
||||
vtputc( ((bp->b_flag & BFTRUNC) != 0) ? '#' : lchar) ; /* truncated? */
|
||||
vtputc( ((bp->b_flag & BFCHG) != 0) ? '*' : lchar) ; /* changed? */
|
||||
vtputc( ' ') ;
|
||||
buffer_p bp = wp->w_bufp ;
|
||||
vtputuc( ((bp->b_flag & BFTRUNC) != 0) ? '#' : lchar) ; /* truncated? */
|
||||
vtputuc( ((bp->b_flag & BFCHG) != 0) ? '*' : lchar) ; /* changed? */
|
||||
vtputuc( ' ') ;
|
||||
|
||||
if( n == term.t_nrow - 1)
|
||||
n = 3 + vtputs( PROGRAM_NAME_UTF8 " " VERSION ": ") ;
|
||||
@ -1040,105 +972,75 @@ static void modeline( window_p wp) {
|
||||
n += vtputs( bp->b_bname) ;
|
||||
n += vtputs( " (") ;
|
||||
|
||||
/* display the modes */
|
||||
|
||||
if( (bp->b_flag & BFTRUNC) != 0) {
|
||||
firstm = FALSE ;
|
||||
/* display the modes */
|
||||
int pos = n ;
|
||||
if( (bp->b_flag & BFTRUNC) != 0)
|
||||
n += vtputs( "Truncated") ;
|
||||
} else
|
||||
firstm = TRUE ;
|
||||
|
||||
for( i = 0 ; i < NUMMODES ; i++) /* add in the mode flags */
|
||||
for( int i = 0 ; i < NUMMODES ; i++) /* add in the mode flags */
|
||||
if( wp->w_bufp->b_mode & (1 << i)) {
|
||||
if( firstm != TRUE)
|
||||
n += vtputs( " ") ;
|
||||
else
|
||||
firstm = FALSE ;
|
||||
if( n > pos) {
|
||||
vtputuc( ' ') ;
|
||||
n += 1 ;
|
||||
}
|
||||
|
||||
n += vtputs( modename[ i]) ;
|
||||
}
|
||||
|
||||
n += vtputs( ") ") ;
|
||||
|
||||
#if PKCODE
|
||||
if( bp->b_fname[ 0] != 0 && strcmp( bp->b_bname, bp->b_fname) != 0) {
|
||||
#else
|
||||
if( bp->b_fname[ 0] != 0) { /* File name. */
|
||||
n += vtputs( "File: ") ;
|
||||
#endif
|
||||
n += vtputs( bp->b_fname) ;
|
||||
vtputc(' ') ;
|
||||
vtputuc( ' ') ;
|
||||
++n ;
|
||||
}
|
||||
|
||||
while( n < term.t_ncol) { /* Pad to full width. */
|
||||
vtputc( lchar) ;
|
||||
vtputuc( lchar) ;
|
||||
++n ;
|
||||
}
|
||||
|
||||
{ /* determine if top line, bottom line, or both are visible */
|
||||
line_p lp = wp->w_linep ;
|
||||
int rows = wp->w_ntrows ;
|
||||
/* determine if top line, bottom line, or both are visible */
|
||||
char *msg = NULL ;
|
||||
char tline[ 6] ; /* buffer for part of mode line */
|
||||
|
||||
vtcol -= 7 ; /* strlen(" top ") plus a couple */
|
||||
while( rows--) {
|
||||
if( wp->w_linep == wp->w_bufp->b_linep)
|
||||
msg = "Empty" ;
|
||||
else {
|
||||
if( lback( wp->w_linep) == wp->w_bufp->b_linep)
|
||||
msg = " Top " ;
|
||||
|
||||
line_p lp = wp->w_linep ;
|
||||
for( int rows = wp->w_ntrows ; rows > 0 ; rows--) {
|
||||
lp = lforw( lp) ;
|
||||
if( lp == wp->w_bufp->b_linep) {
|
||||
msg = " Bot " ;
|
||||
msg = msg ? " All " : " End " ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if( lback( wp->w_linep) == wp->w_bufp->b_linep) {
|
||||
if( msg) {
|
||||
if( wp->w_linep == wp->w_bufp->b_linep)
|
||||
msg = " Emp " ;
|
||||
else
|
||||
msg = " All " ;
|
||||
} else {
|
||||
msg = " Top " ;
|
||||
}
|
||||
}
|
||||
|
||||
if( !msg) {
|
||||
line_p lp ;
|
||||
int numlines, predlines ;
|
||||
|
||||
lp = lforw( bp->b_linep) ;
|
||||
numlines = 0 ;
|
||||
predlines = 0 ;
|
||||
while( lp != bp->b_linep) {
|
||||
if( lp == wp->w_linep) {
|
||||
predlines = numlines ;
|
||||
/* buffer is not empty, both first and last line not in window */
|
||||
n = 0 ; /* count of lines in buffer */
|
||||
pos = 0 ; /* line number of the top line in window */
|
||||
for( lp = lforw( bp->b_linep) ; lp != bp->b_linep ;
|
||||
lp = lforw( lp)) {
|
||||
n += 1 ;
|
||||
if( lp == wp->w_linep)
|
||||
pos = n ;
|
||||
}
|
||||
++numlines ;
|
||||
lp = lforw( lp) ;
|
||||
}
|
||||
if( wp->w_dotp == bp->b_linep) {
|
||||
msg = " Bot " ;
|
||||
} else {
|
||||
int ratio = 0 ;
|
||||
|
||||
if( numlines != 0)
|
||||
ratio = (100L * predlines) / numlines ;
|
||||
if( ratio > 99)
|
||||
ratio = 99 ;
|
||||
|
||||
tline[ 0] = ' ' ;
|
||||
tline[ 1] = ratio / 10 + '0' ;
|
||||
tline[ 2] = ratio % 10 + '0' ;
|
||||
tline[ 3] = '%' ;
|
||||
tline[ 4] = ' ' ;
|
||||
tline[ 5] = 0 ;
|
||||
if( tline[ 1] == '0')
|
||||
tline[ 1] = ' ' ;
|
||||
pos = (100L * pos) / n ;
|
||||
tline[ 2] = pos % 10 + '0' ;
|
||||
pos /= 10 ;
|
||||
if( pos)
|
||||
tline[ 1] = pos + '0' ;
|
||||
|
||||
msg = tline ;
|
||||
}
|
||||
}
|
||||
|
||||
n += vtputs( msg) ;
|
||||
}
|
||||
vtcol -= 7 ; /* strlen(" top ") plus a couple */
|
||||
vtputs( msg) ;
|
||||
}
|
||||
|
||||
void upmode( void) { /* update all the mode lines */
|
||||
@ -1402,7 +1304,7 @@ void getscreensize( int *widthp, int *heightp) {
|
||||
}
|
||||
|
||||
#ifdef SIGWINCH
|
||||
void sizesignal( int signr) {
|
||||
static void sizesignal( int signr) {
|
||||
int w, h ;
|
||||
int old_errno = errno ;
|
||||
|
||||
@ -1411,33 +1313,37 @@ void sizesignal( int signr) {
|
||||
if( h > 0 && w > 0) {
|
||||
term.t_mrow = h = h < term.t_maxrow ? h : term.t_maxrow ;
|
||||
term.t_mcol = w = w < term.t_maxcol ? w : term.t_maxcol ;
|
||||
if( h - 1 != term.t_nrow || w != term.t_ncol)
|
||||
if( h - 1 != term.t_nrow || w != term.t_ncol) {
|
||||
if( displaying) {
|
||||
chg_width = w ;
|
||||
chg_height = h ;
|
||||
} else {
|
||||
newscreensize( h, w) ;
|
||||
update( TRUE) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signal( SIGWINCH, sizesignal) ;
|
||||
errno = old_errno ;
|
||||
}
|
||||
|
||||
static int newscreensize( int h, int w) {
|
||||
/* do the change later */
|
||||
if( displaying) {
|
||||
chg_width = w ;
|
||||
chg_height = h ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
static void newscreensize( int h, int w) {
|
||||
chg_width = chg_height = 0 ;
|
||||
vtfree() ;
|
||||
if( h < MINROWS)
|
||||
h = MINROWS ;
|
||||
|
||||
if( w < MINCOLS)
|
||||
w = MINCOLS ;
|
||||
|
||||
vtalloc( h, w) ;
|
||||
if( h <= term.t_mrow)
|
||||
newsize( TRUE, h) ;
|
||||
|
||||
if( w <= term.t_mcol)
|
||||
newwidth( TRUE, w) ;
|
||||
|
||||
update( TRUE) ;
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
15
display.h
15
display.h
@ -4,10 +4,13 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "estruct.h"
|
||||
#include "defines.h" /* UNIX */
|
||||
#include "names.h" /* BINDABLE() */
|
||||
#include "utf8.h" /* unicode_t */
|
||||
|
||||
#define MINROWS 3
|
||||
#define MINCOLS 10
|
||||
|
||||
extern int mpresf ; /* Stuff in message line */
|
||||
extern int scrollcount ; /* number of lines to scroll */
|
||||
extern int discmd ; /* display command flag */
|
||||
@ -15,13 +18,17 @@ extern int disinp ; /* display input characters (echo) */
|
||||
extern int gfcolor ; /* global forgrnd color (white) */
|
||||
extern int gbcolor ; /* global backgrnd color (black) */
|
||||
|
||||
/* global variables */
|
||||
extern boolean viewtab ; /* $viewtab = TRUE to visualize hardcoded tab */
|
||||
|
||||
/* Bindable functions */
|
||||
BINDABLE( upscreen) ;
|
||||
TBINDABLE( upscreen) ;
|
||||
|
||||
void vtinit( void) ;
|
||||
void vtfree( void) ;
|
||||
void vttidy( void) ;
|
||||
boolean update( boolean force_f) ;
|
||||
void update( boolean force_f) ;
|
||||
void updmargin( void) ;
|
||||
void upmode( void) ;
|
||||
void movecursor( int row, int col) ;
|
||||
void mlerase( void) ;
|
||||
@ -37,8 +44,6 @@ void getscreensize( int *widthp, int *heightp) ;
|
||||
# include <signal.h>
|
||||
# ifdef SIGWINCH
|
||||
extern int chg_width, chg_height ;
|
||||
|
||||
void sizesignal( int signr) ;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
12
emacs.hlp
12
emacs.hlp
@ -19,7 +19,7 @@
|
||||
-------------------------------------------------------------------------------
|
||||
=> THE VERY BASICS
|
||||
Notations: ^X means <Ctrl> and X. The <Meta> key is <Esc> on most systems.
|
||||
Exiting: ^G aborts almost any operation. ^X ^C will get you out of uEmacs.
|
||||
Exiting: ^G aborts almost any operation. ^X ^C will get you out of µEMACS.
|
||||
|
||||
A BUFFER is a named area containing a FILE being edited. Many buffers may
|
||||
be active at once. Many WINDOWS may be active at once on the screen. All
|
||||
@ -37,7 +37,7 @@ Beginning of file ..... Meta < End of file ........... Meta >
|
||||
-------------------------------------------------------------------------------
|
||||
=> FILE COMMANDS
|
||||
Find file ............. ^X ^F Quick exit ............ Meta Z
|
||||
View file ............. ^X ^V Exit emacs ............ ^X ^C
|
||||
View file ............. ^X ^V Exit µEMACS ........... ^X ^C
|
||||
Insert file ........... ^X ^I
|
||||
Change file name ...... ^X N Filter buffer ......... ^X #
|
||||
Save file ............. ^X ^D
|
||||
@ -118,12 +118,12 @@ Query replace string .. Meta ^R :: Yes/no Y/N, replace rest !, cancel ^G.
|
||||
-------------------------------------------------------------------------------
|
||||
=> ACCESSING THE OPERATING SYSTEM
|
||||
Quick exit ............ Meta Z :: Write out all changed buffers and exit.
|
||||
Exit emacs ............ ^X ^C :: Exit without automatic save.
|
||||
Exit µEMACS ........... ^X ^C :: Exit without automatic save.
|
||||
I shell ............... ^X C :: Start a new command processor.
|
||||
Shell command ......... ^X ! :: Execute one operating system command.
|
||||
Pipe command .......... ^X @ :: Pipe command results to a new buffer. *
|
||||
Filter buffer ......... ^X # :: Filter buffer through a program. *
|
||||
Execute program ....... ^X $ :: * Not under VMS.
|
||||
Pipe command .......... ^X @ :: Pipe command results to a new buffer.
|
||||
Filter buffer ......... ^X # :: Filter buffer through a program.
|
||||
Execute program ....... ^X $ ::
|
||||
-------------------------------------------------------------------------------
|
||||
=> MACRO COMMANDS
|
||||
Begin macro ........... ^X (
|
||||
|
296
emacs.rc
296
emacs.rc
@ -1,113 +1,51 @@
|
||||
; EMACS.RC / .emacsrc
|
||||
; .emacsrc -- Startup file for µEMACS 4.2
|
||||
;
|
||||
; Startup file for MicroEMACS 3.9 and uEmacs/PK 4.0
|
||||
; This file is executed every time the editor is entered.
|
||||
;
|
||||
; Modified by Petri Kutvonen, last edited September 1991.
|
||||
|
||||
set $discmd "FALSE"
|
||||
set $discmd FALSE
|
||||
!if ¬ &seq $progname µEMACS
|
||||
; uemacs/PK and MicroEMACS
|
||||
set $discmd TRUE
|
||||
!return
|
||||
!endif
|
||||
|
||||
!if &seq $progname "µEMACS"
|
||||
!force execute-file &cat $HOME "/.uerc"
|
||||
set $tab 4
|
||||
# set $viewtab TRUE # uncomment this line if you need to visualize tabs
|
||||
set $fillcol 76
|
||||
|
||||
|
||||
## Help facility
|
||||
!if &seq $TERM cygwin
|
||||
set $scroll FALSE
|
||||
set %F1 FNP #currently not readable
|
||||
set %Home FN1
|
||||
set %End FN4
|
||||
!else
|
||||
|
||||
; First, try to resolve if we are on a PC ... yes, this is a kludge
|
||||
|
||||
!if &seq $sres "NORMAL"
|
||||
set %system "OTHER"
|
||||
!else
|
||||
set %system "PC"
|
||||
set %F1 FNP
|
||||
set %Home FNH
|
||||
set %End FNF
|
||||
!endif
|
||||
|
||||
!if &seq %system "PC"
|
||||
|
||||
; PC specific initialization
|
||||
|
||||
write-message "(Setting up)"
|
||||
|
||||
; Comment out or change this line if you want more than 25 lines,
|
||||
; other possible $sres values include EGA and VGA
|
||||
|
||||
set $sres "CGA"
|
||||
|
||||
; Uncomment next line if your old screen "snows"
|
||||
|
||||
;set $flicker "TRUE"
|
||||
|
||||
; If your screen "snows" you'll not like scrolling
|
||||
|
||||
!if &seq $flicker "TRUE"
|
||||
set $scroll "FALSE"
|
||||
!endif
|
||||
|
||||
; Function keys (unshifted)
|
||||
; f1 f2 f3 f4 f5 f6 f7 f8 f9 f10
|
||||
; FN; FN< FN= FN> FN? FN@ FNA FNB FNC FND
|
||||
|
||||
bind-to-key help FN;
|
||||
bind-to-key exit-emacs FND
|
||||
|
||||
; Function keys (shifted)
|
||||
; F1 F2 F3 F4 F5 F6 F7 F8 F9 F10
|
||||
; FNT FNU FNV FNW FNX FNY FNZ FN[ FN\ FN]
|
||||
|
||||
; Other special keys (unshifted)
|
||||
; Home End Ins Del PgUp PgDn
|
||||
; FNG FNO FNR FNS FNI FNQ
|
||||
|
||||
; Some common Alt-keys
|
||||
; Alt-X Alt-Z Alt-C Alt-F Alt-O
|
||||
; FN- FN, FN. FN! FN^X
|
||||
|
||||
bind-to-key exit-emacs FN-
|
||||
bind-to-key quick-exit FN,
|
||||
bind-to-key i-shell FN.
|
||||
bind-to-key find-file FN!
|
||||
bind-to-key view-file FN/
|
||||
bind-to-key next-window FN^X
|
||||
|
||||
; Set screen colors
|
||||
|
||||
; You can define a DOS environment variable EMACS_BW (any value)
|
||||
; if you don't like colors, e.g. if you have a LCD screen
|
||||
|
||||
!if &seq &env "EMACS_BW" ""
|
||||
add-global-mode "blue"
|
||||
add-global-mode "HIGH"
|
||||
!endif
|
||||
|
||||
!endif
|
||||
|
||||
; Help facility
|
||||
|
||||
40 store-macro
|
||||
set $discmd "FALSE"
|
||||
!store 40
|
||||
set $discmd FALSE
|
||||
!if ¬ &seq $cbufname "emacs.hlp"
|
||||
write-message "(Loading Help)"
|
||||
!force help
|
||||
!force 8 resize-window
|
||||
!if &seq %system "PC"
|
||||
!if &seq &env "EMACS_BW" ""
|
||||
add-mode "red"
|
||||
!endif
|
||||
bind-to-key execute-macro-38 FNI
|
||||
bind-to-key execute-macro-37 FNQ
|
||||
!if ¬ &seq $cbufname "emacs.hlp"
|
||||
write-message "(Failed to load Help)"
|
||||
!else
|
||||
bind-to-key execute-macro-38 FN5
|
||||
bind-to-key execute-macro-37 FN6
|
||||
!endif
|
||||
!force 8 resize-window
|
||||
bind-to-key execute-macro-39 FN5
|
||||
bind-to-key execute-macro-38 FN6
|
||||
bind-to-key execute-macro-37 %Home
|
||||
bind-to-key execute-macro-36 %End
|
||||
beginning-of-line
|
||||
2 forward-character
|
||||
1 redraw-display
|
||||
save-window
|
||||
!if &seq %system "PC"
|
||||
set %hlpupdn "<PgUp> / <PgDn>"
|
||||
set %hlphelp "<F1>"
|
||||
!else
|
||||
set %hlpupdn "<Prev Scrn> / <Next Scrn>"
|
||||
set %hlphelp "<Help>"
|
||||
set %hlpupdn "[PgUp] / [PgDn]"
|
||||
set %hlphelp "[F1]"
|
||||
run helponhelp
|
||||
!endif
|
||||
execute-macro-39
|
||||
!else
|
||||
set %hlpcode &lef $line 2
|
||||
!if &seq %hlpcode ".."
|
||||
@ -117,33 +55,29 @@ bind-to-key next-window FN^X
|
||||
beginning-of-line
|
||||
2 forward-character
|
||||
1 redraw-display
|
||||
execute-macro-39
|
||||
!else
|
||||
!if &seq %system "PC"
|
||||
bind-to-key previous-page FNI
|
||||
bind-to-key next-page FNQ
|
||||
run helponhelp
|
||||
!else
|
||||
!force search-reverse "=>"
|
||||
bind-to-key previous-page FN5
|
||||
bind-to-key next-page FN6
|
||||
!endif
|
||||
!force restore-window
|
||||
bind-to-key beginning-of-file %Home
|
||||
bind-to-key end-of-file %End
|
||||
!force delete-window
|
||||
clear-message-line
|
||||
!endif
|
||||
!endif
|
||||
set $discmd "TRUE"
|
||||
set $discmd TRUE
|
||||
!endm
|
||||
|
||||
bind-to-key execute-macro-40 M-?
|
||||
!if &seq %system "PC"
|
||||
bind-to-key execute-macro-40 FN;
|
||||
!else
|
||||
bind-to-key execute-macro-40 FNh
|
||||
!endif
|
||||
bind-to-key execute-macro-40 %F1
|
||||
bind-to-key execute-macro-40 M-O
|
||||
bind-to-key beginning-of-file %Home
|
||||
bind-to-key end-of-file %End
|
||||
|
||||
; Help on Help
|
||||
|
||||
39 store-macro
|
||||
## Help on Help
|
||||
!store helponhelp
|
||||
!if &seq &rig $line 5 "INDEX"
|
||||
write-message &cat "Select topic from list and press " %hlphelp
|
||||
!else
|
||||
@ -151,150 +85,72 @@ bind-to-key execute-macro-40 M-?
|
||||
!endif
|
||||
!endm
|
||||
|
||||
; Previous help page
|
||||
|
||||
38 store-macro
|
||||
## Previous help page
|
||||
!store 39
|
||||
!if &seq $cbufname "emacs.hlp"
|
||||
beginning-of-line
|
||||
!force search-reverse "=>"
|
||||
2 forward-character
|
||||
1 redraw-display
|
||||
execute-macro-39
|
||||
run helponhelp
|
||||
!else
|
||||
previous-page
|
||||
!endif
|
||||
!endm
|
||||
|
||||
; Next help page
|
||||
|
||||
37 store-macro
|
||||
## Next help page
|
||||
!store 38
|
||||
!if &seq $cbufname "emacs.hlp"
|
||||
beginning-of-line
|
||||
2 forward-character
|
||||
!force search-forward "=>"
|
||||
1 redraw-display
|
||||
execute-macro-39
|
||||
run helponhelp
|
||||
!else
|
||||
next-page
|
||||
!endif
|
||||
!endm
|
||||
|
||||
; Set up auto CMODE
|
||||
!store 37
|
||||
beginning-of-file
|
||||
!if &seq $cbufname "emacs.hlp"
|
||||
execute-macro-39
|
||||
!endif
|
||||
!endm
|
||||
|
||||
36 store-macro
|
||||
!if &seq &mid $cfname 1 7 "/tmp/Re"
|
||||
add-mode "wrap"
|
||||
!store 36
|
||||
end-of-file
|
||||
!if &seq $cbufname "emacs.hlp"
|
||||
execute-macro-39
|
||||
!endif
|
||||
!endm
|
||||
|
||||
|
||||
## Set up auto CMODE or WRAP
|
||||
!store 35
|
||||
set %rctmp &right $cfname 4
|
||||
!if &or &seq .txt %rctmp &seq .doc %rctmp
|
||||
add-mode wrap
|
||||
!return
|
||||
!endif
|
||||
!if &gre &sin $cfname "/.ed" 0
|
||||
add-mode "wrap"
|
||||
set %rctmp &right %rctmp 2
|
||||
!if &or &seq .c %rctmp &seq .h %rctmp
|
||||
add-mode cmode
|
||||
!return
|
||||
!endif
|
||||
!if &gre &sin $cfname "/.let" 0
|
||||
add-mode "wrap"
|
||||
!return
|
||||
!endif
|
||||
!if &gre &sin $cfname "/.art" 0
|
||||
add-mode "wrap"
|
||||
!return
|
||||
!endif
|
||||
!if &gre &sin $cfname "/nn." 0
|
||||
add-mode "wrap"
|
||||
!return
|
||||
!endif
|
||||
set %rctmp &sin $cfname "."
|
||||
!if &equ %rctmp 0
|
||||
!return
|
||||
!endif
|
||||
set %rctmp &mid $cfname &add %rctmp 1 5
|
||||
!if &or &seq %rctmp "c" &seq %rctmp "h"
|
||||
add-mode "cmode"
|
||||
!endif
|
||||
!if &or &seq %rctmp "txt" &or &seq %rctmp "doc" &or &seq %rctmp "tmp" &seq %rctmp "tex"
|
||||
add-mode "wrap"
|
||||
!endif
|
||||
|
||||
!endm
|
||||
|
||||
bind-to-key execute-macro-36 M-FNR
|
||||
bind-to-key execute-macro-35 M-FNR
|
||||
|
||||
; Setup for ASCII {|}[\] to ISO Latin-1 translation
|
||||
|
||||
21 store-macro
|
||||
insert-string "ä"
|
||||
!endm
|
||||
22 store-macro
|
||||
insert-string "ö"
|
||||
!endm
|
||||
23 store-macro
|
||||
insert-string "å"
|
||||
!endm
|
||||
24 store-macro
|
||||
insert-string "Ä"
|
||||
!endm
|
||||
25 store-macro
|
||||
insert-string "Ö"
|
||||
!endm
|
||||
26 store-macro
|
||||
insert-string "Å"
|
||||
!endm
|
||||
|
||||
27 store-macro
|
||||
bind-to-key execute-macro-21 {
|
||||
bind-to-key execute-macro-22 |
|
||||
bind-to-key execute-macro-23 }
|
||||
bind-to-key execute-macro-24 [
|
||||
bind-to-key execute-macro-25 \
|
||||
bind-to-key execute-macro-26 ]
|
||||
write-message "ISO Latin-1 äöåÄÖÅ"
|
||||
!endm
|
||||
|
||||
28 store-macro
|
||||
unbind-key {
|
||||
unbind-key |
|
||||
unbind-key }
|
||||
unbind-key [
|
||||
unbind-key \
|
||||
unbind-key ]
|
||||
write-message "ASCII {|}[\]"
|
||||
!endm
|
||||
|
||||
bind-to-key execute-macro-27 ^X[
|
||||
bind-to-key execute-macro-28 ^X]
|
||||
|
||||
; Make cut-paste easier in window systems
|
||||
|
||||
## Make cut-paste easier in window systems
|
||||
bind-to-key newline ^J
|
||||
|
||||
; uEmacs/PK specific initialization
|
||||
|
||||
!if &seq $progname "uEmacs/PK"
|
||||
|
||||
; Don't scroll on a Sun
|
||||
|
||||
!if &or &seq $TERM "sun" &seq $TERM "sun-cmd"
|
||||
set $scroll "FALSE"
|
||||
!endif
|
||||
|
||||
; Execute local initialization files
|
||||
|
||||
!if &seq %system "PC"
|
||||
!force execute-file "EM.RC"
|
||||
!else
|
||||
!force execute-file &cat $HOME "/.emrc"
|
||||
!force execute-file ".emrc"
|
||||
!endif
|
||||
!endif
|
||||
|
||||
!if &gre &sin $LANG "UTF-8" 0
|
||||
!if &or &sin $LANG "UTF-8" &sin $LANG "utf8"
|
||||
add-global-mode "utf-8"
|
||||
!endif
|
||||
|
||||
!if &gre &sin $LANG "utf8" 0
|
||||
add-global-mode "utf-8"
|
||||
!endif
|
||||
add-global-mode "utf-8"
|
||||
|
||||
!endif
|
||||
|
||||
set $discmd "TRUE"
|
||||
set $discmd TRUE
|
||||
|
135
estruct.h
135
estruct.h
@ -1,135 +0,0 @@
|
||||
/* estruct.h -- */
|
||||
#ifndef _ESTRUCT_H_
|
||||
#define _ESTRUCT_H_
|
||||
|
||||
/* Structure and preprocessor defines
|
||||
*
|
||||
* written by Dave G. Conroy
|
||||
* modified by Steve Wilhite, George Jones
|
||||
* substantially modified by Daniel Lawrence
|
||||
* modified by Petri Kutvonen
|
||||
*/
|
||||
|
||||
#ifdef MSDOS
|
||||
# undef MSDOS
|
||||
#endif
|
||||
|
||||
/* Machine/OS definitions. */
|
||||
|
||||
#if defined(AUTOCONF) || defined(BSD) || defined(SYSV)
|
||||
|
||||
/* Make an intelligent guess about the target system. */
|
||||
|
||||
# if defined(BSD) || defined(sun) || defined(ultrix) || defined(__osf__)
|
||||
# ifndef BSD
|
||||
# define BSD 1 /* Berkeley UNIX */
|
||||
# endif
|
||||
# else
|
||||
# define BSD 0
|
||||
# endif
|
||||
|
||||
# if defined(SVR4) || defined(__linux__) /* ex. SunOS 5.3 */
|
||||
# define SVR4 1
|
||||
# define SYSV 1
|
||||
# undef BSD
|
||||
# endif
|
||||
|
||||
# if defined(SYSV) || defined(u3b2) || defined(_AIX) || (defined(i386) && defined(unix)) || defined( __unix__)
|
||||
# define USG 1 /* System V UNIX */
|
||||
# else
|
||||
# define USG 0
|
||||
# endif
|
||||
|
||||
#else
|
||||
# define BSD 0 /* UNIX BSD 4.2 and ULTRIX */
|
||||
# define USG 1 /* UNIX system V */
|
||||
#endif /*autoconf || BSD || SYSV */
|
||||
|
||||
#define MSDOS 0 /* MS-DOS */
|
||||
|
||||
/* Compiler definitions */
|
||||
#ifndef AUTOCONF
|
||||
# define UNIX 1 /* a random UNIX compiler */
|
||||
#else
|
||||
# define UNIX (BSD | USG)
|
||||
#endif /*autoconf */
|
||||
|
||||
/* Debugging options */
|
||||
|
||||
#define RAMSIZE 0 /* dynamic RAM memory usage tracking */
|
||||
#if RAMSIZE
|
||||
# define RAMSHOW 1 /* auto dynamic RAM reporting */
|
||||
#endif
|
||||
|
||||
#ifndef AUTOCONF
|
||||
/* Terminal Output definitions */
|
||||
# define TERMCAP 0 /* Use TERMCAP */
|
||||
# define IBMPC 1 /* IBM-PC CGA/MONO/EGA driver */
|
||||
#else
|
||||
# define TERMCAP UNIX
|
||||
# define IBMPC MSDOS
|
||||
#endif /* Autoconf. */
|
||||
|
||||
/* Configuration options */
|
||||
|
||||
#define VISMAC 0 /* update display during keyboard macros */
|
||||
|
||||
#ifndef AUTOCONF
|
||||
# define COLOR 1 /* color commands and windows */
|
||||
# define FILOCK 0 /* file locking under unix BSD 4.2 */
|
||||
#else
|
||||
# define COLOR MSDOS
|
||||
# ifdef SVR4
|
||||
# define FILOCK 1
|
||||
# else
|
||||
# define FILOCK BSD
|
||||
# endif
|
||||
#endif /* Autoconf. */
|
||||
|
||||
#define CLEAN 0 /* de-alloc memory on exit */
|
||||
|
||||
#ifndef AUTOCONF
|
||||
# define XONXOFF 0 /* don't disable XON-XOFF flow control P.K. */
|
||||
#else
|
||||
# define XONXOFF UNIX
|
||||
#endif /* Autoconf. */
|
||||
|
||||
#define PKCODE 1 /* include my extensions P.K., define always */
|
||||
#define SCROLLCODE 1 /* scrolling code P.K. */
|
||||
|
||||
/* Define some ability flags. */
|
||||
|
||||
#if IBMPC
|
||||
# define MEMMAP 1
|
||||
#else
|
||||
# define MEMMAP 0
|
||||
#endif
|
||||
|
||||
#if USG | BSD
|
||||
# define ENVFUNC 1
|
||||
#else
|
||||
# define ENVFUNC 0
|
||||
#endif
|
||||
|
||||
/* Dynamic RAM tracking and reporting redefinitions */
|
||||
|
||||
#if RAMSIZE
|
||||
# include <stdlib.h>
|
||||
void *allocate( size_t size) ;
|
||||
void release( void *ptr) ;
|
||||
# define malloc allocate
|
||||
# define free release
|
||||
#endif
|
||||
|
||||
/* De-allocate memory always on exit (if the operating system or
|
||||
main program can not
|
||||
*/
|
||||
|
||||
#if CLEAN
|
||||
# define exit(a) cexit(a)
|
||||
|
||||
void cexit( int status) ;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* end of estruct.h */
|
550
eval.c
550
eval.c
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
@ -16,8 +15,8 @@
|
||||
#include "basic.h"
|
||||
#include "bind.h"
|
||||
#include "buffer.h"
|
||||
#include "defines.h"
|
||||
#include "display.h"
|
||||
#include "estruct.h"
|
||||
#include "exec.h"
|
||||
#include "execute.h"
|
||||
#include "flook.h"
|
||||
@ -31,8 +30,6 @@
|
||||
#include "version.h"
|
||||
#include "window.h"
|
||||
|
||||
#define MAXVARS 255
|
||||
|
||||
/* Macro argument token types */
|
||||
|
||||
#define TKNUL 0 /* end-of-string */
|
||||
@ -47,7 +44,6 @@
|
||||
#define TKSTR 9 /* quoted string literal */
|
||||
#define TKCMD 10 /* command name */
|
||||
|
||||
static int gettyp( char *token) ;
|
||||
|
||||
/* Emacs global flag bit definitions (for gflags). */
|
||||
/* if GFREAD is set, current buffer will be set on first file (read in) */
|
||||
@ -68,17 +64,19 @@ int rval = 0 ; /* return value of a subprocess */
|
||||
static int saveflag = 0 ; /* Flags, saved with the $target var */
|
||||
|
||||
|
||||
long envram = 0l ; /* # of bytes current in use by malloc */
|
||||
unsigned envram = 0 ; /* # of bytes current in use by malloc */
|
||||
|
||||
|
||||
/* Max #chars in a var name. */
|
||||
#define NVSIZE 10
|
||||
/* User variables ******************************************/
|
||||
#define MAXVARS 255
|
||||
#define NVSIZE 10 /* Max #chars in a var name. */
|
||||
|
||||
/* Structure to hold user variables and their definitions. */
|
||||
struct user_variable {
|
||||
char u_name[NVSIZE + 1]; /* name of user variable */
|
||||
char *u_value; /* value (string) */
|
||||
};
|
||||
static struct {
|
||||
char u_name[ NVSIZE + 1] ; /* name of user variable */
|
||||
char *u_value ; /* value (string) */
|
||||
} uv[ MAXVARS + 1] ;
|
||||
|
||||
|
||||
static char errorm[] = "ERROR" ; /* error literal */
|
||||
|
||||
@ -129,6 +127,7 @@ static const char *envars[] = {
|
||||
"rval", /* child process return value */
|
||||
"tab", /* tab width, 1... */
|
||||
"hardtab", /* TRUE for hard coded tab, FALSE for soft ones */
|
||||
"viewtab", /* TRUE to visualize hard coded tabs */
|
||||
"overlap",
|
||||
"jump",
|
||||
#if SCROLLCODE
|
||||
@ -136,7 +135,7 @@ static const char *envars[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
/* And its preprocesor definitions. */
|
||||
/* And its preprocessor definitions. */
|
||||
|
||||
#define EVFILLCOL 0
|
||||
#define EVPAGELEN 1
|
||||
@ -177,9 +176,10 @@ static const char *envars[] = {
|
||||
#define EVRVAL 36
|
||||
#define EVTAB 37
|
||||
#define EVHARDTAB 38
|
||||
#define EVOVERLAP 39
|
||||
#define EVSCROLLCOUNT 40
|
||||
#define EVSCROLL 41
|
||||
#define EVVIEWTAB 39
|
||||
#define EVOVERLAP 40
|
||||
#define EVSCROLLCOUNT 41
|
||||
#define EVSCROLL 42
|
||||
|
||||
enum function_type {
|
||||
NILNAMIC = 0,
|
||||
@ -188,6 +188,9 @@ enum function_type {
|
||||
TRINAMIC = (3 << 6)
|
||||
} ;
|
||||
|
||||
#define ARGCOUNT( ft) (ft >> 6)
|
||||
#define FUNID( ft) (ft & ((1 << 6) - 1))
|
||||
|
||||
enum function_code {
|
||||
UFADD = 0, UFSUB, UFTIMES, UFDIV, UFMOD, UFNEG,
|
||||
UFCAT, UFLEFT, UFRIGHT, UFMID, UFNOT, UFEQUAL,
|
||||
@ -202,7 +205,7 @@ enum function_code {
|
||||
static struct {
|
||||
const char f_name[ 4] ;
|
||||
const int f_type ;
|
||||
} funcs[] = {
|
||||
} const funcs[] = {
|
||||
{ "abs", UFABS | MONAMIC }, /* absolute value of a number */
|
||||
{ "add", UFADD | DYNAMIC }, /* add two numbers together */
|
||||
{ "and", UFAND | DYNAMIC }, /* logical and */
|
||||
@ -212,7 +215,7 @@ static struct {
|
||||
{ "bno", UFBNOT | MONAMIC }, /* bitwise not */
|
||||
{ "bor", UFBOR | DYNAMIC }, /* bitwise or 9-10-87 jwm */
|
||||
{ "bxo", UFBXOR | DYNAMIC }, /* bitwise xor 9-10-87 jwm */
|
||||
{ "cat", UFCAT | DYNAMIC }, /* concatinate string */
|
||||
{ "cat", UFCAT | DYNAMIC }, /* concatenate string */
|
||||
{ "chr", UFCHR | MONAMIC }, /* integer to char conversion */
|
||||
{ "div", UFDIV | DYNAMIC }, /* division */
|
||||
{ "env", UFENV | MONAMIC }, /* retrieve a system environment var */
|
||||
@ -237,7 +240,7 @@ static struct {
|
||||
{ "sgr", UFSGREAT | DYNAMIC }, /* string logical greater than */
|
||||
{ "sin", UFSINDEX | DYNAMIC }, /* find the index of one string in another */
|
||||
{ "sle", UFSLESS | DYNAMIC }, /* string logical less than */
|
||||
{ "sub", UFSUB | DYNAMIC }, /* subtraction */
|
||||
{ "sub", UFSUB | DYNAMIC }, /* substraction */
|
||||
{ "tim", UFTIMES | DYNAMIC }, /* multiplication */
|
||||
{ "tru", UFTRUTH | MONAMIC }, /* Truth of the universe logical test */
|
||||
{ "upp", UFUPPER | MONAMIC }, /* uppercase string */
|
||||
@ -245,21 +248,18 @@ static struct {
|
||||
} ;
|
||||
|
||||
|
||||
/* User variables */
|
||||
static struct user_variable uv[MAXVARS + 1];
|
||||
|
||||
/* When emacs' command interpetor needs to get a variable's name,
|
||||
* rather than it's value, it is passed back as a variable description
|
||||
* structure. The v_num field is a index into the appropriate variable table.
|
||||
*/
|
||||
struct variable_description {
|
||||
int v_type; /* Type of variable. */
|
||||
int v_num; /* Ordinal pointer to variable in list. */
|
||||
};
|
||||
typedef struct {
|
||||
int v_type ; /* Type of variable. */
|
||||
int v_num ; /* Ordinal pointer to variable in list. */
|
||||
} variable_description ;
|
||||
|
||||
static void findvar( char *var, struct variable_description *vd, int size) ;
|
||||
static int svar( struct variable_description *var, char *value) ;
|
||||
static char *i_to_a( int i) ;
|
||||
static void findvar( char *var, variable_description *vd, int size) ;
|
||||
static int svar( variable_description *var, char *value) ;
|
||||
static const char *i_to_a( int i) ;
|
||||
|
||||
/*
|
||||
* putctext:
|
||||
@ -307,25 +307,22 @@ void varinit(void)
|
||||
seed = time( NULL) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluate a function.
|
||||
|
||||
/* Evaluate a function.
|
||||
*
|
||||
* @fname: name of function to evaluate.
|
||||
*/
|
||||
static const char *gtfun( char *fname) {
|
||||
unsigned fnum ; /* index to function to eval */
|
||||
char *arg1 ; /* value of first argument */
|
||||
char *arg2 ; /* value of second argument */
|
||||
char *arg3 ; /* last argument */
|
||||
char *argv[ 3] ;
|
||||
const char *retstr ; /* return value */
|
||||
int low, high ; /* binary search indexes */
|
||||
int i ;
|
||||
|
||||
/* look the function up in the function table */
|
||||
fname[3] = 0; /* only first 3 chars significant */
|
||||
mklower(fname); /* and let it be upper or lower case */
|
||||
fnum = ARRAY_SIZE( funcs) ;
|
||||
low = 0 ;
|
||||
high = fnum - 1 ;
|
||||
/* look the function up in the function table */
|
||||
fname[ 3] = 0 ; /* only first 3 chars significant */
|
||||
mklower( fname) ; /* and let it be upper or lower case */
|
||||
unsigned fnum = ARRAY_SIZE( funcs) ; /* index to function to eval */
|
||||
int low = 0 ; /* binary search low bound */
|
||||
int high = fnum - 1 ; /* binary search high bound */
|
||||
do {
|
||||
int s, cur ;
|
||||
|
||||
@ -340,92 +337,70 @@ static const char *gtfun( char *fname) {
|
||||
low = cur + 1 ;
|
||||
} while( low <= high) ;
|
||||
|
||||
/* return errorm on a bad reference */
|
||||
if (fnum == ARRAY_SIZE(funcs))
|
||||
return errorm;
|
||||
/* return errorm on a bad reference */
|
||||
if( fnum == ARRAY_SIZE( funcs))
|
||||
return errorm ;
|
||||
|
||||
arg1 = arg2 = arg3 = NULL ;
|
||||
/* fetch arguments */
|
||||
assert( clexec == TRUE) ; /* means macarg can be replaced by gettokval */
|
||||
/* if needed, retrieve the first argument */
|
||||
if (funcs[fnum].f_type >= MONAMIC) {
|
||||
arg1 = getnewtokval() ;
|
||||
if( arg1 == NULL)
|
||||
return errorm;
|
||||
int argc = ARGCOUNT( funcs[ fnum].f_type) ;
|
||||
for( int i = 0 ; i < argc ; i++) {
|
||||
argv[ i] = getnewtokval() ;
|
||||
if( argv[ i] == NULL) {
|
||||
while( i > 0)
|
||||
free( argv[ --i]) ;
|
||||
|
||||
/* if needed, retrieve the second argument */
|
||||
if (funcs[fnum].f_type >= DYNAMIC) {
|
||||
arg2 = getnewtokval() ;
|
||||
if( arg2 == NULL) {
|
||||
free( arg1) ;
|
||||
return errorm;
|
||||
}
|
||||
|
||||
/* if needed, retrieve the third argument */
|
||||
if (funcs[fnum].f_type >= TRINAMIC) {
|
||||
arg3 = getnewtokval() ;
|
||||
if( arg3 == NULL) {
|
||||
free( arg1) ;
|
||||
free( arg2) ;
|
||||
return errorm;
|
||||
}
|
||||
}
|
||||
return errorm ;
|
||||
}
|
||||
}
|
||||
|
||||
/* and now evaluate it! */
|
||||
switch( funcs[ fnum].f_type) {
|
||||
int sz ;
|
||||
/* and now evaluate it! */
|
||||
switch( FUNID( funcs[ fnum].f_type)) {
|
||||
int sz, sz1 ;
|
||||
unicode_t c ;
|
||||
|
||||
case UFADD | DYNAMIC:
|
||||
retstr = i_to_a( atoi( arg1) + atoi( arg2)) ;
|
||||
case UFADD:
|
||||
retstr = i_to_a( atoi( argv[ 0]) + atoi( argv[ 1])) ;
|
||||
break ;
|
||||
case UFSUB | DYNAMIC:
|
||||
retstr = i_to_a( atoi( arg1) - atoi( arg2)) ;
|
||||
case UFSUB:
|
||||
retstr = i_to_a( atoi( argv[ 0]) - atoi( argv[ 1])) ;
|
||||
break ;
|
||||
case UFTIMES | DYNAMIC:
|
||||
retstr = i_to_a( atoi( arg1) * atoi( arg2)) ;
|
||||
case UFTIMES:
|
||||
retstr = i_to_a( atoi( argv[ 0]) * atoi( argv[ 1])) ;
|
||||
break ;
|
||||
case UFDIV | DYNAMIC:
|
||||
sz = atoi( arg2) ;
|
||||
retstr = (sz == 0) ? errorm : i_to_a( atoi( arg1) / sz) ;
|
||||
case UFDIV:
|
||||
sz = atoi( argv[ 1]) ;
|
||||
retstr = (sz == 0) ? errorm : i_to_a( atoi( argv[ 0]) / sz) ;
|
||||
break ;
|
||||
case UFMOD | DYNAMIC:
|
||||
sz = atoi( arg2) ;
|
||||
retstr = (sz == 0) ? errorm : i_to_a( atoi( arg1) % sz) ;
|
||||
case UFMOD:
|
||||
sz = atoi( argv[ 1]) ;
|
||||
retstr = (sz == 0) ? errorm : i_to_a( atoi( argv[ 0]) % sz) ;
|
||||
break ;
|
||||
case UFNEG | MONAMIC:
|
||||
retstr = i_to_a( -atoi( arg1)) ;
|
||||
case UFNEG:
|
||||
retstr = i_to_a( -atoi( argv[ 0])) ;
|
||||
break ;
|
||||
case UFCAT | DYNAMIC: {
|
||||
int sz1 ;
|
||||
|
||||
sz1 = strlen( arg1) ;
|
||||
sz = sz1 + strlen( arg2) + 1 ;
|
||||
case UFCAT:
|
||||
sz1 = strlen( argv[ 0]) ;
|
||||
sz = sz1 + strlen( argv[ 1]) + 1 ;
|
||||
if( sz > ressize) {
|
||||
free( result) ;
|
||||
result = malloc( sz) ;
|
||||
ressize = sz ;
|
||||
}
|
||||
|
||||
strcpy( result, arg1) ;
|
||||
strcpy( &result[ sz1], arg2) ;
|
||||
strcpy( result, argv[ 0]) ;
|
||||
strcpy( &result[ sz1], argv[ 1]) ;
|
||||
retstr = result ;
|
||||
}
|
||||
break ;
|
||||
case UFLEFT | DYNAMIC: {
|
||||
int sz1, i ;
|
||||
|
||||
sz1 = strlen( arg1) ;
|
||||
case UFLEFT:
|
||||
sz1 = strlen( argv[ 0]) ;
|
||||
sz = 0 ;
|
||||
for( i = atoi( arg2) ; i > 0 ; i -= 1) {
|
||||
for( int i = atoi( argv[ 1]) ; i > 0 ; i -= 1) {
|
||||
unicode_t c ;
|
||||
int bytc ;
|
||||
|
||||
bytc = utf8_to_unicode( arg1, sz, sz1, &c) ;
|
||||
if( bytc == 0)
|
||||
sz += utf8_to_unicode( argv[ 0], sz, sz1, &c) ;
|
||||
if( sz == sz1)
|
||||
break ;
|
||||
else
|
||||
sz += bytc ;
|
||||
}
|
||||
|
||||
if( sz >= ressize) {
|
||||
@ -434,41 +409,40 @@ static const char *gtfun( char *fname) {
|
||||
ressize = sz + 1 ;
|
||||
}
|
||||
|
||||
mystrscpy( result, arg1, sz + 1) ;
|
||||
mystrscpy( result, argv[ 0], sz + 1) ;
|
||||
retstr = result ;
|
||||
}
|
||||
break ;
|
||||
case UFRIGHT | DYNAMIC:
|
||||
sz = atoi( arg2) ;
|
||||
case UFRIGHT:
|
||||
sz = strlen( argv[ 0]) ;
|
||||
for( sz1 = atoi( argv[ 1]) ; sz1 > 0 && sz > 0 ; sz1--)
|
||||
if( --sz > 0)
|
||||
sz -= utf8_revdelta( (unsigned char *) &( argv[ 0])[ sz], sz) ;
|
||||
|
||||
retstr = &( argv[ 0])[ sz] ;
|
||||
sz = strlen( retstr) ;
|
||||
if( sz >= ressize) {
|
||||
free( result) ;
|
||||
result = malloc( sz + 1) ;
|
||||
ressize = sz + 1 ;
|
||||
result = malloc( ressize) ;
|
||||
}
|
||||
|
||||
retstr = strcpy( result, &arg1[ strlen( arg1) - sz]) ;
|
||||
retstr = strcpy( result, retstr) ;
|
||||
break ;
|
||||
case UFMID | TRINAMIC: {
|
||||
int sz1, start, i, bytc ;
|
||||
unicode_t c ;
|
||||
|
||||
sz1 = strlen( arg1) ;
|
||||
start = 0 ;
|
||||
for( i = atoi( arg2) - 1 ; i > 0 ; i -= 1) {
|
||||
bytc = utf8_to_unicode( arg1, start, sz1, &c) ;
|
||||
if( bytc == 0)
|
||||
case UFMID:
|
||||
sz1 = strlen( argv[ 0]) ;
|
||||
int start = 0 ;
|
||||
for( i = atoi( argv[ 1]) - 1 ; i > 0 ; i -= 1) {
|
||||
start += utf8_to_unicode( argv[ 0], start, sz1, &c) ;
|
||||
if( start == sz1)
|
||||
break ;
|
||||
else
|
||||
start += bytc ;
|
||||
}
|
||||
|
||||
sz = start ;
|
||||
for( i = atoi( arg3) ; i > 0 ; i -= 1) {
|
||||
bytc = utf8_to_unicode( arg1, sz, sz1, &c) ;
|
||||
if( bytc == 0)
|
||||
if( sz < sz1)
|
||||
for( i = atoi( argv[ 2]) ; i > 0 ; i -= 1) {
|
||||
sz += utf8_to_unicode( argv[ 0], sz, sz1, &c) ;
|
||||
if( sz == sz1)
|
||||
break ;
|
||||
else
|
||||
sz += bytc ;
|
||||
}
|
||||
|
||||
sz -= start ;
|
||||
@ -478,33 +452,32 @@ static const char *gtfun( char *fname) {
|
||||
ressize = sz + 1 ;
|
||||
}
|
||||
|
||||
mystrscpy( result, &arg1[ start], sz + 1) ;
|
||||
mystrscpy( result, &(argv[ 0][ start]), sz + 1) ;
|
||||
retstr = result ;
|
||||
}
|
||||
break ;
|
||||
case UFNOT | MONAMIC:
|
||||
retstr = ltos( stol( arg1) == FALSE) ;
|
||||
case UFNOT:
|
||||
retstr = ltos( stol( argv[ 0]) == FALSE) ;
|
||||
break ;
|
||||
case UFEQUAL | DYNAMIC:
|
||||
retstr = ltos( atoi( arg1) == atoi( arg2)) ;
|
||||
case UFEQUAL:
|
||||
retstr = ltos( atoi( argv[ 0]) == atoi( argv[ 1])) ;
|
||||
break ;
|
||||
case UFLESS | DYNAMIC:
|
||||
retstr = ltos( atoi( arg1) < atoi( arg2)) ;
|
||||
case UFLESS:
|
||||
retstr = ltos( atoi( argv[ 0]) < atoi( argv[ 1])) ;
|
||||
break ;
|
||||
case UFGREATER | DYNAMIC:
|
||||
retstr = ltos( atoi( arg1) > atoi( arg2)) ;
|
||||
case UFGREATER:
|
||||
retstr = ltos( atoi( argv[ 0]) > atoi( argv[ 1])) ;
|
||||
break ;
|
||||
case UFSEQUAL | DYNAMIC:
|
||||
retstr = ltos( strcmp( arg1, arg2) == 0) ;
|
||||
case UFSEQUAL:
|
||||
retstr = ltos( strcmp( argv[ 0], argv[ 1]) == 0) ;
|
||||
break ;
|
||||
case UFSLESS | DYNAMIC:
|
||||
retstr = ltos( strcmp( arg1, arg2) < 0) ;
|
||||
case UFSLESS:
|
||||
retstr = ltos( strcmp( argv[ 0], argv[ 1]) < 0) ;
|
||||
break ;
|
||||
case UFSGREAT | DYNAMIC:
|
||||
retstr = ltos( strcmp( arg1, arg2) > 0) ;
|
||||
case UFSGREAT:
|
||||
retstr = ltos( strcmp( argv[ 0], argv[ 1]) > 0) ;
|
||||
break ;
|
||||
case UFIND | MONAMIC:
|
||||
retstr = getval( arg1) ;
|
||||
case UFIND:
|
||||
retstr = getval( argv[ 0]) ;
|
||||
sz = strlen( retstr) + 1 ;
|
||||
if( sz > ressize) {
|
||||
free( result) ;
|
||||
@ -514,51 +487,45 @@ static const char *gtfun( char *fname) {
|
||||
|
||||
retstr = strcpy( result, retstr) ;
|
||||
break ;
|
||||
case UFAND | DYNAMIC:
|
||||
retstr = ltos( stol( arg1) && stol( arg2)) ;
|
||||
case UFAND:
|
||||
retstr = ltos( stol( argv[ 0]) && stol( argv[ 1])) ;
|
||||
break ;
|
||||
case UFOR | DYNAMIC:
|
||||
retstr = ltos( stol( arg1) || stol( arg2)) ;
|
||||
case UFOR:
|
||||
retstr = ltos( stol( argv[ 0]) || stol( argv[ 1])) ;
|
||||
break ;
|
||||
case UFLENGTH | MONAMIC:
|
||||
retstr = i_to_a( strlen( arg1)) ;
|
||||
case UFLENGTH:
|
||||
retstr = i_to_a( strlen( argv[ 0])) ;
|
||||
break ;
|
||||
case UFUPPER | MONAMIC:
|
||||
sz = strlen( arg1) ;
|
||||
case UFUPPER:
|
||||
sz = strlen( argv[ 0]) ;
|
||||
if( sz >= ressize) {
|
||||
free( result) ;
|
||||
result = malloc( sz + 1) ;
|
||||
ressize = sz + 1 ;
|
||||
}
|
||||
|
||||
retstr = mkupper( result, arg1) ;
|
||||
retstr = mkupper( result, argv[ 0]) ;
|
||||
break ;
|
||||
case UFLOWER | MONAMIC:
|
||||
sz = strlen( arg1) ;
|
||||
case UFLOWER:
|
||||
sz = strlen( argv[ 0]) ;
|
||||
if( sz >= ressize) {
|
||||
free( result) ;
|
||||
result = malloc( sz + 1) ;
|
||||
ressize = sz + 1 ;
|
||||
}
|
||||
|
||||
strcpy( result, arg1) ; /* result is at least as long as arg1 */
|
||||
strcpy( result, argv[ 0]) ; /* result is at least as long as argv[ 0] */
|
||||
retstr = mklower( result) ;
|
||||
break ;
|
||||
case UFTRUTH | MONAMIC:
|
||||
retstr = ltos( atoi( arg1) == 42) ;
|
||||
case UFTRUTH:
|
||||
retstr = ltos( atoi( argv[ 0]) == 42) ;
|
||||
break ;
|
||||
case UFASCII | MONAMIC: {
|
||||
unicode_t c ;
|
||||
|
||||
utf8_to_unicode( arg1, 0, 4, &c) ;
|
||||
case UFASCII:
|
||||
utf8_to_unicode( argv[ 0], 0, 4, &c) ;
|
||||
retstr = i_to_a( c) ;
|
||||
}
|
||||
|
||||
break ;
|
||||
case UFCHR | MONAMIC: {
|
||||
unicode_t c ;
|
||||
|
||||
c = atoi( arg1) ;
|
||||
case UFCHR:
|
||||
c = atoi( argv[ 0]) ;
|
||||
if( c > 0x10FFFF)
|
||||
retstr = errorm ;
|
||||
else {
|
||||
@ -566,71 +533,63 @@ static const char *gtfun( char *fname) {
|
||||
result[ sz] = 0 ;
|
||||
retstr = result ;
|
||||
}
|
||||
}
|
||||
|
||||
break ;
|
||||
case UFGTKEY | NILNAMIC:
|
||||
case UFGTKEY:
|
||||
result[0] = tgetc();
|
||||
result[1] = 0;
|
||||
retstr = result ;
|
||||
break ;
|
||||
case UFRND | MONAMIC:
|
||||
retstr = i_to_a( ernd( atoi( arg1))) ;
|
||||
case UFRND:
|
||||
retstr = i_to_a( ernd( atoi( argv[ 0]))) ;
|
||||
break ;
|
||||
case UFABS | MONAMIC:
|
||||
retstr = i_to_a( abs( atoi( arg1))) ;
|
||||
case UFABS:
|
||||
retstr = i_to_a( abs( atoi( argv[ 0]))) ;
|
||||
break ;
|
||||
case UFSINDEX | DYNAMIC:
|
||||
retstr = i_to_a( sindex( arg1, arg2)) ;
|
||||
case UFSINDEX:
|
||||
retstr = i_to_a( sindex( argv[ 0], argv[ 1])) ;
|
||||
break ;
|
||||
case UFENV | MONAMIC:
|
||||
case UFENV:
|
||||
#if ENVFUNC
|
||||
retstr = getenv( arg1) ;
|
||||
retstr = getenv( argv[ 0]) ;
|
||||
if( retstr == NULL)
|
||||
retstr = "" ;
|
||||
#else
|
||||
retstr = "" ;
|
||||
#endif
|
||||
retstr = "" ;
|
||||
|
||||
break ;
|
||||
case UFBIND | MONAMIC:
|
||||
retstr = transbind( arg1) ;
|
||||
case UFBIND:
|
||||
retstr = transbind( argv[ 0]) ;
|
||||
break ;
|
||||
case UFEXIST | MONAMIC:
|
||||
retstr = ltos( fexist( arg1)) ;
|
||||
case UFEXIST:
|
||||
retstr = ltos( fexist( argv[ 0])) ;
|
||||
break ;
|
||||
case UFFIND | MONAMIC:
|
||||
retstr = flook( arg1, TRUE) ;
|
||||
case UFFIND:
|
||||
retstr = flook( argv[ 0], TRUE) ;
|
||||
if( retstr == NULL)
|
||||
retstr = "" ;
|
||||
break ;
|
||||
case UFBAND | DYNAMIC:
|
||||
retstr = i_to_a( atoi( arg1) & atoi( arg2)) ;
|
||||
case UFBAND:
|
||||
retstr = i_to_a( atoi( argv[ 0]) & atoi( argv[ 1])) ;
|
||||
break ;
|
||||
case UFBOR | DYNAMIC:
|
||||
retstr = i_to_a( atoi( arg1) | atoi( arg2)) ;
|
||||
case UFBOR:
|
||||
retstr = i_to_a( atoi( argv[ 0]) | atoi( argv[ 1])) ;
|
||||
break ;
|
||||
case UFBXOR | DYNAMIC:
|
||||
retstr = i_to_a( atoi( arg1) ^ atoi( arg2)) ;
|
||||
case UFBXOR:
|
||||
retstr = i_to_a( atoi( argv[ 0]) ^ atoi( argv[ 1])) ;
|
||||
break ;
|
||||
case UFBNOT | MONAMIC:
|
||||
retstr = i_to_a( ~atoi( arg1)) ;
|
||||
case UFBNOT:
|
||||
retstr = i_to_a( ~atoi( argv[ 0])) ;
|
||||
break ;
|
||||
case UFXLATE | TRINAMIC:
|
||||
retstr = xlat( arg1, arg2, arg3) ;
|
||||
case UFXLATE:
|
||||
retstr = xlat( argv[ 0], argv[ 1], argv[ 2]) ;
|
||||
break ;
|
||||
default:
|
||||
assert( FALSE) ; /* never should get here */
|
||||
retstr = errorm ;
|
||||
}
|
||||
|
||||
if( arg3)
|
||||
free( arg3) ;
|
||||
|
||||
if( arg2)
|
||||
free( arg2) ;
|
||||
|
||||
if( arg1)
|
||||
free( arg1) ;
|
||||
while( argc > 0)
|
||||
free( argv[ --argc]) ;
|
||||
|
||||
return retstr ;
|
||||
}
|
||||
@ -656,33 +615,55 @@ static char *gtusr( char *vname) {
|
||||
return errorm;
|
||||
}
|
||||
|
||||
/*
|
||||
* gtenv()
|
||||
|
||||
/* 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 */
|
||||
for (vnum = 0; vnum < ARRAY_SIZE(envars); vnum++)
|
||||
if (strcmp(vname, envars[vnum]) == 0)
|
||||
break;
|
||||
for( vnum = 0 ; vnum < ARRAY_SIZE( envars) ; vnum++)
|
||||
if( strcmp( vname, envars[ vnum]) == 0)
|
||||
break ;
|
||||
|
||||
/* return errorm on a bad reference */
|
||||
if (vnum == ARRAY_SIZE(envars))
|
||||
if( vnum == ARRAY_SIZE( envars)) {
|
||||
#if ENVFUNC
|
||||
{
|
||||
char *ename = getenv(vname);
|
||||
|
||||
if (ename != NULL)
|
||||
return ename;
|
||||
else
|
||||
return errorm;
|
||||
}
|
||||
#else
|
||||
return errorm;
|
||||
if( ename != NULL)
|
||||
return ename ;
|
||||
#endif
|
||||
return errorm ;
|
||||
}
|
||||
|
||||
/* otherwise, fetch the appropriate value */
|
||||
switch (vnum) {
|
||||
@ -778,6 +759,8 @@ static char *gtenv( char *vname) {
|
||||
return i_to_a( tabwidth) ;
|
||||
case EVHARDTAB:
|
||||
return ltos( hardtab) ;
|
||||
case EVVIEWTAB:
|
||||
return ltos( viewtab) ;
|
||||
case EVOVERLAP:
|
||||
return i_to_a(overlap);
|
||||
case EVSCROLLCOUNT:
|
||||
@ -803,7 +786,7 @@ static char *gtenv( char *vname) {
|
||||
*/
|
||||
BINDABLE( setvar) {
|
||||
int status; /* status return */
|
||||
struct variable_description vd; /* variable num/type */
|
||||
variable_description vd ; /* variable num/type */
|
||||
char var[NVSIZE + 2]; /* name of variable to fetch %1234567890\0 */
|
||||
char *value ; /* value to set variable to */
|
||||
|
||||
@ -891,7 +874,7 @@ int mdbugout( char *fmt, ...) {
|
||||
* @vd: structure to hold type and pointer.
|
||||
* @size: size of variable array.
|
||||
*/
|
||||
static void findvar(char *var, struct variable_description *vd, int size)
|
||||
static void findvar(char *var, variable_description *vd, int size)
|
||||
{
|
||||
unsigned vnum = 0 ; /* subscript in variable arrays */
|
||||
int vtype; /* type to return */
|
||||
@ -947,7 +930,7 @@ fvar:
|
||||
* @var: variable to set.
|
||||
* @value: value to set to.
|
||||
*/
|
||||
static int svar(struct variable_description *var, char *value)
|
||||
static int svar( variable_description *var, char *value)
|
||||
{
|
||||
int vnum; /* ordinal number of var refrenced */
|
||||
int vtype; /* type of variable to set */
|
||||
@ -1100,6 +1083,9 @@ static int svar(struct variable_description *var, char *value)
|
||||
case EVHARDTAB:
|
||||
hardtab = stol( value) ;
|
||||
break ;
|
||||
case EVVIEWTAB:
|
||||
viewtab = stol( value) ;
|
||||
break ;
|
||||
case EVOVERLAP:
|
||||
overlap = atoi(value);
|
||||
break;
|
||||
@ -1125,7 +1111,7 @@ static int svar(struct 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 */
|
||||
@ -1151,88 +1137,75 @@ static char *i_to_a( int i) {
|
||||
return sp ;
|
||||
}
|
||||
|
||||
/*
|
||||
* find the type of a passed token
|
||||
|
||||
/* find the type of a token based on first character
|
||||
*
|
||||
* char *token; token to analyze
|
||||
* char c ; first character of analyzed token
|
||||
*/
|
||||
static int gettyp( char *token) {
|
||||
char c; /* first char in token */
|
||||
|
||||
/* grab the first char (this is all we need) */
|
||||
c = *token;
|
||||
|
||||
switch (c) {
|
||||
static int gettyp( char c) {
|
||||
switch( c) {
|
||||
case '*':
|
||||
case ':':
|
||||
return TKLBL ;
|
||||
case 0: /* no blanks!!! */
|
||||
return TKNUL ;
|
||||
case '"':
|
||||
return TKSTR;
|
||||
|
||||
return TKSTR ;
|
||||
case '!':
|
||||
return TKDIR;
|
||||
return TKDIR ;
|
||||
case '@':
|
||||
return TKARG;
|
||||
return TKARG ;
|
||||
case '=':
|
||||
return TKBUF;
|
||||
return TKBUF ;
|
||||
case '$':
|
||||
return TKENV;
|
||||
return TKENV ;
|
||||
case '%':
|
||||
return TKVAR;
|
||||
return TKVAR ;
|
||||
case '&':
|
||||
return TKFUN;
|
||||
case '*':
|
||||
return TKLBL;
|
||||
return TKFUN ;
|
||||
|
||||
default:
|
||||
/* a numeric literal? */
|
||||
if( (c >= '0' && c <= '9') || c == '-')
|
||||
return TKLIT;
|
||||
return TKLIT ;
|
||||
else
|
||||
return TKCMD;
|
||||
return TKCMD ;
|
||||
}
|
||||
}
|
||||
|
||||
int is_it_cmd( char *token) {
|
||||
return TKCMD == gettyp( token) ;
|
||||
return TKCMD == gettyp( *token) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* find the value of a token
|
||||
|
||||
/* find the value of a token
|
||||
*
|
||||
* char *token; token to evaluate
|
||||
*/
|
||||
const char *getval(char *token)
|
||||
{
|
||||
int status; /* error return */
|
||||
struct buffer *bp; /* temp buffer pointer */
|
||||
unsigned blen ; /* length of buffer argument */
|
||||
int distmp; /* temporary discmd flag */
|
||||
static char buf[NSTRING]; /* string buffer for some returns */
|
||||
|
||||
switch (gettyp(token)) {
|
||||
case TKNUL:
|
||||
return "";
|
||||
const char *getval( char *token) {
|
||||
static char buf[ NSTRING] ; /* string buffer for some returns */
|
||||
|
||||
switch( gettyp( *token)) {
|
||||
case TKARG: /* interactive argument */
|
||||
strcpy(token, getval(&token[1]));
|
||||
distmp = discmd; /* echo it always! */
|
||||
discmd = TRUE;
|
||||
status = getstring( token, buf, NSTRING, nlc) ;
|
||||
discmd = distmp;
|
||||
strcpy( token, getval( &token[ 1])) ;
|
||||
int distmp = discmd ; /* echo it always! */
|
||||
discmd = TRUE ;
|
||||
int status = getstring( token, buf, NSTRING, nlc) ;
|
||||
discmd = distmp ;
|
||||
if (status == ABORT)
|
||||
return errorm;
|
||||
return buf;
|
||||
return errorm ;
|
||||
|
||||
return buf ;
|
||||
|
||||
case TKBUF: /* buffer contents fetch */
|
||||
|
||||
/* grab the right buffer */
|
||||
strcpy(token, getval(&token[1]));
|
||||
bp = bfind(token, FALSE, 0);
|
||||
strcpy( token, getval( &token[ 1])) ;
|
||||
buffer_p bp = bfind( token, FALSE, 0) ;
|
||||
if (bp == NULL)
|
||||
return errorm;
|
||||
return errorm ;
|
||||
|
||||
/* if the buffer is displayed, get the window
|
||||
vars instead of the buffer vars */
|
||||
/* if the buffer is displayed,
|
||||
get the window vars instead of the buffer vars */
|
||||
if (bp->b_nwnd > 0) {
|
||||
curbp->b_dotp = curwp->w_dotp;
|
||||
curbp->b_doto = curwp->w_doto;
|
||||
@ -1243,7 +1216,7 @@ const char *getval(char *token)
|
||||
return errorm;
|
||||
|
||||
/* grab the line as an argument */
|
||||
blen = bp->b_dotp->l_used - bp->b_doto;
|
||||
unsigned blen = bp->b_dotp->l_used - bp->b_doto;
|
||||
if( blen >= sizeof buf)
|
||||
blen = sizeof buf - 1 ;
|
||||
|
||||
@ -1269,18 +1242,19 @@ const char *getval(char *token)
|
||||
return gtenv(token + 1);
|
||||
case TKFUN:
|
||||
return gtfun(token + 1);
|
||||
case TKDIR:
|
||||
return errorm;
|
||||
case TKLBL:
|
||||
return errorm;
|
||||
case TKLIT:
|
||||
return token;
|
||||
case TKSTR:
|
||||
return token + 1;
|
||||
case TKCMD:
|
||||
return token;
|
||||
case TKDIR:
|
||||
case TKLBL:
|
||||
case TKNUL:
|
||||
return "" ;
|
||||
}
|
||||
return errorm;
|
||||
|
||||
return errorm ;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1368,30 +1342,26 @@ static int ernd( int i) {
|
||||
return (i <= 0) ? s : s % i + 1 ;
|
||||
}
|
||||
|
||||
/*
|
||||
* find pattern within source
|
||||
|
||||
/* find pattern within source
|
||||
*
|
||||
* char *source; source string to search
|
||||
* char *pattern; string to look for
|
||||
*/
|
||||
static int sindex( char *source, char *pattern) {
|
||||
char *sp; /* ptr to current position to scan */
|
||||
|
||||
/* scanning through the source string */
|
||||
sp = source;
|
||||
/* scanning through the source string */
|
||||
char *sp = source ; /* ptr to current position to scan */
|
||||
int idx = 1 ;
|
||||
int pos = 0 ;
|
||||
int len = strlen( source) ;
|
||||
|
||||
while (*sp) {
|
||||
char *csp; /* ptr to source string during comparison */
|
||||
char *cp; /* ptr to place to check for equality */
|
||||
while( *sp) {
|
||||
char c ;
|
||||
unicode_t uc ;
|
||||
|
||||
/* scan through the pattern */
|
||||
cp = pattern;
|
||||
csp = sp;
|
||||
char *cp = pattern ; /* ptr to place to check for equality */
|
||||
char *csp = sp ; /* ptr to source string during comparison */
|
||||
|
||||
while( (c = *cp++) && eq( c, *csp))
|
||||
csp++ ;
|
||||
@ -1406,7 +1376,7 @@ static int sindex( char *source, char *pattern) {
|
||||
}
|
||||
|
||||
/* no match at all.. */
|
||||
return 0;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*
|
||||
|
2
eval.h
2
eval.h
@ -12,7 +12,7 @@
|
||||
extern int macbug ; /* macro debuging flag */
|
||||
extern int cmdstatus ; /* last command status */
|
||||
extern int rval ; /* return value of a subprocess */
|
||||
extern long envram ; /* # of bytes current in use by malloc */
|
||||
extern unsigned envram ; /* # of bytes current in use by malloc */
|
||||
|
||||
int readfirst_f( void) ;
|
||||
int is_it_cmd( char *token) ;
|
||||
|
14
exec.h
14
exec.h
@ -12,13 +12,13 @@ boolean gettokval( char *tok, int maxtoksize) ;
|
||||
char *getnewtokval( void) ;
|
||||
|
||||
/* Bindable functions */
|
||||
BINDABLE( execbuf) ;
|
||||
BINDABLE( execcmd) ;
|
||||
BINDABLE( execfile) ;
|
||||
BINDABLE( execproc) ;
|
||||
BINDABLE( namedcmd) ;
|
||||
BINDABLE( storemac) ;
|
||||
BINDABLE( storeproc) ;
|
||||
BINDABLE( execbuf) ;
|
||||
BINDABLE( execcmd) ;
|
||||
BINDABLE( execfile) ;
|
||||
BINDABLE( execproc) ;
|
||||
BINDABLE( namedcmd) ;
|
||||
BBINDABLE( storemac) ;
|
||||
BINDABLE( storeproc) ;
|
||||
BINDABLE( cbuf1) ;
|
||||
BINDABLE( cbuf2) ;
|
||||
BINDABLE( cbuf3) ;
|
||||
|
37
execute.c
37
execute.c
@ -7,12 +7,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "estruct.h"
|
||||
#include "random.h"
|
||||
#include "defines.h"
|
||||
#include "display.h"
|
||||
#include "file.h"
|
||||
#include "input.h"
|
||||
#include "mlout.h"
|
||||
#include "random.h"
|
||||
#include "search.h"
|
||||
#include "terminal.h"
|
||||
#include "window.h"
|
||||
@ -55,10 +55,7 @@ static int inspound( int n) {
|
||||
static int insbrace( int n, int c) {
|
||||
int ch ; /* last character before input */
|
||||
int oc ; /* caractere oppose a c */
|
||||
int i, count ;
|
||||
int target ; /* column brace should go after */
|
||||
struct line *oldlp ;
|
||||
int oldoff ;
|
||||
|
||||
/* if not called with {, acts as insertion */
|
||||
if( c == '}')
|
||||
@ -67,16 +64,17 @@ static int insbrace( int n, int c) {
|
||||
return linsert( n, c) ;
|
||||
|
||||
/* scan to see if all preceding spaces are white spaces, if not, insert */
|
||||
for( i = curwp->w_doto - 1 ; i >= 0 ; --i) {
|
||||
for( int i = curwp->w_doto - 1 ; i >= 0 ; --i) {
|
||||
ch = lgetc( curwp->w_dotp, i) ;
|
||||
if( ch != ' ' && ch != '\t')
|
||||
return linsert( n, c) ;
|
||||
}
|
||||
|
||||
oldlp = curwp->w_dotp ;
|
||||
oldoff = curwp->w_doto ;
|
||||
/* save the original cursor position */
|
||||
line_p oldlp = curwp->w_dotp ;
|
||||
int oldoff = curwp->w_doto ;
|
||||
|
||||
count = 1 ;
|
||||
int count = 1 ;
|
||||
do {
|
||||
if( boundary( curwp->w_dotp, curwp->w_doto, REVERSE)) {
|
||||
/* at beginning of buffer, no match to be found */
|
||||
@ -132,10 +130,6 @@ static int insbrace( int n, int c) {
|
||||
* char ch; fence type to match against
|
||||
*/
|
||||
static void fmatch( int ch) {
|
||||
struct line *oldlp ; /* original line pointer */
|
||||
int oldoff ; /* and offset */
|
||||
struct line *toplp ; /* top line in current window */
|
||||
int count ; /* current fence level count */
|
||||
int opench ; /* open fence */
|
||||
|
||||
/* $tpause <= 0 disable fmatch */
|
||||
@ -146,8 +140,8 @@ static void fmatch( int ch) {
|
||||
update( FALSE) ;
|
||||
|
||||
/* save the original cursor position */
|
||||
oldlp = curwp->w_dotp ;
|
||||
oldoff = curwp->w_doto ;
|
||||
line_p oldlp = curwp->w_dotp ;
|
||||
int oldoff = curwp->w_doto ;
|
||||
|
||||
/* setup proper open fence for passed close fence */
|
||||
if( ch == ')')
|
||||
@ -158,11 +152,11 @@ static void fmatch( int ch) {
|
||||
opench = '[' ;
|
||||
|
||||
/* find the top line and set up for scan */
|
||||
toplp = curwp->w_linep->l_bp ;
|
||||
line_p toplp = curwp->w_linep->l_bp ;
|
||||
backchar( FALSE, 1) ; /* . was after the }, move back */
|
||||
|
||||
/* scan back until we find it, or reach past the top of the window */
|
||||
count = 1 ;
|
||||
int count = 1 ; /* current fence level count */
|
||||
do {
|
||||
/* At beginning of window or buffer, no match to be found */
|
||||
if( curwp->w_dotp == toplp
|
||||
@ -209,17 +203,14 @@ static void fmatch( int ch) {
|
||||
* int f, n; not used
|
||||
*/
|
||||
BINDABLE( getfence) {
|
||||
struct line *oldlp; /* original line pointer */
|
||||
int oldoff; /* and offset */
|
||||
int sdir; /* direction of search (1/-1) */
|
||||
int count; /* current fence level count */
|
||||
char ch; /* fence type to match against */
|
||||
char ofence; /* open fence */
|
||||
char c; /* current character in scan */
|
||||
|
||||
/* save the original cursor position */
|
||||
oldlp = curwp->w_dotp;
|
||||
oldoff = curwp->w_doto;
|
||||
line_p oldlp = curwp->w_dotp ;
|
||||
int oldoff = curwp->w_doto ;
|
||||
|
||||
/* get the current character */
|
||||
if (oldoff == llength(oldlp))
|
||||
@ -259,7 +250,7 @@ BINDABLE( getfence) {
|
||||
}
|
||||
|
||||
/* scan until we find a match, or reach the end of file */
|
||||
count = 1 ;
|
||||
int count = 1 ; /* current fence level count */
|
||||
do {
|
||||
if( boundary( curwp->w_dotp, curwp->w_doto, sdir)) {
|
||||
/* at buffer limit, no match to be found */
|
||||
|
1
file.c
1
file.c
@ -17,7 +17,6 @@
|
||||
#include "buffer.h"
|
||||
#include "defines.h"
|
||||
#include "display.h"
|
||||
#include "estruct.h"
|
||||
#include "execute.h"
|
||||
#include "fileio.h"
|
||||
#include "input.h"
|
||||
|
81
floodmaz.cmd
81
floodmaz.cmd
@ -1,35 +1,16 @@
|
||||
## floodmaz.cmd -- solve maze by painting wall on the right
|
||||
|
||||
# 6 set $seed
|
||||
execute-file maze.cmd
|
||||
# either maze.cmd or sharpmaz.cmd
|
||||
execute-file sharpmaz.cmd
|
||||
|
||||
set %thisbuf $cbufname
|
||||
|
||||
store-procedure 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-procedure 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
|
||||
set %meml $curline
|
||||
set %memc $curcol
|
||||
|
||||
set $curline 1
|
||||
set $curcol 0
|
||||
run pushxy #push stop position
|
||||
!gosub pushxy #push stop position
|
||||
set %x 1
|
||||
set $curline 4
|
||||
set $curcol %x
|
||||
@ -40,29 +21,47 @@ set %NC &asc "█"
|
||||
set %cc $curcol
|
||||
set %ll $curline
|
||||
set $curcol &add %cc 1
|
||||
!if &equ $curchar %OC
|
||||
run pushxy
|
||||
!endif
|
||||
!gosub probe
|
||||
set $curcol &add %cc -1
|
||||
!if &equ $curchar %OC
|
||||
run pushxy
|
||||
!endif
|
||||
!gosub probe
|
||||
set $curline &add %ll 1
|
||||
set $curcol %cc
|
||||
!if &equ $curchar %OC
|
||||
run pushxy
|
||||
!endif
|
||||
!gosub probe
|
||||
set $curline &add %ll -1
|
||||
set $curcol %cc
|
||||
!if &equ $curchar %OC
|
||||
run pushxy
|
||||
!endif
|
||||
run popxy
|
||||
!gosub probe
|
||||
# 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
|
||||
set $curline 3
|
||||
set $curcol 1
|
||||
|
||||
set $curline %meml
|
||||
set $curcol %memc
|
||||
select-buffer stack
|
||||
unmark-buffer
|
||||
select-buffer %thisbuf
|
||||
unmark-buffer
|
||||
delete-buffer stack
|
||||
!return
|
||||
|
||||
:probe
|
||||
!if ¬ &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
|
||||
|
2
input.c
2
input.c
@ -13,8 +13,8 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bind.h"
|
||||
#include "estruct.h"
|
||||
#include "bindable.h"
|
||||
#include "defines.h"
|
||||
#include "display.h" /* rubout(), echos(), echoc(), update() */
|
||||
#include "exec.h"
|
||||
#include "isa.h"
|
||||
|
@ -27,8 +27,8 @@
|
||||
|
||||
#include "basic.h"
|
||||
#include "buffer.h"
|
||||
#include "defines.h"
|
||||
#include "display.h"
|
||||
#include "estruct.h"
|
||||
#include "exec.h"
|
||||
#include "input.h"
|
||||
#include "line.h"
|
||||
|
762
line.c
762
line.c
@ -20,7 +20,8 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "estruct.h"
|
||||
#include "defines.h"
|
||||
#include "list.h"
|
||||
#include "mlout.h"
|
||||
#include "utf8.h"
|
||||
#include "window.h"
|
||||
@ -37,11 +38,11 @@ static int ldelnewline( void) ;
|
||||
* was taken up by the keycode structure).
|
||||
*/
|
||||
|
||||
#define KBLOCK 250 /* sizeof kill buffer chunks */
|
||||
#define KBLOCK 248 /* sizeof kill buffer chunks */
|
||||
|
||||
typedef struct kill {
|
||||
struct kill *d_next; /* Link to next chunk, NULL if last. */
|
||||
char d_chunk[KBLOCK]; /* Deleted text. */
|
||||
struct kill *d_next ; /* Link to next chunk, NULL if last. */
|
||||
char d_chunk[ KBLOCK] ; /* Deleted text. */
|
||||
} *kill_p ;
|
||||
|
||||
static kill_p kbufp = NULL ; /* current kill buffer chunk pointer */
|
||||
@ -53,42 +54,30 @@ 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 ;
|
||||
}
|
||||
|
||||
|
||||
/* Move the cursor backwards by "n" characters. If "n" is less than zero
|
||||
call "forwchar" to actually do the move. Otherwise compute the new
|
||||
cursor location. Error if you try and move out of the buffer. Set the
|
||||
flag if the line pointer for dot changes.
|
||||
/* Move the cursor backwards by "n" combined characters. If "n" is less
|
||||
than zero call "forwchar" to actually do the move. Otherwise compute
|
||||
the new cursor location. Error if you try and move out of the buffer.
|
||||
Set the flag if the line pointer for dot changes.
|
||||
*/
|
||||
BBINDABLE( backchar) {
|
||||
assert( f == TRUE || n == 1) ;
|
||||
@ -105,9 +94,26 @@ BBINDABLE( backchar) {
|
||||
curwp->w_doto = llength( lp) ;
|
||||
curwp->w_flag |= WFMOVE ;
|
||||
} else {
|
||||
unsigned pos = curwp->w_doto -= 1 ;
|
||||
if( pos > 0)
|
||||
curwp->w_doto -= utf8_revdelta( (unsigned char *) &( (curwp->w_dotp)->l_text[ pos]), pos) ;
|
||||
unsigned pos ;
|
||||
/* move back over combining unicode */
|
||||
combined:
|
||||
pos = curwp->w_doto -= 1 ;
|
||||
/* check if at end of unicode */
|
||||
if( pos > 0) {
|
||||
unsigned delta = utf8_revdelta(
|
||||
(unsigned char *) &( (curwp->w_dotp)->l_text[ pos]), pos) ;
|
||||
if( delta != 0) {
|
||||
pos = curwp->w_doto -= delta ;
|
||||
if( pos > 0) { /* check if on combining unicode */
|
||||
unicode_t unc ;
|
||||
|
||||
utf8_to_unicode( curwp->w_dotp->l_text, pos,
|
||||
llength( curwp->w_dotp), &unc) ;
|
||||
if( utf8_width( unc) == 0)
|
||||
goto combined ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,10 +121,11 @@ BBINDABLE( backchar) {
|
||||
}
|
||||
|
||||
|
||||
/* Move the cursor forwards by "n" characters. If "n" is less than zero
|
||||
call "backchar" to actually do the move. Otherwise compute the new
|
||||
cursor location, and move ".". Error if you try and move off the end of
|
||||
the buffer. Set the flag if the line pointer for dot changes.
|
||||
/* Move the cursor forwards by "n" combined characters. If "n" is less
|
||||
than zero call "backchar" to actually do the move. Otherwise compute
|
||||
the new cursor location, and move ".". Error if you try and move off
|
||||
the end of the buffer. Set the flag if the line pointer for dot
|
||||
changes.
|
||||
*/
|
||||
BBINDABLE( forwchar) {
|
||||
assert( f == TRUE || n == 1) ;
|
||||
@ -140,7 +147,7 @@ BBINDABLE( forwchar) {
|
||||
curwp->w_doto += utf8_to_unicode( curwp->w_dotp->l_text,
|
||||
curwp->w_doto, len, &unc) ;
|
||||
/* check if next char is null width unicode */
|
||||
while( curwp->w_doto != len) {
|
||||
while( curwp->w_doto < len - 1) {
|
||||
unsigned bytes = utf8_to_unicode( curwp->w_dotp->l_text,
|
||||
curwp->w_doto, len, &unc) ;
|
||||
if( utf8_width( unc) == 0)
|
||||
@ -154,8 +161,8 @@ BBINDABLE( forwchar) {
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine allocates a block of memory large enough to hold a struct line
|
||||
|
||||
/* This routine allocates a block of memory large enough to hold a struct line
|
||||
* containing "used" characters. The block is always rounded up a bit. Return
|
||||
* a pointer to the new block, or NULL if there isn't any memory left. Print a
|
||||
* message in the message line if no space.
|
||||
@ -163,13 +170,13 @@ BBINDABLE( forwchar) {
|
||||
line_p lalloc( int used) {
|
||||
#define BLOCK_SIZE 16 /* Line block chunk size. */
|
||||
|
||||
/* rounding down use masking instead or modulo when BLOCK_SIZE is power of 2 */
|
||||
/* rounding down use masking instead of modulo when BLOCK_SIZE is power of 2 */
|
||||
#if (BLOCK_SIZE & -BLOCK_SIZE) == BLOCK_SIZE
|
||||
int size = (used + BLOCK_SIZE) & ~(BLOCK_SIZE - 1) ;
|
||||
#else
|
||||
int size = used + BLOCK_SIZE - used % BLOCK_SIZE ;
|
||||
#endif
|
||||
line_p lp = (line_p) malloc( offsetof( struct line, l_text) + size) ;
|
||||
line_p lp = malloc( sizeof *lp + size) ;
|
||||
if( lp == NULL)
|
||||
mloutstr( "(OUT OF MEMORY)") ;
|
||||
else {
|
||||
@ -180,76 +187,70 @@ 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (bp->b_markp == lp) {
|
||||
bp->b_markp = lp->l_fp;
|
||||
bp->b_marko = 0;
|
||||
|
||||
if( wp->w_markp == lp) {
|
||||
wp->w_markp = lp->l_fp ;
|
||||
wp->w_marko = 0 ;
|
||||
}
|
||||
}
|
||||
bp = bp->b_bufp;
|
||||
|
||||
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 ;
|
||||
}
|
||||
lp->l_bp->l_fp = lp->l_fp;
|
||||
lp->l_fp->l_bp = lp->l_bp;
|
||||
free((char *) lp);
|
||||
|
||||
if( bp->b_markp == lp) {
|
||||
bp->b_markp = lp->l_fp ;
|
||||
bp->b_marko = 0 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lp->l_bp->l_fp = lp->l_fp ;
|
||||
lp->l_fp->l_bp = lp->l_bp ;
|
||||
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 ;
|
||||
}
|
||||
|
||||
/*
|
||||
* insert spaces forward into text
|
||||
|
||||
/* insert spaces forward into text
|
||||
*
|
||||
* int f, n; default flag and numeric argument
|
||||
*/
|
||||
@ -260,24 +261,18 @@ BINDABLE( insspace) {
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
/*
|
||||
* linstr -- Insert a string at the current point
|
||||
*/
|
||||
|
||||
int linstr( char *instr) {
|
||||
int status = TRUE ;
|
||||
|
||||
/* linstr -- Insert a string at the current point */
|
||||
boolean linstr( char *instr) {
|
||||
boolean status = TRUE ;
|
||||
if( instr != NULL) {
|
||||
unicode_t tmpc ;
|
||||
int c ;
|
||||
|
||||
while( (tmpc = *instr++ & 0xFF)) {
|
||||
status =
|
||||
(tmpc == '\n' ? lnewline() : (int) linsert_byte( 1, tmpc)) ;
|
||||
|
||||
/* Insertion error? */
|
||||
if( status != TRUE) {
|
||||
while( (c = (unsigned char) *instr++)) {
|
||||
status = (c == '\n') ? lnewline() : linsert_byte( 1, c) ;
|
||||
if( status != TRUE) { /* Insertion error? */
|
||||
mloutstr( "%Out of memory while inserting") ;
|
||||
return status ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -298,84 +293,88 @@ int 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 ;
|
||||
}
|
||||
|
||||
int linsert( int n, unicode_t c) {
|
||||
boolean linsert( int n, unicode_t c) {
|
||||
assert( n >= 0) ;
|
||||
assert( !(curbp->b_mode & MDVIEW)) ;
|
||||
|
||||
@ -403,7 +402,7 @@ int linsert( int n, unicode_t c) {
|
||||
*
|
||||
* int c ; character to overwrite on current position
|
||||
*/
|
||||
static int lowrite( int c) {
|
||||
static boolean lowrite( int c) {
|
||||
if( curwp->w_doto < curwp->w_dotp->l_used
|
||||
&& ( lgetc( curwp->w_dotp, curwp->w_doto) != '\t'
|
||||
|| (curwp->w_doto % tabwidth) == (tabwidth - 1)
|
||||
@ -413,20 +412,18 @@ static int lowrite( int c) {
|
||||
return linsert( 1, c) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* lover -- Overwrite a string at the current point
|
||||
*/
|
||||
int lover( char *ostr) {
|
||||
int status = TRUE ;
|
||||
|
||||
/* lover -- Overwrite a string at the current point */
|
||||
boolean lover( char *ostr) {
|
||||
boolean status = TRUE ;
|
||||
if( ostr != NULL) {
|
||||
char tmpc ;
|
||||
int c ;
|
||||
|
||||
while( (tmpc = *ostr++)) {
|
||||
status = (tmpc == '\n' ? lnewline() : lowrite( tmpc)) ;
|
||||
while( (c = (unsigned char) *ostr++)) {
|
||||
status = (c == '\n') ? lnewline() : lowrite( c) ;
|
||||
if( status != TRUE) { /* Insertion error? */
|
||||
mloutstr( "%Out of memory while overwriting") ;
|
||||
return status ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -434,21 +431,15 @@ int lover( char *ostr) {
|
||||
return status ;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a newline into the buffer at the current location of dot in the
|
||||
* current window. The funny ass-backwards way it does things is not a botch;
|
||||
* it just makes the last line in the file not a special case. Return TRUE if
|
||||
* everything works out and FALSE on error (memory allocation failure). The
|
||||
* update of dot and mark is a bit easier then in the above case, because the
|
||||
* split forces more updating.
|
||||
*/
|
||||
int lnewline( void) {
|
||||
char *cp1;
|
||||
char *cp2;
|
||||
line_p lp1, lp2 ;
|
||||
int doto;
|
||||
struct window *wp;
|
||||
|
||||
/* Insert a newline into the buffer at the current location of dot in the
|
||||
current window. The funny ass-backwards way it does things is not a
|
||||
botch; it just makes the last line in the file not a special case.
|
||||
Return TRUE if everything works out and FALSE on error (memory
|
||||
allocation failure). The update of dot and mark is a bit easier then in
|
||||
the above case, because the split forces more updating.
|
||||
*/
|
||||
boolean lnewline( void) {
|
||||
assert( !(curbp->b_mode & MDVIEW)) ;
|
||||
|
||||
#if SCROLLCODE
|
||||
@ -456,75 +447,104 @@ int lnewline( void) {
|
||||
#else
|
||||
lchange(WFHARD);
|
||||
#endif
|
||||
lp1 = curwp->w_dotp; /* Get the address and */
|
||||
doto = curwp->w_doto; /* offset of "." */
|
||||
lp2 = lalloc( doto) ; /* New first half line */
|
||||
line_p lp1 = curwp->w_dotp ; /* Get the address and */
|
||||
int doto = curwp->w_doto ; /* offset of "." */
|
||||
line_p lp2 = lalloc( doto) ; /* New first half line */
|
||||
if( lp2 == NULL)
|
||||
return FALSE ;
|
||||
|
||||
cp1 = &lp1->l_text[0]; /* Shuffle text around */
|
||||
cp2 = &lp2->l_text[0];
|
||||
while (cp1 != &lp1->l_text[doto])
|
||||
*cp2++ = *cp1++;
|
||||
cp2 = &lp1->l_text[0];
|
||||
while (cp1 != &lp1->l_text[lp1->l_used])
|
||||
*cp2++ = *cp1++;
|
||||
lp1->l_used -= doto;
|
||||
lp2->l_bp = lp1->l_bp;
|
||||
lp1->l_bp = lp2;
|
||||
lp2->l_bp->l_fp = lp2;
|
||||
lp2->l_fp = lp1;
|
||||
wp = wheadp; /* Windows */
|
||||
while (wp != NULL) {
|
||||
if (wp->w_linep == lp1)
|
||||
wp->w_linep = lp2;
|
||||
if (wp->w_dotp == lp1) {
|
||||
if (wp->w_doto < doto)
|
||||
wp->w_dotp = lp2;
|
||||
memcpy( lp2->l_text, lp1->l_text, doto) ;
|
||||
lp1->l_used -= doto ;
|
||||
memcpy( lp1->l_text, &lp1->l_text[ doto], lp1->l_used) ;
|
||||
lp2->l_fp = lp1 ;
|
||||
lp2->l_bp = lp1->l_bp ;
|
||||
lp1->l_bp = lp2 ;
|
||||
lp2->l_bp->l_fp = lp2 ;
|
||||
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) {
|
||||
if( wp->w_doto < doto)
|
||||
wp->w_dotp = lp2 ;
|
||||
else
|
||||
wp->w_doto -= doto;
|
||||
wp->w_doto -= doto ;
|
||||
}
|
||||
|
||||
if (wp->w_markp == lp1) {
|
||||
if (wp->w_marko < doto)
|
||||
wp->w_markp = lp2;
|
||||
if( wp->w_marko < doto)
|
||||
wp->w_markp = lp2 ;
|
||||
else
|
||||
wp->w_marko -= doto;
|
||||
wp->w_marko -= doto ;
|
||||
}
|
||||
wp = wp->w_wndp;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
int lgetchar( unicode_t *c) {
|
||||
if( curwp->w_dotp->l_used == curwp->w_doto) {
|
||||
*c = (curbp->b_mode & MDDOS) ? '\r' : '\n' ;
|
||||
|
||||
/* lgetchar():
|
||||
* get unicode value and return UTF-8 size of character at dot.
|
||||
*/
|
||||
int lgetchar( unicode_t *cp) {
|
||||
if( curwp->w_dotp->l_used == curwp->w_doto) { /* at EOL? */
|
||||
*cp = (curbp->b_mode & MDDOS) ? '\r' : '\n' ;
|
||||
return 1 ;
|
||||
} else
|
||||
return utf8_to_unicode( curwp->w_dotp->l_text, curwp->w_doto,
|
||||
llength( curwp->w_dotp), c) ;
|
||||
llength( curwp->w_dotp), cp) ;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/* lcombinedsize():
|
||||
* return total UTF-8 size of combined character at dot.
|
||||
*/
|
||||
static int lcombinedsize( void) {
|
||||
if( curwp->w_dotp->l_used == curwp->w_doto) /* EOL? */
|
||||
return 1 ;
|
||||
else {
|
||||
unicode_t c ;
|
||||
|
||||
int pos = curwp->w_doto ;
|
||||
unsigned bytes = utf8_to_unicode( curwp->w_dotp->l_text, pos,
|
||||
llength( curwp->w_dotp), &c) ;
|
||||
/* check if followed by combining unicode character */
|
||||
pos += bytes ;
|
||||
while( pos < llength( curwp->w_dotp) - 1) { /* at least 2 bytes */
|
||||
unsigned cnt = utf8_to_unicode( curwp->w_dotp->l_text, pos,
|
||||
llength( curwp->w_dotp), &c) ;
|
||||
if( utf8_width( c) == 0) {
|
||||
bytes += cnt ;
|
||||
pos += cnt ;
|
||||
} else
|
||||
break ;
|
||||
}
|
||||
|
||||
return bytes ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ldelchar():
|
||||
* delete forward combined characters starting at dot.
|
||||
*
|
||||
* ldelete() really fundamentally works on bytes, not characters.
|
||||
* It is used for things like "scan 5 words forwards, and remove
|
||||
* the bytes we scanned".
|
||||
*
|
||||
* If you want to delete characters, use ldelchar().
|
||||
*/
|
||||
boolean ldelchar( long n, boolean kflag) {
|
||||
boolean ldelchar( long n, boolean kill_f) {
|
||||
/* testing for read only mode is done by ldelete() */
|
||||
while( n-- > 0) {
|
||||
unicode_t c;
|
||||
|
||||
if( !ldelete( lgetchar( &c), kflag))
|
||||
while( n-- > 0)
|
||||
if( !ldelete( lcombinedsize(), kill_f))
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function deletes "n" bytes, starting at dot. It understands how do deal
|
||||
|
||||
/* This function deletes "n" bytes, starting at dot. It understands how do deal
|
||||
* with end of lines, etc. It returns TRUE if all of the characters were
|
||||
* deleted, and FALSE if they were not (because dot ran into the end of the
|
||||
* buffer. The "kflag" is TRUE if the text should be put in the kill buffer.
|
||||
@ -533,101 +553,72 @@ boolean ldelchar( long n, boolean kflag) {
|
||||
* 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;
|
||||
if( ldelnewline() == FALSE
|
||||
|| (kflag != FALSE && kinsert( '\n') == FALSE))
|
||||
return FALSE ;
|
||||
|
||||
--n ;
|
||||
continue ;
|
||||
} else if( chunk > n)
|
||||
chunk = n ;
|
||||
|
||||
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 ;
|
||||
}
|
||||
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] ;
|
||||
}
|
||||
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 ;
|
||||
}
|
||||
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 ;
|
||||
}
|
||||
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 ;
|
||||
}
|
||||
n -= chunk;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
/* 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) ;
|
||||
|
||||
rsize = size + 1 ;
|
||||
rline = malloc( rsize) ;
|
||||
if( rline == NULL) {
|
||||
rsize = 0 ;
|
||||
return "" ;
|
||||
}
|
||||
}
|
||||
|
||||
/* copy it across */
|
||||
memcpy( rline, lp->l_text, size) ;
|
||||
rline[ size] = 0 ;
|
||||
return rline ;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -638,104 +629,101 @@ 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;
|
||||
}
|
||||
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 (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;
|
||||
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 ;
|
||||
}
|
||||
|
||||
lp3 = lalloc( lp1->l_used + lp2->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 ;
|
||||
}
|
||||
}
|
||||
|
||||
lp1->l_used += lp2->l_used ;
|
||||
lp1->l_fp = lp2->l_fp ;
|
||||
lp2->l_fp->l_bp = lp1 ;
|
||||
free( lp2) ;
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
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 ;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
if (kbufh != NULL) {
|
||||
|
||||
void kdelete( void) {
|
||||
if( kbufh != NULL) {
|
||||
/* first, delete all the chunks */
|
||||
kbufp = kbufh;
|
||||
while (kbufp != NULL) {
|
||||
kp = kbufp->d_next;
|
||||
free(kbufp);
|
||||
kbufp = kp;
|
||||
}
|
||||
freelist( (list_p) kbufh) ;
|
||||
|
||||
/* and reset all the kill buffer pointers */
|
||||
kbufh = kbufp = NULL;
|
||||
kused = KBLOCK;
|
||||
kbufh = kbufp = NULL ;
|
||||
kused = KBLOCK ;
|
||||
klen = 0 ;
|
||||
if( value != NULL) {
|
||||
free( value) ;
|
||||
|
16
line.h
16
line.h
@ -18,7 +18,7 @@ typedef struct line {
|
||||
struct line *l_bp ; /* Backward link to the previous line */
|
||||
int l_size ; /* Allocated size */
|
||||
int l_used ; /* Used size */
|
||||
char l_text[ 1] ; /* A bunch of characters */
|
||||
char l_text[] ; /* A bunch of characters */
|
||||
} *line_p ;
|
||||
|
||||
#define lforw(lp) ((lp)->l_fp)
|
||||
@ -29,28 +29,26 @@ 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) ;
|
||||
int linstr( char *instr) ;
|
||||
int linsert( int n, unicode_t c) ;
|
||||
boolean linstr( char *instr) ;
|
||||
boolean linsert( int n, unicode_t c) ;
|
||||
boolean linsert_byte( int n, int c) ;
|
||||
int lover( char *ostr) ;
|
||||
int lnewline( void) ;
|
||||
boolean lover( char *ostr) ;
|
||||
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. */
|
||||
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 */
|
||||
|
||||
|
16
list.c
Normal file
16
list.c
Normal 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
13
list.h
Normal 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 */
|
2
lock.h
2
lock.h
@ -2,7 +2,7 @@
|
||||
#ifndef _LOCK_H_
|
||||
#define _LOCK_H_
|
||||
|
||||
#include "estruct.h"
|
||||
#include "defines.h" /* BSD, SVR4 */
|
||||
|
||||
#if BSD | SVR4
|
||||
int lockchk( const char *fname) ;
|
||||
|
167
main.c
167
main.c
@ -62,14 +62,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "estruct.h" /* Global structures and defines. */
|
||||
#include "defines.h" /* OS specific customization */
|
||||
#if UNIX
|
||||
#include <signal.h>
|
||||
# include <signal.h>
|
||||
#endif
|
||||
|
||||
#include "basic.h"
|
||||
@ -91,9 +90,8 @@
|
||||
#include "window.h"
|
||||
|
||||
#if UNIX
|
||||
static void emergencyexit(int signr)
|
||||
{
|
||||
quickexit(FALSE, 0);
|
||||
static void emergencyexit( int signr) {
|
||||
quickexit( FALSE, 0) ;
|
||||
quit( TRUE, 0) ; /* If quickexit fails (to save changes), do a force quit */
|
||||
}
|
||||
#endif
|
||||
@ -124,13 +122,12 @@ static void usage( void) {
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct buffer *bp; /* temp buffer pointer */
|
||||
int main( int argc, char *argv[]) {
|
||||
buffer_p bp; /* temp buffer pointer */
|
||||
int firstfile; /* first file flag */
|
||||
int carg; /* current arg to scan */
|
||||
int startflag; /* startup executed flag */
|
||||
struct buffer *firstbp = NULL; /* ptr to first buffer in cmd line */
|
||||
buffer_p firstbp = NULL; /* ptr to first buffer in cmd line */
|
||||
int viewflag; /* are we starting in view mode? */
|
||||
int gotoflag; /* do we need to goto a line at start? */
|
||||
int gline = 0; /* if so, what line? */
|
||||
@ -138,17 +135,10 @@ int main(int argc, char **argv)
|
||||
int errflag; /* C error processing? */
|
||||
bname_t bname ; /* buffer name of file to read */
|
||||
|
||||
setlocale( LC_CTYPE, "") ; /* expects $LANG like en_GB.UTF-8 */
|
||||
|
||||
#if PKCODE & BSD
|
||||
sleep(1); /* Time for window manager. */
|
||||
#endif
|
||||
|
||||
#if UNIX
|
||||
#ifdef SIGWINCH
|
||||
signal(SIGWINCH, sizesignal);
|
||||
#endif
|
||||
#endif
|
||||
if( argc == 2) {
|
||||
if( strcmp( argv[ 1], "--help") == 0) {
|
||||
usage() ;
|
||||
@ -325,7 +315,7 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
static void edinit( char *bname) {
|
||||
buffer_p bp;
|
||||
struct window *wp;
|
||||
window_p wp;
|
||||
|
||||
if( !init_bindings() /* initialize mapping of function to name and key */
|
||||
|| NULL == (bp = bfind( bname, TRUE, 0)) /* First buffer */
|
||||
@ -357,80 +347,67 @@ static void edinit( char *bname) {
|
||||
wp->w_flag = WFMODE | WFHARD; /* Full. */
|
||||
}
|
||||
|
||||
|
||||
/***** Compiler specific Library functions ****/
|
||||
|
||||
#if RAMSIZE
|
||||
/* These routines will allow me to track memory usage by placing
|
||||
a layer on top of the standard system malloc() and free() calls.
|
||||
with this code defined, the environment variable, $RAM, will
|
||||
report on the number of bytes allocated via malloc.
|
||||
|
||||
with SHOWRAM defined, the number is also posted on the
|
||||
end of the bottom mode line and is updated whenever it is changed.
|
||||
/* These routines will allow me to track memory usage by placing a layer on
|
||||
top of the standard system malloc() and free() calls. with this code
|
||||
defined, the environment variable, $RAM, will report on the number of
|
||||
bytes allocated via malloc.
|
||||
|
||||
with SHOWRAM defined, the number is also posted on the end of the bottom
|
||||
mode line and is updated whenever it is changed.
|
||||
*/
|
||||
|
||||
static void dspram( void) ;
|
||||
|
||||
#undef malloc
|
||||
#undef free
|
||||
#if 0
|
||||
char *allocate(nbytes)
|
||||
/* allocate nbytes and track */
|
||||
unsigned nbytes; /* # of bytes to allocate */
|
||||
#endif
|
||||
void *allocate( size_t nbytes)
|
||||
{
|
||||
char *mp; /* ptr returned from malloc */
|
||||
/* char *malloc(); */
|
||||
|
||||
mp = malloc(nbytes);
|
||||
if (mp) {
|
||||
envram += nbytes;
|
||||
#if RAMSHOW
|
||||
dspram();
|
||||
static void dspram( void) ;
|
||||
#endif
|
||||
|
||||
void *allocate( size_t nbytes) {
|
||||
nbytes += sizeof nbytes ; /* add overhead to track allocation */
|
||||
size_t *mp = (malloc)( nbytes) ; /* call the function not the macro */
|
||||
if( mp) {
|
||||
*mp++ = nbytes ;
|
||||
envram += nbytes ;
|
||||
#if RAMSHOW
|
||||
dspram() ;
|
||||
#endif
|
||||
}
|
||||
|
||||
return mp;
|
||||
return mp ;
|
||||
}
|
||||
|
||||
#if 0
|
||||
release(mp)
|
||||
/* release malloced memory and track */
|
||||
char *mp; /* chunk of RAM to release */
|
||||
#endif
|
||||
void release( void *mp)
|
||||
{
|
||||
unsigned *lp; /* ptr to the long containing the block size */
|
||||
|
||||
if (mp) {
|
||||
void release( void *mp) {
|
||||
if( mp) {
|
||||
size_t *sp = mp ;
|
||||
sp-- ;
|
||||
/* update amount of ram currently malloced */
|
||||
lp = ((unsigned *) mp) - 1;
|
||||
envram -= (long) *lp - 2;
|
||||
free(mp);
|
||||
envram -= *sp ;
|
||||
(free)( sp) ; /* call the function not the macro */
|
||||
#if RAMSHOW
|
||||
dspram();
|
||||
dspram() ;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if RAMSHOW
|
||||
static void dspram( void)
|
||||
{ /* display the amount of RAM currently malloced */
|
||||
char mbuf[20];
|
||||
char *sp;
|
||||
static void dspram( void) { /* display the amount of RAM currently malloced */
|
||||
char mbuf[ 20] ;
|
||||
|
||||
TTmove(term.t_nrow - 1, 70);
|
||||
TTmove( term.t_nrow, term.t_ncol - 12) ;
|
||||
#if COLOR
|
||||
TTforg(7);
|
||||
TTbacg(0);
|
||||
TTforg( 7) ;
|
||||
TTbacg(0) ;
|
||||
#endif
|
||||
sprintf(mbuf, "[%lu]", envram);
|
||||
sp = &mbuf[0];
|
||||
while (*sp)
|
||||
TTputc(*sp++);
|
||||
TTmove(term.t_nrow, 0);
|
||||
movecursor(term.t_nrow, 0);
|
||||
sprintf( mbuf, "[%10u]", envram) ;
|
||||
char *sp = mbuf ;
|
||||
while( *sp)
|
||||
TTputc( *sp++) ;
|
||||
|
||||
TTmove( term.t_nrow, 0) ;
|
||||
movecursor( term.t_nrow, 0) ;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@ -442,42 +419,36 @@ static void dspram( void)
|
||||
|
||||
#if CLEAN
|
||||
|
||||
/*
|
||||
* cexit()
|
||||
/* cexit()
|
||||
*
|
||||
* int status; return status of emacs
|
||||
*/
|
||||
void cexit( int status) {
|
||||
struct buffer *bp; /* buffer list pointer */
|
||||
struct window *wp; /* window list pointer */
|
||||
struct window *tp; /* temporary window pointer */
|
||||
|
||||
/* first clean up the windows */
|
||||
wp = wheadp;
|
||||
while (wp) {
|
||||
tp = wp->w_wndp;
|
||||
free(wp);
|
||||
wp = tp;
|
||||
}
|
||||
wheadp = NULL;
|
||||
|
||||
/* then the buffers */
|
||||
bp = bheadp;
|
||||
while (bp) {
|
||||
bp->b_nwnd = 0;
|
||||
bp->b_flag = 0; /* don't say anything about a changed buffer! */
|
||||
zotbuf(bp);
|
||||
bp = bheadp;
|
||||
/* first clean up the windows */
|
||||
window_p wp = wheadp ;
|
||||
while( wp) {
|
||||
window_p tp = wp->w_wndp ;
|
||||
free( wp) ;
|
||||
wp = tp ;
|
||||
}
|
||||
|
||||
/* and the kill buffer */
|
||||
kdelete();
|
||||
wheadp = NULL ;
|
||||
|
||||
/* and the video buffers */
|
||||
vtfree();
|
||||
/* then the buffers */
|
||||
buffer_p bp ;
|
||||
while( (bp = bheadp) != NULL) {
|
||||
bp->b_nwnd = 0 ;
|
||||
bp->b_flag = 0 ; /* don't say anything about a changed buffer! */
|
||||
zotbuf( bp) ;
|
||||
}
|
||||
|
||||
#undef exit
|
||||
exit(status);
|
||||
/* and the kill buffer */
|
||||
kdelete() ;
|
||||
|
||||
/* and the video buffers */
|
||||
vtfree() ;
|
||||
|
||||
(exit)( status) ; /* call the function, not the macro */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
5
maze.cmd
5
maze.cmd
@ -1,6 +1,7 @@
|
||||
# record seed
|
||||
## maze.cmd -- draw a block maze
|
||||
|
||||
# 5 set $seed
|
||||
set %S $seed
|
||||
set %S $seed # record seed
|
||||
|
||||
# setup direction offsets
|
||||
set %D1 0
|
||||
|
9
names.c
9
names.c
@ -16,6 +16,7 @@
|
||||
#include "bind.h"
|
||||
#include "bindable.h"
|
||||
#include "buffer.h"
|
||||
#include "defines.h" /* malloc/allocate */
|
||||
#include "display.h"
|
||||
#include "eval.h"
|
||||
#include "exec.h"
|
||||
@ -49,8 +50,8 @@ const name_bind names[] = {
|
||||
{"!case-word-lower", lowerword, META | 'L'} ,
|
||||
{"!case-word-upper", upperword, META | 'U'} ,
|
||||
{" change-file-name", filename, CTLX | 'N'} ,
|
||||
{" change-screen-size", newsize, META | CTL_ | 'D'} , /* M^S */
|
||||
{" change-screen-width", newwidth, META | CTL_ | 'T'} ,
|
||||
{" change-screen-size", (fnp_t) newsize, META | CTL_ | 'D'} , /* M^S */
|
||||
{" change-screen-width", (fnp_t) newwidth, META | CTL_ | 'T'} ,
|
||||
{" clear-and-redraw", (fnp_t) redraw, CTL_ | 'L'} ,
|
||||
{" clear-message-line", (fnp_t) clrmes, 0} ,
|
||||
{" copy-region", copyregion, META | 'W'} ,
|
||||
@ -191,7 +192,7 @@ const name_bind names[] = {
|
||||
{" shell-command", spawn, CTLX | '!'} ,
|
||||
{" shrink-window", shrinkwind, CTLX | CTL_ | 'Z'} ,
|
||||
{" split-current-window", splitwind, CTLX | '2'} ,
|
||||
{" store-macro", storemac, 0} ,
|
||||
{" store-macro", (fnp_t) storemac, 0} ,
|
||||
{" store-procedure", storeproc, 0} ,
|
||||
#if BSD | SVR4
|
||||
{" suspend-emacs", bktoshell, CTLX | 'D'} , /* BSD MS */
|
||||
@ -201,7 +202,7 @@ const name_bind names[] = {
|
||||
{" unbind-key", unbindkey, META | CTL_ | 'K'} ,
|
||||
{" universal-argument", (fnp_t) unarg, CTL_ | 'U'} ,
|
||||
{" unmark-buffer", unmark, META | '~'} ,
|
||||
{" update-screen", upscreen, 0} ,
|
||||
{" update-screen", (fnp_t) upscreen, 0} ,
|
||||
{" view-file", viewfile, CTLX | CTL_ | 'V'} ,
|
||||
{"!wrap-word", wrapword, META | SPEC | 'W'} , /* hook */
|
||||
{" write-file", filewrite, CTLX | CTL_ | 'W'} ,
|
||||
|
2
pklock.h
2
pklock.h
@ -2,7 +2,7 @@
|
||||
#ifndef _PKLOCK_H_
|
||||
#define _PKLOCK_H_
|
||||
|
||||
#include "estruct.h"
|
||||
#include "defines.h" /* FILOCK, BSD, SVR4 */
|
||||
|
||||
#if (FILOCK && BSD) || SVR4
|
||||
char *dolock( const char *fname) ;
|
||||
|
91
posix.c
91
posix.c
@ -1,18 +1,17 @@
|
||||
/* posix.c -- posix implementation of termio.h */
|
||||
#ifdef POSIX
|
||||
|
||||
#include "termio.h"
|
||||
|
||||
/* posix.c
|
||||
*
|
||||
* The functions in this file negotiate with the operating system for
|
||||
* characters, and write characters in a barely buffered fashion on the
|
||||
* display. All operating systems.
|
||||
*
|
||||
* modified by Petri Kutvonen
|
||||
*
|
||||
* based on termio.c, with all the old cruft removed, and
|
||||
* fixed for termios rather than the old termio.. Linus Torvalds
|
||||
#include "defines.h" /* POSIX */
|
||||
#ifdef POSIX
|
||||
|
||||
/* The functions in this file negotiate with the operating system for
|
||||
characters, and write characters in a barely buffered fashion on the
|
||||
display. All operating systems.
|
||||
|
||||
modified by Petri Kutvonen
|
||||
|
||||
based on termio.c, with all the old cruft removed, and
|
||||
fixed for termios rather than the old termio.. Linus Torvalds
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
@ -24,21 +23,19 @@
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "estruct.h"
|
||||
#include "retcode.h"
|
||||
#include "utf8.h"
|
||||
|
||||
int ttrow = HUGE ; /* Row location of HW cursor */
|
||||
int ttcol = HUGE ; /* Column location of HW cursor */
|
||||
int ttrow = -1 ; /* Row location of HW cursor */
|
||||
int ttcol = -1 ; /* Column location of HW cursor */
|
||||
|
||||
/* Since Mac OS X's termios.h doesn't have the following 2 macros, define them.
|
||||
*/
|
||||
#if BSD || defined(SYSV) && (defined(_DARWIN_C_SOURCE) || defined(_FREEBSD_C_SOURCE))
|
||||
/* Define missing macroes for BSD and CYGWIN environment */
|
||||
#if BSD
|
||||
#define OLCUC 0000002
|
||||
#define XCASE 0000004
|
||||
#endif
|
||||
|
||||
#ifdef CYGWIN
|
||||
#ifdef __CYGWIN__ /* gcc predefined (see cpp -dM) */
|
||||
#define XCASE 0
|
||||
#define ECHOPRT 0
|
||||
#define PENDIN 0
|
||||
@ -96,10 +93,8 @@ void ttopen(void)
|
||||
kbdflgs = fcntl(0, F_GETFL, 0);
|
||||
kbdpoll = FALSE;
|
||||
|
||||
/* on all screens we are not sure of the initial position
|
||||
of the cursor */
|
||||
ttrow = 999;
|
||||
ttcol = 999;
|
||||
/* on all screens we are not sure of the initial position of the cursor */
|
||||
ttrow = ttcol = -1 ;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -154,27 +149,28 @@ void ttflush(void)
|
||||
exit(15);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a character from the terminal, performing no editing and doing no echo
|
||||
* at all.
|
||||
* Very simple on CPM, because the system can do exactly what you want.
|
||||
*/
|
||||
int ttgetc(void)
|
||||
{
|
||||
static char buffer[32];
|
||||
static int pending;
|
||||
unicode_t c;
|
||||
int count, bytes = 1, expected;
|
||||
|
||||
count = pending;
|
||||
if (!count) {
|
||||
count = read(0, buffer, sizeof(buffer));
|
||||
if (count <= 0)
|
||||
return 0;
|
||||
pending = count;
|
||||
/* Read a character from the terminal, performing no editing and doing no
|
||||
echo at all.
|
||||
*/
|
||||
int ttgetc( void) {
|
||||
static char buffer[ 32] ;
|
||||
static int pending ;
|
||||
unicode_t c ;
|
||||
|
||||
int count = pending ;
|
||||
if( !count) {
|
||||
count = read( 0, buffer, sizeof( buffer)) ;
|
||||
if( count <= 0)
|
||||
return 0 ;
|
||||
|
||||
pending = count ;
|
||||
}
|
||||
|
||||
c = (unsigned char) buffer[0];
|
||||
int bytes = 1 ;
|
||||
c = (unsigned char) buffer[ 0] ;
|
||||
#if 0 // temporary fix for wsl
|
||||
|
||||
if (c >= 32 && c < 128)
|
||||
goto done;
|
||||
|
||||
@ -191,7 +187,7 @@ int ttgetc(void)
|
||||
* delay for some *very* unusual utf8 character
|
||||
* input.
|
||||
*/
|
||||
expected = 2;
|
||||
int expected = 2;
|
||||
if ((c & 0xe0) == 0xe0)
|
||||
expected = 6;
|
||||
|
||||
@ -225,9 +221,10 @@ int ttgetc(void)
|
||||
bytes = utf8_to_unicode(buffer, 0, pending, &c);
|
||||
|
||||
done:
|
||||
pending -= bytes;
|
||||
memmove(buffer, buffer+bytes, pending);
|
||||
return c;
|
||||
#endif
|
||||
pending -= bytes ;
|
||||
memmove( buffer, buffer + bytes, pending) ;
|
||||
return c ;
|
||||
}
|
||||
|
||||
/* typahead: Check to see if any characters are already in the
|
||||
@ -247,8 +244,6 @@ int typahead(void)
|
||||
return x;
|
||||
}
|
||||
|
||||
#else
|
||||
typedef void _pedantic_empty_translation_unit ;
|
||||
#endif /* not POSIX */
|
||||
#endif
|
||||
|
||||
/* end of posix.c */
|
||||
|
19
random.c
19
random.c
@ -14,8 +14,8 @@
|
||||
|
||||
#include "basic.h"
|
||||
#include "buffer.h"
|
||||
#include "defines.h"
|
||||
#include "display.h"
|
||||
#include "estruct.h"
|
||||
#include "execute.h"
|
||||
#include "input.h"
|
||||
#include "line.h"
|
||||
@ -219,30 +219,31 @@ boolean setccol( int pos) {
|
||||
*/
|
||||
BBINDABLE( twiddle) {
|
||||
unicode_t c ;
|
||||
boolean eof_f = FALSE ;
|
||||
|
||||
assert( !(curbp->b_mode & MDVIEW)) ;
|
||||
|
||||
int len = llength( curwp->w_dotp) ;
|
||||
if( len < 2 || curwp->w_doto == 0) /* at least 2 chars & not bol */
|
||||
if( len < 2 || curwp->w_doto == 0) /* at least 2 bytes & not bol */
|
||||
return FALSE ;
|
||||
|
||||
if( curwp->w_doto == len) { /* at end of line */
|
||||
backchar( FALSE, 1) ;
|
||||
eof_f = TRUE ;
|
||||
if( curwp->w_doto == 0) {
|
||||
/* only one combined character on this line */
|
||||
forwchar( FALSE, 1) ;
|
||||
return FALSE ;
|
||||
}
|
||||
}
|
||||
|
||||
backchar( FALSE, 1) ;
|
||||
len = lgetchar( &c) ; /* len => unicode or extended ASCII */
|
||||
ldelchar( 1, FALSE) ;
|
||||
backchar( FALSE, 1) ;
|
||||
forwchar( FALSE, 1) ;
|
||||
if( len == 1)
|
||||
linsert_byte( 1, c) ;
|
||||
else
|
||||
linsert( 1, c) ;
|
||||
|
||||
if( eof_f == TRUE)
|
||||
forwchar( FALSE, 1) ;
|
||||
|
||||
lchange( WFEDIT) ;
|
||||
return TRUE ;
|
||||
}
|
||||
@ -836,7 +837,7 @@ static int adjustmode( int kind, int global) {
|
||||
}
|
||||
|
||||
|
||||
static int iovstring( int f, int n, const char *prompt, int (*fun)( char *)) {
|
||||
static int iovstring( int f, int n, const char *prompt, boolean (*fun)( char *)) {
|
||||
char *tstring ; /* string to add */
|
||||
|
||||
/* ask for string to insert */
|
||||
|
2
region.c
2
region.c
@ -12,7 +12,7 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "estruct.h"
|
||||
#include "defines.h"
|
||||
#include "line.h"
|
||||
#include "mlout.h"
|
||||
#include "random.h"
|
||||
|
2
search.c
2
search.c
@ -65,8 +65,8 @@
|
||||
|
||||
#include "basic.h"
|
||||
#include "buffer.h"
|
||||
#include "defines.h"
|
||||
#include "display.h"
|
||||
#include "estruct.h"
|
||||
#include "input.h"
|
||||
#include "isa.h"
|
||||
#include "line.h"
|
||||
|
54
sharpmaz.cmd
Normal file
54
sharpmaz.cmd
Normal file
@ -0,0 +1,54 @@
|
||||
## sharpmaz.cmd -- redraw a block maze using line characters
|
||||
|
||||
execute-file maze.cmd
|
||||
|
||||
set %meml $curline
|
||||
set %memc $curcol
|
||||
end-of-line
|
||||
set %ec &sub $curcol 1
|
||||
end-of-file
|
||||
set %el &sub $curline 1
|
||||
previous-line
|
||||
set %spaces $line
|
||||
beginning-of-file
|
||||
set %old $line
|
||||
set $line %spaces
|
||||
next-line
|
||||
|
||||
!while &less $curline %el
|
||||
set $curcol 1
|
||||
!while &less $curcol %ec
|
||||
!if ¬ &equ $curchar 32
|
||||
set %v 0
|
||||
set %inc 1
|
||||
previous-line
|
||||
!gosub check
|
||||
next-line
|
||||
backward-character
|
||||
!gosub check
|
||||
2 forward-character
|
||||
!gosub check
|
||||
next-line
|
||||
backward-character
|
||||
!gosub check
|
||||
previous-line
|
||||
# alternatively use single width "╳╵╴┘╶└─┴╷│┐┤┌├┬┼"
|
||||
set $curchar &asc &mid "╳╹╸┛╺┗━┻╻┃┓┫┏┣┳╋" &add %v 1 1
|
||||
!endif
|
||||
forward-character
|
||||
!endwhile
|
||||
next-line
|
||||
!endwhile
|
||||
|
||||
beginning-of-file
|
||||
set $line %old
|
||||
set $curline %meml
|
||||
set $curcol %memc
|
||||
!return
|
||||
|
||||
:check
|
||||
!if ¬ &equ $curchar 32
|
||||
set %v &add %v %inc
|
||||
!endif
|
||||
set %inc &tim %inc 2
|
||||
!return
|
93
spawn.c
93
spawn.c
@ -12,11 +12,9 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#include "buffer.h"
|
||||
#include "defines.h"
|
||||
#include "display.h"
|
||||
#include "estruct.h"
|
||||
#include "exec.h"
|
||||
#include "file.h"
|
||||
#include "flook.h"
|
||||
@ -27,8 +25,6 @@
|
||||
|
||||
#if USG | BSD
|
||||
#include <signal.h>
|
||||
#ifdef SIGWINCH
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@ -173,97 +169,88 @@ BINDABLE( execprg) {
|
||||
|
||||
|
||||
/* Pipe a one line command into a window
|
||||
* Bound to ^X @
|
||||
* Bound to pipe-command ^X @
|
||||
*/
|
||||
BINDABLE( pipecmd) {
|
||||
int s ; /* return status from CLI */
|
||||
struct window *wp ; /* pointer to new window */
|
||||
buffer_p bp ; /* pointer to buffer to zot */
|
||||
window_p wp ; /* pointer to new window */
|
||||
char *mlarg ;
|
||||
char *line ; /* command line send to shell */
|
||||
static char bname[] = "command" ;
|
||||
static char filnam[ NSTRING] = "command" ;
|
||||
const char filnam[] = "command" ;
|
||||
|
||||
/* don't allow this command if restricted */
|
||||
/* don't allow this command if restricted */
|
||||
if( restflag)
|
||||
return resterr() ;
|
||||
|
||||
/* get the command to pipe in */
|
||||
s = newmlarg( &mlarg, "@", 0) ;
|
||||
/* get the command to pipe in */
|
||||
int s = newmlarg( &mlarg, "pipe-command: ", 0) ;
|
||||
if( s != TRUE)
|
||||
return s ;
|
||||
|
||||
line = malloc( strlen( mlarg) + strlen( filnam) + 2) ;
|
||||
if( line == NULL) {
|
||||
char *cmdline = malloc( strlen( mlarg) + strlen( filnam) + 4) ;
|
||||
if( cmdline == NULL) {
|
||||
free( mlarg) ;
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
strcpy( line, mlarg) ;
|
||||
strcpy( cmdline, mlarg) ;
|
||||
free( mlarg) ;
|
||||
strcat( cmdline, " > ") ;
|
||||
strcat( cmdline, filnam) ;
|
||||
|
||||
/* get rid of the command output buffer if it exists */
|
||||
if ((bp = bfind(bname, FALSE, 0)) != FALSE) {
|
||||
/* get rid of the command output buffer if it exists */
|
||||
buffer_p bp = bfind( filnam, FALSE, 0) ;
|
||||
if( bp != NULL) {
|
||||
/* try to make sure we are off screen */
|
||||
wp = wheadp;
|
||||
while (wp != NULL) {
|
||||
if (wp->w_bufp == bp) {
|
||||
for( wp = wheadp ; wp != NULL ; wp = wp->w_wndp) {
|
||||
if( wp->w_bufp == bp) {
|
||||
#if PKCODE
|
||||
if (wp == curwp)
|
||||
delwind(FALSE, 1);
|
||||
if( wp == curwp)
|
||||
delwind( FALSE, 1) ;
|
||||
else
|
||||
onlywind(FALSE, 1);
|
||||
break;
|
||||
onlywind( FALSE, 1) ;
|
||||
break ;
|
||||
#else
|
||||
onlywind(FALSE, 1);
|
||||
break;
|
||||
onlywind( FALSE, 1) ;
|
||||
break ;
|
||||
#endif
|
||||
}
|
||||
wp = wp->w_wndp;
|
||||
}
|
||||
|
||||
if( zotbuf( bp) != TRUE) {
|
||||
free( line) ;
|
||||
free( cmdline) ;
|
||||
return FALSE ;
|
||||
}
|
||||
}
|
||||
|
||||
#if USG | BSD
|
||||
TTflush();
|
||||
TTclose(); /* stty to old modes */
|
||||
TTkclose();
|
||||
strcat( line, ">") ;
|
||||
strcat( line, filnam) ;
|
||||
ue_system( line) ;
|
||||
free( line) ;
|
||||
ue_system( cmdline) ;
|
||||
free( cmdline) ;
|
||||
TTopen();
|
||||
TTkopen();
|
||||
TTflush();
|
||||
sgarbf = TRUE;
|
||||
s = TRUE;
|
||||
#else
|
||||
if (s != TRUE)
|
||||
if( s != TRUE)
|
||||
return s;
|
||||
#endif
|
||||
|
||||
/* split the current window to make room for the command output */
|
||||
if (splitwind(FALSE, 1) == FALSE)
|
||||
return FALSE;
|
||||
/* split the current window to make room for the command output
|
||||
** and read the stuff in */
|
||||
if( splitwind( FALSE, 1) == FALSE
|
||||
|| getfile( filnam, FALSE) == FALSE)
|
||||
return FALSE ;
|
||||
|
||||
/* and read the stuff in */
|
||||
if (getfile(filnam, FALSE) == FALSE)
|
||||
return FALSE;
|
||||
/* make this window in VIEW mode, update all mode lines */
|
||||
curwp->w_bufp->b_mode |= MDVIEW ;
|
||||
for( wp = wheadp ; wp != NULL ; wp = wp->w_wndp)
|
||||
wp->w_flag |= WFMODE ;
|
||||
|
||||
/* make this window in VIEW mode, update all mode lines */
|
||||
curwp->w_bufp->b_mode |= MDVIEW;
|
||||
wp = wheadp;
|
||||
while (wp != NULL) {
|
||||
wp->w_flag |= WFMODE;
|
||||
wp = wp->w_wndp;
|
||||
}
|
||||
|
||||
/* and get rid of the temporary file */
|
||||
unlink(filnam);
|
||||
return TRUE;
|
||||
/* and get rid of the temporary file */
|
||||
unlink( filnam) ;
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
|
18
tcap.c
18
tcap.c
@ -20,8 +20,8 @@
|
||||
#include <curses.h>
|
||||
#include <term.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "display.h"
|
||||
#include "estruct.h"
|
||||
#include "termio.h"
|
||||
|
||||
#if TERMCAP
|
||||
@ -83,7 +83,7 @@ static char *_UP, _PC, *CM, *CE, *CL, *SO, *SE;
|
||||
static char *CS, *DL, *AL, *SF, *SR;
|
||||
# endif
|
||||
|
||||
struct terminal term = {
|
||||
terminal_t term = {
|
||||
480, /* actual 479 on 2560x1440 landscape terminal window */
|
||||
2550, /* actual 2541 */
|
||||
0, /* These four values are set dynamically at open time. */
|
||||
@ -231,16 +231,14 @@ static void tcapclose(void)
|
||||
}
|
||||
# endif
|
||||
|
||||
static void tcapkopen(void)
|
||||
{
|
||||
static void tcapkopen( void) {
|
||||
# if PKCODE
|
||||
putpad(TI);
|
||||
ttflush();
|
||||
ttrow = 999;
|
||||
ttcol = 999;
|
||||
sgarbf = TRUE;
|
||||
putpad( TI) ;
|
||||
ttflush() ;
|
||||
ttrow = ttcol = -1 ;
|
||||
sgarbf = TRUE ;
|
||||
# endif
|
||||
strcpy(sres, "NORMAL");
|
||||
strcpy(sres, "NORMAL") ;
|
||||
}
|
||||
|
||||
static void tcapkclose(void)
|
||||
|
63
terminal.h
63
terminal.h
@ -6,45 +6,45 @@
|
||||
#include "retcode.h"
|
||||
#include "utf8.h"
|
||||
|
||||
/* The editor communicates with the display using a high level interface. A
|
||||
* "TERM" structure holds useful variables, and indirect pointers to routines
|
||||
* that do useful operations. The low level get and put routines are here too.
|
||||
* This lets a terminal, in addition to having non standard commands, have
|
||||
* funny get and put character code too. The calls might get changed to
|
||||
* "termp->t_field" style in the future, to make it possible to run more than
|
||||
* one terminal type.
|
||||
/* The editor communicates with the display using a high level interface.
|
||||
A "TERM" structure holds useful variables, and indirect pointers to
|
||||
routines that do useful operations. The low level get and put routines
|
||||
are here too. This lets a terminal, in addition to having non standard
|
||||
commands, have funny get and put character code too. The calls might
|
||||
get changed to "termp->t_field" style in the future, to make it possible
|
||||
to run more than one terminal type.
|
||||
*/
|
||||
struct terminal {
|
||||
typedef struct {
|
||||
const short t_maxrow ; /* max number of rows allowable */
|
||||
const short t_maxcol ; /* max number of columns allowable */
|
||||
short t_mrow ; /* max number of rows displayable */
|
||||
short t_nrow ; /* current number of rows displayed */
|
||||
short t_mcol ; /* max number of rows displayable */
|
||||
short t_ncol ; /* current number of columns displayed */
|
||||
short t_margin; /* min margin for extended lines */
|
||||
short t_scrsiz; /* size of scroll region " */
|
||||
int t_pause; /* # times thru update to pause */
|
||||
void (*t_open)(void); /* Open terminal at the start. */
|
||||
void (*t_close)(void); /* Close terminal at end. */
|
||||
void (*t_kopen)(void); /* Open keyboard */
|
||||
void (*t_kclose)(void); /* close keyboard */
|
||||
int (*t_getchar)(void); /* Get character from keyboard. */
|
||||
int (*t_putchar)( unicode_t) ; /* Put character to display. */
|
||||
void (*t_flush) (void); /* Flush output buffers. */
|
||||
void (*t_move)(int, int);/* Move the cursor, origin 0. */
|
||||
void (*t_eeol)(void); /* Erase to end of line. */
|
||||
void (*t_eeop)(void); /* Erase to end of page. */
|
||||
void (*t_beep)(void); /* Beep. */
|
||||
void (*t_rev)(int); /* set reverse video state */
|
||||
int (*t_rez)(char *); /* change screen resolution */
|
||||
short t_margin ; /* min margin for extended lines */
|
||||
short t_scrsiz ; /* size of scroll region */
|
||||
int t_pause ; /* # times thru update to pause */
|
||||
void (*t_open)( void) ; /* Open terminal at the start */
|
||||
void (*t_close)( void) ; /* Close terminal at end. */
|
||||
void (*t_kopen)( void) ; /* Open keyboard */
|
||||
void (*t_kclose)( void) ; /* close keyboard */
|
||||
int (*t_getchar)( void) ; /* Get character from keyboard */
|
||||
int (*t_putchar)( unicode_t) ; /* Put character to display */
|
||||
void (*t_flush) (void) ; /* Flush output buffers */
|
||||
void (*t_move)( int, int) ; /* Move the cursor, origin 0 */
|
||||
void (*t_eeol)( void) ; /* Erase to end of line */
|
||||
void (*t_eeop)( void) ; /* Erase to end of page */
|
||||
void (*t_beep)( void) ; /* Beep */
|
||||
void (*t_rev)( int) ; /* set reverse video state */
|
||||
int (*t_rez)( char *) ; /* change screen resolution */
|
||||
#if COLOR
|
||||
int (*t_setfor) (); /* set forground color */
|
||||
int (*t_setback) (); /* set background color */
|
||||
int (*t_setfor)() ; /* set forground color */
|
||||
int (*t_setback)() ; /* set background color */
|
||||
#endif
|
||||
#if SCROLLCODE
|
||||
void (*t_scroll)(int, int,int); /* scroll a region of the screen */
|
||||
void (*t_scroll)( int, int,int) ; /* scroll a region of the screen */
|
||||
#endif
|
||||
};
|
||||
} terminal_t ;
|
||||
|
||||
/* TEMPORARY macros for terminal I/O (to be placed in a machine dependant
|
||||
place later)
|
||||
@ -68,11 +68,8 @@ struct terminal {
|
||||
#define TTbacg (*term.t_setback)
|
||||
#endif
|
||||
|
||||
/* Terminal table defined only in term.c */
|
||||
extern struct terminal term ;
|
||||
|
||||
extern int ttrow ; /* Row location of HW cursor */
|
||||
extern int ttcol ; /* Column location of HW cursor */
|
||||
/* Terminal table defined only in tcap.c */
|
||||
extern terminal_t term ;
|
||||
|
||||
extern boolean eolexist ; /* does clear to EOL exist? */
|
||||
extern boolean revexist ; /* does reverse video exist? */
|
||||
|
33
termio.c
33
termio.c
@ -1,21 +1,19 @@
|
||||
/* termio.c -- implements termio.h */
|
||||
#if !defined( POSIX)
|
||||
|
||||
#include "termio.h"
|
||||
|
||||
/* TERMIO.C
|
||||
*
|
||||
* The functions in this file negotiate with the operating system for
|
||||
* characters, and write characters in a barely buffered fashion on the display.
|
||||
* All operating systems.
|
||||
*
|
||||
* modified by Petri Kutvonen
|
||||
#include "defines.h" /* POSIX */
|
||||
#ifndef POSIX
|
||||
|
||||
/* The functions in this file negotiate with the operating system for
|
||||
characters, and write characters in a barely buffered fashion on the
|
||||
display. All operating systems.
|
||||
|
||||
modified by Petri Kutvonen
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "estruct.h"
|
||||
#include "retcode.h"
|
||||
#include "utf8.h"
|
||||
|
||||
@ -23,8 +21,8 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
int ttrow = HUGE ; /* Row location of HW cursor */
|
||||
int ttcol = HUGE ; /* Column location of HW cursor */
|
||||
int ttrow = -1 ; /* Row location of HW cursor */
|
||||
int ttcol = -1 ; /* Column location of HW cursor */
|
||||
|
||||
|
||||
#if USG /* System V */
|
||||
@ -141,8 +139,7 @@ void ttopen(void)
|
||||
|
||||
/* on all screens we are not sure of the initial position
|
||||
of the cursor */
|
||||
ttrow = 999;
|
||||
ttcol = 999;
|
||||
ttrow = ttcol = -1 ;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -258,14 +255,12 @@ int typahead( void)
|
||||
return kbdqp;
|
||||
#endif
|
||||
|
||||
#if !UNIX
|
||||
# if !UNIX
|
||||
return FALSE;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#else
|
||||
typedef void _pedantic_empty_translation_unit ;
|
||||
#endif /* not POSIX */
|
||||
|
||||
/* end of termio.c */
|
||||
|
2
termio.h
2
termio.h
@ -6,8 +6,6 @@
|
||||
|
||||
#define TYPEAH 1 /* type ahead causes update to be skipped */
|
||||
|
||||
#define HUGE 1000 /* Huge number (for row/col) */
|
||||
|
||||
extern int ttrow ; /* Row location of HW cursor */
|
||||
extern int ttcol ; /* Column location of HW cursor */
|
||||
|
||||
|
163
ue.rc
163
ue.rc
@ -1,163 +0,0 @@
|
||||
# UE.RC
|
||||
#
|
||||
# Startup file for µEMACS 4.2
|
||||
# This file is executed every time the editor is entered.
|
||||
# If you want to keep compatibility with em (uEmacs/PK) or me (MicroEMACS)
|
||||
# cp emacs.rc ~/.emacsrc
|
||||
# cp ue.rc ~/.uerc
|
||||
# otherwise
|
||||
# cp ue.rc ~/.emacsrc
|
||||
|
||||
set $discmd "FALSE"
|
||||
set $tab 4
|
||||
|
||||
; Help facility
|
||||
|
||||
40 store-macro
|
||||
set $discmd "FALSE"
|
||||
!if ¬ &seq $cbufname "emacs.hlp"
|
||||
write-message "(Loading Help)"
|
||||
!force help
|
||||
!if ¬ &seq $cbufname "emacs.hlp"
|
||||
write-message "(Failed to load Help)"
|
||||
!else
|
||||
!force 8 resize-window
|
||||
bind-to-key execute-macro-39 FN5
|
||||
bind-to-key execute-macro-38 FN6
|
||||
bind-to-key execute-macro-37 FNH
|
||||
bind-to-key execute-macro-36 FNF
|
||||
beginning-of-line
|
||||
2 forward-character
|
||||
1 redraw-display
|
||||
set %hlpupdn "[PgUp] / [PgDn]"
|
||||
set %hlphelp "[F1]"
|
||||
run helponhelp
|
||||
!endif
|
||||
!else
|
||||
set %hlpcode &lef $line 2
|
||||
!if &seq %hlpcode ".."
|
||||
set %hlptopic &mid $line 4 99
|
||||
end-of-line
|
||||
!force search-forward %hlptopic
|
||||
beginning-of-line
|
||||
2 forward-character
|
||||
1 redraw-display
|
||||
run helponhelp
|
||||
!else
|
||||
!force search-reverse "=>"
|
||||
bind-to-key previous-page FN5
|
||||
bind-to-key next-page FN6
|
||||
bind-to-key beginning-of-file FNH
|
||||
bind-to-key end-of-file FNF
|
||||
!force delete-window
|
||||
clear-message-line
|
||||
!endif
|
||||
!endif
|
||||
set $discmd "TRUE"
|
||||
!endm
|
||||
|
||||
bind-to-key execute-macro-40 M-?
|
||||
bind-to-key execute-macro-40 FNP
|
||||
bind-to-key beginning-of-file FNH
|
||||
bind-to-key end-of-file FNF
|
||||
|
||||
; Help on Help
|
||||
|
||||
store-procedure helponhelp
|
||||
!if &seq &rig $line 5 "INDEX"
|
||||
write-message &cat "Select topic from list and press " %hlphelp
|
||||
!else
|
||||
write-message &cat "Use " &cat %hlpupdn &cat " to scan help file -- " &cat %hlphelp " to toggle help window"
|
||||
!endif
|
||||
!endm
|
||||
|
||||
; Previous help page
|
||||
|
||||
39 store-macro
|
||||
!if &seq $cbufname "emacs.hlp"
|
||||
beginning-of-line
|
||||
!force search-reverse "=>"
|
||||
2 forward-character
|
||||
1 redraw-display
|
||||
run helponhelp
|
||||
!else
|
||||
previous-page
|
||||
!endif
|
||||
!endm
|
||||
|
||||
; Next help page
|
||||
|
||||
38 store-macro
|
||||
!if &seq $cbufname "emacs.hlp"
|
||||
beginning-of-line
|
||||
2 forward-character
|
||||
!force search-forward "=>"
|
||||
1 redraw-display
|
||||
run helponhelp
|
||||
!else
|
||||
next-page
|
||||
!endif
|
||||
!endm
|
||||
|
||||
37 store-macro
|
||||
beginning-of-file
|
||||
!if &seq $cbufname "emacs.hlp"
|
||||
execute-macro-39
|
||||
!endif
|
||||
!endm
|
||||
|
||||
36 store-macro
|
||||
end-of-file
|
||||
!if &seq $cbufname "emacs.hlp"
|
||||
execute-macro-39
|
||||
!endif
|
||||
!endm
|
||||
|
||||
; Set up auto CMODE
|
||||
|
||||
35 store-macro
|
||||
!if &seq &mid $cfname 1 7 "/tmp/Re"
|
||||
add-mode "wrap"
|
||||
!return
|
||||
!endif
|
||||
!if &gre &sin $cfname "/.ed" 0
|
||||
add-mode "wrap"
|
||||
!return
|
||||
!endif
|
||||
!if &gre &sin $cfname "/.let" 0
|
||||
add-mode "wrap"
|
||||
!return
|
||||
!endif
|
||||
!if &gre &sin $cfname "/.art" 0
|
||||
add-mode "wrap"
|
||||
!return
|
||||
!endif
|
||||
!if &gre &sin $cfname "/nn." 0
|
||||
add-mode "wrap"
|
||||
!return
|
||||
!endif
|
||||
set %rctmp &sin $cfname "."
|
||||
!if &equ %rctmp 0
|
||||
!return
|
||||
!endif
|
||||
set %rctmp &mid $cfname &add %rctmp 1 5
|
||||
!if &or &seq %rctmp "c" &seq %rctmp "h"
|
||||
add-mode "cmode"
|
||||
!endif
|
||||
!if &or &seq %rctmp "txt" &or &seq %rctmp "doc" &or &seq %rctmp "tmp" &seq %rctmp "tex"
|
||||
add-mode "wrap"
|
||||
!endif
|
||||
|
||||
!endm
|
||||
|
||||
bind-to-key execute-macro-35 M-FNR
|
||||
|
||||
; Make cut-paste easier in window systems
|
||||
|
||||
bind-to-key newline ^J
|
||||
|
||||
!if &or &gre &sin $LANG "UTF-8" 0 &gre &sin $LANG "utf8" 0
|
||||
add-global-mode "utf-8"
|
||||
!endif
|
||||
|
||||
set $discmd "TRUE"
|
58
utf8.c
58
utf8.c
@ -1,17 +1,13 @@
|
||||
/* utf8.c -- implements utf8.h, converts between unicode and UTF-8 */
|
||||
|
||||
#define _XOPEN_SOURCE /* wcwidth in wchar.h */
|
||||
|
||||
/* utf8.c -- implements utf8.h, conversion between unicode and UTF-8 */
|
||||
#include "utf8.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <wchar.h>
|
||||
#include <wchar.h> /* either _XOPEN_SOURCE or _GNU_SOURCE */
|
||||
|
||||
|
||||
/* Display width of UTF-8 character */
|
||||
int _utf8_width( unicode_t c) {
|
||||
#if CYGWIN
|
||||
assert( sizeof( wchar_t) == 2) ; /* wcwidth only supports UTF-16 */
|
||||
#if __SIZEOF_WCHAR_T__ == 2 /* wcwidth only supports UTF-16 */
|
||||
return (c < 0x10000) ? wcwidth( (wchar_t) c) : -1 ;
|
||||
#else
|
||||
return wcwidth( (wchar_t) c) ;
|
||||
@ -39,54 +35,48 @@ int utf8_width( unicode_t c) {
|
||||
*/
|
||||
unsigned utf8_to_unicode( const char *line, unsigned index, unsigned len,
|
||||
unicode_t *res) {
|
||||
unicode_t value ;
|
||||
unsigned c ;
|
||||
unsigned bytes, mask, i;
|
||||
assert( index < len) ;
|
||||
unsigned c = *res = (unsigned char) line[ index] ;
|
||||
|
||||
if( index >= len)
|
||||
return 0 ;
|
||||
|
||||
*res = c = line[ index] & 0xFFU ;
|
||||
|
||||
/*
|
||||
* 0xxxxxxx is valid one byte utf8
|
||||
/* 0xxxxxxx is valid one byte utf8
|
||||
* 10xxxxxx is invalid UTF-8 start byte, we assume it is Latin1
|
||||
* 1100000x is start of overlong encoding sequence
|
||||
* Sequence longer than 4 bytes are invalid
|
||||
* Last valid code is 0x10FFFF, encoding start with 0xF4
|
||||
*/
|
||||
if( c <= 0xC1 || c > 0xF4)
|
||||
return 1;
|
||||
return 1 ;
|
||||
|
||||
/* Ok, it's 11xxxxxx, do a stupid decode */
|
||||
mask = 0x20;
|
||||
bytes = 2;
|
||||
unsigned mask = 0x20 ;
|
||||
unsigned bytes = 2 ;
|
||||
while( (c & mask) != 0) {
|
||||
bytes++;
|
||||
mask >>= 1;
|
||||
bytes++ ;
|
||||
mask >>= 1 ;
|
||||
}
|
||||
|
||||
/* bytes is in range [2..4] as c was in range [C2..F4] */
|
||||
len -= index;
|
||||
if (bytes > len)
|
||||
return 1;
|
||||
len -= index ;
|
||||
if( bytes > len)
|
||||
return 1 ;
|
||||
|
||||
value = c & (mask-1);
|
||||
unicode_t value = c & (mask - 1) ;
|
||||
|
||||
/* Ok, do the bytes */
|
||||
line += index;
|
||||
for (i = 1; i < bytes; i++) {
|
||||
c = line[i] & 0xFFU ;
|
||||
if ((c & 0xc0) != 0x80)
|
||||
return 1;
|
||||
value = (value << 6) | (c & 0x3f);
|
||||
line += index ;
|
||||
for( unsigned i = 2 ; i <= bytes ; i++) {
|
||||
c = (unsigned char) *++line ;
|
||||
if( (c & 0xc0) != 0x80)
|
||||
return 1 ;
|
||||
|
||||
value = (value << 6) | (c & 0x3f) ;
|
||||
}
|
||||
|
||||
if( value > 0x10FFFF) /* Avoid 110000 - 13FFFF */
|
||||
return 1 ;
|
||||
|
||||
*res = value;
|
||||
return bytes;
|
||||
*res = value ;
|
||||
return bytes ;
|
||||
}
|
||||
|
||||
|
||||
|
2
utf8.h
2
utf8.h
@ -1,4 +1,4 @@
|
||||
/* utf8.h -- */
|
||||
/* utf8.h -- conversion between unicode and UTF-8 */
|
||||
#ifndef _UTF8_H_
|
||||
#define _UTF8_H_
|
||||
|
||||
|
133
window.c
133
window.c
@ -6,11 +6,12 @@
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h> /* malloc(), free() */
|
||||
|
||||
#include "basic.h"
|
||||
#include "buffer.h"
|
||||
#include "defines.h"
|
||||
#include "display.h" /* upmode() */
|
||||
#include "estruct.h"
|
||||
#include "execute.h"
|
||||
#include "line.h"
|
||||
#include "mlout.h"
|
||||
@ -52,7 +53,7 @@ TBINDABLE( redraw) {
|
||||
|
||||
/* The command make the next window (next => down the screen) the current
|
||||
window. There are no real errors, although the command does nothing if
|
||||
there is only 1 window on the screen. Bound to "C-X C-N".
|
||||
there is only 1 window on the screen. Bound to "C-X O".
|
||||
|
||||
with an argument this command finds the <n>th window from the top
|
||||
|
||||
@ -318,7 +319,10 @@ BINDABLE( splitwind) {
|
||||
return FALSE ;
|
||||
}
|
||||
|
||||
wp = xmalloc( sizeof *wp) ;
|
||||
wp = malloc( sizeof *wp) ;
|
||||
if( wp == NULL)
|
||||
return mloutfail( "Out of memory") ;
|
||||
|
||||
++curbp->b_nwnd; /* Displayed twice. */
|
||||
wp->w_bufp = curbp;
|
||||
wp->w_dotp = curwp->w_dotp;
|
||||
@ -557,89 +561,84 @@ BINDABLE( restwnd) {
|
||||
}
|
||||
|
||||
|
||||
static void adjust( window_p wp, int screenrows) {
|
||||
wp->w_ntrows = screenrows - wp->w_toprow - 2 ;
|
||||
wp->w_flag |= WFHARD | WFMODE ;
|
||||
}
|
||||
|
||||
/* resize the screen, re-writing the screen
|
||||
*
|
||||
* int f; default flag
|
||||
* int n; numeric argument
|
||||
*/
|
||||
BINDABLE( newsize) {
|
||||
window_p wp; /* current window being examined */
|
||||
window_p nextwp; /* next window to scan */
|
||||
window_p lastwp; /* last window scanned */
|
||||
int lastline; /* screen line of last line of current window */
|
||||
BBINDABLE( newsize) {
|
||||
window_p wp ; /* current window being examined */
|
||||
|
||||
/* if the command defaults, assume the largest */
|
||||
if (f == FALSE)
|
||||
if( f == FALSE)
|
||||
n = term.t_mrow ;
|
||||
|
||||
/* make sure it's in range */
|
||||
if( n < 3 || n > term.t_mrow)
|
||||
if( n < MINROWS || n > term.t_mrow)
|
||||
return mloutfail( "%%Screen size out of range") ;
|
||||
|
||||
if (term.t_nrow == n - 1)
|
||||
return TRUE;
|
||||
else if (term.t_nrow < n - 1) {
|
||||
|
||||
if( term.t_nrow == n - 1)
|
||||
/* no change */
|
||||
return TRUE ;
|
||||
else if( term.t_nrow < n - 1) {
|
||||
/* new size is bigger */
|
||||
/* go to the last window */
|
||||
wp = wheadp;
|
||||
while (wp->w_wndp != NULL)
|
||||
wp = wp->w_wndp;
|
||||
for( wp = wheadp ; wp->w_wndp != NULL ; wp = wp->w_wndp)
|
||||
;
|
||||
|
||||
/* and enlarge it as needed */
|
||||
wp->w_ntrows = n - wp->w_toprow - 2;
|
||||
wp->w_flag |= WFHARD | WFMODE;
|
||||
|
||||
adjust( wp, n) ;
|
||||
} else {
|
||||
|
||||
/* new size is smaller */
|
||||
/* rebuild the window structure */
|
||||
assert( wheadp->w_toprow == 0) ; /* proves coverity wrong */
|
||||
nextwp = wheadp;
|
||||
wp = NULL;
|
||||
lastwp = NULL;
|
||||
while (nextwp != NULL) {
|
||||
wp = nextwp;
|
||||
nextwp = wp->w_wndp;
|
||||
window_p lastwp = NULL ;
|
||||
for( window_p nextwp = wheadp ; nextwp != NULL ; ) {
|
||||
wp = nextwp ;
|
||||
nextwp = wp->w_wndp ;
|
||||
|
||||
/* expand previous window if current would have zero lines */
|
||||
if( wp->w_toprow == n - 2)
|
||||
adjust( lastwp, n) ;
|
||||
|
||||
/* get rid of it if it is too low */
|
||||
if (wp->w_toprow > n - 2) {
|
||||
|
||||
if( wp->w_toprow >= n - 2) {
|
||||
/* save the point/mark if needed */
|
||||
if (--wp->w_bufp->b_nwnd == 0) {
|
||||
wp->w_bufp->b_dotp = wp->w_dotp;
|
||||
wp->w_bufp->b_doto = wp->w_doto;
|
||||
wp->w_bufp->b_markp = wp->w_markp;
|
||||
wp->w_bufp->b_marko = wp->w_marko;
|
||||
if( --wp->w_bufp->b_nwnd == 0) {
|
||||
wp->w_bufp->b_dotp = wp->w_dotp ;
|
||||
wp->w_bufp->b_doto = wp->w_doto ;
|
||||
wp->w_bufp->b_markp = wp->w_markp ;
|
||||
wp->w_bufp->b_marko = wp->w_marko ;
|
||||
}
|
||||
|
||||
/* update curwp and lastwp if needed */
|
||||
if (wp == curwp)
|
||||
curwp = wheadp;
|
||||
curbp = curwp->w_bufp;
|
||||
if (lastwp != NULL)
|
||||
lastwp->w_wndp = NULL;
|
||||
if( wp == curwp) {
|
||||
curwp = wheadp ;
|
||||
curbp = curwp->w_bufp ;
|
||||
}
|
||||
|
||||
/* free the structure */
|
||||
free((char *) wp);
|
||||
wp = NULL;
|
||||
|
||||
free( wp) ;
|
||||
lastwp->w_wndp = NULL ;
|
||||
} else {
|
||||
/* need to change this window size? */
|
||||
lastline = wp->w_toprow + wp->w_ntrows - 1;
|
||||
if (lastline >= n - 2) {
|
||||
wp->w_ntrows =
|
||||
n - wp->w_toprow - 2;
|
||||
wp->w_flag |= WFHARD | WFMODE;
|
||||
}
|
||||
}
|
||||
if( (wp->w_toprow + wp->w_ntrows - 1) >= n - 2)
|
||||
adjust( wp, n) ;
|
||||
|
||||
lastwp = wp;
|
||||
lastwp = wp ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* screen is garbage */
|
||||
term.t_nrow = n - 1;
|
||||
sgarbf = TRUE;
|
||||
return TRUE;
|
||||
term.t_nrow = n - 1 ;
|
||||
sgarbf = TRUE ;
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
|
||||
@ -648,31 +647,25 @@ BINDABLE( newsize) {
|
||||
* int f; default flag
|
||||
* int n; numeric argument
|
||||
*/
|
||||
BINDABLE( newwidth) {
|
||||
window_p wp;
|
||||
|
||||
BBINDABLE( newwidth) {
|
||||
/* if the command defaults, assume the largest */
|
||||
if (f == FALSE)
|
||||
n = term.t_mcol;
|
||||
if( f == FALSE)
|
||||
n = term.t_mcol ;
|
||||
|
||||
/* make sure it's in range */
|
||||
if (n < 10 || n > term.t_mcol)
|
||||
if( n < MINCOLS || n > term.t_mcol)
|
||||
return mloutfail( "%%Screen width out of range") ;
|
||||
|
||||
/* otherwise, just re-width it (no big deal) */
|
||||
term.t_ncol = n;
|
||||
term.t_margin = n / 10;
|
||||
term.t_scrsiz = n - (term.t_margin * 2);
|
||||
term.t_ncol = n ;
|
||||
updmargin() ;
|
||||
|
||||
/* florce all windows to redraw */
|
||||
wp = wheadp;
|
||||
while (wp) {
|
||||
wp->w_flag |= WFHARD | WFMOVE | WFMODE;
|
||||
wp = wp->w_wndp;
|
||||
}
|
||||
sgarbf = TRUE;
|
||||
/* force all windows to redraw */
|
||||
for( window_p wp = wheadp ; wp; wp = wp->w_wndp)
|
||||
wp->w_flag |= WFHARD | WFMOVE | WFMODE ;
|
||||
|
||||
return TRUE;
|
||||
sgarbf = TRUE ;
|
||||
return TRUE ;
|
||||
}
|
||||
|
||||
int getwpos(void)
|
||||
|
4
window.h
4
window.h
@ -55,8 +55,8 @@ extern window_p wheadp ; /* Head of list of windows */
|
||||
BINDABLE( enlargewind) ;
|
||||
BINDABLE( mvdnwind) ;
|
||||
BINDABLE( mvupwind) ;
|
||||
BINDABLE( newsize) ;
|
||||
BINDABLE( newwidth) ;
|
||||
BBINDABLE( newsize) ;
|
||||
BBINDABLE( newwidth) ;
|
||||
BINDABLE( nextwind) ;
|
||||
BINDABLE( onlywind) ;
|
||||
BINDABLE( prevwind) ;
|
||||
|
2
word.c
2
word.c
@ -14,7 +14,7 @@
|
||||
|
||||
#include "basic.h"
|
||||
#include "buffer.h"
|
||||
#include "estruct.h"
|
||||
#include "defines.h"
|
||||
#include "isa.h"
|
||||
#include "line.h"
|
||||
#include "mlout.h"
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* wrapper.c -- implements wrapper.h */
|
||||
|
||||
#include "wrapper.h"
|
||||
|
||||
#include <stdio.h>
|
||||
@ -26,12 +25,4 @@ void xmkstemp( char *template) {
|
||||
close( fd) ;
|
||||
}
|
||||
|
||||
void *xmalloc( size_t size) {
|
||||
void *ret = malloc( size) ;
|
||||
if( !ret)
|
||||
die( "Out of memory") ;
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
/* end of wrapper.c */
|
||||
|
Loading…
Reference in New Issue
Block a user