1
0
mirror of https://github.com/rfivet/uemacs.git synced 2025-01-11 18:56:25 -05:00

Compare commits

..

No commits in common. "50b727bf7ffe7d6152c067c989e193882d3ac409" and "893e34b74063e7cecdabf6ef39e5dfeeb678d785" have entirely different histories.

32 changed files with 2330 additions and 2102 deletions

243
basic.c
View File

@ -1,16 +1,19 @@
/* basic.c -- implements basic.h */ /* basic.c -- implements basic.h */
#include "basic.h" #include "basic.h"
/* The routines in this file move the cursor around on the screen. They /* basic.c
compute a new value for the cursor, then adjust ".". The display code *
always updates the cursor location, so only moves between lines, or * The routines in this file move the cursor around on the screen. They
functions that adjust the top line in the window and invalidate the * compute a new value for the cursor, then adjust ".". The display code
framing, are hard. * always updates the cursor location, so only moves between lines, or
* functions that adjust the top line in the window and invalidate the
modified by Petri Kutvonen * framing, are hard.
*
* modified by Petri Kutvonen
*/ */
#include <assert.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "input.h" #include "input.h"
@ -19,20 +22,26 @@
#include "terminal.h" #include "terminal.h"
#include "window.h" #include "window.h"
#define CVMVAS 1 /* arguments to page forward/back in pages */ #define CVMVAS 1 /* arguments to page forward/back in pages */
int overlap = 0 ; /* $overlap: line overlap in forw/back page */
int curgoal ; /* $target: column goal for C-P, C-N */ int overlap = DEFAULT_OVERLAP ; /* line overlap in forw/back page */
int curgoal ; /* Goal for C-P, C-N */
/* This routine, given a pointer to a struct line, and the current cursor /*
goal column, return the best choice for the offset. The offset is * This routine, given a pointer to a struct line, and the current cursor goal
returned. Used by "C-N" and "C-P". * column, return the best choice for the offset. The offset is returned.
* Used by "C-N" and "C-P".
*/ */
static unsigned getgoal( line_p dlp) { static unsigned getgoal( line_p dlp) {
int col = 0 ; int col ;
unsigned idx ;
const unsigned len = llength( dlp) ; const unsigned len = llength( dlp) ;
unsigned idx = 0 ;
col = 0 ;
idx = 0 ;
while( idx < len) { while( idx < len) {
unicode_t c ; unicode_t c ;
unsigned width = utf8_to_unicode( dlp->l_text, idx, len, &c) ; unsigned width = utf8_to_unicode( dlp->l_text, idx, len, &c) ;
@ -40,70 +49,77 @@ static unsigned getgoal( line_p dlp) {
/* Take tabs, ^X and \xx hex characters into account */ /* Take tabs, ^X and \xx hex characters into account */
if( c == '\t') if( c == '\t')
col += tabwidth - col % tabwidth ; col += tabwidth - col % tabwidth ;
else if( c < 0x20 || c == 0x7F) /* ^x */ else if( c < 0x20 || c == 0x7F)
col += 2 ; col += 2 ;
else if( c >= 0x80 && c <= 0xA0) /* \xx */ else if( c >= 0x80 && c <= 0xA0)
col += 3 ; col += 3 ;
else { else
int w = utf8_width( c) ; /* work around */ col += 1 ;
col += (w < 0) ? 2 : w ; /* unknown unicode width as \u */
}
if( col > curgoal) if( col > curgoal)
break ; break ;
else
idx += width ; idx += width ;
} }
return idx ; return idx ;
} }
/*
/* Move the cursor to the beginning of the current line of active window. */ * Move the cursor to the beginning of the current line of active window.
TBINDABLE( gotobol) { */
boolean gotobol( int f, int n) {
curwp->w_doto = 0 ; curwp->w_doto = 0 ;
return TRUE ; return TRUE ;
} }
/*
/* Move the cursor to the end of the current line of active window. */ * Move the cursor to the end of the current line of active window.
TBINDABLE( gotoeol) { */
boolean gotoeol( int f, int n) {
curwp->w_doto = llength( curwp->w_dotp) ; curwp->w_doto = llength( curwp->w_dotp) ;
return TRUE ; return TRUE ;
} }
/*
/* Goto the beginning of the buffer. Massive adjustment of dot. This is * Goto the beginning of the buffer. Massive adjustment of dot. This is
considered to be hard motion; it really isn't if the original value of * considered to be hard motion; it really isn't if the original value of dot
dot is the same as the new value of dot. Normally bound to "M-<". * is the same as the new value of dot. Normally bound to "M-<".
*/ */
TBINDABLE( gotobob) { boolean gotobob( int f, int n) {
curwp->w_dotp = lforw( curbp->b_linep) ; curwp->w_dotp = lforw( curbp->b_linep) ;
curwp->w_doto = 0 ; curwp->w_doto = 0 ;
curwp->w_flag |= WFHARD ; curwp->w_flag |= WFHARD ;
return TRUE ; return TRUE ;
} }
/*
/* Move to the end of the buffer. Dot is always put at the end of the file * Move to the end of the buffer. Dot is always put at the end of the file
(ZJ). The standard screen code does most of the hard parts of update. * (ZJ). The standard screen code does most of the hard parts of update.
Bound to "M->". * Bound to "M->".
*/ */
TBINDABLE( gotoeob) { boolean gotoeob( int f, int n) {
curwp->w_dotp = curbp->b_linep ; curwp->w_dotp = curbp->b_linep ;
curwp->w_doto = 0 ; curwp->w_doto = 0 ;
curwp->w_flag |= WFHARD ; curwp->w_flag |= WFHARD ;
return TRUE ; return TRUE ;
} }
/*
/* Move forward by full lines. If the number of lines to move is less than * Move forward by full lines. If the number of lines to move is less than
zero, call the backward line function to actually do it. The last * zero, call the backward line function to actually do it. The last command
command controls how the goal column is set. Bound to "C-N". No errors * controls how the goal column is set. Bound to "C-N". No errors are
are possible. * possible.
*/ */
BBINDABLE( forwline) { boolean forwline( int f, int n) {
assert( f == TRUE || n == 1) ; line_p dlp ;
if (n < 0)
return backline(f, -n);
/* if we are on the last line as we start....fail the command */
if (curwp->w_dotp == curbp->b_linep)
return FALSE;
/* if the last command was not a line move, reset the goal column */ /* if the last command was not a line move, reset the goal column */
if ((lastflag & CFCPCN) == 0) if ((lastflag & CFCPCN) == 0)
@ -113,62 +129,79 @@ BBINDABLE( forwline) {
thisflag |= CFCPCN; thisflag |= CFCPCN;
/* and move the point down */ /* and move the point down */
if( n) { dlp = curwp->w_dotp;
line_p dlp = curwp->w_dotp ;
if( n > 0)
while( n && dlp != curbp->b_linep) { while( n && dlp != curbp->b_linep) {
dlp = lforw( dlp) ; dlp = lforw( dlp) ;
n -= 1 ; n -= 1 ;
} }
else {
while( n && lback( dlp) != curbp->b_linep) {
dlp = lback( dlp) ;
n += 1 ;
}
}
/* resetting the current position */ /* reseting the current position */
curwp->w_dotp = dlp; curwp->w_dotp = dlp;
curwp->w_doto = getgoal(dlp); curwp->w_doto = getgoal(dlp);
curwp->w_flag |= WFMOVE; curwp->w_flag |= WFMOVE;
}
return (n == 0) ? TRUE : FALSE ; return (n == 0) ? TRUE : FALSE ;
} }
/*
/* This function is like "forwline", but goes backwards. The scheme is * This function is like "forwline", but goes backwards. The scheme is exactly
exactly the same. Check for arguments that are less than zero and call * the same. Check for arguments that are less than zero and call your
your alternate. Figure out the new line and call "movedot" to perform * alternate. Figure out the new line and call "movedot" to perform the
the motion. No errors are possible. Bound to "C-P". * motion. No errors are possible. Bound to "C-P".
*/ */
BBINDABLE( backline) { boolean backline( int f, int n) {
assert( f == TRUE || n == 1) ; line_p dlp ;
return forwline( TRUE, -n) ; if (n < 0)
return forwline(f, -n);
/* if we are on the first line as we start....fail the command */
if (lback(curwp->w_dotp) == curbp->b_linep)
return FALSE;
/* if the last command was not a line move, reset the goal column */
if ((lastflag & CFCPCN) == 0)
curgoal = getccol(FALSE);
/* flag this command as a line move */
thisflag |= CFCPCN;
/* and move the point up */
dlp = curwp->w_dotp;
while( n && lback( dlp) != curbp->b_linep) {
dlp = lback( dlp) ;
n -= 1 ;
} }
/* reseting the current position */
curwp->w_dotp = dlp;
curwp->w_doto = getgoal(dlp);
curwp->w_flag |= WFMOVE;
return (n == 0) ? TRUE : FALSE ;
}
/* Move to a particular line. /*
* Move to a particular line.
* *
* @n: The specified line position at the current buffer. * @n: The specified line position at the current buffer.
*/ */
BINDABLE( gotoline) { int gotoline( int f, int n) {
/* Get an argument if one doesn't exist. */ /* Get an argument if one doesnt exist. */
if( f == FALSE) { if( f == FALSE) {
int status ;
char *arg ; /* Buffer to hold argument. */ char *arg ; /* Buffer to hold argument. */
int status = newmlarg( &arg, "goto-line: ", 0) ; status = newmlarg( &arg, "Line to GOTO: ", 0) ;
if( status != TRUE) if( status != TRUE) {
mloutstr( "(Aborted)") ;
return status ; return status ;
}
n = atoi( arg) ; n = atoi( arg) ;
free( arg) ; free( arg) ;
f = TRUE ;
} }
/* Handle the case where the user may be passed something like this: /* Handle the case where the user may be passed something like this:
* ue filename + * em filename +
* In this case we just go to the end of the buffer. * In this case we just go to the end of the buffer.
*/ */
if (n == 0) if (n == 0)
@ -180,17 +213,16 @@ BINDABLE( gotoline) {
/* First, we go to the begin of the buffer. */ /* First, we go to the begin of the buffer. */
gotobob(f, n); gotobob(f, n);
return (n == 1) ? TRUE : forwline( TRUE, n - 1) ; return (n == 1) ? TRUE : forwline( f, n - 1) ;
} }
/*
/* Scroll forward by a specified number of lines, or by a full page if no * Scroll forward by a specified number of lines, or by a full page if no
argument. Bound to "C-V". The "2" in the arithmetic on the window size * argument. Bound to "C-V". The "2" in the arithmetic on the window size is
is the overlap; this value is the default overlap value in ITS EMACS. * the overlap; this value is the default overlap value in ITS EMACS. Because
Because this zaps the top line in the display window, we have to do a * this zaps the top line in the display window, we have to do a hard update.
hard update.
*/ */
TBINDABLE( forwpage) { boolean forwpage( int f, int n) {
line_p lp ; line_p lp ;
if (f == FALSE) { if (f == FALSE) {
@ -213,15 +245,17 @@ TBINDABLE( forwpage) {
n *= curwp->w_ntrows; /* To lines. */ n *= curwp->w_ntrows; /* To lines. */
#endif #endif
/* lp = curwp->w_linep; */
lp = curwp->w_dotp ; lp = curwp->w_dotp ;
while( n && lp != curbp->b_linep) { while( n && lp != curbp->b_linep) {
lp = lforw( lp) ; lp = lforw( lp) ;
n -= 1 ; n -= 1 ;
} }
/* curwp->w_linep = lp; */
curwp->w_dotp = lp; curwp->w_dotp = lp;
curwp->w_doto = 0; curwp->w_doto = 0;
reposition( TRUE, 0) ; /* center at dot, always succeed */ reposition( TRUE, 0) ;
#if SCROLLCODE #if SCROLLCODE
curwp->w_flag |= WFHARD | WFKILLS; curwp->w_flag |= WFHARD | WFKILLS;
@ -231,13 +265,13 @@ TBINDABLE( forwpage) {
return TRUE; return TRUE;
} }
/*
/* This command is like "forwpage", but it goes backwards. The "2", like * This command is like "forwpage", but it goes backwards. The "2", like
above, is the overlap between the two windows. The value is from the * above, is the overlap between the two windows. The value is from the ITS
ITS EMACS manual. Bound to "M-V". We do a hard update for exactly the * EMACS manual. Bound to "M-V". We do a hard update for exactly the same
same reason. * reason.
*/ */
TBINDABLE( backpage) { boolean backpage( int f, int n) {
line_p lp ; line_p lp ;
if (f == FALSE) { /* interactive, default n = 1 supplied */ if (f == FALSE) { /* interactive, default n = 1 supplied */
@ -288,32 +322,39 @@ TBINDABLE( backpage) {
return TRUE; return TRUE;
} }
/*
/* Set the mark in the current window to the value of "." in the window. * Set the mark in the current window to the value of "." in the window. No
No errors are possible. Bound to M-. set-mark. * errors are possible. Bound to "M-.".
*/ */
TBINDABLE( setmark) { boolean setmark( int f, int n) {
curwp->w_markp = curwp->w_dotp; curwp->w_markp = curwp->w_dotp;
curwp->w_marko = curwp->w_doto; curwp->w_marko = curwp->w_doto;
mloutstr( "(Mark set)") ; mloutstr( "(Mark set)") ;
return TRUE ; return TRUE ;
} }
/*
/* Swap the values of "." and "mark" in the current window. If no mark as * Swap the values of "." and "mark" in the current window. This is pretty
been previously set, set it. Bound to C-X C-X exchange-point-and-mark. * easy, because all of the hard work gets done by the standard routine
* that moves the mark about. The only possible error is "no mark". Bound to
* "C-X C-X".
*/ */
TBINDABLE( swapmark) { boolean swapmark( int f, int n) {
line_p odotp = curwp->w_dotp ; line_p odotp ;
int odoto = curwp->w_doto ; int odoto;
if( curwp->w_markp) {
curwp->w_dotp = curwp->w_markp ; if( curwp->w_markp == NULL) {
curwp->w_doto = curwp->w_marko ; mloutstr( "No mark in this window") ;
curwp->w_flag |= WFMOVE ; return FALSE ;
} }
odotp = curwp->w_dotp;
odoto = curwp->w_doto;
curwp->w_dotp = curwp->w_markp;
curwp->w_doto = curwp->w_marko;
curwp->w_markp = odotp; curwp->w_markp = odotp;
curwp->w_marko = odoto; curwp->w_marko = odoto;
curwp->w_flag |= WFMOVE;
return TRUE; return TRUE;
} }

39
basic.h
View File

@ -1,32 +1,35 @@
/* basic.h -- basic commands for cursor movement in active window */ /* basic.h -- basic commands for cursor movement in active window */
#ifndef _BASIC_H_ #ifndef _BASIC_H_
#define _BASIC_H_ #define _BASIC_H_
# include "names.h" #include "retcode.h"
/* $overlap is the size of the line overlap when kbd calls page forw/back /*
if 0, page will move by 2/3 of the window size (1/3 page overlap) ** $overlap is the size of the line overlap when kbd calls page forw/back
default to 0 ** if 0, page will move by 2/3 of the window size (1/3 page overlap)
** default to 0
*/ */
extern int overlap ; /* $overlap: line overlap in forw/back page */ #define DEFAULT_OVERLAP 0
extern int overlap ; /* line overlap in forw/back page */
/* $target (== curgoal) is the column target when doing line move */ /* $target (== curgoal) is the column target when doing line move */
extern int curgoal ; /* $target: Goal for C-P previous-line, C-N next-line */ extern int curgoal ; /* Goal for C-P previous-line, C-N next-line */
/* Bindable functions */ boolean gotobol( int f, int n) ;
BBINDABLE( backline) ; boolean gotoeol( int f, int n) ;
TBINDABLE( backpage) ; int gotoline( int f, int n) ;
BBINDABLE( forwline) ; boolean gotobob( int f, int n) ;
TBINDABLE( forwpage) ; boolean gotoeob( int f, int n) ;
TBINDABLE( gotobob) ; boolean forwline( int f, int n) ;
TBINDABLE( gotobol) ; boolean backline( int f, int n) ;
TBINDABLE( gotoeob) ; boolean forwpage( int f, int n) ;
TBINDABLE( gotoeol) ; boolean backpage( int f, int n) ;
BINDABLE( gotoline) ; boolean setmark( int f, int n) ;
TBINDABLE( setmark) ; boolean swapmark( int f, int n) ;
TBINDABLE( swapmark) ;
#endif #endif
/* end of basic.h */ /* end of basic.h */

141
bind.c
View File

@ -9,22 +9,24 @@
*/ */
#include <assert.h> #include <assert.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "estruct.h"
#include "bindable.h" #include "bindable.h"
#include "buffer.h" #include "buffer.h"
#include "display.h" /* upmode(), ostring() */ #include "display.h"
#include "exec.h" #include "exec.h"
#include "file.h" #include "file.h"
#include "flook.h" #include "flook.h"
#include "input.h" #include "input.h"
#include "line.h" #include "line.h"
#include "mlout.h"
#include "names.h" #include "names.h"
#include "util.h" #include "util.h"
#include "window.h" #include "window.h"
static int buildlist( char *mstring) ; static int buildlist( char *mstring) ;
static char *cmdstr( unsigned c, char *seq) ; static char *cmdstr( unsigned c, char *seq) ;
static unsigned int getckey( int mflag) ; static unsigned int getckey( int mflag) ;
@ -32,10 +34,14 @@ static unsigned int stock( char *keyname) ;
static const char *getfname( unsigned keycode, const char *failmsg) ; static const char *getfname( unsigned keycode, const char *failmsg) ;
/* give me some help!!!! bring up a fake buffer and read the help file into static boolean cmdfail( const char *msg) {
it with view mode mlwrite( "%s", msg) ;
*/ return FALSE ;
}
BINDABLE( help) { BINDABLE( help) {
/* give me some help!!!!
bring up a fake buffer and read the help file into it with view mode */
char *fname = NULL; /* ptr to file returned by flook() */ char *fname = NULL; /* ptr to file returned by flook() */
/* first check if we are already here */ /* first check if we are already here */
@ -46,7 +52,7 @@ BINDABLE( help) {
if( bp == NULL) { if( bp == NULL) {
fname = flook( hlpfname, FALSE) ; fname = flook( hlpfname, FALSE) ;
if( fname == NULL) if( fname == NULL)
return mloutfail( "(Help file is not online)") ; return cmdfail( "(Help file is not online)") ;
} }
/* split the current window to make room for the help stuff */ /* split the current window to make room for the help stuff */
@ -68,19 +74,17 @@ BINDABLE( help) {
return TRUE; return TRUE;
} }
static boolean invalidkey( void) { static boolean invalidkey( void) {
return mloutfail( "(Invalid key sequence)") ; return cmdfail( "(Invalid key sequence)") ;
} }
/* describe the command for a certain key */ /* describe the command for a certain key */
BINDABLE( deskey) { BINDABLE( deskey) {
const char cmdname[] = "describe-key" ; const char cmdname[] = "describe-key" ;
char outseq[ 8] ; /* output buffer for keystroke sequence */ char outseq[ NSTRING] ; /* output buffer for command sequence */
/* prompt the user to type a key to describe */ /* prompt the user to type a key to describe */
mloutfmt( "%s: ", cmdname) ; mlwrite( "%s: ", cmdname) ;
/* get the command sequence to describe /* get the command sequence to describe
* change it to something we can print as well */ * change it to something we can print as well */
@ -89,23 +93,23 @@ BINDABLE( deskey) {
return invalidkey() ; return invalidkey() ;
/* output the command sequence */ /* output the command sequence */
mloutfmt( "%s %s: 0x%x, %s", cmdname, cmdstr( keycode, outseq), keycode, mlwrite( "%s %s: 0x%x, %s", cmdname, cmdstr( keycode, outseq), keycode,
getfname( keycode, "Not Bound")) ; getfname( keycode, "Not Bound")) ;
return TRUE ; return TRUE ;
} }
/*
/* bindtokey: * bindtokey:
* add a new key to the key binding table * add a new key to the key binding table
* *
* int f, n; command arguments [IGNORED] * int f, n; command arguments [IGNORED]
*/ */
BINDABLE( bindtokey) { BINDABLE( bindtokey) {
kbind_p ktp ; /* pointer into the command table */ kbind_p ktp ; /* pointer into the command table */
char outseq[ 8] ; /* output buffer for keystroke sequence */ char outseq[ 80] ; /* output buffer for keystroke sequence */
/* prompt the user to type in a key to bind */ /* prompt the user to type in a key to bind */
mloutstr( "bind-to-key: ") ; mlwrite("bind-to-key: ");
/* get the function name to bind it to */ /* get the function name to bind it to */
nbind_p nbp = getname() ; nbind_p nbp = getname() ;
@ -114,13 +118,13 @@ BINDABLE( bindtokey) {
fnp_t kfunc = nbp->n_func ; fnp_t kfunc = nbp->n_func ;
if( kfunc == NULL) if( kfunc == NULL)
return mloutfail( "(No such function)") ; return cmdfail( "(No such function)") ;
mloutfmt( "bind-to-key %s: ", bind_name( nbp)) ; mlwrite( "bind-to-key %s: ", bind_name( nbp)) ;
/* get the command sequence to bind */ /* get the command sequence to bind */
boolean prefix_f = (kfunc == (fnp_t) metafn) || (kfunc == (fnp_t) cex) || boolean prefix_f = (kfunc == metafn) || (kfunc == cex) ||
(kfunc == (fnp_t) unarg) || (kfunc == (fnp_t) ctrlg) ; (kfunc == unarg) || (kfunc == ctrlg) ;
int c = getckey( prefix_f) ; int c = getckey( prefix_f) ;
if( c == ~0) if( c == ~0)
return invalidkey() ; return invalidkey() ;
@ -131,13 +135,13 @@ BINDABLE( bindtokey) {
/* key sequence can't be an active prefix key */ /* key sequence can't be an active prefix key */
if( c == metac || c == ctlxc || c == reptc || c == abortc) { if( c == metac || c == ctlxc || c == reptc || c == abortc) {
if( (c == metac && kfunc == (fnp_t) metafn) if( (c == metac && kfunc == metafn)
|| (c == ctlxc && kfunc == (fnp_t) cex) || (c == ctlxc && kfunc == cex)
|| (c == reptc && kfunc == (fnp_t) unarg) || (c == reptc && kfunc == unarg)
|| (c == abortc && kfunc == (fnp_t) ctrlg)) || (c == abortc && kfunc == ctrlg))
return TRUE ; /* be silent if keep current */ return TRUE ;
return mloutfail( "(Can't bind to active prefix)") ; return cmdfail( "(Can't bind to active prefix)") ;
} }
/* if the function is a prefix key */ /* if the function is a prefix key */
@ -150,34 +154,34 @@ BINDABLE( bindtokey) {
} }
/* set the appropriate global prefix variable */ /* set the appropriate global prefix variable */
if( kfunc == (fnp_t) metafn) if( kfunc == metafn)
metac = c ; metac = c ;
else if( kfunc == (fnp_t) cex) else if( kfunc == cex)
ctlxc = c ; ctlxc = c ;
if( kfunc == (fnp_t) unarg) if( kfunc == unarg)
reptc = c ; reptc = c ;
if( kfunc == (fnp_t) ctrlg) if( kfunc == ctrlg)
abortc = c ; abortc = c ;
} }
ktp = setkeybinding( c, nbp) ; ktp = setkeybinding( c, nbp) ;
if( ktp->k_code == 0) if( ktp->k_code == 0)
return mloutfail( "Binding table FULL!") ; return cmdfail( "Binding table FULL!") ;
return TRUE ; return TRUE ;
} }
/*
/* unbindkey: * unbindkey:
* delete a key from the key binding table * delete a key from the key binding table
* *
* int f, n; command arguments [IGNORED] * int f, n; command arguments [IGNORED]
*/ */
BINDABLE( unbindkey) { BINDABLE( unbindkey) {
char outseq[ 8] ; /* output buffer for keystroke sequence */ char outseq[ 80] ; /* output buffer for keystroke sequence */
/* prompt the user to type in a key to unbind */ /* prompt the user to type in a key to unbind */
mloutstr( "unbind-key: ") ; mlwrite( "unbind-key: ") ;
/* get the command sequence to unbind */ /* get the command sequence to unbind */
int c = getckey( FALSE) ; /* get a command sequence */ int c = getckey( FALSE) ; /* get a command sequence */
@ -190,17 +194,19 @@ BINDABLE( unbindkey) {
/* prefix key sequence can't be undound, just redefined */ /* prefix key sequence can't be undound, just redefined */
if( c == reptc || c == abortc) if( c == reptc || c == abortc)
return mloutfail( "(Can't unbind prefix)") ; return cmdfail( "(Can't unbind prefix)") ;
/* if it isn't bound, bitch */ /* if it isn't bound, bitch */
if( delkeybinding( c) == FALSE) if( delkeybinding( c) == FALSE) {
return mloutfail( "(Key not bound)") ; mlwrite( "(Key not bound)") ;
return FALSE ;
}
return TRUE ; return TRUE ;
} }
/*
/* does source include sub? * does source include sub?
* *
* char *source; string to search in * char *source; string to search in
* char *sub; substring to look for * char *sub; substring to look for
@ -226,7 +232,6 @@ static boolean strinc( const char *source, const char *sub) {
return FALSE ; return FALSE ;
} }
/* describe bindings /* describe bindings
* bring up a fake buffer and list the key bindings * bring up a fake buffer and list the key bindings
* into it with view mode * into it with view mode
@ -235,7 +240,6 @@ BINDABLE( desbind) {
return buildlist( "") ; return buildlist( "") ;
} }
/* Apropos (List functions that match a substring) */ /* Apropos (List functions that match a substring) */
BINDABLE( apro) { BINDABLE( apro) {
char *mstring ; /* string to match cmd names to */ char *mstring ; /* string to match cmd names to */
@ -250,14 +254,17 @@ BINDABLE( apro) {
return status ; return status ;
} }
/*
/* build a binding list (limited or full) * build a binding list (limited or full)
* *
* char *mstring; match string if a partial list, "" matches all * char *mstring; match string if a partial list, "" matches all
*/ */
static int buildlist( char *mstring) { static int buildlist( char *mstring) {
#define PADDING 28 struct window *wp; /* scanning pointer to windows */
char outseq[ PADDING + 8] ; /* output buffer for command + keystroke */ kbind_p ktp; /* pointer into the command table */
nbind_p nptr;/* pointer into the name binding table */
struct buffer *bp; /* buffer to put binding list into */
char outseq[80]; /* output buffer for keystroke sequence */
/* split the current window to make room for the binding list */ /* split the current window to make room for the binding list */
if( wheadp->w_wndp == NULL /* One window */ if( wheadp->w_wndp == NULL /* One window */
@ -265,12 +272,12 @@ static int buildlist( char *mstring) {
return FALSE; return FALSE;
/* and get a buffer for it */ /* and get a buffer for it */
buffer_p bp = bfind( "*Binding list*", TRUE, 0) ; bp = bfind("*Binding list*", TRUE, 0);
if( bp == NULL || bclear( bp) == FALSE) if( bp == NULL || bclear( bp) == FALSE)
return mloutfail( "Can't display binding list") ; return cmdfail( "Can't display binding list") ;
/* let us know this is in progress */ /* let us know this is in progress */
mloutstr( "(Building binding list)") ; mlwrite("(Building binding list)");
/* disconnect the current buffer */ /* disconnect the current buffer */
if (--curbp->b_nwnd == 0) { /* Last use. */ if (--curbp->b_nwnd == 0) { /* Last use. */
@ -284,7 +291,7 @@ static int buildlist( char *mstring) {
curbp = bp; /* make this buffer current in current window */ curbp = bp; /* make this buffer current in current window */
bp->b_mode = 0; /* no modes active in binding list */ bp->b_mode = 0; /* no modes active in binding list */
bp->b_nwnd++; /* mark us as more in use */ bp->b_nwnd++; /* mark us as more in use */
window_p wp = curwp ; wp = curwp;
wp->w_bufp = bp; wp->w_bufp = bp;
wp->w_linep = bp->b_linep; wp->w_linep = bp->b_linep;
wp->w_flag = WFHARD | WFFORCE; wp->w_flag = WFHARD | WFFORCE;
@ -294,7 +301,7 @@ static int buildlist( char *mstring) {
wp->w_marko = 0; wp->w_marko = 0;
/* build the contents of this window, inserting it line by line */ /* build the contents of this window, inserting it line by line */
for( nbind_p nptr = names ; nptr->n_func != NULL ; nptr++) { for( nptr = names ; nptr->n_func != NULL ; nptr++) {
int cpos ; /* current position to use in outseq */ int cpos ; /* current position to use in outseq */
/* if we are executing an apropos command..... */ /* if we are executing an apropos command..... */
@ -307,10 +314,10 @@ static int buildlist( char *mstring) {
cpos = strlen(outseq); cpos = strlen(outseq);
/* search down any keys bound to this */ /* search down any keys bound to this */
for( kbind_p ktp = keytab ; ktp->k_code != 0 ; ktp++) { for( ktp = keytab ; ktp->k_code != 0 ; ktp++) {
if( ktp->k_nbp == nptr) { if( ktp->k_nbp == nptr) {
/* padd out some spaces */ /* padd out some spaces */
while( cpos < PADDING) while (cpos < 28)
outseq[cpos++] = ' '; outseq[cpos++] = ' ';
/* add in the command sequence */ /* add in the command sequence */
@ -339,12 +346,12 @@ static int buildlist( char *mstring) {
wp->w_dotp = lforw(bp->b_linep); /* back to the beginning */ wp->w_dotp = lforw(bp->b_linep); /* back to the beginning */
wp->w_doto = 0; wp->w_doto = 0;
upmode() ; /* and update ALL mode lines */ upmode() ; /* and update ALL mode lines */
mloutstr( "") ; /* clear the mode line */ mlwrite(""); /* clear the mode line */
return TRUE; return TRUE;
} }
/*
/* get a command key sequence from the keyboard * get a command key sequence from the keyboard
* *
* int mflag; going for a meta sequence? * int mflag; going for a meta sequence?
* returns ~0 on failure * returns ~0 on failure
@ -371,8 +378,8 @@ static unsigned int getckey( int mflag) {
return c ; return c ;
} }
/*
/* execute the startup file * execute the startup file
* *
* char *fname; name of startup file (null if default) * char *fname; name of startup file (null if default)
*/ */
@ -387,8 +394,8 @@ int startup( const char *fname) {
return dofile( fname) ; /* otherwise, execute the sucker */ return dofile( fname) ; /* otherwise, execute the sucker */
} }
/*
/* change a key command to a string we can print out * change a key command to a string we can print out
* *
* int c; sequence to translate * int c; sequence to translate
* char *seq; destination string for sequence * char *seq; destination string for sequence
@ -404,14 +411,14 @@ static char *cmdstr( unsigned c, char *seq) {
/* apply ^X sequence if needed */ /* apply ^X sequence if needed */
if( c & CTLX) { if( c & CTLX) {
if( ctlxc & CTL_) if( ctlxc & CTRL)
*ptr++ = '^' ; *ptr++ = '^' ;
*ptr++ = ctlxc & ~PRFXMASK ; *ptr++ = ctlxc & ~PRFXMASK ;
} }
/* apply control sequence if needed */ /* apply control sequence if needed */
if( c & CTL_) if( c & CTRL)
*ptr++ = '^' ; *ptr++ = '^' ;
/* apply SPEC sequence if needed */ /* apply SPEC sequence if needed */
@ -426,7 +433,6 @@ static char *cmdstr( unsigned c, char *seq) {
return seq ; return seq ;
} }
static const char *getfname( unsigned keycode, const char *failmsg) { static const char *getfname( unsigned keycode, const char *failmsg) {
/* takes a key code and gets the name of the function bound to it */ /* takes a key code and gets the name of the function bound to it */
kbind_p kbp = getkeybinding( keycode) ; kbind_p kbp = getkeybinding( keycode) ;
@ -438,7 +444,6 @@ static const char *getfname( unsigned keycode, const char *failmsg) {
return found ; return found ;
} }
/* stock: /* stock:
* String key name TO Command Key * String key name TO Command Key
* *
@ -461,7 +466,7 @@ static unsigned int stock( char *keyname) {
/* a control char? */ /* a control char? */
if( *keyname == '^' && keyname[ 1] != 0) { if( *keyname == '^' && keyname[ 1] != 0) {
c |= CTL_ ; c |= CTRL ;
++keyname ; ++keyname ;
} }
@ -477,7 +482,7 @@ static unsigned int stock( char *keyname) {
/* only way to redefine ^X is by quoting binary value */ /* only way to redefine ^X is by quoting binary value */
if( *keyname < 32 || *keyname == 0x7F) { if( *keyname < 32 || *keyname == 0x7F) {
c |= CTL_ ; c |= CTRL ;
*keyname ^= 0x40 ; *keyname ^= 0x40 ;
} else if( c && !(c & SPEC) } else if( c && !(c & SPEC)
&& *keyname >= 'a' && *keyname <= 'z') && *keyname >= 'a' && *keyname <= 'z')
@ -489,8 +494,8 @@ static unsigned int stock( char *keyname) {
return c ; return c ;
} }
/*
/* string key name to binding name.... * string key name to binding name....
* *
* char *skey; name of key to get binding for * char *skey; name of key to get binding for
*/ */

4
bind.h
View File

@ -1,5 +1,3 @@
/* bind.h -- bindable functions dealing with name and key bindings */
#ifndef _BIND_H_ #ifndef _BIND_H_
#define _BIND_H_ #define _BIND_H_
@ -19,5 +17,3 @@ int startup( const char *fname) ;
const char *transbind( char *skey) ; /* by string representation of key */ const char *transbind( char *skey) ; /* by string representation of key */
#endif #endif
/* end of bind.h */

View File

@ -3,48 +3,64 @@
#include <stdlib.h> #include <stdlib.h>
#include "defines.h" #include "defines.h"
#include "buffer.h" #include "buffer.h"
#include "display.h" /* vttidy() */ #include "display.h"
#include "estruct.h"
#include "file.h" #include "file.h"
#include "input.h" #include "input.h"
#include "lock.h" #include "lock.h"
#include "mlout.h" #include "mlout.h"
#include "terminal.h" #include "terminal.h"
/*
/* Fancy quit command, as implemented by Norm. If any buffer has changed * Fancy quit command, as implemented by Norm. If the any buffer has
do a write on that buffer and exit emacs, otherwise simply exit. * changed do a write on that buffer and exit emacs, otherwise simply exit.
*/ */
BINDABLE( quickexit) { int quickexit(int f, int n)
buffer_p oldcb = curbp ; /* save in case we fail */ {
for( buffer_p bp = bheadp ; bp != NULL ; bp = bp->b_bufp) { struct buffer *bp; /* scanning pointer to buffers */
if( (bp->b_flag & (BFCHG | BFTRUNC | BFINVS)) == BFCHG) { struct buffer *oldcb; /* original current buffer */
/* Changed, Not truncated and real buffer */ int status;
oldcb = curbp; /* save in case we fail */
bp = bheadp;
while (bp != NULL) {
if ((bp->b_flag & BFCHG) != 0 /* Changed. */
&& (bp->b_flag & BFTRUNC) == 0 /* Not truncated P.K. */
&& (bp->b_flag & BFINVS) == 0) { /* Real. */
curbp = bp; /* make that buffer cur */ curbp = bp; /* make that buffer cur */
mloutfmt( "(Saving %s)", bp->b_fname) ; mloutfmt( "(Saving %s)", bp->b_fname) ;
int status = filesave( f, n) ; #if PKCODE
if( status != TRUE) { #else
mloutstr( "\n") ;
#endif
if ((status = filesave(f, n)) != TRUE) {
curbp = oldcb; /* restore curbp */ curbp = oldcb; /* restore curbp */
return status; return status;
} }
} }
bp = bp->b_bufp; /* on to the next buffer */
}
quit(f, n); /* conditionally quit */
return TRUE;
} }
return quit( f, n) ; /* conditionally quit */ /*
} * Quit command. If an argument, always quit. Otherwise confirm if a buffer
/* Quit command. If an argument, always quit. Otherwise confirm if a buffer
* has been changed and not written out. Normally bound to "C-X C-C". * has been changed and not written out. Normally bound to "C-X C-C".
*/ */
BINDABLE( quit) { int quit(int f, int n)
int s ; /* status of user query */ {
int s;
if (f != FALSE /* Argument forces it. */ if (f != FALSE /* Argument forces it. */
|| anycb() == FALSE /* All buffers clean. */ || anycb() == FALSE /* All buffers clean. */
/* User says it's OK. */ /* User says it's OK. */
|| (s = mlyesno( "Modified buffers exist. Leave anyway")) == TRUE) { || (s =
mlyesno("Modified buffers exist. Leave anyway")) == TRUE) {
#if (FILOCK && BSD) || SVR4 #if (FILOCK && BSD) || SVR4
if (lockrel() != TRUE) { if (lockrel() != TRUE) {
TTputc('\n'); TTputc('\n');
@ -60,67 +76,70 @@ BINDABLE( quit) {
else else
exit( EXIT_SUCCESS) ; exit( EXIT_SUCCESS) ;
} }
mloutstr( "") ; mloutstr( "") ;
return s; return s;
} }
/*
/* Begin a keyboard macro. * Begin a keyboard macro.
* Error if not at the top level in keyboard processing. Set up variables and * Error if not at the top level in keyboard processing. Set up variables and
* return. * return.
*/ */
BBINDABLE( ctlxlp) { int ctlxlp(int f, int n)
if( kbdmode != STOP) {
return mloutfail( "%Macro already active") ; if (kbdmode != STOP) {
mloutstr( "%Macro already active") ;
return FALSE;
}
mloutstr( "(Start macro)") ; mloutstr( "(Start macro)") ;
kbdptr = kbdm ; kbdptr = &kbdm[0];
kbdend = kbdptr; kbdend = kbdptr;
kbdmode = RECORD; kbdmode = RECORD;
return TRUE; return TRUE;
} }
/*
/* End keyboard macro. Check for the same limit conditions as the above * End keyboard macro. Check for the same limit conditions as the above
* routine. Set up the variables and return to the caller. * routine. Set up the variables and return to the caller.
*/ */
BBINDABLE( ctlxrp) { int ctlxrp(int f, int n)
if( kbdmode == STOP) {
return mloutfail( "%Macro not active") ; if (kbdmode == STOP) {
mloutstr( "%Macro not active") ;
return FALSE;
}
if (kbdmode == RECORD) { if (kbdmode == RECORD) {
mloutstr( "(End macro)") ; mloutstr( "(End macro)") ;
kbdmode = STOP; kbdmode = STOP;
} }
return TRUE; return TRUE;
} }
/*
/* Execute a macro. * Execute a macro.
* The command argument is the number of times to loop. Quit as soon as a * The command argument is the number of times to loop. Quit as soon as a
* command gets an error. Return TRUE if all ok, else FALSE. * command gets an error. Return TRUE if all ok, else FALSE.
*/ */
BBINDABLE( ctlxe) { int ctlxe(int f, int n)
if( kbdmode != STOP) {
return mloutfail( "%Macro already active") ; if (kbdmode != STOP) {
mloutstr( "%Macro already active") ;
return FALSE;
}
if (n <= 0) if (n <= 0)
return TRUE; return TRUE;
kbdrep = n; /* remember how many times to execute */ kbdrep = n; /* remember how many times to execute */
kbdmode = PLAY; /* start us in play mode */ kbdmode = PLAY; /* start us in play mode */
kbdptr = kbdm ; /* at the beginning */ kbdptr = &kbdm[0]; /* at the beginning */
return TRUE; return TRUE;
} }
/*
/* abort: * abort:
* Beep the beeper. Kill off any keyboard macro, etc., that is in progress. * Beep the beeper. Kill off any keyboard macro, etc., that is in progress.
* Sometimes called as a routine, to do general aborting of stuff. * Sometimes called as a routine, to do general aborting of stuff.
*/ */
BINDABLE( ctrlg) { int ctrlg( int f, int n) {
kbdmode = STOP ; kbdmode = STOP ;
mloutfmt( "%B(Aborted)") ; mloutfmt( "%B(Aborted)") ;
return ABORT ; return ABORT ;

View File

@ -1,16 +1,9 @@
/* bindable.h -- misc bindable functions */
#ifndef _BINDABLE_H_
#define _BINDABLE_H_
#include "names.h" #include "names.h"
/* functions that can be bound to keys or procedure names */ /* functions that can be bound to keys or procedure names */
BBINDABLE( ctlxe) ;
BBINDABLE( ctlxlp) ;
BBINDABLE( ctlxrp) ;
BINDABLE( ctrlg) ; /* ABORT */
BINDABLE( quickexit) ; BINDABLE( quickexit) ;
BINDABLE( quit) ; BINDABLE( quit) ;
BINDABLE( ctlxlp) ;
#endif BINDABLE( ctlxrp) ;
/* end of bindable.h */ BINDABLE( ctlxe) ;
BINDABLE( ctrlg) ;

355
buffer.c
View File

@ -1,12 +1,18 @@
/* buffer.c -- implements buffer.h */ /* buffer.c -- implements buffer.h */
#include "buffer.h" #include "buffer.h"
/* Buffer management. Some of the functions are internal, and some are actually attached to /* buffer.c
user keys. Like everyone else, they set hints for the display system. *
* Buffer management.
modified by Petri Kutvonen * 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
*/ */
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -20,11 +26,11 @@
#include "window.h" #include "window.h"
buffer_p curbp ; /* Current buffer */ struct buffer *curbp ; /* Current buffer */
buffer_p bheadp ; /* Head of list of buffers */ struct buffer *bheadp ; /* Head of list of buffers */
buffer_p blistp ; /* Buffer for C-X C-B */ struct buffer *blistp ; /* Buffer for C-X C-B */
const char *modename[ NUMMODES] = { /* name of modes */ const char *modename[] = { /* name of modes */
"Wrap", "Cmode", "Exact", "View", "Over", "Wrap", "Cmode", "Exact", "View", "Over",
"Magic", "Magic",
"Asave", "Utf-8", "Dos" "Asave", "Utf-8", "Dos"
@ -37,20 +43,24 @@ static int addline( char *text) ;
static void l_to_a( char *buf, int width, long num) ; static void l_to_a( char *buf, int width, long num) ;
/* Attach a buffer to a window. The values of dot and mark come from the /*
buffer if the use count is 0. Otherwise, they come from some other * Attach a buffer to a window. The
window. * values of dot and mark come from the buffer
* if the use count is 0. Otherwise, they come
* from some other window.
*/ */
BINDABLE( usebuffer) { int usebuffer( int f, int n) {
struct buffer *bp ;
int status ;
char *bufn ; char *bufn ;
/* Get buffer name */ /* Get buffer name */
int status = newmlarg( &bufn, "select-buffer: ", sizeof( bname_t)) ; status = newmlarg( &bufn, "Use buffer: ", sizeof( bname_t)) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
/* Find buffer in list */ /* Find buffer in list */
buffer_p bp = bfind( bufn, TRUE, 0) ; bp = bfind( bufn, TRUE, 0) ;
free( bufn) ; free( bufn) ;
if( bp == NULL) if( bp == NULL)
return FALSE ; return FALSE ;
@ -59,27 +69,28 @@ BINDABLE( usebuffer) {
return swbuffer( bp) ; return swbuffer( bp) ;
} }
/*
/* switch to the next buffer in the buffer list * switch to the next buffer in the buffer list
* *
* int f, n; default flag, numeric argument * int f, n; default flag, numeric argument
*/ */
BINDABLE( nextbuffer) { int nextbuffer(int f, int n)
buffer_p bp = NULL ; /* eligible buffer to switch to */ {
struct buffer *bp = NULL; /* eligable buffer to switch to */
struct buffer *bbp; /* eligable buffer to switch to */
/* make sure the arg is legit */ /* make sure the arg is legit */
if (f == FALSE) if (f == FALSE)
n = 1; n = 1;
if (n < 1) if (n < 1)
return FALSE; return FALSE;
buffer_p bbp = curbp ; /* eligible buffer to switch to */ bbp = curbp;
while (n-- > 0) { while (n-- > 0) {
/* advance to the next buffer */ /* advance to the next buffer */
bp = bbp->b_bufp; bp = bbp->b_bufp;
/* cycle through the buffers to find an eligible one */ /* cycle through the buffers to find an eligable one */
while (bp == NULL || bp->b_flag & BFINVS) { while (bp == NULL || bp->b_flag & BFINVS) {
if (bp == NULL) if (bp == NULL)
bp = bheadp; bp = bheadp;
@ -89,6 +100,7 @@ BINDABLE( nextbuffer) {
/* don't get caught in an infinite loop! */ /* don't get caught in an infinite loop! */
if (bp == bbp) if (bp == bbp)
return FALSE; return FALSE;
} }
bbp = bp; bbp = bp;
@ -97,11 +109,12 @@ BINDABLE( nextbuffer) {
return swbuffer(bp); return swbuffer(bp);
} }
/*
/* make buffer BP current * make buffer BP current
*/ */
int swbuffer( buffer_p bp) { int swbuffer(struct buffer *bp)
window_p wp ; {
struct window *wp;
if (--curbp->b_nwnd == 0) { /* Last use. */ if (--curbp->b_nwnd == 0) { /* Last use. */
curbp->b_dotp = curwp->w_dotp; curbp->b_dotp = curwp->w_dotp;
@ -144,19 +157,21 @@ int swbuffer( buffer_p bp) {
return TRUE; return TRUE;
} }
/*
/* Dispose of a buffer, by name. Ask for the name. Look it up (don't get * Dispose of a buffer, by name.
too upset if it isn't there at all!). Get quite upset if the buffer is * Ask for the name. Look it up (don't get too
being displayed. Clear the buffer (ask if the buffer has been changed). * upset if it isn't there at all!). Get quite upset
Then free the header line and the buffer header. Bound to "C-X K". * if the buffer is being displayed. Clear the buffer (ask
* if the buffer has been changed). Then free the header
* line and the buffer header. Bound to "C-X K".
*/ */
BINDABLE( killbuffer) { int killbuffer( int f, int n) {
buffer_p bp ; struct buffer *bp ;
int status ; int status ;
char *bufn ; char *bufn ;
/* Get buffer name */ /* Get buffer name */
status = newmlarg( &bufn, "delete-buffer: ", sizeof( bname_t)) ; status = newmlarg( &bufn, "Kill buffer: ", sizeof( bname_t)) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
@ -172,60 +187,66 @@ BINDABLE( killbuffer) {
return zotbuf( bp) ; return zotbuf( bp) ;
} }
/*
/* kill the buffer pointed to by bp * kill the buffer pointed to by bp
*/ */
int zotbuf( buffer_p bp) { int zotbuf(struct buffer *bp)
if( bp->b_nwnd != 0) /* Error if on screen. */ {
return mloutfail( "Buffer is being displayed") ; struct buffer *bp1;
struct buffer *bp2;
int s;
int s = bclear( bp) ; /* Blow text away. */ if (bp->b_nwnd != 0) { /* Error if on screen. */
if( s != TRUE) mloutstr("Buffer is being displayed");
return s ; return FALSE;
free( bp->b_linep) ; /* Release header line. */
/* unlink buffer from buffer chain */
if( bheadp == bp)
bheadp = bp->b_bufp ;
else for( buffer_p prev = bheadp ; prev != NULL ; prev = prev->b_bufp)
if( prev->b_bufp == bp) {
prev->b_bufp = bp->b_bufp ;
break ;
} }
if ((s = bclear(bp)) != TRUE) /* Blow text away. */
free( bp) ; /* Release buffer block */ return s;
free((char *) bp->b_linep); /* Release header line. */
bp1 = NULL; /* Find the header. */
bp2 = bheadp;
while (bp2 != bp) {
bp1 = bp2;
bp2 = bp2->b_bufp;
}
bp2 = bp2->b_bufp; /* Next one in chain. */
if (bp1 == NULL) /* Unlink it. */
bheadp = bp2;
else
bp1->b_bufp = bp2;
free((char *) bp); /* Release buffer block */
return TRUE; return TRUE;
} }
/*
/* Rename the current buffer * Rename the current buffer
* *
* int f, n; default Flag & Numeric arg * int f, n; default Flag & Numeric arg
*/ */
BINDABLE( namebuffer) { int namebuffer( int f, int n) {
char *bufn ; /* buffer to hold buffer name */ struct buffer *bp ; /* pointer to scan through all buffers */
int status ; int status ;
char *bufn ; /* buffer to hold buffer name */
/* iterate until it gets a unique new buffer name */ /* prompt for and get the new buffer name */
do { ask:
/* prompt for it */ status = newmlarg( &bufn, "Change buffer name to: ", sizeof( bname_t)) ;
status = newmlarg( &bufn, "name-buffer: ", sizeof( bname_t)) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
/* and check for duplicates */ /* and check for duplicates */
for( buffer_p bp = bheadp ; bp != NULL ; bp = bp->b_bufp) { bp = bheadp ;
if( bp != curbp) { /* it's ok to rename buffer to same, so skip */ while( bp != NULL) {
if( bp != curbp) {
/* retry if the names are the same */ /* retry if the names are the same */
if( strcmp( bufn, bp->b_bname) == 0) { if( strcmp( bufn, bp->b_bname) == 0) {
free( bufn) ; free( bufn) ;
status = FALSE ; /* try again */ goto ask ; /* try again */
break ;
} }
} }
bp = bp->b_bufp ; /* onward */
} }
} while( !status) ;
/* copy buffer name to structure */ /* copy buffer name to structure */
mystrscpy( curbp->b_bname, bufn, sizeof( bname_t)) ; mystrscpy( curbp->b_bname, bufn, sizeof( bname_t)) ;
@ -236,28 +257,28 @@ BINDABLE( namebuffer) {
return TRUE ; return TRUE ;
} }
/*
/* List all of the active buffers. First update the special buffer that * List all of the active buffers. First update the special
holds the list. Next make sure at least 1 window is displaying the * buffer that holds the list. Next make sure at least 1
buffer list, splitting the screen if this is what it takes. Lastly, * window is displaying the buffer list, splitting the screen
repaint all of the windows that are displaying the list. Bound to "C-X * if this is what it takes. Lastly, repaint all of the
C-B". * windows that are displaying the list. Bound to "C-X C-B".
*
A numeric argument forces it to list invisible buffers as well. * A numeric argument forces it to list invisible buffers as
* well.
*/ */
BINDABLE( listbuffers) { int listbuffers(int f, int n)
window_p wp ; {
struct window *wp;
int s;
int s = makelist( f) ; if ((s = makelist(f)) != TRUE)
if( s != TRUE)
return s; return s;
if (blistp->b_nwnd == 0) { /* Not on screen yet. */ if (blistp->b_nwnd == 0) { /* Not on screen yet. */
buffer_p bp ; struct buffer *bp ;
if ((wp = wpopup()) == NULL) if ((wp = wpopup()) == NULL)
return FALSE; return FALSE;
bp = wp->w_bufp; bp = wp->w_bufp;
if (--bp->b_nwnd == 0) { if (--bp->b_nwnd == 0) {
bp->b_dotp = wp->w_dotp; bp->b_dotp = wp->w_dotp;
@ -265,12 +286,11 @@ BINDABLE( listbuffers) {
bp->b_markp = wp->w_markp; bp->b_markp = wp->w_markp;
bp->b_marko = wp->w_marko; bp->b_marko = wp->w_marko;
} }
wp->w_bufp = blistp; wp->w_bufp = blistp;
++blistp->b_nwnd; ++blistp->b_nwnd;
} }
wp = wheadp;
for( wp = wheadp ; wp != NULL ; wp = wp->w_wndp) { while (wp != NULL) {
if (wp->w_bufp == blistp) { if (wp->w_bufp == blistp) {
wp->w_linep = lforw(blistp->b_linep); wp->w_linep = lforw(blistp->b_linep);
wp->w_dotp = lforw(blistp->b_linep); wp->w_dotp = lforw(blistp->b_linep);
@ -279,18 +299,21 @@ BINDABLE( listbuffers) {
wp->w_marko = 0; wp->w_marko = 0;
wp->w_flag |= WFMODE | WFHARD; wp->w_flag |= WFMODE | WFHARD;
} }
wp = wp->w_wndp;
} }
return TRUE; return TRUE;
} }
/*
/* This routine rebuilds the text in the special secret buffer that holds * This routine rebuilds the
the buffer list. It is called by the list buffers command. Return TRUE * text in the special secret buffer
if everything works. Return FALSE if there is an error (if there is no * that holds the buffer list. It is called
memory). Iflag indicates wether to list hidden buffers. * by the list buffers command. Return TRUE
* if everything works. Return FALSE if there
int iflag; list hidden buffer flag * is an error (if there is no memory). Iflag
* indicates wether to list hidden buffers.
*
* int iflag; list hidden buffer flag
*/ */
/* Layout: "ACT MODES Size Buffer File" /* Layout: "ACT MODES Size Buffer File"
AAA MMMMMMMMMSSSSSSSSSS BBBBBBBBBBBBBBB FFF... AAA MMMMMMMMMSSSSSSSSSS BBBBBBBBBBBBBBB FFF...
@ -310,7 +333,6 @@ static void do_layout( char *line, int mode) {
line[ 4 + i] = '.' ; line[ 4 + i] = '.' ;
} }
static unsigned int utf8_disp_len( const char *s) { static unsigned int utf8_disp_len( const char *s) {
unsigned int len = 0 ; unsigned int len = 0 ;
@ -324,9 +346,9 @@ static unsigned int utf8_disp_len( const char *s) {
return len ; return len ;
} }
static int makelist( int iflag)
static int makelist( int iflag) { {
buffer_p bp; struct buffer *bp;
int s; int s;
char line[ FNAMSTART + sizeof( fname_t)] ; char line[ FNAMSTART + sizeof( fname_t)] ;
@ -349,7 +371,7 @@ static int makelist( int iflag) {
for( bp = bheadp ; bp != NULL ; bp = bp->b_bufp) { /* For all buffers */ for( bp = bheadp ; bp != NULL ; bp = bp->b_bufp) { /* For all buffers */
char *cp1, *cp2 ; char *cp1, *cp2 ;
int c ; int c ;
line_p lp ; struct line *lp ;
long nbytes ; /* # of bytes in current buffer */ long nbytes ; /* # of bytes in current buffer */
long nlines ; /* # of lines in current buffer */ long nlines ; /* # of lines in current buffer */
@ -408,8 +430,8 @@ static int makelist( int iflag) {
return TRUE ; /* All done */ return TRUE ; /* All done */
} }
static void l_to_a(char *buf, int width, long num)
static void l_to_a(char *buf, int width, long num) { {
buf[ --width] = 0 ; /* End of string. */ buf[ --width] = 0 ; /* End of string. */
while (num >= 10) { /* Conditional digits. */ while (num >= 10) { /* Conditional digits. */
buf[--width] = (int) (num % 10L) + '0'; buf[--width] = (int) (num % 10L) + '0';
@ -420,82 +442,87 @@ static void l_to_a(char *buf, int width, long num) {
buf[--width] = ' '; buf[--width] = ' ';
} }
/*
/* The argument "text" points to a string. Append this line to the buffer * The argument "text" points to
list buffer. Handcraft the EOL on the end. Return TRUE if it worked * a string. Append this line to the
and FALSE if you ran out of room. * buffer list buffer. Handcraft the EOL
* on the end. Return TRUE if it worked and
* FALSE if you ran out of room.
*/ */
static int addline( char *text) { static int addline( char *text)
int ntext = strlen( text) ; {
line_p lp = lalloc( ntext) ; struct line *lp;
if( lp == NULL) int i;
int ntext;
ntext = strlen(text);
if ((lp = lalloc(ntext)) == NULL)
return FALSE; return FALSE;
for (i = 0; i < ntext; ++i)
for( int i = 0 ; i < ntext ; ++i)
lputc(lp, i, text[i]); lputc(lp, i, text[i]);
blistp->b_linep->l_bp->l_fp = lp; /* Hook onto the end */ blistp->b_linep->l_bp->l_fp = lp; /* Hook onto the end */
lp->l_bp = blistp->b_linep->l_bp; lp->l_bp = blistp->b_linep->l_bp;
blistp->b_linep->l_bp = lp; blistp->b_linep->l_bp = lp;
lp->l_fp = blistp->b_linep; lp->l_fp = blistp->b_linep;
if (blistp->b_dotp == blistp->b_linep) /* If "." is at the end */ if (blistp->b_dotp == blistp->b_linep) /* If "." is at the end */
blistp->b_dotp = lp; /* move it to new line */ blistp->b_dotp = lp; /* move it to new line */
return TRUE; return TRUE;
} }
/*
/* Look through the list of buffers. Return TRUE if there are any changed * Look through the list of
buffers. Buffers that hold magic internal stuff are not considered; who * buffers. Return TRUE if there
cares if the list of buffer names is hacked. Return FALSE if no buffers * are any changed buffers. Buffers
have been changed. * that hold magic internal stuff are
* not considered; who cares if the
* list of buffer names is hacked.
* Return FALSE if no buffers
* have been changed.
*/ */
boolean anycb( void) { int anycb(void)
for( buffer_p bp = bheadp ; bp != NULL ; bp = bp->b_bufp) { {
if( (bp->b_flag & (BFINVS | BFCHG)) == BFCHG) struct buffer *bp;
return TRUE ;
}
bp = bheadp;
while (bp != NULL) {
if ((bp->b_flag & BFINVS) == 0
&& (bp->b_flag & BFCHG) != 0)
return TRUE;
bp = bp->b_bufp;
}
return FALSE; return FALSE;
} }
/*
/* Find a buffer, by name. Return a pointer to the buffer structure * Find a buffer, by name. Return a pointer
associated with it. If the buffer is not found and the "create_f" is * to the buffer structure associated with it.
TRUE, create it. The "flags" is the settings for the buffer flags. * If the buffer is not found
* and the "cflag" is TRUE, create it. The "bflag" is
* the settings for the flags in in buffer.
*/ */
buffer_p bfind( const char *bname, boolean create_f, int flags) { struct buffer *bfind( const char *bname, int cflag, int bflag)
buffer_p bp ; {
struct buffer *bp;
struct line *lp;
for( bp = bheadp ; bp != NULL ; bp = bp->b_bufp) for( bp = bheadp ; bp != NULL ; bp = bp->b_bufp)
if( strcmp( bname, bp->b_bname) == 0) if( strcmp( bname, bp->b_bname) == 0)
return bp ; return bp ;
if( create_f != FALSE) { if (cflag != FALSE) {
/* allocate empty buffer */ if ((bp = (struct buffer *)malloc(sizeof(struct buffer))) == NULL)
bp = malloc( sizeof *bp) ;
if( bp == NULL)
return NULL; return NULL;
if ((lp = lalloc(0)) == NULL) {
line_p lp = lalloc( 0) ; free((char *) bp);
if( lp == NULL) {
free( bp) ;
return NULL; return NULL;
} }
lp->l_fp = lp ;
lp->l_bp = lp ;
bp->b_linep = lp ;
bp->b_dotp = lp ;
bp->b_doto = 0 ;
/* find the place in the list to insert this buffer */ /* find the place in the list to insert this buffer */
if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0) { if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0) {
/* insert at the beginning */ /* insert at the beginning */
bp->b_bufp = bheadp; bp->b_bufp = bheadp;
bheadp = bp; bheadp = bp;
} else { } else {
buffer_p sb ; /* buffer to insert after */ struct buffer *sb; /* buffer to insert after */
for( sb = bheadp ; sb->b_bufp != NULL ; sb = sb->b_bufp) for( sb = bheadp ; sb->b_bufp != NULL ; sb = sb->b_bufp)
if( strcmp( sb->b_bufp->b_bname, bname) > 0) if( strcmp( sb->b_bufp->b_bname, bname) > 0)
@ -508,37 +535,44 @@ buffer_p bfind( const char *bname, boolean create_f, int flags) {
/* and set up the other buffer fields */ /* and set up the other buffer fields */
bp->b_active = TRUE; bp->b_active = TRUE;
bp->b_dotp = lp;
bp->b_doto = 0;
bp->b_markp = NULL; bp->b_markp = NULL;
bp->b_marko = 0; bp->b_marko = 0;
bp->b_flag = flags ; bp->b_flag = bflag;
bp->b_mode = gmode; bp->b_mode = gmode;
bp->b_nwnd = 0; bp->b_nwnd = 0;
bp->b_linep = lp;
bp->b_fname[ 0] = '\0' ; bp->b_fname[ 0] = '\0' ;
mystrscpy( bp->b_bname, bname, sizeof( bname_t)) ; mystrscpy( bp->b_bname, bname, sizeof( bname_t)) ;
lp->l_fp = lp;
lp->l_bp = lp;
} }
return bp; return bp;
} }
/*
/* This routine blows away all of the text in a buffer. If the buffer is * This routine blows away all of the text
marked as changed then we ask if it is ok to blow it away; this is to * in a buffer. If the buffer is marked as changed
save the user the grief of losing text. The window chain is nearly * then we ask if it is ok to blow it away; this is
always wrong if this gets called; the caller must arrange for the * to save the user the grief of losing text. The
updates that are required. Return TRUE if everything looks good. * window chain is nearly always wrong if this gets
* called; the caller must arrange for the updates
* that are required. Return TRUE if everything
* looks good.
*/ */
int bclear( buffer_p bp) { int bclear(struct buffer *bp)
line_p lp ; {
struct line *lp;
int s; int s;
if( (bp->b_flag & (BFINVS | BFCHG)) == BFCHG /* regular and changed */ if ((bp->b_flag & BFINVS) == 0 /* Not scratch buffer. */
&& (bp->b_flag & BFCHG) != 0 /* Something changed */
&& (s = mlyesno("Discard changes")) != TRUE) && (s = mlyesno("Discard changes")) != TRUE)
return s; return s;
bp->b_flag &= ~BFCHG; /* Not changed */ bp->b_flag &= ~BFCHG; /* Not changed */
while ((lp = lforw(bp->b_linep)) != bp->b_linep) while ((lp = lforw(bp->b_linep)) != bp->b_linep)
lfree(lp); lfree(lp);
bp->b_dotp = bp->b_linep; /* Fix "." */ bp->b_dotp = bp->b_linep; /* Fix "." */
bp->b_doto = 0; bp->b_doto = 0;
bp->b_markp = NULL; /* Invalidate "mark" */ bp->b_markp = NULL; /* Invalidate "mark" */
@ -546,15 +580,14 @@ int bclear( buffer_p bp) {
return TRUE; return TRUE;
} }
/*
/* unmark the current buffers change flag * unmark the current buffers change flag
* *
* int f, n; unused command arguments * int f, n; unused command arguments
*/ */
BINDABLE( unmark) { int unmark(int f, int n)
{
curbp->b_flag &= ~BFCHG; curbp->b_flag &= ~BFCHG;
curwp->w_flag |= WFMODE; curwp->w_flag |= WFMODE;
return TRUE; return TRUE;
} }
/* end of buffer.c */

View File

@ -1,25 +1,22 @@
/* buffer.h -- buffer type and functions */
#ifndef _BUFFER_H_ #ifndef _BUFFER_H_
#define _BUFFER_H_ #define _BUFFER_H_
#include "line.h" #include "line.h"
#include "names.h"
/* Text is kept in buffers. A buffer header, described below, exists for
every buffer in the system. The buffers are kept in a big list, so that
commands that search for a buffer by name can find the buffer header.
There is a safe store for the dot and mark in the header, but this is
only valid if the buffer is not being displayed (that is, if "b_nwnd" is
0). The text for the buffer is kept in a circularly linked list of
lines, with a pointer to the header line in "b_linep".
Buffers may be "Inactive" which means the files associated with them
have not been read in yet. These get read in at "use buffer" time.
*/
typedef char fname_t[ 256] ; /* file name type */ typedef char fname_t[ 256] ; /* file name type */
typedef char bname_t[ 16] ; /* buffer name type */ typedef char bname_t[ 16] ; /* buffer name type */
/*
* Text is kept in buffers. A buffer header, described below, exists for every
* buffer in the system. The buffers are kept in a big list, so that commands
* that search for a buffer by name can find the buffer header. There is a
* safe store for the dot and mark in the header, but this is only valid if
* the buffer is not being displayed (that is, if "b_nwnd" is 0). The text for
* the buffer is kept in a circularly linked list of lines, with a pointer to
* the header line in "b_linep".
* Buffers may be "Inactive" which means the files associated with them
* have not been read in yet. These get read in at "use buffer" time.
*/
typedef struct buffer { typedef struct buffer {
struct buffer *b_bufp; /* Link to next struct buffer */ struct buffer *b_bufp; /* Link to next struct buffer */
line_p b_dotp ; /* Link to "." struct line structure */ line_p b_dotp ; /* Link to "." struct line structure */
@ -56,27 +53,22 @@ extern buffer_p blistp ; /* Buffer for C-X C-B */
#define MDUTF8 0x0080 /* utf8 mode */ #define MDUTF8 0x0080 /* utf8 mode */
#define MDDOS 0x0100 /* CRLF eol mode */ #define MDDOS 0x0100 /* CRLF eol mode */
extern const char *modename[ NUMMODES] ; /* text names of modes */
extern const char *modename[] ; /* text names of modes */
extern int gmode ; /* global editor mode */ extern int gmode ; /* global editor mode */
/* Bindable functions */ int usebuffer( int f, int n) ;
BINDABLE( killbuffer) ; int nextbuffer( int f, int n) ;
BINDABLE( listbuffers) ; int swbuffer( buffer_p bp) ;
BINDABLE( namebuffer) ; int killbuffer( int f, int n) ;
BINDABLE( nextbuffer) ; int zotbuf( buffer_p bp) ;
BINDABLE( unmark) ; int namebuffer( int f, int n) ;
BINDABLE( usebuffer) ; int listbuffers( int f, int n) ;
int anycb( void) ;
boolean anycb( void) ; /* Any changed buffer? */ int bclear( buffer_p bp) ;
int bclear( buffer_p bp) ; /* empty buffer */ int unmark( int f, int n) ;
int swbuffer( buffer_p bp) ; /* switch to buffer, make it current */ /* Lookup a buffer by name. */
int zotbuf( buffer_p bp) ; /* remove buffer */ buffer_p bfind( const char *bname, int cflag, int bflag) ;
/* Lookup a buffer by name. If not found and create_f is TRUE then create
it with flags set.
*/
buffer_p bfind( const char *bname, boolean create_f, int flags) ;
#endif #endif
/* end of buffer.h */

View File

@ -1,14 +1,17 @@
/* display.c -- implements display.h */ /* display.c -- implements display.h */
#include "display.h" #include "display.h"
#define REVSTA 1 /* Status line appears in reverse video */ #define REVSTA 1 /* Status line appears in reverse video */
/* The functions in this file handle redisplay. There are two halves, the /* display.c
ones that update the virtual display screen, and the ones that make the *
physical display screen the same as the virtual display screen. These * The functions in this file handle redisplay. There are two halves, the
functions use hints that are left in the windows by the commands. * ones that update the virtual display screen, and the ones that make the
* physical display screen the same as the virtual display screen. These
Modified by Petri Kutvonen * functions use hints that are left in the windows by the commands.
*
* Modified by Petri Kutvonen
*/ */
#include <errno.h> #include <errno.h>
@ -248,11 +251,13 @@ static void vteeol( void) {
vcp[ vtcol++] = ' ' ; vcp[ vtcol++] = ' ' ;
} }
/* upscreen: /*
* upscreen:
* user routine to force a screen update * user routine to force a screen update
* always finishes complete update * always finishes complete update
*/ */
BINDABLE( upscreen) { int upscreen(int f, int n)
{
update(TRUE); update(TRUE);
return TRUE; return TRUE;
} }
@ -261,24 +266,25 @@ BINDABLE( upscreen) {
static int scrflags; static int scrflags;
#endif #endif
/*
/* Make sure that the display is right. This is a three part process. * Make sure that the display is right. This is a three part process. First,
First, scan through all of the windows looking for dirty ones. Check * scan through all of the windows looking for dirty ones. Check the framing,
the framing, and refresh the screen. Second, make sure that "currow" * and refresh the screen. Second, make sure that "currow" and "curcol" are
and "curcol" are correct for the current window. Third, make the * correct for the current window. Third, make the virtual and physical
virtual and physical screens the same. * screens the same.
*
boolean force_f ; force update past type ahead? * int force; force update past type ahead?
*/ */
int update( boolean force_f) { int update(int force)
{
struct window *wp; struct window *wp;
#if TYPEAH && ! PKCODE #if TYPEAH && ! PKCODE
if( force_f == FALSE && typahead()) if (force == FALSE && typahead())
return TRUE; return TRUE;
#endif #endif
#if VISMAC == 0 #if VISMAC == 0
if( force_f == FALSE && kbdmode == PLAY) if (force == FALSE && kbdmode == PLAY)
return TRUE; return TRUE;
#endif #endif
@ -353,7 +359,7 @@ int update( boolean force_f) {
updgar(); updgar();
/* update the virtual screen to the physical screen */ /* update the virtual screen to the physical screen */
updupd( force_f) ; updupd(force);
/* update the cursor and flush the buffers */ /* update the cursor and flush the buffers */
movecursor(currow, curcol - lbound); movecursor(currow, curcol - lbound);

View File

@ -1,12 +1,10 @@
/* display.h -- display functionality */
#ifndef _DISPLAY_H_ #ifndef _DISPLAY_H_
#define _DISPLAY_H_ #define _DISPLAY_H_
#include <stdarg.h> #include <stdarg.h>
#include "estruct.h" #include "estruct.h"
# include "names.h" /* BINDABLE() */ #include "utf8.h"
# include "utf8.h" /* unicode_t */
extern int mpresf ; /* Stuff in message line */ extern int mpresf ; /* Stuff in message line */
extern int scrollcount ; /* number of lines to scroll */ extern int scrollcount ; /* number of lines to scroll */
@ -15,13 +13,11 @@ extern int disinp ; /* display input characters (echo) */
extern int gfcolor ; /* global forgrnd color (white) */ extern int gfcolor ; /* global forgrnd color (white) */
extern int gbcolor ; /* global backgrnd color (black) */ extern int gbcolor ; /* global backgrnd color (black) */
/* Bindable functions */
BINDABLE( upscreen) ;
void vtinit( void) ; void vtinit( void) ;
void vtfree( void) ; void vtfree( void) ;
void vttidy( void) ; void vttidy( void) ;
int update( boolean force_f) ; int upscreen( int f, int n) ;
int update( int force) ;
void updpos( void) ; void updpos( void) ;
void upddex( void) ; void upddex( void) ;
void updgar( void) ; void updgar( void) ;
@ -45,5 +41,5 @@ extern int chg_width, chg_height ;
void sizesignal( int signr) ; void sizesignal( int signr) ;
#endif #endif
#endif #endif
#endif #endif
/* end of display.h */

30
eval.c
View File

@ -1,7 +1,9 @@
/* eval.c -- implements eval.h */ /* eval.c -- implements eval.h */
#include "eval.h" #include "eval.h"
/* Expression evaluation functions /* eval.c
*
* Expression evaluation functions
* *
* written 1986 by Daniel Lawrence * written 1986 by Daniel Lawrence
* modified by Petri Kutvonen * modified by Petri Kutvonen
@ -208,7 +210,7 @@ static struct {
{ "and", UFAND | DYNAMIC }, /* logical and */ { "and", UFAND | DYNAMIC }, /* logical and */
{ "asc", UFASCII | MONAMIC }, /* char to integer conversion */ { "asc", UFASCII | MONAMIC }, /* char to integer conversion */
{ "ban", UFBAND | DYNAMIC }, /* bitwise and 9-10-87 jwm */ { "ban", UFBAND | DYNAMIC }, /* bitwise and 9-10-87 jwm */
{ "bin", UFBIND | MONAMIC }, /* look up function name bound to key */ { "bin", UFBIND | MONAMIC }, /* loopup what function name is bound to a key */
{ "bno", UFBNOT | MONAMIC }, /* bitwise not */ { "bno", UFBNOT | MONAMIC }, /* bitwise not */
{ "bor", UFBOR | DYNAMIC }, /* bitwise or 9-10-87 jwm */ { "bor", UFBOR | DYNAMIC }, /* bitwise or 9-10-87 jwm */
{ "bxo", UFBXOR | DYNAMIC }, /* bitwise xor 9-10-87 jwm */ { "bxo", UFBXOR | DYNAMIC }, /* bitwise xor 9-10-87 jwm */
@ -795,13 +797,14 @@ static char *gtenv( char *vname) {
return errorm ; return errorm ;
} }
/*
/* set a variable * set a variable
* *
* int f; default flag * int f; default flag
* int n; numeric arg (can overide prompted value) * int n; numeric arg (can overide prompted value)
*/ */
BINDABLE( setvar) { int setvar(int f, int n)
{
int status; /* status return */ int status; /* status return */
struct variable_description vd; /* variable num/type */ struct variable_description vd; /* variable num/type */
char var[NVSIZE + 2]; /* name of variable to fetch %1234567890\0 */ char var[NVSIZE + 2]; /* name of variable to fetch %1234567890\0 */
@ -1463,25 +1466,28 @@ static void mlforce( char *s) {
discmd = oldcmd; /* and restore the original setting */ discmd = oldcmd; /* and restore the original setting */
} }
/*
/* This function simply clears the message line, mainly for macro usage * This function simply clears the message line,
* mainly for macro usage
* *
* int f, n; arguments ignored * int f, n; arguments ignored
*/ */
TBINDABLE( clrmes) { int clrmes( int f, int n) {
mlforce( "") ; mlforce( "") ;
return TRUE ; return TRUE ;
} }
/*
/* This function writes a string on the message line mainly for macro usage * This function writes a string on the message line
* mainly for macro usage
* *
* int f, n; arguments ignored * int f, n; arguments ignored
*/ */
BINDABLE( writemsg) { int writemsg( int f, int n) {
int status ;
char *buf ; /* buffer to receive message into */ char *buf ; /* buffer to receive message into */
int status = newmlarg( &buf, "write-message: ", 0) ; status = newmlarg( &buf, "Message to write: ", 0) ;
if( status == TRUE) { if( status == TRUE) {
/* write the message out */ /* write the message out */
mlforce( buf) ; mlforce( buf) ;

12
eval.h
View File

@ -1,8 +1,6 @@
/* eval.h -- variables and operands evaluation */
#ifndef _EVAL_H_ #ifndef _EVAL_H_
#define _EVAL_H_ #define _EVAL_H_
#include "names.h"
#define DEBUGM 1 /* $debug triggers macro debugging */ #define DEBUGM 1 /* $debug triggers macro debugging */
@ -10,6 +8,7 @@
int mdbugout( char *fmt, ...) ; int mdbugout( char *fmt, ...) ;
#endif #endif
extern int macbug ; /* macro debuging flag */ extern int macbug ; /* macro debuging flag */
extern int cmdstatus ; /* last command status */ extern int cmdstatus ; /* last command status */
extern int rval ; /* return value of a subprocess */ extern int rval ; /* return value of a subprocess */
@ -19,15 +18,12 @@ int readfirst_f( void) ;
int is_it_cmd( char *token) ; int is_it_cmd( char *token) ;
void varinit( void) ; void varinit( void) ;
int setvar( int f, int n) ;
const char *getval( char *token) ; const char *getval( char *token) ;
int stol( char *val) ; int stol( char *val) ;
char *mklower( char *str) ; char *mklower( char *str) ;
/* Bindable functions */ int clrmes( int f, int n) ;
TBINDABLE( clrmes) ; int writemsg( int f, int n) ;
BINDABLE( setvar) ;
BINDABLE( writemsg) ;
#endif #endif
/* end of eval.h */

481
exec.c
View File

@ -1,31 +1,38 @@
/* exec.c -- implements exec.h */ /* exec.c -- implements exec.h */
#include "exec.h" #include "exec.h"
/* This file is for bindable functions dealing with execution of commands, /* exec.c
command lines, buffers, files and startup files. *
* This file is for functions dealing with execution of
written 1986 by Daniel Lawrence * commands, command lines, buffers, files and startup files.
modified by Petri Kutvonen *
* written 1986 by Daniel Lawrence
* modified by Petri Kutvonen
*/ */
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "buffer.h" #include "buffer.h"
#include "bind.h" #include "bind.h"
#include "display.h"
#include "estruct.h"
#include "eval.h" #include "eval.h"
#include "file.h" #include "file.h"
#include "flook.h" #include "flook.h"
#include "input.h" #include "input.h"
#include "line.h" #include "line.h"
#include "mlout.h"
#include "random.h" #include "random.h"
#include "util.h" #include "util.h"
#include "window.h" #include "window.h"
static char *execstr = NULL ; /* pointer to string to execute */ static char *execstr = NULL ; /* pointer to string to execute */
boolean clexec = FALSE ; /* command line execution flag */ boolean clexec = FALSE ; /* command line execution flag */
/* Directive definitions */ /* Directive definitions */
#define DIF 0 #define DIF 0
@ -39,52 +46,59 @@ boolean clexec = FALSE ; /* command line execution flag */
#define DBREAK 8 #define DBREAK 8
#define DFORCE 9 #define DFORCE 9
#define NUMDIRS 10
/* The !WHILE directive in the execution language needs to /* The !WHILE directive in the execution language needs to
* stack references to pending whiles. These are stored linked * stack references to pending whiles. These are stored linked
* to each currently open procedure via a linked list of * to each currently open procedure via a linked list of
* the following structure. * the following structure.
*/ */
typedef struct while_block { struct while_block {
line_p w_begin ; /* ptr to !while statement */ struct line *w_begin; /* ptr to !while statement */
line_p w_end ; /* ptr to the !endwhile statement */ struct line *w_end; /* ptr to the !endwhile statement */
int w_type; /* block type */ int w_type; /* block type */
struct while_block *w_next; /* next while */ struct while_block *w_next; /* next while */
} *while_p ; };
#define BTWHILE 1 #define BTWHILE 1
#define BTBREAK 2 #define BTBREAK 2
/* directive name table: holds the names of all the directives.... */ /* directive name table:
This holds the names of all the directives.... */
static const char *dname[] = { static const char *dname[] = {
"if", "else", "endif", "goto", "return", "if", "else", "endif",
"endm", "while", "endwhile", "break", "force" "goto", "return", "endm",
"while", "endwhile", "break",
"force"
}; };
#define NUMDIRS ARRAY_SIZE( dname)
static char golabel[ NSTRING] = "" ; /* current line to go to */ static char golabel[ NSTRING] = "" ; /* current line to go to */
static int execlevel = 0 ; /* execution IF level */ static int execlevel = 0 ; /* execution IF level */
static buffer_p bstore = NULL ; /* buffer to store macro text to */ static struct buffer *bstore = NULL ; /* buffer to store macro text to */
static int mstore = FALSE ; /* storing text to macro flag */ static int mstore = FALSE ; /* storing text to macro flag */
static int dobuf( buffer_p bp) ; static int dobuf( struct buffer *bp) ;
static void freewhile( struct while_block *wp) ;
static int macarg( char *tok, int toksz) ; static int macarg( char *tok, int toksz) ;
/* Execute a named command even if it is not bound. */ /*
BINDABLE( namedcmd) { * Execute a named command even if it is not bound.
*/
int namedcmd( int f, int n) {
/* prompt the user to type a named command */ /* prompt the user to type a named command */
mloutstr( "execute-named-cmd: "); mlwrite("execute-named-cmd: ");
/* and now get the function name to execute */ /* and now get the function name to execute */
nbind_p nbp = getname() ; nbind_p nbp = getname() ;
if( nbp == NULL) /* abort */ if( nbp == NULL) /* abort */
return ABORT ; return FALSE ;
fnp_t kfunc = nbp->n_func ; fnp_t kfunc = nbp->n_func ;
if( kfunc == NULL) if (kfunc == NULL) {
return mloutfail( "(No such function)") ; mlwrite("(No such function)");
return FALSE;
}
if( (bind_tag( nbp) & 1) && (curbp->b_mode & MDVIEW)) if( (bind_tag( nbp) & 1) && (curbp->b_mode & MDVIEW))
return rdonly() ; return rdonly() ;
@ -95,17 +109,19 @@ BINDABLE( namedcmd) {
static int docmd( char *cline) ; static int docmd( char *cline) ;
/* execcmd: /*
* execcmd:
* Execute a command line command to be typed in * Execute a command line command to be typed in
* by the user * by the user
* *
* int f, n; default Flag and Numeric argument * int f, n; default Flag and Numeric argument
*/ */
BINDABLE( execcmd) { int execcmd( int f, int n) {
int status ; /* status return */
char *cmdstr ; /* string holding command to execute */ char *cmdstr ; /* string holding command to execute */
/* get the line wanted */ /* get the line wanted */
int status = newmlarg( &cmdstr, "execute-command-line: ", 0) ; status = newmlarg( &cmdstr, "execute-command-line: ", 0) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
@ -117,7 +133,8 @@ BINDABLE( execcmd) {
return status ; return status ;
} }
/* docmd: /*
* docmd:
* take a passed string as a command line and translate * take a passed string as a command line and translate
* it to be executed as a command. This function will be * it to be executed as a command. This function will be
* used by execute-command-line and by all source and * used by execute-command-line and by all source and
@ -130,6 +147,9 @@ BINDABLE( execcmd) {
* char *cline; command line to execute * char *cline; command line to execute
*/ */
static int docmd( char *cline) { static int docmd( char *cline) {
int f; /* default argument flag */
int n; /* numeric repeat value */
int status; /* return status of function */
boolean oldcle ; /* old contents of clexec flag */ boolean oldcle ; /* old contents of clexec flag */
char *oldestr; /* original exec string */ char *oldestr; /* original exec string */
char tkn[NSTRING]; /* next token off of command line */ char tkn[NSTRING]; /* next token off of command line */
@ -142,12 +162,12 @@ static int docmd( char *cline) {
execstr = cline; /* and set this one as current */ execstr = cline; /* and set this one as current */
/* first set up the default command values */ /* first set up the default command values */
int f = FALSE ; f = FALSE;
int n = 1 ; n = 1;
lastflag = thisflag; lastflag = thisflag;
thisflag = 0; thisflag = 0;
int status = macarg( tkn, sizeof tkn) ; status = macarg( tkn, sizeof tkn) ;
if( status != TRUE) { /* and grab the first token */ if( status != TRUE) { /* and grab the first token */
execstr = oldestr; execstr = oldestr;
return status; return status;
@ -173,8 +193,9 @@ static int docmd( char *cline) {
nbind_p nbp = fncmatch( tkn) ; nbind_p nbp = fncmatch( tkn) ;
fnp_t fnc = nbp->n_func ; fnp_t fnc = nbp->n_func ;
if( fnc == NULL) { if( fnc == NULL) {
mlwrite("(No such Function)");
execstr = oldestr; execstr = oldestr;
return mloutfail( "(No such Function)") ; return FALSE;
} }
if( (bind_tag( nbp) & 1) && (curbp->b_mode & MDVIEW)) if( (bind_tag( nbp) & 1) && (curbp->b_mode & MDVIEW))
@ -201,16 +222,20 @@ static int docmd( char *cline) {
* char **tokref out, destination of newly allocated token string * char **tokref out, destination of newly allocated token string
*/ */
static char *newtoken( char *src, char **tokref) { static char *newtoken( char *src, char **tokref) {
char *tok = malloc( NSTRING) ; boolean quotef ; /* is the current string quoted? */
int size = (tok == NULL) ? 0 : NSTRING ; char *tok ; /* allocated string */
int size ; /* allocated size */
int idx = 0 ; /* insertion point into token string */ int idx = 0 ; /* insertion point into token string */
tok = malloc( NSTRING) ;
size = (tok == NULL) ? 0 : NSTRING ;
/* first scan past any whitespace in the source string */ /* first scan past any whitespace in the source string */
while (*src == ' ' || *src == '\t') while (*src == ' ' || *src == '\t')
++src; ++src;
/* scan through the source string */ /* scan through the source string */
boolean quotef = FALSE ; /* is the current string quoted? */ quotef = FALSE;
while (*src) { while (*src) {
char c ; /* temporary character */ char c ; /* temporary character */
@ -370,23 +395,32 @@ static int macarg( char *tok, int toksz) {
static char macbufname[] = "*Macro xx*" ; static char macbufname[] = "*Macro xx*" ;
#define MACDIGITPOS 7 #define MACDIGITPOS 7
BINDABLE( storemac) { int storemac(int f, int n)
{
struct buffer *bp; /* pointer to macro buffer */
/* must have a numeric argument to this function */ /* must have a numeric argument to this function */
if( f == FALSE) if (f == FALSE) {
return mloutfail( "No macro number specified"); mlwrite("No macro specified");
return FALSE;
}
/* range check the macro number */ /* range check the macro number */
if( n < 1 || n > 40) if (n < 1 || n > 40) {
return mloutfail( "Macro number out of range") ; mlwrite("Macro number out of range");
return FALSE;
}
/* construct the macro buffer name */ /* construct the macro buffer name */
macbufname[ MACDIGITPOS] = '0' + (n / 10) ; macbufname[ MACDIGITPOS] = '0' + (n / 10) ;
macbufname[ MACDIGITPOS + 1] = '0' + (n % 10) ; macbufname[ MACDIGITPOS + 1] = '0' + (n % 10) ;
/* set up the new macro buffer */ /* set up the new macro buffer */
buffer_p bp = bfind( macbufname, TRUE, BFINVS) ; bp = bfind( macbufname, TRUE, BFINVS) ;
if( bp == NULL) if( bp == NULL) {
return mloutfail( "Can not create macro") ; mlwrite("Can not create macro");
return FALSE;
}
/* and make sure it is empty */ /* and make sure it is empty */
bclear(bp); bclear(bp);
@ -402,10 +436,12 @@ BINDABLE( storemac) {
** common to execute buffer, procedure and macro ** common to execute buffer, procedure and macro
*/ */
static int exec( int n, char *bufname, char *errstr) { static int exec( int n, char *bufname, char *errstr) {
struct buffer *bp ; /* ptr to buffer to execute */
/* find the pointer to that buffer */ /* find the pointer to that buffer */
buffer_p bp = bfind( bufname, FALSE, 0) ; bp = bfind( bufname, FALSE, 0) ;
if( bp == NULL) { if( bp == NULL) {
mloutfmt( "No such %s", errstr) ; mlwrite( "No such %s", errstr) ;
return FALSE ; return FALSE ;
} }
@ -417,6 +453,7 @@ static int exec( int n, char *bufname, char *errstr) {
return status ; return status ;
} }
#if PROC
/* /*
* storeproc: * storeproc:
* Set up a procedure buffer and flag to store all * Set up a procedure buffer and flag to store all
@ -425,7 +462,9 @@ static int exec( int n, char *bufname, char *errstr) {
* int f; default flag * int f; default flag
* int n; macro number to use * int n; macro number to use
*/ */
BINDABLE( storeproc) { int storeproc( int f, int n) {
struct buffer *bp ; /* pointer to macro buffer */
int status ; /* return status */
bname_t bname ; /* name of buffer to use */ bname_t bname ; /* name of buffer to use */
char *name ; char *name ;
@ -434,7 +473,7 @@ BINDABLE( storeproc) {
return storemac( f, n) ; return storemac( f, n) ;
/* get the name of the procedure */ /* get the name of the procedure */
int status = newmlarg( &name, "Procedure name: ", sizeof bname - 2) ; status = newmlarg( &name, "Procedure name: ", sizeof bname - 2) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
@ -445,9 +484,11 @@ BINDABLE( storeproc) {
free( name) ; free( name) ;
/* set up the new macro buffer */ /* set up the new macro buffer */
buffer_p bp = bfind( bname, TRUE, BFINVS) ; bp = bfind( bname, TRUE, BFINVS) ;
if( bp == NULL) if( bp == NULL) {
return mloutfail( "Can not create macro") ; mlwrite( "Can not create macro") ;
return FALSE ;
}
/* and make sure it is empty */ /* and make sure it is empty */
bclear( bp) ; bclear( bp) ;
@ -464,12 +505,13 @@ BINDABLE( storeproc) {
* *
* int f, n; default flag and numeric arg * int f, n; default flag and numeric arg
*/ */
BINDABLE( execproc) { int execproc( int f, int n) {
int status ; /* status return */
bname_t bufn ; /* name of buffer to execute */ bname_t bufn ; /* name of buffer to execute */
char *name ; char *name ;
/* find out what buffer the user wants to execute */ /* find out what buffer the user wants to execute */
int status = newmlarg( &name, "execute-procedure: ", sizeof bufn - 2) ; status = newmlarg( &name, "execute-procedure: ", sizeof bufn - 2) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
@ -481,18 +523,20 @@ BINDABLE( execproc) {
return exec( n, bufn, "procedure") ; return exec( n, bufn, "procedure") ;
} }
#endif
/*
/* execbuf: * execbuf:
* Execute the contents of a buffer of commands * Execute the contents of a buffer of commands
* *
* int f, n; default flag and numeric arg * int f, n; default flag and numeric arg
*/ */
BINDABLE( execbuf) { int execbuf( int f, int n) {
int status ; /* status return */
char *bufn ; /* name of buffer to execute */ char *bufn ; /* name of buffer to execute */
/* find out what buffer the user wants to execute */ /* find out what buffer the user wants to execute */
int status = newmlarg( &bufn, "Execute buffer: ", sizeof( bname_t)) ; status = newmlarg( &bufn, "Execute buffer: ", sizeof( bname_t)) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
@ -501,21 +545,8 @@ BINDABLE( execbuf) {
return status ; return status ;
} }
/*
/* free a list of while block pointers * dobuf:
*
* while_p wp; head of structure to free
*/
static void freewhile( while_p wp) {
while( wp != NULL) {
while_p next = wp->w_next ;
free( wp) ;
wp = next ;
}
}
/* dobuf:
* execute the contents of the buffer pointed to * execute the contents of the buffer pointed to
* by the passed BP * by the passed BP
* *
@ -535,23 +566,36 @@ static void freewhile( while_p wp) {
* *
* *LBL01 * *LBL01
* *
* buffer_p bp; buffer to execute * struct buffer *bp; buffer to execute
*/ */
static int dobuf( buffer_p bp) { static int dobuf(struct buffer *bp)
{
int status; /* status return */
struct line *lp; /* pointer to line to execute */
struct line *hlp; /* pointer to line header */
struct line *glp; /* line to goto */
struct line *mp; /* Macro line storage temp */
int dirnum; /* directive index */
int linlen; /* length of line to execute */ int linlen; /* length of line to execute */
int i; /* index */ int i; /* index */
while_p whtemp ; /* temporary ptr to a struct while_block */ int force; /* force TRUE result? */
struct window *wp; /* ptr to windows to scan */
struct while_block *whlist; /* ptr to !WHILE list */
struct while_block *scanner; /* ptr during scan */
struct while_block *whtemp; /* temporary ptr to a struct while_block */
char *einit; /* initial value of eline */
char *eline; /* text of line to execute */ char *eline; /* text of line to execute */
char tkn[ NSTRING] ; /* buffer to evaluate an expression in */ char tkn[NSTRING]; /* buffer to evaluate an expresion in */
/* clear IF level flags/while ptr */ /* clear IF level flags/while ptr */
execlevel = 0; execlevel = 0;
while_p whlist = NULL ; /* ptr to !WHILE list */ whlist = NULL;
while_p scanner = NULL ; /* ptr during scan */ scanner = NULL;
/* scan the buffer to execute, building WHILE header blocks */ /* scan the buffer to execute, building WHILE header blocks */
line_p hlp = bp->b_linep ; /* pointer to line header */ hlp = bp->b_linep;
for( line_p lp = hlp->l_fp ; lp != hlp ; lp = lp->l_fp) { lp = hlp->l_fp;
while (lp != hlp) {
/* scan the current line */ /* scan the current line */
eline = lp->l_text; eline = lp->l_text;
i = lp->l_used; i = lp->l_used;
@ -562,22 +606,19 @@ static int dobuf( buffer_p bp) {
/* if theres nothing here, don't bother */ /* if theres nothing here, don't bother */
if (i <= 0) if (i <= 0)
continue ; goto nxtscan;
/* if it is a while directive, make a block... */ /* if is a while directive, make a block... */
if( eline[0] == '!' if (eline[0] == '!' && eline[1] == 'w' && eline[2] == 'h') {
&& eline[1] == 'w' whtemp = (struct while_block *)malloc(sizeof(struct while_block));
&& eline[2] == 'h') {
whtemp = malloc( sizeof *whtemp) ;
if (whtemp == NULL) { if (whtemp == NULL) {
noram: noram:mlwrite
mloutstr( "%%Out of memory during while scan") ; ("%%Out of memory during while scan");
failexit: failexit:freewhile
freewhile( scanner) ; (scanner);
freewhile(whlist); freewhile(whlist);
return FALSE; return FALSE;
} }
whtemp->w_begin = lp; whtemp->w_begin = lp;
whtemp->w_type = BTWHILE; whtemp->w_type = BTWHILE;
whtemp->w_next = scanner; whtemp->w_next = scanner;
@ -585,18 +626,15 @@ static int dobuf( buffer_p bp) {
} }
/* if is a BREAK directive, make a block... */ /* if is a BREAK directive, make a block... */
if( eline[0] == '!' if (eline[0] == '!' && eline[1] == 'b' && eline[2] == 'r') {
&& eline[1] == 'b'
&& eline[2] == 'r') {
if (scanner == NULL) { if (scanner == NULL) {
mloutstr( "%%!BREAK outside of any !WHILE loop") ; mlwrite
("%%!BREAK outside of any !WHILE loop");
goto failexit; goto failexit;
} }
whtemp = (struct while_block *)malloc(sizeof(struct while_block));
whtemp = malloc( sizeof *whtemp) ;
if (whtemp == NULL) if (whtemp == NULL)
goto noram; goto noram;
whtemp->w_begin = lp; whtemp->w_begin = lp;
whtemp->w_type = BTBREAK; whtemp->w_type = BTBREAK;
whtemp->w_next = scanner; whtemp->w_next = scanner;
@ -604,14 +642,13 @@ static int dobuf( buffer_p bp) {
} }
/* if it is an endwhile directive, record the spot... */ /* if it is an endwhile directive, record the spot... */
if( eline[0] == '!' if (eline[0] == '!' && strncmp(&eline[1], "endw", 4) == 0) {
&& strncmp( &eline[1], "endw", 4) == 0) {
if (scanner == NULL) { if (scanner == NULL) {
mloutfmt( "%%!ENDWHILE with no preceding !WHILE in '%s'", mlwrite
("%%!ENDWHILE with no preceding !WHILE in '%s'",
bp->b_bname); bp->b_bname);
goto failexit; goto failexit;
} }
/* move top records from the scanner list to the /* move top records from the scanner list to the
whlist until we have moved all BREAK records whlist until we have moved all BREAK records
and one WHILE record */ and one WHILE record */
@ -623,11 +660,15 @@ static int dobuf( buffer_p bp) {
whlist->w_next = whtemp; whlist->w_next = whtemp;
} while (whlist->w_type == BTBREAK); } while (whlist->w_type == BTBREAK);
} }
nxtscan: /* on to the next line */
lp = lp->l_fp;
} }
/* while and endwhile should match! */ /* while and endwhile should match! */
if (scanner != NULL) { if (scanner != NULL) {
mloutfmt( "%%!WHILE with no matching !ENDWHILE in '%s'", bp->b_bname) ; mlwrite("%%!WHILE with no matching !ENDWHILE in '%s'",
bp->b_bname);
goto failexit; goto failexit;
} }
@ -636,19 +677,14 @@ static int dobuf( buffer_p bp) {
/* starting at the beginning of the buffer */ /* starting at the beginning of the buffer */
hlp = bp->b_linep; hlp = bp->b_linep;
char *einit = NULL ; /* initial value of eline */ lp = hlp->l_fp;
int status = TRUE ; /* status of command execution */ while (lp != hlp) {
boolean done = FALSE ;
for( line_p lp = hlp->l_fp ; !done && (lp != hlp) ; lp = lp->l_fp) {
if( einit)
free( einit) ;
/* allocate eline and copy macro line to it */ /* allocate eline and copy macro line to it */
linlen = lp->l_used; linlen = lp->l_used;
einit = eline = malloc( linlen + 1) ; if ((einit = eline = malloc(linlen + 1)) == NULL) {
if( eline == NULL) { mlwrite("%%Out of Memory during macro execution");
status = mloutfail( "%%Out of Memory during macro execution") ; freewhile(whlist);
break ; return FALSE;
} }
mystrscpy( eline, lp->l_text, linlen + 1) ; mystrscpy( eline, lp->l_text, linlen + 1) ;
@ -659,7 +695,7 @@ static int dobuf( buffer_p bp) {
/* dump comments and blank lines */ /* dump comments and blank lines */
if (*eline == ';' || *eline == '#' || *eline == 0) if (*eline == ';' || *eline == '#' || *eline == 0)
continue ; goto onward;
#if DEBUGM #if DEBUGM
/* if $debug == TRUE, every line to execute /* if $debug == TRUE, every line to execute
@ -672,8 +708,9 @@ static int dobuf( buffer_p bp) {
/* debug macro name, if levels and lastly the line */ /* debug macro name, if levels and lastly the line */
c = mdbugout( "<<<%s:%d:%s>>>", bp->b_bname, execlevel, eline) ; c = mdbugout( "<<<%s:%d:%s>>>", bp->b_bname, execlevel, eline) ;
if( c == abortc) { if( c == abortc) {
status = FALSE ; freewhile( whlist) ;
break ; free( einit) ;
return FALSE ;
} else if( c == metac) { } else if( c == metac) {
macbug = FALSE ; macbug = FALSE ;
} }
@ -681,25 +718,28 @@ static int dobuf( buffer_p bp) {
#endif #endif
/* Parse directives here.... */ /* Parse directives here.... */
unsigned dirnum = NUMDIRS ; /* directive index */ dirnum = -1;
if (*eline == '!') { if (*eline == '!') {
/* Find out which directive this is */ /* Find out which directive this is */
++eline; ++eline;
for (dirnum = 0; dirnum < NUMDIRS; dirnum++) for (dirnum = 0; dirnum < NUMDIRS; dirnum++)
if( !strncmp( eline, dname[ dirnum], strlen( dname[ dirnum]))) if (strncmp(eline, dname[dirnum],
strlen(dname[dirnum])) == 0)
break; break;
/* and bitch if it's illegal */ /* and bitch if it's illegal */
if (dirnum == NUMDIRS) { if (dirnum == NUMDIRS) {
status = mloutfail( "%%Unknown Directive") ; mlwrite("%%Unknown Directive");
break ; freewhile(whlist);
free( einit) ;
return FALSE;
} }
/* service only the !ENDM macro here */ /* service only the !ENDM macro here */
if (dirnum == DENDM) { if (dirnum == DENDM) {
mstore = FALSE; mstore = FALSE;
bstore = NULL; bstore = NULL;
continue ; goto onward;
} }
/* restore the original eline.... */ /* restore the original eline.... */
@ -710,10 +750,10 @@ static int dobuf( buffer_p bp) {
if (mstore) { if (mstore) {
/* allocate the space for the line */ /* allocate the space for the line */
linlen = strlen(eline); linlen = strlen(eline);
line_p mp = lalloc( linlen) ; if ((mp = lalloc(linlen)) == NULL) {
if( mp == NULL) { free( einit) ;
status = mloutfail( "Out of memory while storing macro") ; mlwrite( "Out of memory while storing macro") ;
break ; return FALSE ;
} }
/* copy the text into the new line */ /* copy the text into the new line */
@ -725,129 +765,136 @@ static int dobuf( buffer_p bp) {
mp->l_bp = bstore->b_linep->l_bp; mp->l_bp = bstore->b_linep->l_bp;
bstore->b_linep->l_bp = mp; bstore->b_linep->l_bp = mp;
mp->l_fp = bstore->b_linep; mp->l_fp = bstore->b_linep;
continue ; goto onward;
} }
int force = FALSE ; /* force TRUE result? */
force = FALSE;
/* dump comments */ /* dump comments */
if (*eline == '*') if (*eline == '*')
continue ; goto onward;
/* now, execute directives */ /* now, execute directives */
if( dirnum != NUMDIRS) { if (dirnum != -1) {
/* skip past the directive */ /* skip past the directive */
while (*eline && *eline != ' ' && *eline != '\t') while (*eline && *eline != ' ' && *eline != '\t')
++eline; ++eline;
execstr = eline; execstr = eline;
switch (dirnum) { switch (dirnum) {
case DIF: /* IF directive */ case DIF: /* IF directive */
/* grab the value of the logical exp */ /* grab the value of the logical exp */
if (execlevel == 0) { if (execlevel == 0) {
if( macarg( tkn, sizeof tkn) != TRUE) if( macarg( tkn, sizeof tkn) != TRUE)
done = TRUE ; goto eexec;
else if( stol( tkn) == FALSE) if (stol(tkn) == FALSE)
++execlevel; ++execlevel;
} else } else
++execlevel; ++execlevel;
goto onward;
continue ;
case DWHILE: /* WHILE directive */ case DWHILE: /* WHILE directive */
/* grab the value of the logical exp */ /* grab the value of the logical exp */
if (execlevel == 0) { if (execlevel == 0) {
if( macarg( tkn, sizeof tkn) != TRUE) { if( macarg( tkn, sizeof tkn) != TRUE)
done = TRUE ; goto eexec;
continue ; if (stol(tkn) == TRUE)
} else if( stol( tkn) == TRUE) goto onward;
continue ;
} }
/* drop down and act just like !BREAK */ /* drop down and act just like !BREAK */
/* fallthrough */ /* fallthrough */
case DBREAK: /* BREAK directive */ case DBREAK: /* BREAK directive */
if (dirnum == DBREAK && execlevel) if (dirnum == DBREAK && execlevel)
continue ; goto onward;
/* jump down to the endwhile */ /* jump down to the endwhile */
/* find the right while loop */ /* find the right while loop */
for( whtemp = whlist ; whtemp ; whtemp = whtemp->w_next) whtemp = whlist;
while (whtemp) {
if (whtemp->w_begin == lp) if (whtemp->w_begin == lp)
break; break;
whtemp = whtemp->w_next;
}
if (whtemp == NULL) { if (whtemp == NULL) {
status = mloutfail( "%%Internal While loop error") ; mlwrite
done = TRUE ; ("%%Internal While loop error");
} else freewhile(whlist);
return FALSE;
}
/* reset the line pointer back.. */ /* reset the line pointer back.. */
lp = whtemp->w_end; lp = whtemp->w_end;
goto onward;
continue ;
case DELSE: /* ELSE directive */ case DELSE: /* ELSE directive */
if (execlevel == 1) if (execlevel == 1)
--execlevel; --execlevel;
else if (execlevel == 0) else if (execlevel == 0)
++execlevel; ++execlevel;
goto onward;
continue ;
case DENDIF: /* ENDIF directive */ case DENDIF: /* ENDIF directive */
if (execlevel) if (execlevel)
--execlevel; --execlevel;
goto onward;
continue ;
case DGOTO: /* GOTO directive */ case DGOTO: /* GOTO directive */
/* .....only if we are currently executing */ /* .....only if we are currently executing */
if (execlevel == 0) { if (execlevel == 0) {
line_p glp ; /* line to goto */
/* grab label to jump to */ /* grab label to jump to */
eline = token( eline, golabel, sizeof golabel) ; eline = token( eline, golabel, sizeof golabel) ;
linlen = strlen(golabel); linlen = strlen(golabel);
for( glp = hlp->l_fp ; glp != hlp ; glp = glp->l_fp) { glp = hlp->l_fp;
if( *glp->l_text == '*' while (glp != hlp) {
&& !strncmp( &glp->l_text[ 1], golabel, linlen)) { if (*glp->l_text == '*' &&
break ; (strncmp
} (&glp->l_text[1],
} golabel,
linlen) == 0)) {
if( glp == hlp) {
status = mloutfail( "%%No such label") ;
done = TRUE ;
} else
lp = glp; lp = glp;
goto onward;
} }
glp = glp->l_fp;
continue ; }
mlwrite("%%No such label");
freewhile(whlist);
return FALSE;
}
goto onward;
case DRETURN: /* RETURN directive */ case DRETURN: /* RETURN directive */
if (execlevel == 0) if (execlevel == 0)
done = TRUE ; goto eexec;
goto onward;
continue ;
case DENDWHILE: /* ENDWHILE directive */ case DENDWHILE: /* ENDWHILE directive */
if (execlevel) { if (execlevel) {
--execlevel; --execlevel;
continue ; goto onward;
} else { } else {
/* find the right while loop */ /* find the right while loop */
for( whtemp = whlist ; whtemp ; whtemp = whtemp->w_next) whtemp = whlist;
if( whtemp->w_type == BTWHILE while (whtemp) {
if (whtemp->w_type ==
BTWHILE
&& whtemp->w_end == lp) && whtemp->w_end == lp)
break; break;
whtemp = whtemp->w_next;
}
if (whtemp == NULL) { if (whtemp == NULL) {
status = mloutfail( "%%Internal While loop error") ; mlwrite
done = TRUE ; ("%%Internal While loop error");
} else freewhile(whlist);
return FALSE;
}
/* reset the line pointer back.. */ /* reset the line pointer back.. */
lp = whtemp->w_begin->l_bp; lp = whtemp->w_begin->l_bp;
goto onward;
continue ;
} }
case DFORCE: /* FORCE directive */ case DFORCE: /* FORCE directive */
@ -864,44 +911,66 @@ static int dobuf( buffer_p bp) {
/* check for a command error */ /* check for a command error */
if (status != TRUE) { if (status != TRUE) {
/* look if buffer is showing */ /* look if buffer is showing */
for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) { wp = wheadp;
while (wp != NULL) {
if (wp->w_bufp == bp) { if (wp->w_bufp == bp) {
/* and point it */ /* and point it */
wp->w_dotp = lp; wp->w_dotp = lp;
wp->w_doto = 0; wp->w_doto = 0;
wp->w_flag |= WFHARD; wp->w_flag |= WFHARD;
} }
wp = wp->w_wndp;
} }
/* in any case set the buffer . */ /* in any case set the buffer . */
bp->b_dotp = lp; bp->b_dotp = lp;
bp->b_doto = 0; bp->b_doto = 0;
break ; free(einit);
}
}
execlevel = 0; execlevel = 0;
freewhile(whlist); freewhile(whlist);
if( einit)
free( einit) ;
return status; return status;
} }
onward: /* on to the next line */
free(einit);
lp = lp->l_fp;
}
/* execute a series of commands in a file eexec: /* exit the current function */
execlevel = 0;
freewhile(whlist);
return TRUE;
}
/*
* free a list of while block pointers
*
* struct while_block *wp; head of structure to free
*/
static void freewhile(struct while_block *wp)
{
if (wp == NULL)
return;
if (wp->w_next)
freewhile(wp->w_next);
free(wp);
}
/*
* execute a series of commands in a file
* *
* int f, n; default flag and numeric arg to pass on to file * int f, n; default flag and numeric arg to pass on to file
*/ */
BINDABLE( execfile) { int execfile( int f, int n) {
int status ; /* return status of name query */
char *fname ; /* name of file to execute */ char *fname ; /* name of file to execute */
char *fspec ; /* full file spec */
int status = newmlarg( &fname, "Execute file: ", 0) ; status = newmlarg( &fname, "Execute file: ", 0) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
/* look up the path for the file */ /* look up the path for the file */
char *fspec = flook( fname, FALSE) ; /* used to be TRUE, P.K. */ fspec = flook( fname, FALSE) ; /* used to be TRUE, P.K. */
free( fname) ; free( fname) ;
/* if it isn't around */ /* if it isn't around */
@ -915,54 +984,46 @@ BINDABLE( execfile) {
return status ; return status ;
} }
/* dofile: /*
* dofile:
* yank a file into a buffer and execute it * yank a file into a buffer and execute it
* if there are no errors, delete the buffer on exit * if there are no errors, delete the buffer on exit
* *
* char *fname; file name to execute * char *fname; file name to execute
*/ */
int dofile( const char *fname) { int dofile( const char *fname) {
struct buffer *bp; /* buffer to place file to exeute */
struct buffer *cb; /* temp to hold current buf while we read */
int status; /* results of various calls */
bname_t bname ; /* name of buffer */ bname_t bname ; /* name of buffer */
makename(bname, fname); /* derive the name of the buffer */ makename(bname, fname); /* derive the name of the buffer */
unqname(bname); /* make sure we don't stomp things */ unqname(bname); /* make sure we don't stomp things */
buffer_p bp = bfind( bname, TRUE, 0) ; /* get the needed buffer */ if ((bp = bfind(bname, TRUE, 0)) == NULL) /* get the needed buffer */
if( bp == NULL)
return FALSE; return FALSE;
bp->b_mode = MDVIEW; /* mark the buffer as read only */ bp->b_mode = MDVIEW; /* mark the buffer as read only */
buffer_p cb = curbp ; /* save the old buffer */ cb = curbp; /* save the old buffer */
curbp = bp; /* make this one current */ curbp = bp; /* make this one current */
/* and try to read in the file to execute */ /* and try to read in the file to execute */
int status = readin( fname, FALSE) ; if ((status = readin(fname, FALSE)) != TRUE) {
curbp = cb; /* restore the current buffer */ curbp = cb; /* restore the current buffer */
if( status == TRUE) { return status;
/* go execute it! */
status = dobuf( bp) ;
if( status == TRUE && bp->b_nwnd == 0)
/* if not displayed, remove the now unneeded buffer and exit */
zotbuf( bp) ;
} }
return status ;
#if 0
if( status != TRUE)
return status ;
/* go execute it! */ /* go execute it! */
status = dobuf( bp) ; curbp = cb; /* restore the current buffer */
if( status != TRUE) if ((status = dobuf(bp)) != TRUE)
return status; return status;
/* if not displayed, remove the now unneeded buffer and exit */ /* if not displayed, remove the now unneeded buffer and exit */
if (bp->b_nwnd == 0) if (bp->b_nwnd == 0)
zotbuf(bp); zotbuf(bp);
return TRUE; return TRUE;
#endif
} }
/* cbuf: /*
* cbuf:
* Execute the contents of a numbered buffer * Execute the contents of a numbered buffer
* *
* int f, n; default flag and numeric arg * int f, n; default flag and numeric arg
@ -978,7 +1039,7 @@ static int cbuf( int f, int n, int bufnum) {
/* execute buffer of numbered macro [1..40] */ /* execute buffer of numbered macro [1..40] */
#define cbufnn( nn) \ #define cbufnn( nn) \
BINDABLE( cbuf##nn) { \ int cbuf##nn( int f, int n) { \
return cbuf( f, n, nn) ; \ return cbuf( f, n, nn) ; \
} }

110
exec.h
View File

@ -1,65 +1,69 @@
/* exec.h -- bindable functions to execute functions, macros and procedures */
#ifndef _EXEC_H_ #ifndef _EXEC_H_
#define _EXEC_H_ #define _EXEC_H_
#include "names.h" #include "retcode.h"
#define PROC 1 /* named procedures */
#if PROC
int storeproc( int f, int n) ;
int execproc( int f, int n) ;
#endif
extern boolean clexec ; /* command line execution flag */ extern boolean clexec ; /* command line execution flag */
int dofile( const char *fname) ;
int namedcmd( int f, int n) ;
int execcmd( int f, int n) ;
void gettoken( char *tok, int maxtoksize) ; void gettoken( char *tok, int maxtoksize) ;
boolean gettokval( char *tok, int maxtoksize) ; boolean gettokval( char *tok, int maxtoksize) ;
char *getnewtokval( void) ; char *getnewtokval( void) ;
int storemac( int f, int n) ;
int execbuf( int f, int n) ;
int execfile( int f, int n) ;
int dofile( const char *fname) ;
/* Bindable functions */ int cbuf1( int f, int n) ;
BINDABLE( execbuf) ; int cbuf2( int f, int n) ;
BINDABLE( execcmd) ; int cbuf3( int f, int n) ;
BINDABLE( execfile) ; int cbuf4( int f, int n) ;
BINDABLE( execproc) ; int cbuf5( int f, int n) ;
BINDABLE( namedcmd) ; int cbuf6( int f, int n) ;
BINDABLE( storemac) ; int cbuf7( int f, int n) ;
BINDABLE( storeproc) ; int cbuf8( int f, int n) ;
BINDABLE( cbuf1) ; int cbuf9( int f, int n) ;
BINDABLE( cbuf2) ; int cbuf10( int f, int n) ;
BINDABLE( cbuf3) ; int cbuf11( int f, int n) ;
BINDABLE( cbuf4) ; int cbuf12( int f, int n) ;
BINDABLE( cbuf5) ; int cbuf13( int f, int n) ;
BINDABLE( cbuf6) ; int cbuf14( int f, int n) ;
BINDABLE( cbuf7) ; int cbuf15( int f, int n) ;
BINDABLE( cbuf8) ; int cbuf16( int f, int n) ;
BINDABLE( cbuf9) ; int cbuf17( int f, int n) ;
BINDABLE( cbuf10) ; int cbuf18( int f, int n) ;
BINDABLE( cbuf11) ; int cbuf19( int f, int n) ;
BINDABLE( cbuf12) ; int cbuf20( int f, int n) ;
BINDABLE( cbuf13) ; int cbuf21( int f, int n) ;
BINDABLE( cbuf14) ; int cbuf22( int f, int n) ;
BINDABLE( cbuf15) ; int cbuf23( int f, int n) ;
BINDABLE( cbuf16) ; int cbuf24( int f, int n) ;
BINDABLE( cbuf17) ; int cbuf25( int f, int n) ;
BINDABLE( cbuf18) ; int cbuf26( int f, int n) ;
BINDABLE( cbuf19) ; int cbuf27( int f, int n) ;
BINDABLE( cbuf20) ; int cbuf28( int f, int n) ;
BINDABLE( cbuf21) ; int cbuf29( int f, int n) ;
BINDABLE( cbuf22) ; int cbuf30( int f, int n) ;
BINDABLE( cbuf23) ; int cbuf31( int f, int n) ;
BINDABLE( cbuf24) ; int cbuf32( int f, int n) ;
BINDABLE( cbuf25) ; int cbuf33( int f, int n) ;
BINDABLE( cbuf26) ; int cbuf34( int f, int n) ;
BINDABLE( cbuf27) ; int cbuf35( int f, int n) ;
BINDABLE( cbuf28) ; int cbuf36( int f, int n) ;
BINDABLE( cbuf29) ; int cbuf37( int f, int n) ;
BINDABLE( cbuf30) ; int cbuf38( int f, int n) ;
BINDABLE( cbuf31) ; int cbuf39( int f, int n) ;
BINDABLE( cbuf32) ; int cbuf40( int f, int n) ;
BINDABLE( cbuf33) ;
BINDABLE( cbuf34) ;
BINDABLE( cbuf35) ;
BINDABLE( cbuf36) ;
BINDABLE( cbuf37) ;
BINDABLE( cbuf38) ;
BINDABLE( cbuf39) ;
BINDABLE( cbuf40) ;
#endif #endif
/* end of exec.h */

33
file.c
View File

@ -1,11 +1,13 @@
/* file.c -- implements file.h */ /* file.c -- implements file.h */
#include "file.h" #include "file.h"
/* The routines in this file handle the reading, writing and lookup of disk /* file.c
files. All of details about the reading and writing of the disk are in *
"fileio.c". * The routines in this file handle the reading, writing
* and lookup of disk files. All of details about the
modified by Petri Kutvonen * reading and writing of the disk are in "fileio.c".
*
* modified by Petri Kutvonen
*/ */
#include <assert.h> #include <assert.h>
@ -231,8 +233,8 @@ int getfile( const char *fname, boolean lockfl) {
return s; return s;
} }
/*
/* Read file "fname" into the current buffer, blowing away any text * Read file "fname" into the current buffer, blowing away any text
* found there. Called by both the read and find commands. Return * found there. Called by both the read and find commands. Return
* the final status of the read. Also called by the mainline, to * the final status of the read. Also called by the mainline, to
* read in a file specified on the command line as an argument. * read in a file specified on the command line as an argument.
@ -285,7 +287,7 @@ int readin(const char *fname, boolean lockfl)
while ((s = ffgetline()) == FIOSUC) { while ((s = ffgetline()) == FIOSUC) {
line_p lp ; line_p lp ;
if( nline >= 10000000 /* Maximum # of lines from one file */ if( nline >= 10000000 /* MAXNLINE Maximum # of lines from one file */
|| (lp = lalloc( fpayload)) == NULL) { || (lp = lalloc( fpayload)) == NULL) {
s = FIOMEM ; /* Keep message on the */ s = FIOMEM ; /* Keep message on the */
break ; /* display. */ break ; /* display. */
@ -325,11 +327,12 @@ int readin(const char *fname, boolean lockfl)
if( fcode == FCODE_UTF_8) if( fcode == FCODE_UTF_8)
curbp->b_mode |= MDUTF8 ; curbp->b_mode |= MDUTF8 ;
if( s == FIOERR if( s == FIOERR) {
|| s == FIOMEM) { errmsg = "I/O ERROR, " ;
errmsg = (s == FIOERR) ? "I/O ERROR, " : "OUT OF MEMORY, " ; curbp->b_flag |= BFTRUNC ;
} else if( s == FIOMEM) {
errmsg = "OUT OF MEMORY, " ;
curbp->b_flag |= BFTRUNC ; curbp->b_flag |= BFTRUNC ;
curbp->b_mode |= MDVIEW ; /* force view mode as lost data */
} else } else
errmsg = "" ; errmsg = "" ;
@ -461,8 +464,10 @@ BINDABLE( filesave) {
/* complain about truncated files */ /* complain about truncated files */
if( (curbp->b_flag & BFTRUNC) != 0 if( (curbp->b_flag & BFTRUNC) != 0
&& mlyesno( "Truncated file ... write it out") == FALSE) && mlyesno("Truncated file ... write it out") == FALSE) {
return mloutfail( "(Aborted)") ; mloutfmt( "%B(Aborted)") ;
return FALSE ;
}
return writeout( curbp->b_fname) ; return writeout( curbp->b_fname) ;
} }

46
input.c
View File

@ -15,10 +15,9 @@
#include "bind.h" #include "bind.h"
#include "estruct.h" #include "estruct.h"
#include "bindable.h" #include "bindable.h"
#include "display.h" /* rubout(), echos(), echoc(), update() */ #include "display.h"
#include "exec.h" #include "exec.h"
#include "isa.h" #include "isa.h"
#include "mlout.h"
#include "names.h" #include "names.h"
#include "terminal.h" #include "terminal.h"
#include "utf8.h" #include "utf8.h"
@ -39,12 +38,12 @@ kbdstate kbdmode = STOP ; /* current keyboard macro mode */
int lastkey = 0 ; /* last keystoke */ int lastkey = 0 ; /* last keystoke */
int kbdrep = 0 ; /* number of repetitions */ int kbdrep = 0 ; /* number of repetitions */
int metac = CTL_ | '[' ; /* current meta character */ int metac = CTRL | '[' ; /* current meta character */
int ctlxc = CTL_ | 'X' ; /* current control X prefix char */ int ctlxc = CTRL | 'X' ; /* current control X prefix char */
int reptc = CTL_ | 'U' ; /* current universal repeat char */ int reptc = CTRL | 'U' ; /* current universal repeat char */
int abortc = CTL_ | 'G' ; /* current abort command char */ int abortc = CTRL | 'G' ; /* current abort command char */
const int nlc = CTL_ | 'J' ; /* end of input char */ const int nlc = CTRL | 'J' ; /* end of input char */
void ue_system( const char *cmd) { void ue_system( const char *cmd) {
@ -67,7 +66,7 @@ int mlyesno( const char *prompt)
for (;;) { for (;;) {
/* prompt the user */ /* prompt the user */
mloutfmt( "%s (y/n)? ", prompt) ; mlwrite( "%s (y/n)? ", prompt) ;
/* get the response */ /* get the response */
c = get1key() ; c = get1key() ;
@ -143,11 +142,11 @@ int newmlargt( char **outbufref, const char *prompt, int size) {
/* /*
* ectoc: * ectoc:
* expanded character to character * expanded character to character
* collapse the CTL_ and SPEC flags back into an ascii code * collapse the CTRL and SPEC flags back into an ascii code
*/ */
int ectoc( int c) { int ectoc( int c) {
if( c & CTL_) if( c & CTRL)
c ^= CTL_ | 0x40 ; c ^= CTRL | 0x40 ;
if( c & SPEC) if( c & SPEC)
c &= 255 ; c &= 255 ;
@ -191,7 +190,7 @@ nbind_p getname( void) {
return fncmatch( buf) ; return fncmatch( buf) ;
} else if (c == ectoc(abortc)) { /* Bell, abort */ } else if (c == ectoc(abortc)) { /* Bell, abort */
ctrlg( FALSE, 1) ; ctrlg(FALSE, 0);
TTflush(); TTflush();
return NULL; return NULL;
@ -323,7 +322,7 @@ int tgetc(void)
} }
/* GET1KEY: Get one keystroke. The only prefixes legal here are the SPEC /* GET1KEY: Get one keystroke. The only prefixes legal here are the SPEC
and CTL_ prefixes. */ and CTRL prefixes. */
static int get1unicode( int *up) { static int get1unicode( int *up) {
/* Accept UTF-8 sequence */ /* Accept UTF-8 sequence */
int bytes ; int bytes ;
@ -344,7 +343,7 @@ static int get1unicode( int *up) {
bytes = utf8_to_unicode( utf, 0, sizeof utf, (unicode_t *) up) ; bytes = utf8_to_unicode( utf, 0, sizeof utf, (unicode_t *) up) ;
} else { } else {
if( (c >= 0x00 && c <= 0x1F) || c == 0x7F) /* C0 control -> C- */ if( (c >= 0x00 && c <= 0x1F) || c == 0x7F) /* C0 control -> C- */
c ^= CTL_ | 0x40 ; c ^= CTRL | 0x40 ;
*up = c ; *up = c ;
bytes = 1 ; bytes = 1 ;
@ -384,7 +383,7 @@ int getcmd( void) {
c = *(kptr++) = get1key() ; c = *(kptr++) = get1key() ;
if( c == 0x9B) if( c == 0x9B)
goto foundCSI ; goto foundCSI ;
else if( c == (CTL_ | '[')) { else if( c == (CTRL | '[')) {
/* fetch terminal sequence */ /* fetch terminal sequence */
c = *(kptr++) = get1key() ; c = *(kptr++) = get1key() ;
if( c == 'O') { /* F1 .. F4 */ if( c == 'O') { /* F1 .. F4 */
@ -408,7 +407,7 @@ int getcmd( void) {
mask = META ; mask = META ;
if( (v - 1) & 4) if( (v - 1) & 4)
mask |= CTL_ ; mask |= CTRL ;
v = v1 ; v = v1 ;
} }
@ -514,7 +513,7 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
quote_f = FALSE; quote_f = FALSE;
/* prompt the user for the input string */ /* prompt the user for the input string */
mloutstr( prompt); mlwrite( "%s", prompt);
for (;;) { for (;;) {
#if COMPLC #if COMPLC
@ -539,22 +538,23 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
} }
/* If it is a <ret>, change it to a <NL> */ /* If it is a <ret>, change it to a <NL> */
if( c == (CTL_ | 'M')) if( c == (CTRL | 'M'))
c = CTL_ | 0x40 | '\n' ; c = CTRL | 0x40 | '\n' ;
if( c == eolchar) { if( c == eolchar) {
/* if they hit the line terminator, wrap it up */ /* if they hit the line terminator, wrap it up */
buf[ cpos] = 0 ; buf[ cpos] = 0 ;
/* clear the message line */ /* clear the message line */
mloutstr( "") ; mlwrite("");
/* if we default the buffer, return FALSE */ /* if we default the buffer, return FALSE */
retval = cpos != 0 ; retval = cpos != 0 ;
break ; break ;
} else if( c == abortc) { } else if( c == abortc) {
/* Abort the input? */ /* Abort the input? */
retval = ctrlg( FALSE, 1) ; ctrlg( FALSE, 0) ;
retval = ABORT ;
break ; break ;
} }
@ -574,7 +574,7 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
} }
} else if( c == 0x15) { } else if( c == 0x15) {
/* C-U, kill */ /* C-U, kill */
mloutstr( prompt) ; mlwrite( "%s", prompt) ;
cpos = 0 ; cpos = 0 ;
#if COMPLC #if COMPLC
} else if( (c == 0x09 || c == ' ') && file_f) { } else if( (c == 0x09 || c == ' ') && file_f) {
@ -588,7 +588,7 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
didtry = 1; didtry = 1;
ocpos = cpos; ocpos = cpos;
mloutstr( prompt) ; mlwrite( "%s", prompt) ;
while( cpos != 0) { while( cpos != 0) {
c = buf[ --cpos] ; c = buf[ --cpos] ;
if( c == '*' || c == '?') { if( c == '*' || c == '?') {

View File

@ -1,7 +1,8 @@
/* isearch.c -- implements isearch.h */
#include "isearch.h" #include "isearch.h"
/* The functions in this file implement commands that perform incremental /* isearch.c
*
* The functions in this file implement commands that perform incremental
* searches in the forward and backward directions. This "ISearch" command * searches in the forward and backward directions. This "ISearch" command
* is intended to emulate the same command from the original EMACS * is intended to emulate the same command from the original EMACS
* implementation (ITS). Contains references to routines internal to * implementation (ITS). Contains references to routines internal to
@ -23,6 +24,7 @@
* Modified by Petri Kutvonen * Modified by Petri Kutvonen
*/ */
#include <stdio.h>
#include <string.h> #include <string.h>
#include "basic.h" #include "basic.h"
@ -40,6 +42,8 @@
/* /*
* Incremental search defines. * Incremental search defines.
*/ */
#if ISRCH
#define CMDBUFLEN 256 /* Length of our command buffer */ #define CMDBUFLEN 256 /* Length of our command buffer */
#define IS_ABORT 0x07 /* Abort the isearch */ #define IS_ABORT 0x07 /* Abort the isearch */
@ -56,7 +60,10 @@
/* IS_QUIT is no longer used, the variable metac is used instead */ /* IS_QUIT is no longer used, the variable metac is used instead */
static BINDABLE( isearch) ; /* internal use, not to be bound */ #endif
static int isearch( int f, int n) ;
static int checknext( char chr, char *patrn, int dir) ; static int checknext( char chr, char *patrn, int dir) ;
static int scanmore( char *patrn, int dir) ; static int scanmore( char *patrn, int dir) ;
static int match_pat( char *patrn) ; static int match_pat( char *patrn) ;
@ -66,6 +73,8 @@ static int uneat( void) ;
static void reeat( int c) ; static void reeat( int c) ;
#if ISRCH
static int echo_char(int c, int col); static int echo_char(int c, int col);
/* A couple of "own" variables for re-eat */ /* A couple of "own" variables for re-eat */
@ -80,10 +89,12 @@ static int cmd_offset; /* Current offset into command buff */
static int cmd_reexecute = -1; /* > 0 if re-executing command */ static int cmd_reexecute = -1; /* > 0 if re-executing command */
/* Subroutine to do incremental reverse search. It actually uses the /*
* Subroutine to do incremental reverse search. It actually uses the
* same code as the normal incremental search, as both can go both ways. * same code as the normal incremental search, as both can go both ways.
*/ */
BINDABLE( risearch) { int risearch(int f, int n)
{
struct line *curline; /* Current line on entry */ struct line *curline; /* Current line on entry */
int curoff; /* Current offset on entry */ int curoff; /* Current offset on entry */
@ -113,10 +124,11 @@ BINDABLE( risearch) {
return TRUE; return TRUE;
} }
/*
/* Again, but for the forward direction * Again, but for the forward direction
*/ */
BINDABLE( fisearch) { int fisearch(int f, int n)
{
struct line *curline; /* Current line on entry */ struct line *curline; /* Current line on entry */
int curoff; /* Current offset on entry */ int curoff; /* Current offset on entry */
@ -144,8 +156,8 @@ BINDABLE( fisearch) {
return TRUE; return TRUE;
} }
/*
/* Subroutine to do an incremental search. In general, this works similarly * Subroutine to do an incremental search. In general, this works similarly
* to the older micro-emacs search function, except that the search happens * to the older micro-emacs search function, except that the search happens
* as each character is typed, with the screen and cursor updated with each * as each character is typed, with the screen and cursor updated with each
* new search character. * new search character.
@ -170,7 +182,8 @@ BINDABLE( fisearch) {
* exists (or until the search is aborted). * exists (or until the search is aborted).
*/ */
static BINDABLE( isearch) { static int isearch(int f, int n)
{
int status; /* Search status */ int status; /* Search status */
int col; /* prompt column */ int col; /* prompt column */
unsigned cpos ; /* character number in search string */ unsigned cpos ; /* character number in search string */
@ -528,6 +541,8 @@ static void reeat(int c)
saved_get_char = term.t_getchar; /* Save the char get routine */ saved_get_char = term.t_getchar; /* Save the char get routine */
term.t_getchar = uneat; /* Replace it with ours */ term.t_getchar = uneat; /* Replace it with ours */
} }
#else
int isearch(int f, int n)
/* end of isearch.c */ {
}
#endif

View File

@ -1,11 +1,11 @@
/* isearch.h -- incremental search */
#ifndef __ISEARCH_H__ #ifndef __ISEARCH_H__
#define __ISEARCH_H__ #define __ISEARCH_H__
# include "names.h" /* BINDABLE */ #define ISRCH 1 /* Incremental searches like ITS EMACS */
BINDABLE( risearch) ; #if ISRCH
BINDABLE( fisearch) ; int risearch( int f, int n) ;
int fisearch( int f, int n) ;
#endif
#endif #endif
/* end of isearch */

6
line.c
View File

@ -249,7 +249,8 @@ void lchange(int flag)
* *
* int f, n; default flag and numeric argument * int f, n; default flag and numeric argument
*/ */
BINDABLE( insspace) { int insspace(int f, int n)
{
assert( !(curbp->b_mode & MDVIEW)) ; assert( !(curbp->b_mode & MDVIEW)) ;
linsert(n, ' '); linsert(n, ' ');
backchar(f, n); backchar(f, n);
@ -820,7 +821,8 @@ BINDABLE( yank) {
* VIEW (read-only) mode * VIEW (read-only) mode
*/ */
boolean rdonly( void) { boolean rdonly( void) {
return mloutfail( "(Key illegal in VIEW mode)") ; mloutfmt( "%B(Key illegal in VIEW mode)") ;
return FALSE ;
} }
/* end of line.c */ /* end of line.c */

View File

@ -12,9 +12,4 @@ void mloutstr( const char *str) {
mloutfmt( (*str) ? "%s" : "", str) ; mloutfmt( (*str) ? "%s" : "", str) ;
} }
boolean mloutfail( const char *msg) {
mloutfmt( "%B%s", msg) ;
return FALSE ;
}
/* end of mlout.c */ /* end of mlout.c */

View File

@ -3,12 +3,9 @@
#ifndef __MLOUT_H__ #ifndef __MLOUT_H__
#define __MLOUT_H__ #define __MLOUT_H__
#include "retcode.h"
extern void (*mloutfmt)( const char *, ...) ; extern void (*mloutfmt)( const char *, ...) ;
void mloutstr( const char *str) ; void mloutstr( const char *str) ;
boolean mloutfail( const char *msg) ; /* output with BELL and return FALSE */
#endif /* __MLOUT_H__ */ #endif /* __MLOUT_H__ */

192
names.c
View File

@ -33,51 +33,51 @@
const name_bind names[] = { const name_bind names[] = {
{" abort-command", ctrlg, CTL_ | 'G'} , {" abort-command", ctrlg, CTRL | 'G'} ,
{" add-global-mode", setgmode, META | 'M'} , {" add-global-mode", setgmode, META | 'M'} ,
{" add-mode", setemode, CTLX | 'M'} , {" add-mode", setemode, CTLX | 'M'} ,
{" apropos", apro, META | 'A'} , {" apropos", apro, META | 'A'} ,
{" backward-character", (fnp_t) backchar, CTL_ | 'B'} , {" backward-character", (fnp_t) backchar, CTRL | 'B'} ,
{" begin-macro", (fnp_t) ctlxlp, CTLX | '('} , {" begin-macro", ctlxlp, CTLX | '('} ,
{" beginning-of-file", (fnp_t) gotobob, META | '<'} , {" beginning-of-file", (fnp_t) gotobob, META | '<'} ,
{" beginning-of-line", (fnp_t) gotobol, CTL_ | 'A'} , {" beginning-of-line", (fnp_t) gotobol, CTRL | 'A'} ,
{" bind-to-key", bindtokey, META | 'K'} , {" bind-to-key", bindtokey, META | 'K'} ,
{" buffer-position", showcpos, CTLX | '='} , {" buffer-position", showcpos, CTLX | '='} ,
{"!case-region-lower", lowerregion, CTLX | CTL_ | 'L'} , {"!case-region-lower", lowerregion, CTLX | CTRL | 'L'} ,
{"!case-region-upper", upperregion, CTLX | CTL_ | 'U'} , {"!case-region-upper", upperregion, CTLX | CTRL | 'U'} ,
{"!case-word-capitalize", capword, META | 'C'} , {"!case-word-capitalize", capword, META | 'C'} ,
{"!case-word-lower", lowerword, META | 'L'} , {"!case-word-lower", lowerword, META | 'L'} ,
{"!case-word-upper", upperword, META | 'U'} , {"!case-word-upper", upperword, META | 'U'} ,
{" change-file-name", filename, CTLX | 'N'} , {" change-file-name", filename, CTLX | 'N'} ,
{" change-screen-size", newsize, META | CTL_ | 'D'} , /* M^S */ {" change-screen-size", newsize, META | CTRL | 'D'} , /* M^S */
{" change-screen-width", newwidth, META | CTL_ | 'T'} , {" change-screen-width", newwidth, META | CTRL | 'T'} ,
{" clear-and-redraw", (fnp_t) redraw, CTL_ | 'L'} , {" clear-and-redraw", redraw, CTRL | 'L'} ,
{" clear-message-line", (fnp_t) clrmes, 0} , {" clear-message-line", clrmes, 0} ,
{" copy-region", copyregion, META | 'W'} , {" copy-region", copyregion, META | 'W'} ,
{" count-words", wordcount, META | CTL_ | 'C'} , {" count-words", wordcount, META | CTRL | 'C'} ,
{" ctlx-prefix", (fnp_t) cex, CTL_ | 'X'} , {" ctlx-prefix", cex, CTRL | 'X'} ,
{"!delete-blank-lines", deblank, CTLX | CTL_ | 'O'} , {"!delete-blank-lines", deblank, CTLX | CTRL | 'O'} ,
{" delete-buffer", killbuffer, CTLX | 'K'} , {" delete-buffer", killbuffer, CTLX | 'K'} ,
{" delete-global-mode", delgmode, META | CTL_ | 'M'} , {" delete-global-mode", delgmode, META | CTRL | 'M'} ,
{" delete-mode", delmode, CTLX | CTL_ | 'M'} , {" delete-mode", delmode, CTLX | CTRL | 'M'} ,
{"!delete-next-character", forwdel, CTL_ | 'D'} , {"!delete-next-character", forwdel, CTRL | 'D'} ,
{"!delete-next-word", delfword, META | 'D'} , {"!delete-next-word", delfword, META | 'D'} ,
{" delete-other-windows", onlywind, CTLX | '1'} , {" delete-other-windows", onlywind, CTLX | '1'} ,
{"!delete-previous-character", backdel, CTL_ | 'H'} , /* ^? */ {"!delete-previous-character", backdel, CTRL | 'H'} , /* ^? */
{"!delete-previous-word", delbword, META | CTL_ | 'H'} , /* M^? */ {"!delete-previous-word", delbword, META | CTRL | 'H'} , /* M^? */
{" delete-window", delwind, CTLX | '0'} , {" delete-window", delwind, CTLX | '0'} ,
{" describe-bindings", desbind, 0} , {" describe-bindings", desbind, 0} ,
{" describe-key", deskey, CTLX | '?'} , {" describe-key", deskey, CTLX | '?'} ,
{"!detab-line", detab, CTLX | CTL_ | 'D'} , /* X^A */ {"!detab-line", detab, CTLX | CTRL | 'D'} , /* X^A */
{" end-macro", (fnp_t) ctlxrp, CTLX | ')'} , {" end-macro", ctlxrp, CTLX | ')'} ,
{" end-of-file", (fnp_t) gotoeob, META | '>'} , {" end-of-file", (fnp_t) gotoeob, META | '>'} ,
{" end-of-line", (fnp_t) gotoeol, CTL_ | 'E'} , {" end-of-line", (fnp_t) gotoeol, CTRL | 'E'} ,
{"!entab-line", entab, CTLX | CTL_ | 'E'} , {"!entab-line", entab, CTLX | CTRL | 'E'} ,
{" exchange-point-and-mark", (fnp_t) swapmark, CTLX | CTL_ | 'X'} , {" exchange-point-and-mark", (fnp_t) swapmark, CTLX | CTRL | 'X'} ,
{" execute-buffer", execbuf, 0} , {" execute-buffer", execbuf, 0} ,
{" execute-command-line", execcmd, 0} , {" execute-command-line", execcmd, 0} ,
{" execute-file", execfile, 0} , {" execute-file", execfile, 0} ,
{" execute-macro", (fnp_t) ctlxe, CTLX | 'E'} , {" execute-macro", ctlxe, CTLX | 'E'} ,
{" execute-macro-1", cbuf1, 0} , {" execute-macro-1", cbuf1, 0} ,
{" execute-macro-10", cbuf10, 0} , {" execute-macro-10", cbuf10, 0} ,
{" execute-macro-11", cbuf11, 0} , {" execute-macro-11", cbuf11, 0} ,
@ -119,106 +119,116 @@ const name_bind names[] = {
{" execute-macro-8", cbuf8, 0} , {" execute-macro-8", cbuf8, 0} ,
{" execute-macro-9", cbuf9, 0} , {" execute-macro-9", cbuf9, 0} ,
{" execute-named-command", namedcmd, META | 'X'} , {" execute-named-command", namedcmd, META | 'X'} ,
{" execute-procedure", execproc, META | CTL_ | 'E'} , #if PROC
{" execute-procedure", execproc, META | CTRL | 'E'} ,
#endif
{" execute-program", execprg, CTLX | '$'} , {" execute-program", execprg, CTLX | '$'} ,
{" exit-emacs", quit, CTLX | CTL_ | 'C'} , {" exit-emacs", quit, CTLX | CTRL | 'C'} ,
{"!fill-paragraph", fillpara, META | 'Q'} , {"!fill-paragraph", fillpara, META | 'Q'} ,
{"!filter-buffer", filter_buffer, CTLX | '#'} , {"!filter-buffer", filter_buffer, CTLX | '#'} ,
{" find-file", filefind, CTLX | CTL_ | 'F'} , {" find-file", filefind, CTLX | CTRL | 'F'} ,
{" forward-character", (fnp_t) forwchar, CTL_ | 'F'} , {" forward-character", (fnp_t) forwchar, CTRL | 'F'} ,
{" goto-line", gotoline, META | 'G'} , {" goto-line", gotoline, META | 'G'} ,
#if CFENCE #if CFENCE
{" goto-matching-fence", getfence, META | CTL_ | 'F'} , {" goto-matching-fence", getfence, META | CTRL | 'F'} ,
#endif #endif
{" grow-window", enlargewind, CTLX | 'Z'} , /* X^ */ {" grow-window", enlargewind, CTLX | 'Z'} , /* X^ */
{"!handle-tab", insert_tab, CTL_ | 'I'} , {"!handle-tab", insert_tab, CTRL | 'I'} ,
{" help", help, META | '?'} , {" help", help, META | '?'} ,
{" hunt-backward", backhunt, 0} , {" hunt-backward", backhunt, 0} ,
{" hunt-forward", forwhunt, META | 'S'} , {" hunt-forward", forwhunt, META | 'S'} ,
{" i-shell", spawncli, CTLX | 'C'} , {" i-shell", spawncli, CTLX | 'C'} ,
#if ISRCH
{" incremental-search", fisearch, CTLX | 'S'} , {" incremental-search", fisearch, CTLX | 'S'} ,
{"!insert-file", insfile, CTLX | CTL_ | 'I'} , #endif
{"!insert-space", insspace, CTL_ | 'C'} , {"!insert-file", insfile, CTLX | CTRL | 'I'} ,
{"!insert-space", insspace, CTRL | 'C'} ,
{"!insert-string", istring, 0} , {"!insert-string", istring, 0} ,
#if PKCODE #if PKCODE
{"!justify-paragraph", justpara, META | 'J'} , {"!justify-paragraph", justpara, META | 'J'} ,
#endif #endif
{"!kill-paragraph", killpara, META | CTL_ | 'W'} , {"!kill-paragraph", killpara, META | CTRL | 'W'} ,
{"!kill-region", killregion, CTL_ | 'W'} , {"!kill-region", killregion, CTRL | 'W'} ,
{"!kill-to-end-of-line", killtext, CTL_ | 'K'} , {"!kill-to-end-of-line", killtext, CTRL | 'K'} ,
{" list-buffers", listbuffers, CTLX | CTL_ | 'B'} , {" list-buffers", listbuffers, CTLX | CTRL | 'B'} ,
{" meta-prefix", (fnp_t) metafn, CTL_ | '['} , {" meta-prefix", metafn, CTRL | '['} ,
{" move-window-down", mvdnwind, CTLX | CTL_ | 'N'} , {" move-window-down", mvdnwind, CTLX | CTRL | 'N'} ,
{" move-window-up", mvupwind, CTLX | CTL_ | 'P'} , {" move-window-up", mvupwind, CTLX | CTRL | 'P'} ,
{" name-buffer", namebuffer, META | CTL_ | 'N'} , {" name-buffer", namebuffer, META | CTRL | 'N'} ,
{"!newline", insert_newline, CTL_ | 'M'} , {"!newline", insert_newline, CTRL | 'M'} ,
{"!newline-and-indent", indent, CTL_ | 'J'} , {"!newline-and-indent", indent, CTRL | 'J'} ,
{" next-buffer", nextbuffer, CTLX | 'X'} , {" next-buffer", nextbuffer, CTLX | 'X'} ,
{" next-line", (fnp_t) forwline, CTL_ | 'N'} , {" next-line", (fnp_t) forwline, CTRL | 'N'} ,
{" next-page", (fnp_t) forwpage, CTL_ | 'V'} , {" next-page", (fnp_t) forwpage, CTRL | 'V'} ,
{" next-paragraph", gotoeop, META | 'N'} , {" next-paragraph", gotoeop, META | 'N'} ,
{" next-window", nextwind, CTLX | 'O'} , {" next-window", nextwind, CTLX | 'O'} ,
{" next-word", forwword, META | 'F'} , {" next-word", forwword, META | 'F'} ,
{" nop", (fnp_t) nullproc, META | SPEC | 'C'}, /* hook */ {" nop", nullproc, SPEC | META | 'C'}, /* hook */
{"!open-line", openline, CTL_ | 'O'} , {"!open-line", openline, CTRL | 'O'} ,
{"!overwrite-string", ovstring, 0} , {"!overwrite-string", ovstring, 0} ,
{" pipe-command", pipecmd, CTLX | '@'} , {" pipe-command", pipecmd, CTLX | '@'} ,
{" previous-line", (fnp_t) backline, CTL_ | 'P'} , {" previous-line", (fnp_t) backline, CTRL | 'P'} ,
{" previous-page", (fnp_t) backpage, CTL_ | 'Z'} , /* MV */ {" previous-page", (fnp_t) backpage, CTRL | 'Z'} , /* MV */
{" previous-paragraph", gotobop, META | 'P'} , {" previous-paragraph", gotobop, META | 'P'} ,
{" previous-window", prevwind, CTLX | 'P'} , {" previous-window", prevwind, CTLX | 'P'} ,
{" previous-word", backword, META | 'B'} , {" previous-word", backword, META | 'B'} ,
{"!query-replace-string", qreplace, META | CTL_ | 'R'} , {"!query-replace-string", qreplace, META | CTRL | 'R'} ,
{" quick-exit", quickexit, META | 'Z'} , {" quick-exit", quickexit, META | 'Z'} ,
{"!quote-character", quote, CTL_ | 'Q'} , {"!quote-character", quote, CTRL | 'Q'} , /* also XQ */
{"!read-file", fileread, CTLX | CTL_ | 'R'} , {"!read-file", fileread, CTLX | CTRL | 'R'} ,
{" redraw-display", (fnp_t) reposition, META | CTL_ | 'L'} , {" redraw-display", reposition, META | CTRL | 'L'} , /* M! */
{"!replace-string", sreplace, META | 'R'} , {"!replace-string", sreplace, META | 'R'} ,
{" resize-window", resize, CTLX | 'W'} , {" resize-window", resize, CTLX | 'W'} ,
{" restore-window", restwnd, 0} , {" restore-window", restwnd, 0} ,
#if ISRCH
{" reverse-incremental-search", risearch, CTLX | 'R'} , {" reverse-incremental-search", risearch, CTLX | 'R'} ,
{" run", execproc, 0} , /* alias of execute-procedure */ #endif
{"!save-file", filesave, CTLX | CTL_ | 'S'} , /* also X^D */ #if PROC
{" run", execproc, 0} , // alias of execute-procedure
#endif
{"!save-file", filesave, CTLX | CTRL | 'S'} , /* also X^D */
{" save-window", savewnd, 0} , {" save-window", savewnd, 0} ,
{" scroll-next-down", scrnextdw, META | CTL_ | 'V'} , {" scroll-next-down", scrnextdw, META | CTRL | 'V'} ,
{" scroll-next-up", scrnextup, META | CTL_ | 'Z'} , {" scroll-next-up", scrnextup, META | CTRL | 'Z'} ,
{" search-forward", forwsearch, CTL_ | 'S'} , {" search-forward", forwsearch, CTRL | 'S'} ,
{" search-reverse", backsearch, CTL_ | 'R'} , {" search-reverse", backsearch, CTRL | 'R'} ,
{" select-buffer", usebuffer, CTLX | 'B'} , {" select-buffer", usebuffer, CTLX | 'B'} ,
{" set", setvar, CTLX | 'A'} , {" set", setvar, CTLX | 'A'} ,
{" set-fill-column", setfillcol, CTLX | 'F'} , {" set-fill-column", setfillcol, CTLX | 'F'} ,
{" set-mark", (fnp_t) setmark, META | ' '} , /* M. */ {" set-mark", (fnp_t) setmark, META | ' '} , /* M. */
{" shell-command", spawn, CTLX | '!'} , {" shell-command", spawn, CTLX | '!'} ,
{" shrink-window", shrinkwind, CTLX | CTL_ | 'Z'} , {" shrink-window", shrinkwind, CTLX | CTRL | 'Z'} ,
{" split-current-window", splitwind, CTLX | '2'} , {" split-current-window", splitwind, CTLX | '2'} ,
{" store-macro", storemac, 0} , {" store-macro", storemac, 0} ,
#if PROC
{" store-procedure", storeproc, 0} , {" store-procedure", storeproc, 0} ,
#endif
#if BSD | SVR4 #if BSD | SVR4
{" suspend-emacs", bktoshell, CTLX | 'D'} , /* BSD MS */ {" suspend-emacs", bktoshell, CTLX | 'D'} , /* BSD MS */
#endif #endif
{"!transpose-characters", (fnp_t) twiddle, CTL_ | 'T'} , {"!transpose-characters", (fnp_t) twiddle, CTRL | 'T'} ,
{"!trim-line", trim, CTLX | CTL_ | 'T'} , {"!trim-line", trim, CTLX | CTRL | 'T'} ,
{" unbind-key", unbindkey, META | CTL_ | 'K'} , {" unbind-key", unbindkey, META | CTRL | 'K'} ,
{" universal-argument", (fnp_t) unarg, CTL_ | 'U'} , {" universal-argument", unarg, CTRL | 'U'} ,
{" unmark-buffer", unmark, META | '~'} , {" unmark-buffer", unmark, META | '~'} ,
{" update-screen", upscreen, 0} , {" update-screen", upscreen, 0} ,
{" view-file", viewfile, CTLX | CTL_ | 'V'} , {" view-file", viewfile, CTLX | CTRL | 'V'} ,
{"!wrap-word", wrapword, META | SPEC | 'W'} , /* hook */ {"!wrap-word", wrapword, SPEC | META | 'W'} , /* hook */
{" write-file", filewrite, CTLX | CTL_ | 'W'} , {" write-file", filewrite, CTLX | CTRL | 'W'} ,
{" write-message", writemsg, 0} , {" write-message", writemsg, 0} ,
{"!yank", yank, CTL_ | 'Y'} , {"!yank", yank, CTRL | 'Y'} ,
{" ", NULL, 0}, {" ", NULL, 0},
/* extra key mapping */ /* extra key mapping */
// { NULL, newsize, META | CTL_ | 'S'}, // { NULL, newsize, META | CTRL | 'S'},
{ NULL, backdel, CTL_ | '?'}, { NULL, backdel, CTRL | '?'},
{ NULL, delbword, META | CTL_ | '?'}, { NULL, delbword, META | CTRL | '?'},
{ NULL, detab, CTLX | CTL_ | 'A'}, { NULL, detab, CTLX | CTRL | 'A'},
{ NULL, enlargewind, CTLX | '^'}, { NULL, enlargewind, CTLX | '^'},
{ NULL, (fnp_t) backpage, META | 'V'}, { NULL, (fnp_t) backpage, META | 'V'},
{ NULL, quote, CTLX | 'Q'}, { NULL, quote, CTLX | 'Q'},
{ NULL, (fnp_t) reposition, META | '!'}, { NULL, reposition, META | '!'},
//detab { NULL, filesave, CTLX | CTL_ | 'D'}, //detab { NULL, filesave, CTLX | CTRL | 'D'},
{ NULL, (fnp_t) setmark, META | '.'}, { NULL, (fnp_t) setmark, META | '.'},
// { NULL, bktoshell, META | 'S'}, // { NULL, bktoshell, META | 'S'},
@ -236,15 +246,15 @@ const name_bind names[] = {
{ NULL, help, SPEC | 'P'}, /* F1 */ { NULL, help, SPEC | 'P'}, /* F1 */
/* hooks */ /* hooks */
{ NULL, (fnp_t) nullproc, META | SPEC | 'R'}, /* hook */ { NULL, nullproc, SPEC | META | 'R'}, /* hook */
{ NULL, (fnp_t) nullproc, META | SPEC | 'X'}, /* hook */ { NULL, nullproc, SPEC | META | 'X'}, /* hook */
{ NULL, NULL, 0} { NULL, NULL, 0}
} ; } ;
static int lastnmidx = 0 ; /* index of last name entry */ static int lastnmidx = 0 ; /* index of last name entry */
kbind_p keytab ; kbind_p keytab ;
static int ktsize = 140 ; /* last check: need at least 133 + 1 */ static int ktsize = 140 ; /* last check: need at least 133 + 1 */
@ -272,9 +282,6 @@ boolean init_bindings( void) {
/* Add key definition */ /* Add key definition */
if( nbp->n_keycode) { if( nbp->n_keycode) {
kbind_p ktp = setkeybinding( nbp->n_keycode, nbp) ; kbind_p ktp = setkeybinding( nbp->n_keycode, nbp) ;
if( ktp->k_code == 0) /* Table full, no memory left */
return FALSE ;
/* check it was indeed an insertion at end of table not a /* check it was indeed an insertion at end of table not a
* key code re-definition */ * key code re-definition */
assert( (++ktp)->k_code == 0) ; assert( (++ktp)->k_code == 0) ;
@ -286,20 +293,14 @@ boolean init_bindings( void) {
/* Process extra key bindings if any */ /* Process extra key bindings if any */
for( nbp++ ; nbp->n_func != NULL ; nbp++) { for( nbp++ ; nbp->n_func != NULL ; nbp++) {
/* Check entry: a keycode and no name */ /* Check entry */
assert( nbp->n_keycode && (nbp->n_name == NULL)) ; assert( nbp->n_keycode && (nbp->n_name == NULL)) ;
/* Look for corresponding function and add extra key binding */ /* Look for corresponding function and add extra key binding */
nbind_p fnbp ; nbind_p fnbp ;
for( fnbp = names ; fnbp->n_func != NULL ; fnbp++) for( fnbp = names ; fnbp->n_func != NULL ; fnbp++)
if( fnbp->n_func == nbp->n_func) { if( fnbp->n_func == nbp->n_func) {
kbind_p ktp = setkeybinding( nbp->n_keycode, fnbp) ; setkeybinding( nbp->n_keycode, fnbp) ;
if( ktp->k_code == 0) /* Table full, no memory left */
return FALSE ;
/* check it was indeed an insertion at end of table not a
* key code re-definition */
assert( (++ktp)->k_code == 0) ;
break ; break ;
} }
@ -369,8 +370,8 @@ boolean delkeybinding( unsigned key) {
return FALSE ; return FALSE ;
} }
/*
/* This function looks a key binding up in the binding table * This function looks a key binding up in the binding table
* *
* int c; key to find what is bound to it * int c; key to find what is bound to it
*/ */
@ -415,26 +416,23 @@ nbind_p fncmatch( char *name) {
} }
/* user function that does NOTHING (bound to hooks) */ /* user function that does NOTHING */
TBINDABLE( nullproc) { BINDABLE( nullproc) {
return TRUE ; return TRUE ;
} }
/* dummy function for binding to meta prefix */ /* dummy function for binding to meta prefix */
TBINDABLE( metafn) { BINDABLE( metafn) {
return TRUE ; return TRUE ;
} }
/* dummy function for binding to control-x prefix */ /* dummy function for binding to control-x prefix */
TBINDABLE( cex) { BINDABLE( cex) {
return TRUE ; return TRUE ;
} }
/* dummy function for binding to universal-argument */ /* dummy function for binding to universal-argument */
TBINDABLE( unarg) { BINDABLE( unarg) {
return TRUE ; return TRUE ;
} }

17
names.h
View File

@ -1,10 +1,12 @@
/* names.h -- mapping of functions to names and keys */ /* names.h -- mapping of functions to names and keys */
#ifndef _NAMES_H_ #ifndef _NAMES_H_
#define _NAMES_H_ #define _NAMES_H_
#include "retcode.h" #include "retcode.h"
#define CTL_ 0x01000000 /* Control flag, or'ed in */
#define CTRL 0x01000000 /* Control flag, or'ed in */
#define META 0x02000000 /* Meta flag, or'ed in */ #define META 0x02000000 /* Meta flag, or'ed in */
#define CTLX 0x04000000 /* ^X flag, or'ed in */ #define CTLX 0x04000000 /* ^X flag, or'ed in */
#define SPEC 0x08000000 /* special key (function keys) */ #define SPEC 0x08000000 /* special key (function keys) */
@ -12,9 +14,7 @@
/* Bindable uEMACS function pointer type and definition template */ /* Bindable uEMACS function pointer type and definition template */
#define BINDABLE( fname) int fname( boolean f, int n) #define BINDABLE( fname) int fname( int f, int n)
#define BBINDABLE( fname) boolean fname( boolean f, int n)
#define TBINDABLE BBINDABLE
typedef BINDABLE( (*fnp_t)) ; typedef BINDABLE( (*fnp_t)) ;
@ -53,10 +53,11 @@ nbind_p fncmatch( char *name) ; /* look up by name */
/* bindable functions mapped to prefix keys and hooks */ /* bindable functions mapped to prefix keys and hooks */
TBINDABLE( nullproc) ; BINDABLE( nullproc) ;
TBINDABLE( metafn) ; BINDABLE( metafn) ;
TBINDABLE( cex) ; BINDABLE( cex) ;
TBINDABLE( unarg) ; BINDABLE( unarg) ;
#endif #endif
/* end of names.h */ /* end of names.h */

View File

@ -144,9 +144,11 @@ int getcline(void)
return numlines + 1; return numlines + 1;
} }
/* Return current column. Stop at first non-blank given TRUE argument. /*
* Return current column. Stop at first non-blank given TRUE argument.
*/ */
int getccol( int bflg) { int getccol(int bflg)
{
int i, col; int i, col;
line_p dlp = curwp->w_dotp ; line_p dlp = curwp->w_dotp ;
int byte_offset = curwp->w_doto; int byte_offset = curwp->w_doto;
@ -165,12 +167,9 @@ int getccol( int bflg) {
col += 2 ; col += 2 ;
else if (c >= 0x80 && c <= 0xa0) /* displayed as \xx */ else if (c >= 0x80 && c <= 0xa0) /* displayed as \xx */
col += 3 ; col += 3 ;
else { else
int w = utf8_width( c) ; /* incomplete wc_width */ col += 1 ;
col += (w < 0) ? 2 : w ;
} }
}
return col; return col;
} }
@ -715,40 +714,60 @@ BINDABLE( killtext) {
return ldelete(chunk, TRUE); return ldelete(chunk, TRUE);
} }
/*
/* prompt and set an editor mode * prompt and set an editor mode
* *
* int f, n; default and argument * int f, n; default and argument
*/ */
BINDABLE( setemode) { int setemode(int f, int n)
{
#if PKCODE
return adjustmode(TRUE, FALSE); return adjustmode(TRUE, FALSE);
#else
adjustmode(TRUE, FALSE);
#endif
} }
/*
/* prompt and delete an editor mode * prompt and delete an editor mode
* *
* int f, n; default and argument * int f, n; default and argument
*/ */
BINDABLE( delmode) { int delmode(int f, int n)
{
#if PKCODE
return adjustmode(FALSE, FALSE); return adjustmode(FALSE, FALSE);
#else
adjustmode(FALSE, FALSE);
#endif
} }
/*
/* prompt and set a global editor mode * prompt and set a global editor mode
* *
* int f, n; default and argument * int f, n; default and argument
*/ */
BINDABLE( setgmode) { int setgmode(int f, int n)
{
#if PKCODE
return adjustmode(TRUE, TRUE); return adjustmode(TRUE, TRUE);
#else
adjustmode(TRUE, TRUE);
#endif
} }
/*
/* prompt and delete a global editor mode * prompt and delete a global editor mode
* *
* int f, n; default and argument * int f, n; default and argument
*/ */
BINDABLE( delgmode) { int delgmode(int f, int n)
{
#if PKCODE
return adjustmode(FALSE, TRUE); return adjustmode(FALSE, TRUE);
#else
adjustmode(FALSE, TRUE);
#endif
} }
/* /*
@ -839,10 +858,11 @@ 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, int (*fun)( char *)) {
int status ; /* status return code */
char *tstring ; /* string to add */ char *tstring ; /* string to add */
/* ask for string to insert */ /* ask for string to insert */
int status = newmlargt( &tstring, prompt, 0) ; status = newmlargt( &tstring, prompt, 0) ; /* grab as big a token as screen allow */
if( tstring == NULL) if( tstring == NULL)
return status ; return status ;

View File

@ -9,7 +9,7 @@
*/ */
#include <assert.h> #include <assert.h>
#include <stddef.h> #include <stdio.h>
#include "buffer.h" #include "buffer.h"
#include "estruct.h" #include "estruct.h"
@ -139,9 +139,10 @@ int getregion( region_p rp) {
line_p flp, blp ; line_p flp, blp ;
long fsize, bsize ; long fsize, bsize ;
if (curwp->w_markp == NULL) if (curwp->w_markp == NULL) {
return mloutfail( "No mark set in this window") ; mloutstr( "No mark set in this window") ;
return FALSE;
}
if (curwp->w_dotp == curwp->w_markp) { if (curwp->w_dotp == curwp->w_markp) {
rp->r_linep = curwp->w_dotp; rp->r_linep = curwp->w_dotp;
if (curwp->w_doto < curwp->w_marko) { if (curwp->w_doto < curwp->w_marko) {
@ -181,8 +182,8 @@ int getregion( region_p rp) {
} }
} }
} }
mloutstr( "Bug: lost mark") ;
return mloutfail( "Bug: lost mark") ; return FALSE;
} }
/* end of region.c */ /* end of region.c */

View File

@ -1,7 +1,9 @@
/* search.c -- implements search.h */ /* search.c -- implements search.h */
#include "search.h" #include "search.h"
/* The functions in this file implement commands that search in the forward /* search.c
*
* The functions in this file implement commands that search in the forward
* and backward directions. There are no special characters in the search * and backward directions. There are no special characters in the search
* strings. Probably should have a regular expression search, or something * strings. Probably should have a regular expression search, or something
* like that. * like that.
@ -175,14 +177,15 @@ static int biteq(int bc, char *cclmap);
static char *clearbits(void); static char *clearbits(void);
static void setbit(int bc, char *cclmap); static void setbit(int bc, char *cclmap);
/*
/* forwsearch -- Search forward. Get a search string from the user, and * forwsearch -- Search forward. Get a search string from the user, and
* search for the string. If found, reset the "." to be just after * search for the string. If found, reset the "." to be just after
* the match string, and (perhaps) repaint the display. * the match string, and (perhaps) repaint the display.
* *
* int f, n; default flag / numeric argument * int f, n; default flag / numeric argument
*/ */
BINDABLE( forwsearch) { int forwsearch(int f, int n)
{
int status = TRUE; int status = TRUE;
/* If n is negative, search backwards. /* If n is negative, search backwards.
@ -220,14 +223,15 @@ BINDABLE( forwsearch) {
return status; return status;
} }
/*
/* forwhunt -- Search forward for a previously acquired search string. * forwhunt -- Search forward for a previously acquired search string.
* If found, reset the "." to be just after the match string, * If found, reset the "." to be just after the match string,
* and (perhaps) repaint the display. * and (perhaps) repaint the display.
* *
* int f, n; default flag / numeric argument * int f, n; default flag / numeric argument
*/ */
BINDABLE( forwhunt) { int forwhunt(int f, int n)
{
int status = TRUE; int status = TRUE;
if (n < 0) /* search backwards */ if (n < 0) /* search backwards */
@ -272,15 +276,16 @@ BINDABLE( forwhunt) {
return status; return status;
} }
/*
/* backsearch -- Reverse search. Get a search string from the user, and * backsearch -- Reverse search. Get a search string from the user, and
* search, starting at "." and proceeding toward the front of the buffer. * search, starting at "." and proceeding toward the front of the buffer.
* If found "." is left pointing at the first character of the pattern * If found "." is left pointing at the first character of the pattern
* (the last character that was matched). * (the last character that was matched).
* *
* int f, n; default flag / numeric argument * int f, n; default flag / numeric argument
*/ */
BINDABLE( backsearch) { int backsearch(int f, int n)
{
int status = TRUE; int status = TRUE;
/* If n is negative, search forwards. /* If n is negative, search forwards.
@ -319,15 +324,16 @@ BINDABLE( backsearch) {
return status; return status;
} }
/*
/* backhunt -- Reverse search for a previously acquired search string, * backhunt -- Reverse search for a previously acquired search string,
* starting at "." and proceeding toward the front of the buffer. * starting at "." and proceeding toward the front of the buffer.
* If found "." is left pointing at the first character of the pattern * If found "." is left pointing at the first character of the pattern
* (the last character that was matched). * (the last character that was matched).
* *
* int f, n; default flag / numeric argument * int f, n; default flag / numeric argument
*/ */
BINDABLE( backhunt) { int backhunt(int f, int n)
{
int status = TRUE; int status = TRUE;
if (n < 0) if (n < 0)
@ -782,23 +788,25 @@ void rvstrcpy(char *rvstr, char *str)
*rvstr = '\0'; *rvstr = '\0';
} }
/*
/* sreplace -- Search and replace. * sreplace -- Search and replace.
* *
* int f; default flag * int f; default flag
* int n; # of repetitions wanted * int n; # of repetitions wanted
*/ */
BINDABLE( sreplace) { int sreplace(int f, int n)
{
return replaces(FALSE, f, n); return replaces(FALSE, f, n);
} }
/*
/* qreplace -- search and replace with query. * qreplace -- search and replace with query.
* *
* int f; default flag * int f; default flag
* int n; # of repetitions wanted * int n; # of repetitions wanted
*/ */
BINDABLE( qreplace) { int qreplace(int f, int n)
{
return replaces(TRUE, f, n); return replaces(TRUE, f, n);
} }

39
spawn.c
View File

@ -1,7 +1,9 @@
/* spawn.c -- implements spawn.h */ /* spawn.c -- implements spawn.h */
#include "spawn.h" #include "spawn.h"
/* Various operating system access commands. /* spawn.c
*
* Various operating system access commands.
* *
* Modified by Petri Kutvonen * Modified by Petri Kutvonen
*/ */
@ -32,11 +34,13 @@
#endif #endif
/* Create a subjob with a copy of the command intrepreter in it. When the /*
* Create a subjob with a copy of the command intrepreter in it. When the
* command interpreter exits, mark the screen as garbage so that you do a full * command interpreter exits, mark the screen as garbage so that you do a full
* repaint. Bound to "^X C". * repaint. Bound to "^X C".
*/ */
BINDABLE( spawncli) { int spawncli(int f, int n)
{
#if USG | BSD #if USG | BSD
char *cp; char *cp;
#endif #endif
@ -77,8 +81,9 @@ BINDABLE( spawncli) {
} }
#if BSD | SVR4 #if BSD | SVR4
/* suspend MicroEMACS and wait to wake up */
BINDABLE( bktoshell) { int bktoshell(int f, int n)
{ /* suspend MicroEMACS and wait to wake up */
vttidy(); vttidy();
/****************************** /******************************
int pid; int pid;
@ -98,12 +103,12 @@ void rtfrmshell(void)
} }
#endif #endif
/*
/* Run a one-liner in a subjob. When the command returns, wait for a single * Run a one-liner in a subjob. When the command returns, wait for a single
* character to be typed, then mark the screen as garbage so a full repaint is * character to be typed, then mark the screen as garbage so a full repaint is
* done. Bound to "C-X !". * done. Bound to "C-X !".
*/ */
BINDABLE( spawn) { int spawn( int f, int n) {
int s ; int s ;
char *line ; char *line ;
@ -136,13 +141,13 @@ BINDABLE( spawn) {
#endif #endif
} }
/*
/* Run an external program with arguments. When it returns, wait for a single * Run an external program with arguments. When it returns, wait for a single
* character to be typed, then mark the screen as garbage so a full repaint is * character to be typed, then mark the screen as garbage so a full repaint is
* done. Bound to "C-X $". * done. Bound to "C-X $".
*/ */
BINDABLE( execprg) { int execprg( int f, int n) {
int s ; int s ;
char *line ; char *line ;
@ -171,11 +176,11 @@ BINDABLE( execprg) {
#endif #endif
} }
/*
/* Pipe a one line command into a window * Pipe a one line command into a window
* Bound to ^X @ * Bound to ^X @
*/ */
BINDABLE( pipecmd) { int pipecmd( int f, int n) {
int s ; /* return status from CLI */ int s ; /* return status from CLI */
struct window *wp ; /* pointer to new window */ struct window *wp ; /* pointer to new window */
buffer_p bp ; /* pointer to buffer to zot */ buffer_p bp ; /* pointer to buffer to zot */
@ -266,11 +271,11 @@ BINDABLE( pipecmd) {
return TRUE; return TRUE;
} }
/*
/* filter a buffer through an external DOS program * filter a buffer through an external DOS program
* Bound to ^X # * Bound to ^X #
*/ */
BINDABLE( filter_buffer) { int filter_buffer( int f, int n) {
int s ; /* return status from CLI */ int s ; /* return status from CLI */
buffer_p bp ; /* pointer to buffer to zot */ buffer_p bp ; /* pointer to buffer to zot */
char *mlarg ; char *mlarg ;

11
util.c
View File

@ -1,20 +1,17 @@
/* util.c -- implements util.h */
#include "util.h" #include "util.h"
/* Safe zeroing, no complaining about overlap */ /* Safe zeroing, no complaining about overlap */
void mystrscpy( char *dst, const char *src, int size) { void mystrscpy(char *dst, const char *src, int size)
if( size <= 0) {
if (!size)
return; return;
while (--size) { while (--size) {
char c = *src++; char c = *src++;
if (!c) if (!c)
break; break;
*dst++ = c; *dst++ = c;
} }
*dst = 0; *dst = 0;
} }
/* end of util.c */

2
util.h
View File

@ -1,4 +1,3 @@
/* util.h -- utility functions */
#ifndef UTIL_H_ #ifndef UTIL_H_
#define UTIL_H_ #define UTIL_H_
@ -6,4 +5,3 @@
void mystrscpy(char *dst, const char *src, int size); void mystrscpy(char *dst, const char *src, int size);
#endif /* UTIL_H_ */ #endif /* UTIL_H_ */
/* end of util.h */

287
window.c
View File

@ -1,44 +1,54 @@
/* window.c -- inplements window.h */ /* window.c -- inplements window.h */
#include "window.h" #include "window.h"
/* Window management. Some of the functions are internal, and some are /* window.c
attached to keys that the user actually types. *
* Window management. Some of the functions are internal, and some are
* attached to keys that the user actually types.
*
*/ */
#include <assert.h> #include <assert.h>
#include <stdio.h>
#include "basic.h" #include "basic.h"
#include "buffer.h" #include "buffer.h"
#include "display.h" /* upmode() */ #include "display.h"
#include "estruct.h" #include "estruct.h"
#include "execute.h" #include "execute.h"
#include "line.h" #include "line.h"
#include "mlout.h"
#include "terminal.h" #include "terminal.h"
#include "wrapper.h" #include "wrapper.h"
window_p curwp ; /* Current window */
window_p wheadp ; /* Head of list of windows */
static window_p savwindow = NULL ; /* saved window pointer */ struct window *curwp ; /* Current window */
struct window *wheadp ; /* Head of list of windows */
static struct window *swindow = NULL ; /* saved window pointer */
/* Reposition dot in the current window to line "n". If the argument is /*
positive, it is that line. If it is negative it is that line from the * Reposition dot in the current window to line "n". If the argument is
bottom. If it is 0 the window is centered (this is what the standard * positive, it is that line. If it is negative it is that line from the
redisplay code does). With no argument it defaults to 0. Bound to M-!. * bottom. If it is 0 the window is centered (this is what the standard
* redisplay code does). With no argument it defaults to 0. Bound to M-!.
*/ */
TBINDABLE( reposition) { int reposition(int f, int n)
curwp->w_force = (f == FALSE) ? 0 : n ; /* default to 0 to center screen */ {
if (f == FALSE) /* default to 0 to center screen */
n = 0;
curwp->w_force = n;
curwp->w_flag |= WFFORCE; curwp->w_flag |= WFFORCE;
return TRUE; return TRUE;
} }
/*
/* Refresh the screen. With no argument, it just does the refresh. With * Refresh the screen. With no argument, it just does the refresh. With an
an argument it recenters "." in the current window. Bound to "C-L". * argument it recenters "." in the current window. Bound to "C-L".
*/ */
TBINDABLE( redraw) { int redraw(int f, int n)
{
if (f == FALSE) if (f == FALSE)
sgarbf = TRUE; sgarbf = TRUE;
else { else {
@ -49,17 +59,19 @@ TBINDABLE( redraw) {
return TRUE; return TRUE;
} }
/*
/* The command make the next window (next => down the screen) the current * The command make the next window (next => down the screen) the current
window. There are no real errors, although the command does nothing if * 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 C-N".
*
with an argument this command finds the <n>th window from the top * with an argument this command finds the <n>th window from the top
*
int f, n; default flag and numeric argument * int f, n; default flag and numeric argument
*
*/ */
BINDABLE( nextwind) { int nextwind(int f, int n)
window_p wp; {
struct window *wp;
int nwindows; /* total number of windows */ int nwindows; /* total number of windows */
if (f) { if (f) {
@ -82,8 +94,10 @@ BINDABLE( nextwind) {
wp = wheadp; wp = wheadp;
while (--n) while (--n)
wp = wp->w_wndp; wp = wp->w_wndp;
} else } else {
return mloutfail( "Window number out of range") ; mlwrite("Window number out of range");
return FALSE;
}
} else if ((wp = curwp->w_wndp) == NULL) } else if ((wp = curwp->w_wndp) == NULL)
wp = wheadp; wp = wheadp;
curwp = wp; curwp = wp;
@ -93,14 +107,15 @@ BINDABLE( nextwind) {
return TRUE; return TRUE;
} }
/*
/* This command makes the previous window (previous => up the screen) the * This command makes the previous window (previous => up the screen) the
current window. There arn't any errors, although the command does not * current window. There arn't any errors, although the command does not do a
do a lot if there is 1 window. * lot if there is 1 window.
*/ */
BINDABLE( prevwind) { int prevwind(int f, int n)
window_p wp1; {
window_p wp2; struct window *wp1;
struct window *wp2;
/* if we have an argument, we mean the nth window from the bottom */ /* if we have an argument, we mean the nth window from the bottom */
if (f) if (f)
@ -122,26 +137,28 @@ BINDABLE( prevwind) {
return TRUE; return TRUE;
} }
/*
/* This command moves the current window down by "arg" lines. Recompute the * This command moves the current window down by "arg" lines. Recompute the
* top line in the window. The move up and move down code is almost completely * top line in the window. The move up and move down code is almost completely
* the same; most of the work has to do with reframing the window, and picking * the same; most of the work has to do with reframing the window, and picking
* a new dot. We share the code by having "move down" just be an interface to * a new dot. We share the code by having "move down" just be an interface to
* "move up". Magic. Bound to "C-X C-N". * "move up". Magic. Bound to "C-X C-N".
*/ */
BINDABLE( mvdnwind) { int mvdnwind(int f, int n)
{
return mvupwind(f, -n); return mvupwind(f, -n);
} }
/*
/* Move the current window up by "arg" lines. Recompute the new top line of * Move the current window up by "arg" lines. Recompute the new top line of
* the window. Look to see if "." is still on the screen. If it is, you win. * the window. Look to see if "." is still on the screen. If it is, you win.
* If it isn't, then move "." to center it in the new framing of the window * If it isn't, then move "." to center it in the new framing of the window
* (this command does not really move "."; it moves the frame). Bound to * (this command does not really move "."; it moves the frame). Bound to
* "C-X C-P". * "C-X C-P".
*/ */
BINDABLE( mvupwind) { int mvupwind(int f, int n)
line_p lp; {
struct line *lp;
int i; int i;
lp = curwp->w_linep; lp = curwp->w_linep;
@ -176,16 +193,17 @@ BINDABLE( mvupwind) {
return TRUE; return TRUE;
} }
/*
/* This command makes the current window the only window on the screen. Bound * This command makes the current window the only window on the screen. Bound
* to "C-X 1". Try to set the framing so that "." does not have to move on the * to "C-X 1". Try to set the framing so that "." does not have to move on the
* display. Some care has to be taken to keep the values of dot and mark in * display. Some care has to be taken to keep the values of dot and mark in
* the buffer structures right if the distruction of a window makes a buffer * the buffer structures right if the distruction of a window makes a buffer
* become undisplayed. * become undisplayed.
*/ */
BINDABLE( onlywind) { int onlywind(int f, int n)
window_p wp; {
line_p lp; struct window *wp;
struct line *lp;
int i; int i;
while (wheadp != curwp) { while (wheadp != curwp) {
@ -223,20 +241,23 @@ BINDABLE( onlywind) {
return TRUE; return TRUE;
} }
/*
/* Delete the current window, placing its space in the window above, * Delete the current window, placing its space in the window above,
* or, if it is the top window, the window below. Bound to C-X 0. * or, if it is the top window, the window below. Bound to C-X 0.
* *
* int f, n; arguments are ignored for this command * int f, n; arguments are ignored for this command
*/ */
BINDABLE( delwind) { int delwind(int f, int n)
window_p wp; /* window to recieve deleted space */ {
window_p lwp; /* ptr window before curwp */ struct window *wp; /* window to recieve deleted space */
struct window *lwp; /* ptr window before curwp */
int target; /* target line to search for */ int target; /* target line to search for */
/* if there is only one window, don't delete it */ /* if there is only one window, don't delete it */
if( wheadp->w_wndp == NULL) if (wheadp->w_wndp == NULL) {
return mloutfail( "Can not delete this window") ; mlwrite("Can not delete this window");
return FALSE;
}
/* find window before curwp in linked list */ /* find window before curwp in linked list */
wp = wheadp; wp = wheadp;
@ -295,8 +316,8 @@ BINDABLE( delwind) {
return TRUE; return TRUE;
} }
/*
/* Split the current window. A window smaller than 3 lines cannot be * Split the current window. A window smaller than 3 lines cannot be
* split. An argument of 1 forces the cursor into the upper window, an * split. An argument of 1 forces the cursor into the upper window, an
* argument of two forces the cursor to the lower window. The only * argument of two forces the cursor to the lower window. The only
* other error that is possible is a "malloc" failure allocating the * other error that is possible is a "malloc" failure allocating the
@ -304,21 +325,21 @@ BINDABLE( delwind) {
* *
* int f, n; default flag and numeric argument * int f, n; default flag and numeric argument
*/ */
BINDABLE( splitwind) { int splitwind(int f, int n)
window_p wp; {
line_p lp; struct window *wp;
struct line *lp;
int ntru; int ntru;
int ntrl; int ntrl;
int ntrd; int ntrd;
window_p wp1; struct window *wp1;
window_p wp2; struct window *wp2;
if (curwp->w_ntrows < 3) { if (curwp->w_ntrows < 3) {
mloutfmt( "Cannot split a %d line window", curwp->w_ntrows) ; mlwrite("Cannot split a %d line window", curwp->w_ntrows);
return FALSE; return FALSE;
} }
wp = xmalloc(sizeof(struct window));
wp = xmalloc( sizeof *wp) ;
++curbp->b_nwnd; /* Displayed twice. */ ++curbp->b_nwnd; /* Displayed twice. */
wp->w_bufp = curbp; wp->w_bufp = curbp;
wp->w_dotp = curwp->w_dotp; wp->w_dotp = curwp->w_dotp;
@ -377,30 +398,33 @@ BINDABLE( splitwind) {
return TRUE; return TRUE;
} }
/*
/* Enlarge the current window. Find the window that loses space. Make sure it * Enlarge the current window. Find the window that loses space. Make sure it
* is big enough. If so, hack the window descriptions, and ask redisplay to do * is big enough. If so, hack the window descriptions, and ask redisplay to do
* all the hard work. You don't just set "force reframe" because dot would * all the hard work. You don't just set "force reframe" because dot would
* move. Bound to "C-X Z". * move. Bound to "C-X Z".
*/ */
BINDABLE( enlargewind) { int enlargewind(int f, int n)
window_p adjwp; {
line_p lp; struct window *adjwp;
struct line *lp;
int i; int i;
if (n < 0) if (n < 0)
return shrinkwind(f, -n); return shrinkwind(f, -n);
if( wheadp->w_wndp == NULL) if (wheadp->w_wndp == NULL) {
return mloutfail( "Only one window") ; mlwrite("Only one window");
return FALSE;
}
if ((adjwp = curwp->w_wndp) == NULL) { if ((adjwp = curwp->w_wndp) == NULL) {
adjwp = wheadp; adjwp = wheadp;
while (adjwp->w_wndp != curwp) while (adjwp->w_wndp != curwp)
adjwp = adjwp->w_wndp; adjwp = adjwp->w_wndp;
} }
if( adjwp->w_ntrows <= n) if (adjwp->w_ntrows <= n) {
return mloutfail( "Impossible change") ; mlwrite("Impossible change");
return FALSE;
}
if (curwp->w_wndp == adjwp) { /* Shrink below. */ if (curwp->w_wndp == adjwp) { /* Shrink below. */
lp = adjwp->w_linep; lp = adjwp->w_linep;
for (i = 0; i < n && lp != adjwp->w_bufp->b_linep; ++i) for (i = 0; i < n && lp != adjwp->w_bufp->b_linep; ++i)
@ -426,29 +450,32 @@ BINDABLE( enlargewind) {
return TRUE; return TRUE;
} }
/*
/* Shrink the current window. Find the window that gains space. Hack at the * Shrink the current window. Find the window that gains space. Hack at the
* window descriptions. Ask the redisplay to do all the hard work. Bound to * window descriptions. Ask the redisplay to do all the hard work. Bound to
* "C-X C-Z". * "C-X C-Z".
*/ */
BINDABLE( shrinkwind) { int shrinkwind(int f, int n)
window_p adjwp; {
line_p lp; struct window *adjwp;
struct line *lp;
int i; int i;
if (n < 0) if (n < 0)
return enlargewind(f, -n); return enlargewind(f, -n);
if( wheadp->w_wndp == NULL) if (wheadp->w_wndp == NULL) {
return mloutfail( "Only one window") ; mlwrite("Only one window");
return FALSE;
}
if ((adjwp = curwp->w_wndp) == NULL) { if ((adjwp = curwp->w_wndp) == NULL) {
adjwp = wheadp; adjwp = wheadp;
while (adjwp->w_wndp != curwp) while (adjwp->w_wndp != curwp)
adjwp = adjwp->w_wndp; adjwp = adjwp->w_wndp;
} }
if( curwp->w_ntrows <= n) if (curwp->w_ntrows <= n) {
return mloutfail( "Impossible change") ; mlwrite("Impossible change");
return FALSE;
}
if (curwp->w_wndp == adjwp) { /* Grow below. */ if (curwp->w_wndp == adjwp) { /* Grow below. */
lp = adjwp->w_linep; lp = adjwp->w_linep;
for (i = 0; i < n && lback(lp) != adjwp->w_bufp->b_linep; for (i = 0; i < n && lback(lp) != adjwp->w_bufp->b_linep;
@ -475,12 +502,13 @@ BINDABLE( shrinkwind) {
return TRUE; return TRUE;
} }
/*
/* Resize the current window to the requested size * Resize the current window to the requested size
* *
* int f, n; default flag and numeric argument * int f, n; default flag and numeric argument
*/ */
BINDABLE( resize) { int resize(int f, int n)
{
int clines; /* current # of lines in window */ int clines; /* current # of lines in window */
/* must have a non-default argument, else ignore call */ /* must have a non-default argument, else ignore call */
@ -497,14 +525,14 @@ BINDABLE( resize) {
return enlargewind(TRUE, n - clines); return enlargewind(TRUE, n - clines);
} }
/*
/* Pick a window for a pop-up. Split the screen if there is only one window. * Pick a window for a pop-up. Split the screen if there is only one window.
* Pick the uppermost window that isn't the current window. An LRU algorithm * Pick the uppermost window that isn't the current window. An LRU algorithm
* might be better. Return a pointer, or NULL on error. * might be better. Return a pointer, or NULL on error.
*/ */
window_p wpopup(void) struct window *wpopup(void)
{ {
window_p wp; struct window *wp;
if (wheadp->w_wndp == NULL /* Only 1 window */ if (wheadp->w_wndp == NULL /* Only 1 window */
&& splitwind(FALSE, 0) == FALSE) /* and it won't split */ && splitwind(FALSE, 0) == FALSE) /* and it won't split */
@ -515,57 +543,59 @@ window_p wpopup(void)
return wp; return wp;
} }
int scrnextup(int f, int n)
/* scroll the next window up (back) a page */ { /* scroll the next window up (back) a page */
BINDABLE( scrnextup) {
nextwind(FALSE, 1); nextwind(FALSE, 1);
backpage(f, n); backpage(f, n);
prevwind(FALSE, 1); prevwind(FALSE, 1);
return TRUE; return TRUE;
} }
int scrnextdw(int f, int n)
/* scroll the next window down (forward) a page */ { /* scroll the next window down (forward) a page */
BINDABLE( scrnextdw) {
nextwind(FALSE, 1); nextwind(FALSE, 1);
forwpage(f, n); forwpage(f, n);
prevwind(FALSE, 1); prevwind(FALSE, 1);
return TRUE; return TRUE;
} }
int savewnd(int f, int n)
/* save ptr to current window */ { /* save ptr to current window */
BINDABLE( savewnd) { swindow = curwp;
savwindow = curwp ;
return TRUE; return TRUE;
} }
int restwnd(int f, int n)
{ /* restore the saved screen */
struct window *wp;
/* restore the saved screen */ /* find the window */
BINDABLE( restwnd) { wp = wheadp;
/* check the saved window still exists */ while (wp != NULL) {
for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) { if (wp == swindow) {
if( wp == savwindow) {
curwp = wp; curwp = wp;
curbp = wp->w_bufp; curbp = wp->w_bufp;
upmode(); upmode();
return TRUE; return TRUE;
} }
wp = wp->w_wndp;
} }
return mloutfail( "(No such window exists)") ; mlwrite("(No such window exists)");
return FALSE;
} }
/*
/* resize the screen, re-writing the screen * resize the screen, re-writing the screen
* *
* int f; default flag * int f; default flag
* int n; numeric argument * int n; numeric argument
*/ */
BINDABLE( newsize) { int newsize(int f, int n)
window_p wp; /* current window being examined */ {
window_p nextwp; /* next window to scan */ struct window *wp; /* current window being examined */
window_p lastwp; /* last window scanned */ struct window *nextwp; /* next window to scan */
struct window *lastwp; /* last window scanned */
int lastline; /* screen line of last line of current window */ int lastline; /* screen line of last line of current window */
/* if the command defaults, assume the largest */ /* if the command defaults, assume the largest */
@ -573,8 +603,10 @@ BINDABLE( newsize) {
n = term.t_mrow ; n = term.t_mrow ;
/* make sure it's in range */ /* make sure it's in range */
if( n < 3 || n > term.t_mrow) if (n < 3 || n > term.t_mrow) {
return mloutfail( "%%Screen size out of range") ; mlwrite("%%Screen size out of range");
return FALSE;
}
if (term.t_nrow == n - 1) if (term.t_nrow == n - 1)
return TRUE; return TRUE;
@ -642,22 +674,25 @@ BINDABLE( newsize) {
return TRUE; return TRUE;
} }
/*
/* resize the screen, re-writing the screen * resize the screen, re-writing the screen
* *
* int f; default flag * int f; default flag
* int n; numeric argument * int n; numeric argument
*/ */
BINDABLE( newwidth) { int newwidth(int f, int n)
window_p wp; {
struct window *wp;
/* if the command defaults, assume the largest */ /* if the command defaults, assume the largest */
if (f == FALSE) if (f == FALSE)
n = term.t_mcol; n = term.t_mcol;
/* make sure it's in range */ /* make sure it's in range */
if (n < 10 || n > term.t_mcol) if (n < 10 || n > term.t_mcol) {
return mloutfail( "%%Screen width out of range") ; mlwrite("%%Screen width out of range");
return FALSE;
}
/* otherwise, just re-width it (no big deal) */ /* otherwise, just re-width it (no big deal) */
term.t_ncol = n; term.t_ncol = n;
@ -678,7 +713,7 @@ BINDABLE( newwidth) {
int getwpos(void) int getwpos(void)
{ /* get screen offset of current line in current window */ { /* get screen offset of current line in current window */
int sline; /* screen line from top of window */ int sline; /* screen line from top of window */
line_p lp; /* scannile line pointer */ struct line *lp; /* scannile line pointer */
/* search down the line we want */ /* search down the line we want */
lp = curwp->w_linep; lp = curwp->w_linep;
@ -696,5 +731,3 @@ void cknewwindow(void)
{ {
execute(META | SPEC | 'X', FALSE, 1); execute(META | SPEC | 'X', FALSE, 1);
} }
/* end of window.c */

View File

@ -1,22 +1,21 @@
/* window.h -- window functionality */
#ifndef _WINDOW_H_ #ifndef _WINDOW_H_
#define _WINDOW_H_ #define _WINDOW_H_
#include "defines.h" /* COLOR, SCROLLCODE */ #include "defines.h" /* COLOR, SCROLLCODE */
#include "buffer.h" /* buffer_p, line_p */ #include "buffer.h" /* buffer, line */
#include "names.h" /* BINDABLE() */
/* There is a window structure allocated for every active display window. /*
The windows are kept in a big list, in top to bottom screen order, with * There is a window structure allocated for every active display window. The
the listhead at "wheadp". Each window contains its own values of dot * windows are kept in a big list, in top to bottom screen order, with the
and mark. The flag field contains some bits that are set by commands to * listhead at "wheadp". Each window contains its own values of dot and mark.
guide redisplay. Although this is a bit of a compromise in terms of * The flag field contains some bits that are set by commands to guide
decoupling, the full blown redisplay is just too expensive to run for * redisplay. Although this is a bit of a compromise in terms of decoupling,
every input character. * the full blown redisplay is just too expensive to run for every input
* character.
*/ */
typedef struct window { typedef struct window {
struct window *w_wndp; /* Next window */ struct window *w_wndp; /* Next window */
buffer_p w_bufp ; /* Buffer displayed in window */ struct buffer *w_bufp; /* Buffer displayed in window */
line_p w_linep ; /* Top line in the window */ line_p w_linep ; /* Top line in the window */
line_p w_dotp ; /* Line containing "." */ line_p w_dotp ; /* Line containing "." */
line_p w_markp ; /* Line containing "mark" */ line_p w_markp ; /* Line containing "mark" */
@ -50,29 +49,26 @@ extern window_p wheadp ; /* Head of list of windows */
#define WFINS 0x80 /* something was inserted */ #define WFINS 0x80 /* something was inserted */
#endif #endif
/* Bindable functions */ int reposition( int f, int n);
BINDABLE( delwind) ; int redraw( int f, int n) ;
BINDABLE( enlargewind) ; int nextwind( int f, int n) ;
BINDABLE( mvdnwind) ; int prevwind( int f, int n) ;
BINDABLE( mvupwind) ; int mvdnwind( int f, int n) ;
BINDABLE( newsize) ; int mvupwind( int f, int n) ;
BINDABLE( newwidth) ; int onlywind( int f, int n) ;
BINDABLE( nextwind) ; int delwind( int f, int n) ;
BINDABLE( onlywind) ; int splitwind( int f, int n) ;
BINDABLE( prevwind) ; int enlargewind( int f, int n) ;
TBINDABLE( redraw) ; int shrinkwind( int f, int n) ;
TBINDABLE( reposition) ; int resize( int f, int n) ;
BINDABLE( resize) ; int scrnextup( int f, int n) ;
BINDABLE( restwnd) ; int scrnextdw( int f, int n) ;
BINDABLE( savewnd) ; int savewnd( int f, int n) ;
BINDABLE( scrnextdw) ; int restwnd( int f, int n) ;
BINDABLE( scrnextup) ; int newsize( int f, int n) ;
BINDABLE( shrinkwind) ; int newwidth( int f, int n) ;
BINDABLE( splitwind) ;
int getwpos( void) ; int getwpos( void) ;
void cknewwindow( void) ; void cknewwindow( void) ;
window_p wpopup( void) ; /* Pop up window creation. */ window_p wpopup( void) ; /* Pop up window creation. */
#endif #endif
/* end of window.h */

152
word.c
View File

@ -1,11 +1,13 @@
/* word.c -- implements word.h */ /* word.c -- implements word.h */
#include "word.h" #include "word.h"
/* The routines in this file implement commands that work word or a /* word.c
paragraph at a time. There are all sorts of word mode commands. If I *
do any sentence mode commands, they are likely to be put in this file. * The routines in this file implement commands that work word or a
* paragraph at a time. There are all sorts of word mode commands. If I
Modified by Petri Kutvonen * do any sentence mode commands, they are likely to be put in this file.
*
* Modified by Petri Kutvonen
*/ */
#include <assert.h> #include <assert.h>
@ -29,18 +31,18 @@ static int justflag = FALSE ; /* justify, don't fill */
static int inword( void) ; static int inword( void) ;
/* Word wrap on n-spaces. Back-over whatever precedes the point on the /* Word wrap on n-spaces. Back-over whatever precedes the point on the current
current line and stop on the first word-break or the beginning of the * line and stop on the first word-break or the beginning of the line. If we
line. If we reach the beginning of the line, jump back to the end of * reach the beginning of the line, jump back to the end of the word and start
the word and start a new line. Otherwise, break the line at the * a new line. Otherwise, break the line at the word-break, eat it, and jump
word-break, eat it, and jump back to the end of the word. * back to the end of the word.
* Returns TRUE on success, FALSE on errors.
Returns TRUE on success, FALSE on errors. *
* @f: default flag.
@f: default flag. * @n: numeric argument.
@n: numeric argument.
*/ */
BINDABLE( wrapword) { int wrapword(int f, int n)
{
int cnt; /* size of word wrapped to next line */ int cnt; /* size of word wrapped to next line */
int c; /* charector temporary */ int c; /* charector temporary */
@ -79,12 +81,11 @@ BINDABLE( wrapword) {
return TRUE; return TRUE;
} }
/* Move the cursor backward by "n" words. All of the details of motion are /* Move the cursor backward by "n" words. All of the details of motion are
performed by the "backchar" and "forwchar" routines. Error if you try * performed by the "backchar" and "forwchar" routines. Error if you try to
to move beyond the buffers. * move beyond the buffers.
*/ */
BINDABLE( backword) { int backword( int f, int n) {
if( n < 0) if( n < 0)
return forwword( f, -n) ; return forwword( f, -n) ;
@ -105,12 +106,10 @@ BINDABLE( backword) {
return forwchar( FALSE, 1) ; return forwchar( FALSE, 1) ;
} }
/* Move the cursor forward by the specified number of words. All of the motion
/* Move the cursor forward by the specified number of words. All of the * is done by "forwchar". Error if you try and move beyond the buffer's end.
motion is done by "forwchar". Error if you try and move beyond the
buffer's end.
*/ */
BINDABLE( forwword) { int forwword( int f, int n) {
if( n < 0) if( n < 0)
return backword( f, -n) ; return backword( f, -n) ;
@ -173,41 +172,40 @@ static boolean capcapword( int n, boolean first_f, boolean rest_f) {
return TRUE ; return TRUE ;
} }
/* Move the cursor forward by the specified number of words. As you move, /* Move the cursor forward by the specified number of words. As you move,
convert any characters to upper case. Error if you try and move beyond * convert any characters to upper case. Error if you try and move beyond the
the end of the buffer. Bound to "M-U". * end of the buffer. Bound to "M-U".
*/ */
BINDABLE( upperword) { int upperword( int f, int n) {
return capcapword( n, TRUE, TRUE) ; return capcapword( n, TRUE, TRUE) ;
} }
/* Move the cursor forward by the specified number of words. As you move /* Move the cursor forward by the specified number of words. As you move
convert characters to lower case. Error if you try and move over the * convert characters to lower case. Error if you try and move over the end of
end of the buffer. Bound to "M-L". * the buffer. Bound to "M-L".
*/ */
BINDABLE( lowerword) { int lowerword( int f, int n) {
return capcapword( n, FALSE, FALSE) ; return capcapword( n, FALSE, FALSE) ;
} }
/* Move the cursor forward by the specified number of words. As you move /* Move the cursor forward by the specified number of words. As you move
convert the first character of the word to upper case, and subsequent * convert the first character of the word to upper case, and subsequent
characters to lower case. Error if you try and move past the end of the * characters to lower case. Error if you try and move past the end of the
buffer. Bound to "M-C". * buffer. Bound to "M-C".
*/ */
BINDABLE( capword) { int capword( int f, int n) {
return capcapword( n, TRUE, FALSE) ; return capcapword( n, TRUE, FALSE) ;
} }
/*
/* Kill forward by "n" words. Remember the location of dot. Move forward * Kill forward by "n" words. Remember the location of dot. Move forward by
by the right number of words. Put dot back where it was and issue the * the right number of words. Put dot back where it was and issue the kill
kill command for the right number of characters. With a zero argument, * command for the right number of characters. With a zero argument, just
just kill one word and no whitespace. Bound to "M-D". * kill one word and no whitespace. Bound to "M-D".
*/ */
BINDABLE( delfword) { int delfword(int f, int n)
{
line_p dotp; /* original cursor line */ line_p dotp; /* original cursor line */
int doto; /* and row */ int doto; /* and row */
int c; /* temp char */ int c; /* temp char */
@ -287,13 +285,13 @@ BINDABLE( delfword) {
return ldelete(size, TRUE); return ldelete(size, TRUE);
} }
/*
/* Kill backwards by "n" words. Move backwards by the desired number of * Kill backwards by "n" words. Move backwards by the desired number of words,
words, counting the characters. When dot is finally moved to its * counting the characters. When dot is finally moved to its resting place,
resting place, fire off the kill command. Bound to "M-Rubout" and to * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace".
"M-Backspace".
*/ */
BINDABLE( delbword) { int delbword(int f, int n)
{
assert( !(curbp->b_mode & MDVIEW)) ; assert( !(curbp->b_mode & MDVIEW)) ;
/* ignore the command if there is a nonpositive argument */ /* ignore the command if there is a nonpositive argument */
@ -354,13 +352,17 @@ static int parafillnjustify( int f, int n, int justify_f) {
assert( !(curbp->b_mode & MDVIEW)) ; assert( !(curbp->b_mode & MDVIEW)) ;
if( fillcol == 0) /* no fill column set */ if (fillcol == 0) { /* no fill column set */
return mloutfail( "No fill column set") ; mloutstr( "No fill column set") ;
return FALSE;
}
if( justify_f) { if( justify_f) {
leftmarg = getccol( FALSE) ; leftmarg = getccol( FALSE) ;
if( leftmarg + 10 > fillcol) if (leftmarg + 10 > fillcol) {
return mloutfail( "Column too narrow") ; mloutstr( "Column too narrow") ;
return FALSE;
}
justflag = justify_f ; justflag = justify_f ;
} }
@ -470,33 +472,33 @@ static int parafillnjustify( int f, int n, int justify_f) {
return TRUE; return TRUE;
} }
/*
/* Fill the current paragraph according to the current * Fill the current paragraph according to the current
* fill column * fill column
* *
* f and n - deFault flag and Numeric argument * f and n - deFault flag and Numeric argument
*/ */
BINDABLE( fillpara) { int fillpara( int f, int n) {
return parafillnjustify( f, n, FALSE) ; return parafillnjustify( f, n, FALSE) ;
} }
/* Fill the current paragraph according to the current /* Fill the current paragraph according to the current
* fill column and cursor position * fill column and cursor position
* *
* int f, n; deFault flag and Numeric argument * int f, n; deFault flag and Numeric argument
*/ */
BINDABLE( justpara) { int justpara( int f, int n) {
return parafillnjustify( f, n, TRUE) ; return parafillnjustify( f, n, TRUE) ;
} }
/*
/* delete n paragraphs starting with the current one * delete n paragraphs starting with the current one
* *
* int f default flag * int f default flag
* int n # of paras to delete * int n # of paras to delete
*/ */
BINDABLE( killpara) { int killpara(int f, int n)
{
while (n--) { /* for each paragraph to delete */ while (n--) { /* for each paragraph to delete */
/* mark out the end and beginning of the para to delete */ /* mark out the end and beginning of the para to delete */
@ -523,13 +525,15 @@ BINDABLE( killpara) {
} }
/* wordcount: count the # of words in the marked region, /*
* wordcount: count the # of words in the marked region,
* along with average word sizes, # of chars, etc, * along with average word sizes, # of chars, etc,
* and report on them. * and report on them.
* *
* int f, n; ignored numeric arguments * int f, n; ignored numeric arguments
*/ */
BINDABLE( wordcount) { int wordcount(int f, int n)
{
line_p lp; /* current line to scan */ line_p lp; /* current line to scan */
int offset; /* current char to scan */ int offset; /* current char to scan */
long size; /* size of region left to count */ long size; /* size of region left to count */
@ -587,14 +591,15 @@ BINDABLE( wordcount) {
return TRUE; return TRUE;
} }
/*
/* go back to the beginning of the current paragraph * go back to the beginning of the current paragraph
* here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE> * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
* combination to delimit the beginning of a paragraph * combination to delimit the beginning of a paragraph
* *
* int f, n; default Flag & Numeric argument * int f, n; default Flag & Numeric argument
*/ */
BINDABLE( gotobop) { int gotobop(int f, int n)
{
if (n < 0) /* the other way... */ if (n < 0) /* the other way... */
return gotoeop(f, -n); return gotoeop(f, -n);
@ -624,14 +629,15 @@ BINDABLE( gotobop) {
return TRUE; return TRUE;
} }
/*
/* Go forward to the end of the current paragraph here we look for a * Go forward to the end of the current paragraph
<NL><NL> or <NL><TAB> or <NL><SPACE> combination to delimit the * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
beginning of a paragraph * combination to delimit the beginning of a paragraph
*
int f, n; default Flag & Numeric argument * int f, n; default Flag & Numeric argument
*/ */
BINDABLE( gotoeop) { int gotoeop(int f, int n)
{
if (n < 0) /* the other way... */ if (n < 0) /* the other way... */
return gotobop(f, -n); return gotobop(f, -n);