1
0
mirror of https://github.com/rfivet/uemacs.git synced 2024-12-18 07:16:23 -05:00

Compare commits

...

4 Commits

Author SHA1 Message Date
50b727bf7f Bindable functions take a boolean as flag.
Emphasize which one always return TRUE.
Use mloutfail() to introduce consistency when a function fails with error message.
2021-08-11 17:02:19 +08:00
665d9ca1da bindable: code review and minor refactoring. 2021-08-09 15:45:01 +08:00
720603ac8e bind: code review and minor refactoring.
basic: minor reformatting.
2021-08-09 15:24:33 +08:00
eaf516110f basic: code review and minor refactoring. 2021-08-09 12:06:07 +08:00
32 changed files with 2082 additions and 2310 deletions

247
basic.c
View File

@ -1,19 +1,16 @@
/* basic.c -- implements basic.h */ /* basic.c -- implements basic.h */
#include "basic.h" #include "basic.h"
/* basic.c /* The routines in this file move the cursor around on the screen. They
* compute a new value for the cursor, then adjust ".". The display code
* The routines in this file move the cursor around on the screen. They always updates the cursor location, so only moves between lines, or
* compute a new value for the cursor, then adjust ".". The display code functions that adjust the top line in the window and invalidate the
* always updates the cursor location, so only moves between lines, or framing, are hard.
* functions that adjust the top line in the window and invalidate the
* framing, are hard. modified by Petri Kutvonen
*
* modified by Petri Kutvonen
*/ */
#include <stdio.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include "input.h" #include "input.h"
@ -22,26 +19,20 @@
#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 overlap = DEFAULT_OVERLAP ; /* line overlap in forw/back page */ int curgoal ; /* $target: column goal for C-P, C-N */
int curgoal ; /* Goal for C-P, C-N */
/* /* This routine, given a pointer to a struct line, and the current cursor
* This routine, given a pointer to a struct line, and the current cursor goal goal column, return the best choice for the offset. The offset is
* column, return the best choice for the offset. The offset is returned. returned. Used by "C-N" and "C-P".
* Used by "C-N" and "C-P".
*/ */
static unsigned getgoal( line_p dlp) { static unsigned getgoal( line_p dlp) {
int col ; int col = 0 ;
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) ;
@ -49,77 +40,70 @@ 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) else if( c < 0x20 || c == 0x7F) /* ^x */
col += 2 ; col += 2 ;
else if( c >= 0x80 && c <= 0xA0) else if( c >= 0x80 && c <= 0xA0) /* \xx */
col += 3 ; col += 3 ;
else else {
col += 1 ; int w = utf8_width( c) ; /* work around */
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 dot considered to be hard motion; it really isn't if the original value of
* is the same as the new value of dot. Normally bound to "M-<". dot is the same as the new value of dot. Normally bound to "M-<".
*/ */
boolean gotobob( int f, int n) { TBINDABLE( gotobob) {
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->".
*/ */
boolean gotoeob( int f, int n) { TBINDABLE( gotoeob) {
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 command zero, call the backward line function to actually do it. The last
* controls how the goal column is set. Bound to "C-N". No errors are command controls how the goal column is set. Bound to "C-N". No errors
* possible. are possible.
*/ */
boolean forwline( int f, int n) { BBINDABLE( forwline) {
line_p dlp ; assert( f == TRUE || n == 1) ;
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)
@ -129,79 +113,62 @@ boolean forwline( int f, int n) {
thisflag |= CFCPCN ; thisflag |= CFCPCN ;
/* and move the point down */ /* and move the point down */
dlp = curwp->w_dotp; if( n) {
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 {
/* reseting the current position */
curwp->w_dotp = dlp;
curwp->w_doto = getgoal(dlp);
curwp->w_flag |= WFMOVE;
return (n == 0) ? TRUE : FALSE ;
}
/*
* This function is like "forwline", but goes backwards. The scheme is exactly
* the same. Check for arguments that are less than zero and call your
* alternate. Figure out the new line and call "movedot" to perform the
* motion. No errors are possible. Bound to "C-P".
*/
boolean backline( int f, int n) {
line_p dlp ;
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) { while( n && lback( dlp) != curbp->b_linep) {
dlp = lback( dlp) ; dlp = lback( dlp) ;
n -= 1 ; n += 1 ;
}
} }
/* reseting the current position */ /* resetting 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 ;
} }
/*
* Move to a particular line. /* This function is like "forwline", but goes backwards. The scheme is
exactly the same. Check for arguments that are less than zero and call
your alternate. Figure out the new line and call "movedot" to perform
the motion. No errors are possible. Bound to "C-P".
*/
BBINDABLE( backline) {
assert( f == TRUE || n == 1) ;
return forwline( TRUE, -n) ;
}
/* Move to a particular line.
* *
* @n: The specified line position at the current buffer. * @n: The specified line position at the current buffer.
*/ */
int gotoline( int f, int n) { BINDABLE( gotoline) {
/* Get an argument if one doesnt exist. */ /* Get an argument if one doesn't exist. */
if( f == FALSE) { if( f == FALSE) {
int status ;
char *arg ; /* Buffer to hold argument. */ char *arg ; /* Buffer to hold argument. */
status = newmlarg( &arg, "Line to GOTO: ", 0) ; int status = newmlarg( &arg, "goto-line: ", 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:
* em filename + * ue 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)
@ -213,16 +180,17 @@ int gotoline( int f, int n) {
/* 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( f, n - 1) ; return (n == 1) ? TRUE : forwline( TRUE, 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 is argument. Bound to "C-V". The "2" in the arithmetic on the window size
* the overlap; this value is the default overlap value in ITS EMACS. Because is the overlap; this value is the default overlap value in ITS EMACS.
* this zaps the top line in the display window, we have to do a hard update. Because this zaps the top line in the display window, we have to do a
hard update.
*/ */
boolean forwpage( int f, int n) { TBINDABLE( forwpage) {
line_p lp ; line_p lp ;
if( f == FALSE) { if( f == FALSE) {
@ -245,17 +213,15 @@ boolean forwpage( int f, int n) {
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) ; reposition( TRUE, 0) ; /* center at dot, always succeed */
#if SCROLLCODE #if SCROLLCODE
curwp->w_flag |= WFHARD | WFKILLS; curwp->w_flag |= WFHARD | WFKILLS;
@ -265,13 +231,13 @@ boolean forwpage( int f, int n) {
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 ITS above, is the overlap between the two windows. The value is from the
* EMACS manual. Bound to "M-V". We do a hard update for exactly the same ITS EMACS manual. Bound to "M-V". We do a hard update for exactly the
* reason. same reason.
*/ */
boolean backpage( int f, int n) { TBINDABLE( backpage) {
line_p lp ; line_p lp ;
if( f == FALSE) { /* interactive, default n = 1 supplied */ if( f == FALSE) { /* interactive, default n = 1 supplied */
@ -322,39 +288,32 @@ boolean backpage( int f, int n) {
return TRUE; return TRUE;
} }
/*
* Set the mark in the current window to the value of "." in the window. No /* Set the mark in the current window to the value of "." in the window.
* errors are possible. Bound to "M-.". No errors are possible. Bound to M-. set-mark.
*/ */
boolean setmark( int f, int n) { TBINDABLE( setmark) {
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. This is pretty /* Swap the values of "." and "mark" in the current window. If no mark as
* easy, because all of the hard work gets done by the standard routine been previously set, set it. Bound to C-X C-X exchange-point-and-mark.
* that moves the mark about. The only possible error is "no mark". Bound to
* "C-X C-X".
*/ */
boolean swapmark( int f, int n) { TBINDABLE( swapmark) {
line_p odotp ; line_p odotp = curwp->w_dotp ;
int odoto; int odoto = curwp->w_doto ;
if( curwp->w_markp) {
if( curwp->w_markp == NULL) {
mloutstr( "No mark in this window") ;
return FALSE ;
}
odotp = curwp->w_dotp;
odoto = curwp->w_doto;
curwp->w_dotp = curwp->w_markp ; curwp->w_dotp = curwp->w_markp ;
curwp->w_doto = curwp->w_marko ; curwp->w_doto = curwp->w_marko ;
curwp->w_flag |= WFMOVE ;
}
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,35 +1,32 @@
/* 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 "retcode.h" # include "names.h"
/* /* $overlap is the size of the line overlap when kbd calls page forw/back
** $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)
** if 0, page will move by 2/3 of the window size (1/3 page overlap) default to 0
** default to 0
*/ */
#define DEFAULT_OVERLAP 0 extern int overlap ; /* $overlap: line overlap in forw/back page */
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 ; /* Goal for C-P previous-line, C-N next-line */ extern int curgoal ; /* $target: Goal for C-P previous-line, C-N next-line */
boolean gotobol( int f, int n) ; /* Bindable functions */
boolean gotoeol( int f, int n) ; BBINDABLE( backline) ;
int gotoline( int f, int n) ; TBINDABLE( backpage) ;
boolean gotobob( int f, int n) ; BBINDABLE( forwline) ;
boolean gotoeob( int f, int n) ; TBINDABLE( forwpage) ;
boolean forwline( int f, int n) ; TBINDABLE( gotobob) ;
boolean backline( int f, int n) ; TBINDABLE( gotobol) ;
boolean forwpage( int f, int n) ; TBINDABLE( gotoeob) ;
boolean backpage( int f, int n) ; TBINDABLE( gotoeol) ;
boolean setmark( int f, int n) ; BINDABLE( gotoline) ;
boolean swapmark( int f, int n) ; TBINDABLE( setmark) ;
TBINDABLE( swapmark) ;
#endif #endif
/* end of basic.h */ /* end of basic.h */

141
bind.c
View File

@ -9,24 +9,22 @@
*/ */
#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" #include "display.h" /* upmode(), ostring() */
#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) ;
@ -34,14 +32,10 @@ static unsigned int stock( char *keyname) ;
static const char *getfname( unsigned keycode, const char *failmsg) ; static const char *getfname( unsigned keycode, const char *failmsg) ;
static boolean cmdfail( const char *msg) { /* give me some help!!!! bring up a fake buffer and read the help file into
mlwrite( "%s", msg) ; it with view mode
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 */
@ -52,7 +46,7 @@ BINDABLE( help) {
if( bp == NULL) { if( bp == NULL) {
fname = flook( hlpfname, FALSE) ; fname = flook( hlpfname, FALSE) ;
if( fname == NULL) if( fname == NULL)
return cmdfail( "(Help file is not online)") ; return mloutfail( "(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 */
@ -74,17 +68,19 @@ BINDABLE( help) {
return TRUE ; return TRUE ;
} }
static boolean invalidkey( void) { static boolean invalidkey( void) {
return cmdfail( "(Invalid key sequence)") ; return mloutfail( "(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[ NSTRING] ; /* output buffer for command sequence */ char outseq[ 8] ; /* output buffer for keystroke sequence */
/* prompt the user to type a key to describe */ /* prompt the user to type a key to describe */
mlwrite( "%s: ", cmdname) ; mloutfmt( "%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 */
@ -93,23 +89,23 @@ BINDABLE( deskey) {
return invalidkey() ; return invalidkey() ;
/* output the command sequence */ /* output the command sequence */
mlwrite( "%s %s: 0x%x, %s", cmdname, cmdstr( keycode, outseq), keycode, mloutfmt( "%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[ 80] ; /* output buffer for keystroke sequence */ char outseq[ 8] ; /* 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 */
mlwrite("bind-to-key: "); mloutstr( "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() ;
@ -118,13 +114,13 @@ BINDABLE( bindtokey) {
fnp_t kfunc = nbp->n_func ; fnp_t kfunc = nbp->n_func ;
if( kfunc == NULL) if( kfunc == NULL)
return cmdfail( "(No such function)") ; return mloutfail( "(No such function)") ;
mlwrite( "bind-to-key %s: ", bind_name( nbp)) ; mloutfmt( "bind-to-key %s: ", bind_name( nbp)) ;
/* get the command sequence to bind */ /* get the command sequence to bind */
boolean prefix_f = (kfunc == metafn) || (kfunc == cex) || boolean prefix_f = (kfunc == (fnp_t) metafn) || (kfunc == (fnp_t) cex) ||
(kfunc == unarg) || (kfunc == ctrlg) ; (kfunc == (fnp_t) unarg) || (kfunc == (fnp_t) ctrlg) ;
int c = getckey( prefix_f) ; int c = getckey( prefix_f) ;
if( c == ~0) if( c == ~0)
return invalidkey() ; return invalidkey() ;
@ -135,13 +131,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 == metafn) if( (c == metac && kfunc == (fnp_t) metafn)
|| (c == ctlxc && kfunc == cex) || (c == ctlxc && kfunc == (fnp_t) cex)
|| (c == reptc && kfunc == unarg) || (c == reptc && kfunc == (fnp_t) unarg)
|| (c == abortc && kfunc == ctrlg)) || (c == abortc && kfunc == (fnp_t) ctrlg))
return TRUE ; return TRUE ; /* be silent if keep current */
return cmdfail( "(Can't bind to active prefix)") ; return mloutfail( "(Can't bind to active prefix)") ;
} }
/* if the function is a prefix key */ /* if the function is a prefix key */
@ -154,34 +150,34 @@ BINDABLE( bindtokey) {
} }
/* set the appropriate global prefix variable */ /* set the appropriate global prefix variable */
if( kfunc == metafn) if( kfunc == (fnp_t) metafn)
metac = c ; metac = c ;
else if( kfunc == cex) else if( kfunc == (fnp_t) cex)
ctlxc = c ; ctlxc = c ;
if( kfunc == unarg) if( kfunc == (fnp_t) unarg)
reptc = c ; reptc = c ;
if( kfunc == ctrlg) if( kfunc == (fnp_t) ctrlg)
abortc = c ; abortc = c ;
} }
ktp = setkeybinding( c, nbp) ; ktp = setkeybinding( c, nbp) ;
if( ktp->k_code == 0) if( ktp->k_code == 0)
return cmdfail( "Binding table FULL!") ; return mloutfail( "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[ 80] ; /* output buffer for keystroke sequence */ char outseq[ 8] ; /* 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 */
mlwrite( "unbind-key: ") ; mloutstr( "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 */
@ -194,19 +190,17 @@ 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 cmdfail( "(Can't unbind prefix)") ; return mloutfail( "(Can't unbind prefix)") ;
/* if it isn't bound, bitch */ /* if it isn't bound, bitch */
if( delkeybinding( c) == FALSE) { if( delkeybinding( c) == FALSE)
mlwrite( "(Key not bound)") ; return mloutfail( "(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
@ -232,6 +226,7 @@ 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
@ -240,6 +235,7 @@ 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 */
@ -254,17 +250,14 @@ 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) {
struct window *wp; /* scanning pointer to windows */ #define PADDING 28
kbind_p ktp; /* pointer into the command table */ char outseq[ PADDING + 8] ; /* output buffer for command + keystroke */
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 */
@ -272,12 +265,12 @@ static int buildlist( char *mstring) {
return FALSE ; return FALSE ;
/* and get a buffer for it */ /* and get a buffer for it */
bp = bfind("*Binding list*", TRUE, 0); buffer_p bp = bfind( "*Binding list*", TRUE, 0) ;
if( bp == NULL || bclear( bp) == FALSE) if( bp == NULL || bclear( bp) == FALSE)
return cmdfail( "Can't display binding list") ; return mloutfail( "Can't display binding list") ;
/* let us know this is in progress */ /* let us know this is in progress */
mlwrite("(Building binding list)"); mloutstr( "(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. */
@ -291,7 +284,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 */
wp = curwp; window_p 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 ;
@ -301,7 +294,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( nptr = names ; nptr->n_func != NULL ; nptr++) { for( nbind_p 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..... */
@ -314,10 +307,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( ktp = keytab ; ktp->k_code != 0 ; ktp++) { for( kbind_p 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 < 28) while( cpos < PADDING)
outseq[ cpos++] = ' ' ; outseq[ cpos++] = ' ' ;
/* add in the command sequence */ /* add in the command sequence */
@ -346,12 +339,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 */
mlwrite(""); /* clear the mode line */ mloutstr( "") ; /* 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
@ -378,8 +371,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)
*/ */
@ -394,8 +387,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
@ -411,14 +404,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 & CTRL) if( ctlxc & CTL_)
*ptr++ = '^' ; *ptr++ = '^' ;
*ptr++ = ctlxc & ~PRFXMASK ; *ptr++ = ctlxc & ~PRFXMASK ;
} }
/* apply control sequence if needed */ /* apply control sequence if needed */
if( c & CTRL) if( c & CTL_)
*ptr++ = '^' ; *ptr++ = '^' ;
/* apply SPEC sequence if needed */ /* apply SPEC sequence if needed */
@ -433,6 +426,7 @@ 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) ;
@ -444,6 +438,7 @@ 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
* *
@ -466,7 +461,7 @@ static unsigned int stock( char *keyname) {
/* a control char? */ /* a control char? */
if( *keyname == '^' && keyname[ 1] != 0) { if( *keyname == '^' && keyname[ 1] != 0) {
c |= CTRL ; c |= CTL_ ;
++keyname ; ++keyname ;
} }
@ -482,7 +477,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 |= CTRL ; c |= CTL_ ;
*keyname ^= 0x40 ; *keyname ^= 0x40 ;
} else if( c && !(c & SPEC) } else if( c && !(c & SPEC)
&& *keyname >= 'a' && *keyname <= 'z') && *keyname >= 'a' && *keyname <= 'z')
@ -494,8 +489,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,3 +1,5 @@
/* bind.h -- bindable functions dealing with name and key bindings */
#ifndef _BIND_H_ #ifndef _BIND_H_
#define _BIND_H_ #define _BIND_H_
@ -17,3 +19,5 @@ 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,64 +3,48 @@
#include <stdlib.h> #include <stdlib.h>
#include "defines.h" #include "defines.h"
#include "buffer.h" #include "buffer.h"
#include "display.h" #include "display.h" /* vttidy() */
#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 the any buffer has /* Fancy quit command, as implemented by Norm. If any buffer has changed
* changed do a write on that buffer and exit emacs, otherwise simply exit. do a write on that buffer and exit emacs, otherwise simply exit.
*/ */
int quickexit(int f, int n) BINDABLE( quickexit) {
{ buffer_p oldcb = curbp ; /* save in case we fail */
struct buffer *bp; /* scanning pointer to buffers */ for( buffer_p bp = bheadp ; bp != NULL ; bp = bp->b_bufp) {
struct buffer *oldcb; /* original current buffer */ if( (bp->b_flag & (BFCHG | BFTRUNC | BFINVS)) == BFCHG) {
int status; /* Changed, Not truncated and real buffer */
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) ;
#if PKCODE int status = filesave( f, n) ;
#else if( status != TRUE) {
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".
*/ */
int quit(int f, int n) BINDABLE( quit) {
{ 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 = || (s = mlyesno( "Modified buffers exist. Leave anyway")) == TRUE) {
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') ;
@ -76,70 +60,67 @@ int quit(int f, int n)
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.
*/ */
int ctlxlp(int f, int n) BBINDABLE( ctlxlp) {
{ if( kbdmode != STOP)
if (kbdmode != STOP) { return mloutfail( "%Macro already active") ;
mloutstr( "%Macro already active") ;
return FALSE;
}
mloutstr( "(Start macro)") ; mloutstr( "(Start macro)") ;
kbdptr = &kbdm[0]; kbdptr = kbdm ;
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.
*/ */
int ctlxrp(int f, int n) BBINDABLE( ctlxrp) {
{ if( kbdmode == STOP)
if (kbdmode == STOP) { return mloutfail( "%Macro not active") ;
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.
*/ */
int ctlxe(int f, int n) BBINDABLE( ctlxe) {
{ if( kbdmode != STOP)
if (kbdmode != STOP) { return mloutfail( "%Macro already active") ;
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[0]; /* at the beginning */ kbdptr = kbdm ; /* 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.
*/ */
int ctrlg( int f, int n) { BINDABLE( ctrlg) {
kbdmode = STOP ; kbdmode = STOP ;
mloutfmt( "%B(Aborted)") ; mloutfmt( "%B(Aborted)") ;
return ABORT ; return ABORT ;

View File

@ -1,9 +1,16 @@
/* 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) ;
BINDABLE( ctlxrp) ; #endif
BINDABLE( ctlxe) ; /* end of bindable.h */
BINDABLE( ctrlg) ;

355
buffer.c
View File

@ -1,18 +1,12 @@
/* buffer.c -- implements buffer.h */ /* buffer.c -- implements buffer.h */
#include "buffer.h" #include "buffer.h"
/* buffer.c /* Buffer management. Some of the functions are internal, and some are actually attached to
* user keys. Like everyone else, they set hints for the display system.
* Buffer management.
* Some of the functions are internal, modified by Petri Kutvonen
* 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>
@ -26,11 +20,11 @@
#include "window.h" #include "window.h"
struct buffer *curbp ; /* Current buffer */ buffer_p curbp ; /* Current buffer */
struct buffer *bheadp ; /* Head of list of buffers */ buffer_p bheadp ; /* Head of list of buffers */
struct buffer *blistp ; /* Buffer for C-X C-B */ buffer_p blistp ; /* Buffer for C-X C-B */
const char *modename[] = { /* name of modes */ const char *modename[ NUMMODES] = { /* name of modes */
"Wrap", "Cmode", "Exact", "View", "Over", "Wrap", "Cmode", "Exact", "View", "Over",
"Magic", "Magic",
"Asave", "Utf-8", "Dos" "Asave", "Utf-8", "Dos"
@ -43,24 +37,20 @@ 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
* Attach a buffer to a window. The buffer if the use count is 0. Otherwise, they come from some other
* values of dot and mark come from the buffer window.
* if the use count is 0. Otherwise, they come
* from some other window.
*/ */
int usebuffer( int f, int n) { BINDABLE( usebuffer) {
struct buffer *bp ;
int status ;
char *bufn ; char *bufn ;
/* Get buffer name */ /* Get buffer name */
status = newmlarg( &bufn, "Use buffer: ", sizeof( bname_t)) ; int status = newmlarg( &bufn, "select-buffer: ", sizeof( bname_t)) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
/* Find buffer in list */ /* Find buffer in list */
bp = bfind( bufn, TRUE, 0) ; buffer_p bp = bfind( bufn, TRUE, 0) ;
free( bufn) ; free( bufn) ;
if( bp == NULL) if( bp == NULL)
return FALSE ; return FALSE ;
@ -69,28 +59,27 @@ int usebuffer( int f, int n) {
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
*/ */
int nextbuffer(int f, int n) BINDABLE( nextbuffer) {
{ 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 ;
bbp = curbp; buffer_p bbp = curbp ; /* eligible buffer to switch to */
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 eligable one */ /* cycle through the buffers to find an eligible 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 ;
@ -100,7 +89,6 @@ int nextbuffer(int f, int n)
/* 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 ;
@ -109,12 +97,11 @@ int nextbuffer(int f, int n)
return swbuffer( bp) ; return swbuffer( bp) ;
} }
/*
* make buffer BP current /* make buffer BP current
*/ */
int swbuffer(struct buffer *bp) int swbuffer( buffer_p 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;
@ -157,21 +144,19 @@ int swbuffer(struct buffer *bp)
return TRUE; return TRUE;
} }
/*
* Dispose of a buffer, by name. /* Dispose of a buffer, by name. Ask for the name. Look it up (don't get
* Ask for the name. Look it up (don't get too too upset if it isn't there at all!). Get quite upset if the buffer is
* upset if it isn't there at all!). Get quite upset being displayed. Clear the buffer (ask if the buffer has been changed).
* if the buffer is being displayed. Clear the buffer (ask Then free the header line and the buffer header. Bound to "C-X K".
* if the buffer has been changed). Then free the header
* line and the buffer header. Bound to "C-X K".
*/ */
int killbuffer( int f, int n) { BINDABLE( killbuffer) {
struct buffer *bp ; buffer_p bp ;
int status ; int status ;
char *bufn ; char *bufn ;
/* Get buffer name */ /* Get buffer name */
status = newmlarg( &bufn, "Kill buffer: ", sizeof( bname_t)) ; status = newmlarg( &bufn, "delete-buffer: ", sizeof( bname_t)) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
@ -187,66 +172,60 @@ int killbuffer( int f, int n) {
return zotbuf( bp) ; return zotbuf( bp) ;
} }
/*
* kill the buffer pointed to by bp
*/
int zotbuf(struct buffer *bp)
{
struct buffer *bp1;
struct buffer *bp2;
int s;
if (bp->b_nwnd != 0) { /* Error if on screen. */ /* kill the buffer pointed to by bp
mloutstr("Buffer is being displayed"); */
return FALSE; int zotbuf( buffer_p bp) {
} if( bp->b_nwnd != 0) /* Error if on screen. */
if ((s = bclear(bp)) != TRUE) /* Blow text away. */ return mloutfail( "Buffer is being displayed") ;
int s = bclear( bp) ; /* Blow text away. */
if( s != TRUE)
return s ; return s ;
free((char *) bp->b_linep); /* Release header line. */
bp1 = NULL; /* Find the header. */ free( bp->b_linep) ; /* Release header line. */
bp2 = bheadp;
while (bp2 != bp) { /* unlink buffer from buffer chain */
bp1 = bp2; if( bheadp == bp)
bp2 = bp2->b_bufp; 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 ;
} }
bp2 = bp2->b_bufp; /* Next one in chain. */
if (bp1 == NULL) /* Unlink it. */ free( bp) ; /* Release buffer block */
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
*/ */
int namebuffer( int f, int n) { BINDABLE( namebuffer) {
struct buffer *bp ; /* pointer to scan through all buffers */
int status ;
char *bufn ; /* buffer to hold buffer name */ char *bufn ; /* buffer to hold buffer name */
int status ;
/* prompt for and get the new buffer name */ /* iterate until it gets a unique new buffer name */
ask: do {
status = newmlarg( &bufn, "Change buffer name to: ", sizeof( bname_t)) ; /* prompt for it */
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 */
bp = bheadp ; for( buffer_p bp = bheadp ; bp != NULL ; bp = bp->b_bufp) {
while( bp != NULL) { if( bp != curbp) { /* it's ok to rename buffer to same, so skip */
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) ;
goto ask ; /* try again */ status = FALSE ; /* 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)) ;
@ -257,28 +236,28 @@ ask:
return TRUE ; return TRUE ;
} }
/*
* List all of the active buffers. First update the special
* buffer that holds the list. Next make sure at least 1
* window is displaying the buffer list, splitting the screen
* if this is what it takes. Lastly, repaint all of the
* windows that are displaying the list. Bound to "C-X C-B".
*
* A numeric argument forces it to list invisible buffers as
* well.
*/
int listbuffers(int f, int n)
{
struct window *wp;
int s;
if ((s = makelist(f)) != TRUE) /* List all of the active buffers. First update the special buffer that
holds the list. Next make sure at least 1 window is displaying the
buffer list, splitting the screen if this is what it takes. Lastly,
repaint all of the windows that are displaying the list. Bound to "C-X
C-B".
A numeric argument forces it to list invisible buffers as well.
*/
BINDABLE( listbuffers) {
window_p wp ;
int s = makelist( f) ;
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. */
struct buffer *bp ; buffer_p 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 ;
@ -286,11 +265,12 @@ int listbuffers(int f, int n)
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;
while (wp != NULL) { for( wp = wheadp ; wp != NULL ; wp = wp->w_wndp) {
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) ;
@ -299,21 +279,18 @@ int listbuffers(int f, int n)
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 /* This routine rebuilds the text in the special secret buffer that holds
* text in the special secret buffer the buffer list. It is called by the list buffers command. Return TRUE
* that holds the buffer list. It is called if everything works. Return FALSE if there is an error (if there is no
* by the list buffers command. Return TRUE memory). Iflag indicates wether to list hidden buffers.
* if everything works. Return FALSE if there
* is an error (if there is no memory). Iflag int iflag; list hidden buffer flag
* 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...
@ -333,6 +310,7 @@ 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 ;
@ -346,9 +324,9 @@ static unsigned int utf8_disp_len( const char *s) {
return len ; return len ;
} }
static int makelist( int iflag)
{ static int makelist( int iflag) {
struct buffer *bp; buffer_p bp;
int s; int s;
char line[ FNAMSTART + sizeof( fname_t)] ; char line[ FNAMSTART + sizeof( fname_t)] ;
@ -371,7 +349,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 ;
struct line *lp ; line_p 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 */
@ -430,8 +408,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';
@ -442,87 +420,82 @@ 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 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)
{
struct line *lp;
int i;
int ntext;
ntext = strlen(text); /* The argument "text" points to a string. Append this line to the buffer
if ((lp = lalloc(ntext)) == NULL) 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) {
int ntext = strlen( text) ;
line_p lp = lalloc( ntext) ;
if( lp == 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 /* Look through the list of buffers. Return TRUE if there are any changed
* buffers. Return TRUE if there buffers. Buffers that hold magic internal stuff are not considered; who
* are any changed buffers. Buffers cares if the list of buffer names is hacked. Return FALSE if no buffers
* that hold magic internal stuff are have been changed.
* not considered; who cares if the
* list of buffer names is hacked.
* Return FALSE if no buffers
* have been changed.
*/ */
int anycb(void) boolean anycb( void) {
{ for( buffer_p bp = bheadp ; bp != NULL ; bp = bp->b_bufp) {
struct buffer *bp; if( (bp->b_flag & (BFINVS | BFCHG)) == BFCHG)
bp = bheadp;
while (bp != NULL) {
if ((bp->b_flag & BFINVS) == 0
&& (bp->b_flag & BFCHG) != 0)
return TRUE ; return TRUE ;
bp = bp->b_bufp;
} }
return FALSE ; return FALSE ;
} }
/*
* Find a buffer, by name. Return a pointer /* Find a buffer, by name. Return a pointer to the buffer structure
* to the buffer structure associated with it. associated with it. If the buffer is not found and the "create_f" is
* If the buffer is not found TRUE, create it. The "flags" is the settings for the buffer flags.
* and the "cflag" is TRUE, create it. The "bflag" is
* the settings for the flags in in buffer.
*/ */
struct buffer *bfind( const char *bname, int cflag, int bflag) buffer_p bfind( const char *bname, boolean create_f, int flags) {
{ 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 (cflag != FALSE) { if( create_f != FALSE) {
if ((bp = (struct buffer *)malloc(sizeof(struct buffer))) == NULL) /* allocate empty buffer */
bp = malloc( sizeof *bp) ;
if( bp == NULL)
return NULL ; return NULL ;
if ((lp = lalloc(0)) == NULL) {
free((char *) bp); line_p lp = lalloc( 0) ;
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 {
struct buffer *sb; /* buffer to insert after */ buffer_p 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)
@ -535,44 +508,37 @@ struct buffer *bfind( const char *bname, int cflag, int bflag)
/* 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 = bflag; bp->b_flag = flags ;
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 /* This routine blows away all of the text in a buffer. If the buffer is
* in a buffer. If the buffer is marked as changed marked as changed then we ask if it is ok to blow it away; this is to
* then we ask if it is ok to blow it away; this is save the user the grief of losing text. The window chain is nearly
* to save the user the grief of losing text. The always wrong if this gets called; the caller must arrange for the
* window chain is nearly always wrong if this gets updates that are required. Return TRUE if everything looks good.
* called; the caller must arrange for the updates
* that are required. Return TRUE if everything
* looks good.
*/ */
int bclear(struct buffer *bp) int bclear( buffer_p bp) {
{ line_p lp ;
struct line *lp;
int s ; int s ;
if ((bp->b_flag & BFINVS) == 0 /* Not scratch buffer. */ if( (bp->b_flag & (BFINVS | BFCHG)) == BFCHG /* regular and changed */
&& (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" */
@ -580,14 +546,15 @@ int bclear(struct buffer *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
*/ */
int unmark(int f, int n) BINDABLE( unmark) {
{
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,22 +1,25 @@
/* 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 */
@ -53,22 +56,27 @@ 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 */
int usebuffer( int f, int n) ; /* Bindable functions */
int nextbuffer( int f, int n) ; BINDABLE( killbuffer) ;
int swbuffer( buffer_p bp) ; BINDABLE( listbuffers) ;
int killbuffer( int f, int n) ; BINDABLE( namebuffer) ;
int zotbuf( buffer_p bp) ; BINDABLE( nextbuffer) ;
int namebuffer( int f, int n) ; BINDABLE( unmark) ;
int listbuffers( int f, int n) ; BINDABLE( usebuffer) ;
int anycb( void) ;
int bclear( buffer_p bp) ; boolean anycb( void) ; /* Any changed buffer? */
int unmark( int f, int n) ; int bclear( buffer_p bp) ; /* empty buffer */
/* Lookup a buffer by name. */ int swbuffer( buffer_p bp) ; /* switch to buffer, make it current */
buffer_p bfind( const char *bname, int cflag, int bflag) ; int zotbuf( buffer_p bp) ; /* remove buffer */
/* 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,17 +1,14 @@
/* 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 */
/* display.c /* The functions in this file handle redisplay. There are two halves, the
* ones that update the virtual display screen, and the ones that make the
* The functions in this file handle redisplay. There are two halves, the physical display screen the same as the virtual display screen. These
* ones that update the virtual display screen, and the ones that make the functions use hints that are left in the windows by the commands.
* physical display screen the same as the virtual display screen. These
* functions use hints that are left in the windows by the commands. Modified by Petri Kutvonen
*
* Modified by Petri Kutvonen
*/ */
#include <errno.h> #include <errno.h>
@ -251,13 +248,11 @@ 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
*/ */
int upscreen(int f, int n) BINDABLE( upscreen) {
{
update( TRUE) ; update( TRUE) ;
return TRUE ; return TRUE ;
} }
@ -266,25 +261,24 @@ int upscreen(int f, int n)
static int scrflags; static int scrflags;
#endif #endif
/*
* Make sure that the display is right. This is a three part process. First, /* Make sure that the display is right. This is a three part process.
* scan through all of the windows looking for dirty ones. Check the framing, First, scan through all of the windows looking for dirty ones. Check
* and refresh the screen. Second, make sure that "currow" and "curcol" are the framing, and refresh the screen. Second, make sure that "currow"
* correct for the current window. Third, make the virtual and physical and "curcol" are correct for the current window. Third, make the
* screens the same. virtual and physical screens the same.
*
* int force; force update past type ahead? boolean force_f ; force update past type ahead?
*/ */
int update(int force) int update( boolean force_f) {
{
struct window *wp; struct window *wp;
#if TYPEAH && ! PKCODE #if TYPEAH && ! PKCODE
if (force == FALSE && typahead()) if( force_f == FALSE && typahead())
return TRUE; return TRUE;
#endif #endif
#if VISMAC == 0 #if VISMAC == 0
if (force == FALSE && kbdmode == PLAY) if( force_f == FALSE && kbdmode == PLAY)
return TRUE; return TRUE;
#endif #endif
@ -359,7 +353,7 @@ int update(int force)
updgar(); updgar();
/* update the virtual screen to the physical screen */ /* update the virtual screen to the physical screen */
updupd(force); updupd( force_f) ;
/* 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,10 +1,12 @@
/* 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 "utf8.h" # include "names.h" /* BINDABLE() */
# 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 */
@ -13,11 +15,13 @@ 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 upscreen( int f, int n) ; int update( boolean force_f) ;
int update( int force) ;
void updpos( void) ; void updpos( void) ;
void upddex( void) ; void upddex( void) ;
void updgar( void) ; void updgar( void) ;
@ -41,5 +45,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,9 +1,7 @@
/* eval.c -- implements eval.h */ /* eval.c -- implements eval.h */
#include "eval.h" #include "eval.h"
/* eval.c /* Expression evaluation functions
*
* Expression evaluation functions
* *
* written 1986 by Daniel Lawrence * written 1986 by Daniel Lawrence
* modified by Petri Kutvonen * modified by Petri Kutvonen
@ -210,7 +208,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 }, /* loopup what function name is bound to a key */ { "bin", UFBIND | MONAMIC }, /* look up function name bound to 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 */
@ -797,14 +795,13 @@ 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)
*/ */
int setvar(int f, int n) BINDABLE( setvar) {
{
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 */
@ -1466,28 +1463,25 @@ 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, /* This function simply clears the message line, mainly for macro usage
* mainly for macro usage
* *
* int f, n; arguments ignored * int f, n; arguments ignored
*/ */
int clrmes( int f, int n) { TBINDABLE( clrmes) {
mlforce( "") ; mlforce( "") ;
return TRUE ; return TRUE ;
} }
/*
* This function writes a string on the message line /* This function writes a string on the message line mainly for macro usage
* mainly for macro usage
* *
* int f, n; arguments ignored * int f, n; arguments ignored
*/ */
int writemsg( int f, int n) { BINDABLE( writemsg) {
int status ;
char *buf ; /* buffer to receive message into */ char *buf ; /* buffer to receive message into */
status = newmlarg( &buf, "Message to write: ", 0) ; int status = newmlarg( &buf, "write-message: ", 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,6 +1,8 @@
/* 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 */
@ -8,7 +10,6 @@
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 */
@ -18,12 +19,15 @@ 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) ;
int clrmes( int f, int n) ; /* Bindable functions */
int writemsg( int f, int n) ; TBINDABLE( clrmes) ;
BINDABLE( setvar) ;
BINDABLE( writemsg) ;
#endif #endif
/* end of eval.h */

481
exec.c
View File

@ -1,38 +1,31 @@
/* exec.c -- implements exec.h */ /* exec.c -- implements exec.h */
#include "exec.h" #include "exec.h"
/* exec.c /* This file is for bindable functions dealing with execution of commands,
* command lines, buffers, files and startup files.
* This file is for functions dealing with execution of
* commands, command lines, buffers, files and startup files. written 1986 by Daniel Lawrence
* 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
@ -46,59 +39,52 @@ 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.
*/ */
struct while_block { typedef struct while_block {
struct line *w_begin; /* ptr to !while statement */ line_p w_begin ; /* ptr to !while statement */
struct line *w_end; /* ptr to the !endwhile statement */ line_p w_end ; /* ptr to the !endwhile statement */
int w_type ; /* block type */ int w_type ; /* block type */
struct while_block *w_next ; /* next while */ struct while_block *w_next ; /* next while */
}; } *while_p ;
#define BTWHILE 1 #define BTWHILE 1
#define BTBREAK 2 #define BTBREAK 2
/* directive name table: /* directive name table: holds the names of all the directives.... */
This holds the names of all the directives.... */
static const char *dname[] = { static const char *dname[] = {
"if", "else", "endif", "if", "else", "endif", "goto", "return",
"goto", "return", "endm", "endm", "while", "endwhile", "break", "force"
"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 struct buffer *bstore = NULL ; /* buffer to store macro text to */ static buffer_p 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( struct buffer *bp) ; static int dobuf( buffer_p 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. */
* Execute a named command even if it is not bound. BINDABLE( namedcmd) {
*/
int namedcmd( int f, int n) {
/* prompt the user to type a named command */ /* prompt the user to type a named command */
mlwrite("execute-named-cmd: "); mloutstr( "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 FALSE ; return ABORT ;
fnp_t kfunc = nbp->n_func ; fnp_t kfunc = nbp->n_func ;
if (kfunc == NULL) { if( kfunc == NULL)
mlwrite("(No such function)"); 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))
return rdonly() ; return rdonly() ;
@ -109,19 +95,17 @@ int namedcmd( int f, int n) {
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
*/ */
int execcmd( int f, int n) { BINDABLE( execcmd) {
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 */
status = newmlarg( &cmdstr, "execute-command-line: ", 0) ; int status = newmlarg( &cmdstr, "execute-command-line: ", 0) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
@ -133,8 +117,7 @@ int execcmd( int f, int n) {
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
@ -147,9 +130,6 @@ int execcmd( int f, int n) {
* 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 */
@ -162,12 +142,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 */
f = FALSE; int f = FALSE ;
n = 1; int n = 1 ;
lastflag = thisflag ; lastflag = thisflag ;
thisflag = 0 ; thisflag = 0 ;
status = macarg( tkn, sizeof tkn) ; int 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;
@ -193,9 +173,8 @@ 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 FALSE; return mloutfail( "(No such Function)") ;
} }
if( (bind_tag( nbp) & 1) && (curbp->b_mode & MDVIEW)) if( (bind_tag( nbp) & 1) && (curbp->b_mode & MDVIEW))
@ -222,20 +201,16 @@ 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) {
boolean quotef ; /* is the current string quoted? */ char *tok = malloc( NSTRING) ;
char *tok ; /* allocated string */ int size = (tok == NULL) ? 0 : NSTRING ;
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 */
quotef = FALSE; boolean quotef = FALSE ; /* is the current string quoted? */
while( *src) { while( *src) {
char c ; /* temporary character */ char c ; /* temporary character */
@ -395,32 +370,23 @@ static int macarg( char *tok, int toksz) {
static char macbufname[] = "*Macro xx*" ; static char macbufname[] = "*Macro xx*" ;
#define MACDIGITPOS 7 #define MACDIGITPOS 7
int storemac(int f, int n) BINDABLE( storemac) {
{
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)
mlwrite("No macro specified"); return mloutfail( "No macro number specified");
return FALSE;
}
/* range check the macro number */ /* range check the macro number */
if (n < 1 || n > 40) { if( n < 1 || n > 40)
mlwrite("Macro number out of range"); return mloutfail( "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 */
bp = bfind( macbufname, TRUE, BFINVS) ; buffer_p bp = bfind( macbufname, TRUE, BFINVS) ;
if( bp == NULL) { if( bp == NULL)
mlwrite("Can not create macro"); return mloutfail( "Can not create macro") ;
return FALSE;
}
/* and make sure it is empty */ /* and make sure it is empty */
bclear( bp) ; bclear( bp) ;
@ -436,12 +402,10 @@ int storemac(int f, int n)
** 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 */
bp = bfind( bufname, FALSE, 0) ; buffer_p bp = bfind( bufname, FALSE, 0) ;
if( bp == NULL) { if( bp == NULL) {
mlwrite( "No such %s", errstr) ; mloutfmt( "No such %s", errstr) ;
return FALSE ; return FALSE ;
} }
@ -453,7 +417,6 @@ 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
@ -462,9 +425,7 @@ 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
*/ */
int storeproc( int f, int n) { BINDABLE( storeproc) {
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 ;
@ -473,7 +434,7 @@ int storeproc( int f, int n) {
return storemac( f, n) ; return storemac( f, n) ;
/* get the name of the procedure */ /* get the name of the procedure */
status = newmlarg( &name, "Procedure name: ", sizeof bname - 2) ; int status = newmlarg( &name, "Procedure name: ", sizeof bname - 2) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
@ -484,11 +445,9 @@ int storeproc( int f, int n) {
free( name) ; free( name) ;
/* set up the new macro buffer */ /* set up the new macro buffer */
bp = bfind( bname, TRUE, BFINVS) ; buffer_p bp = bfind( bname, TRUE, BFINVS) ;
if( bp == NULL) { if( bp == NULL)
mlwrite( "Can not create macro") ; return mloutfail( "Can not create macro") ;
return FALSE ;
}
/* and make sure it is empty */ /* and make sure it is empty */
bclear( bp) ; bclear( bp) ;
@ -505,13 +464,12 @@ int storeproc( int f, int n) {
* *
* int f, n; default flag and numeric arg * int f, n; default flag and numeric arg
*/ */
int execproc( int f, int n) { BINDABLE( execproc) {
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 */
status = newmlarg( &name, "execute-procedure: ", sizeof bufn - 2) ; int status = newmlarg( &name, "execute-procedure: ", sizeof bufn - 2) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
@ -523,20 +481,18 @@ int execproc( int f, int n) {
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
*/ */
int execbuf( int f, int n) { BINDABLE( execbuf) {
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 */
status = newmlarg( &bufn, "Execute buffer: ", sizeof( bname_t)) ; int status = newmlarg( &bufn, "Execute buffer: ", sizeof( bname_t)) ;
if( status != TRUE) if( status != TRUE)
return status ; return status ;
@ -545,8 +501,21 @@ int execbuf( int f, int n) {
return status ; return status ;
} }
/*
* dobuf: /* free a list of while block pointers
*
* while_p wp; head of structure to free
*/
static void freewhile( while_p wp) {
while( wp != NULL) {
while_p next = wp->w_next ;
free( wp) ;
wp = next ;
}
}
/* 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
* *
@ -566,36 +535,23 @@ int execbuf( int f, int n) {
* *
* *LBL01 * *LBL01
* *
* struct buffer *bp; buffer to execute * buffer_p bp; buffer to execute
*/ */
static int dobuf(struct buffer *bp) static int dobuf( buffer_p 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 */
int force; /* force TRUE result? */ while_p whtemp ; /* temporary ptr to a struct while_block */
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 expresion in */ char tkn[ NSTRING] ; /* buffer to evaluate an expression in */
/* clear IF level flags/while ptr */ /* clear IF level flags/while ptr */
execlevel = 0 ; execlevel = 0 ;
whlist = NULL; while_p whlist = NULL ; /* ptr to !WHILE list */
scanner = NULL; while_p scanner = NULL ; /* ptr during scan */
/* scan the buffer to execute, building WHILE header blocks */ /* scan the buffer to execute, building WHILE header blocks */
hlp = bp->b_linep; line_p hlp = bp->b_linep ; /* pointer to line header */
lp = hlp->l_fp; for( line_p lp = hlp->l_fp ; lp != hlp ; lp = lp->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 ;
@ -606,19 +562,22 @@ static int dobuf(struct buffer *bp)
/* if theres nothing here, don't bother */ /* if theres nothing here, don't bother */
if( i <= 0) if( i <= 0)
goto nxtscan; continue ;
/* if is a while directive, make a block... */ /* if it is a while directive, make a block... */
if (eline[0] == '!' && eline[1] == 'w' && eline[2] == 'h') { if( eline[0] == '!'
whtemp = (struct while_block *)malloc(sizeof(struct while_block)); && eline[1] == 'w'
&& eline[2] == 'h') {
whtemp = malloc( sizeof *whtemp) ;
if( whtemp == NULL) { if( whtemp == NULL) {
noram:mlwrite noram:
("%%Out of memory during while scan"); mloutstr( "%%Out of memory during while scan") ;
failexit:freewhile failexit:
(scanner); freewhile( 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 ;
@ -626,15 +585,18 @@ static int dobuf(struct buffer *bp)
} }
/* if is a BREAK directive, make a block... */ /* if is a BREAK directive, make a block... */
if (eline[0] == '!' && eline[1] == 'b' && eline[2] == 'r') { if( eline[0] == '!'
&& eline[1] == 'b'
&& eline[2] == 'r') {
if (scanner == NULL) { if (scanner == NULL) {
mlwrite mloutstr( "%%!BREAK outside of any !WHILE loop") ;
("%%!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;
@ -642,13 +604,14 @@ static int dobuf(struct buffer *bp)
} }
/* if it is an endwhile directive, record the spot... */ /* if it is an endwhile directive, record the spot... */
if (eline[0] == '!' && strncmp(&eline[1], "endw", 4) == 0) { if( eline[0] == '!'
&& strncmp( &eline[1], "endw", 4) == 0) {
if (scanner == NULL) { if (scanner == NULL) {
mlwrite mloutfmt( "%%!ENDWHILE with no preceding !WHILE in '%s'",
("%%!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 */
@ -660,15 +623,11 @@ static int dobuf(struct buffer *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) {
mlwrite("%%!WHILE with no matching !ENDWHILE in '%s'", mloutfmt( "%%!WHILE with no matching !ENDWHILE in '%s'", bp->b_bname) ;
bp->b_bname);
goto failexit ; goto failexit ;
} }
@ -677,14 +636,19 @@ static int dobuf(struct buffer *bp)
/* starting at the beginning of the buffer */ /* starting at the beginning of the buffer */
hlp = bp->b_linep ; hlp = bp->b_linep ;
lp = hlp->l_fp; char *einit = NULL ; /* initial value of eline */
while (lp != hlp) { int status = TRUE ; /* status of command execution */
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 ;
if ((einit = eline = malloc(linlen + 1)) == NULL) { einit = eline = malloc( linlen + 1) ;
mlwrite("%%Out of Memory during macro execution"); if( eline == NULL) {
freewhile(whlist); status = mloutfail( "%%Out of Memory during macro execution") ;
return FALSE; break ;
} }
mystrscpy( eline, lp->l_text, linlen + 1) ; mystrscpy( eline, lp->l_text, linlen + 1) ;
@ -695,7 +659,7 @@ static int dobuf(struct buffer *bp)
/* dump comments and blank lines */ /* dump comments and blank lines */
if( *eline == ';' || *eline == '#' || *eline == 0) if( *eline == ';' || *eline == '#' || *eline == 0)
goto onward; continue ;
#if DEBUGM #if DEBUGM
/* if $debug == TRUE, every line to execute /* if $debug == TRUE, every line to execute
@ -708,9 +672,8 @@ static int dobuf(struct buffer *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) {
freewhile( whlist) ; status = FALSE ;
free( einit) ; break ;
return FALSE ;
} else if( c == metac) { } else if( c == metac) {
macbug = FALSE ; macbug = FALSE ;
} }
@ -718,28 +681,25 @@ static int dobuf(struct buffer *bp)
#endif #endif
/* Parse directives here.... */ /* Parse directives here.... */
dirnum = -1; unsigned dirnum = NUMDIRS ; /* directive index */
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], if( !strncmp( eline, dname[ dirnum], strlen( 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) {
mlwrite("%%Unknown Directive"); status = mloutfail( "%%Unknown Directive") ;
freewhile(whlist); break ;
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 ;
goto onward; continue ;
} }
/* restore the original eline.... */ /* restore the original eline.... */
@ -750,10 +710,10 @@ static int dobuf(struct buffer *bp)
if( mstore) { if( mstore) {
/* allocate the space for the line */ /* allocate the space for the line */
linlen = strlen( eline) ; linlen = strlen( eline) ;
if ((mp = lalloc(linlen)) == NULL) { line_p mp = lalloc( linlen) ;
free( einit) ; if( mp == NULL) {
mlwrite( "Out of memory while storing macro") ; status = mloutfail( "Out of memory while storing macro") ;
return FALSE ; break ;
} }
/* copy the text into the new line */ /* copy the text into the new line */
@ -765,136 +725,129 @@ static int dobuf(struct buffer *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 ;
goto onward; continue ;
} }
int force = FALSE ; /* force TRUE result? */
force = FALSE;
/* dump comments */ /* dump comments */
if( *eline == '*') if( *eline == '*')
goto onward; continue ;
/* now, execute directives */ /* now, execute directives */
if (dirnum != -1) { if( dirnum != NUMDIRS) {
/* 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)
goto eexec; done = TRUE ;
if (stol(tkn) == FALSE) else 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) {
goto eexec; done = TRUE ;
if (stol(tkn) == TRUE) continue ;
goto onward; } else if( stol( tkn) == TRUE)
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)
goto onward; continue ;
/* jump down to the endwhile */ /* jump down to the endwhile */
/* find the right while loop */ /* find the right while loop */
whtemp = whlist; for( whtemp = whlist ; whtemp ; whtemp = whtemp->w_next)
while (whtemp) {
if( whtemp->w_begin == lp) if( whtemp->w_begin == lp)
break ; break ;
whtemp = whtemp->w_next;
}
if( whtemp == NULL) { if( whtemp == NULL) {
mlwrite status = mloutfail( "%%Internal While loop error") ;
("%%Internal While loop error"); done = TRUE ;
freewhile(whlist); } else
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) ;
glp = hlp->l_fp; for( glp = hlp->l_fp ; glp != hlp ; glp = glp->l_fp) {
while (glp != hlp) { if( *glp->l_text == '*'
if (*glp->l_text == '*' && && !strncmp( &glp->l_text[ 1], golabel, linlen)) {
(strncmp break ;
(&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)
goto eexec; done = TRUE ;
goto onward;
continue ;
case DENDWHILE: /* ENDWHILE directive */ case DENDWHILE: /* ENDWHILE directive */
if( execlevel) { if( execlevel) {
--execlevel ; --execlevel ;
goto onward; continue ;
} else { } else {
/* find the right while loop */ /* find the right while loop */
whtemp = whlist; for( whtemp = whlist ; whtemp ; whtemp = whtemp->w_next)
while (whtemp) { if( whtemp->w_type == BTWHILE
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) {
mlwrite status = mloutfail( "%%Internal While loop error") ;
("%%Internal While loop error"); done = TRUE ;
freewhile(whlist); } else
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 */
@ -911,66 +864,44 @@ static int dobuf(struct buffer *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 */
wp = wheadp; for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) {
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 ;
free(einit); break ;
}
}
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;
}
eexec: /* exit the current function */ /* execute a series of commands in a file
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
*/ */
int execfile( int f, int n) { BINDABLE( execfile) {
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 */
status = newmlarg( &fname, "Execute file: ", 0) ; int 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 */
fspec = flook( fname, FALSE) ; /* used to be TRUE, P.K. */ char *fspec = flook( fname, FALSE) ; /* used to be TRUE, P.K. */
free( fname) ; free( fname) ;
/* if it isn't around */ /* if it isn't around */
@ -984,46 +915,54 @@ int execfile( int f, int n) {
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 */
if ((bp = bfind(bname, TRUE, 0)) == NULL) /* get the needed buffer */ buffer_p bp = bfind( bname, TRUE, 0) ; /* 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 */
cb = curbp; /* save the old buffer */ buffer_p 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 */
if ((status = readin(fname, FALSE)) != TRUE) { int status = readin( fname, FALSE) ;
curbp = cb ; /* restore the current buffer */ curbp = cb ; /* restore the current buffer */
return status; if( status == TRUE) {
/* 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! */
curbp = cb; /* restore the current buffer */ status = dobuf( bp) ;
if ((status = dobuf(bp)) != TRUE) if( status != 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
@ -1039,7 +978,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) \
int cbuf##nn( int f, int n) { \ BINDABLE( cbuf##nn) { \
return cbuf( f, n, nn) ; \ return cbuf( f, n, nn) ; \
} }

110
exec.h
View File

@ -1,69 +1,65 @@
/* exec.h -- bindable functions to execute functions, macros and procedures */
#ifndef _EXEC_H_ #ifndef _EXEC_H_
# define _EXEC_H_ # define _EXEC_H_
#include "retcode.h" #include "names.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) ;
int cbuf1( int f, int n) ; /* Bindable functions */
int cbuf2( int f, int n) ; BINDABLE( execbuf) ;
int cbuf3( int f, int n) ; BINDABLE( execcmd) ;
int cbuf4( int f, int n) ; BINDABLE( execfile) ;
int cbuf5( int f, int n) ; BINDABLE( execproc) ;
int cbuf6( int f, int n) ; BINDABLE( namedcmd) ;
int cbuf7( int f, int n) ; BINDABLE( storemac) ;
int cbuf8( int f, int n) ; BINDABLE( storeproc) ;
int cbuf9( int f, int n) ; BINDABLE( cbuf1) ;
int cbuf10( int f, int n) ; BINDABLE( cbuf2) ;
int cbuf11( int f, int n) ; BINDABLE( cbuf3) ;
int cbuf12( int f, int n) ; BINDABLE( cbuf4) ;
int cbuf13( int f, int n) ; BINDABLE( cbuf5) ;
int cbuf14( int f, int n) ; BINDABLE( cbuf6) ;
int cbuf15( int f, int n) ; BINDABLE( cbuf7) ;
int cbuf16( int f, int n) ; BINDABLE( cbuf8) ;
int cbuf17( int f, int n) ; BINDABLE( cbuf9) ;
int cbuf18( int f, int n) ; BINDABLE( cbuf10) ;
int cbuf19( int f, int n) ; BINDABLE( cbuf11) ;
int cbuf20( int f, int n) ; BINDABLE( cbuf12) ;
int cbuf21( int f, int n) ; BINDABLE( cbuf13) ;
int cbuf22( int f, int n) ; BINDABLE( cbuf14) ;
int cbuf23( int f, int n) ; BINDABLE( cbuf15) ;
int cbuf24( int f, int n) ; BINDABLE( cbuf16) ;
int cbuf25( int f, int n) ; BINDABLE( cbuf17) ;
int cbuf26( int f, int n) ; BINDABLE( cbuf18) ;
int cbuf27( int f, int n) ; BINDABLE( cbuf19) ;
int cbuf28( int f, int n) ; BINDABLE( cbuf20) ;
int cbuf29( int f, int n) ; BINDABLE( cbuf21) ;
int cbuf30( int f, int n) ; BINDABLE( cbuf22) ;
int cbuf31( int f, int n) ; BINDABLE( cbuf23) ;
int cbuf32( int f, int n) ; BINDABLE( cbuf24) ;
int cbuf33( int f, int n) ; BINDABLE( cbuf25) ;
int cbuf34( int f, int n) ; BINDABLE( cbuf26) ;
int cbuf35( int f, int n) ; BINDABLE( cbuf27) ;
int cbuf36( int f, int n) ; BINDABLE( cbuf28) ;
int cbuf37( int f, int n) ; BINDABLE( cbuf29) ;
int cbuf38( int f, int n) ; BINDABLE( cbuf30) ;
int cbuf39( int f, int n) ; BINDABLE( cbuf31) ;
int cbuf40( int f, int n) ; BINDABLE( cbuf32) ;
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,13 +1,11 @@
/* file.c -- implements file.h */ /* file.c -- implements file.h */
#include "file.h" #include "file.h"
/* file.c /* The routines in this file handle the reading, writing and lookup of disk
* files. All of details about the reading and writing of the disk are in
* The routines in this file handle the reading, writing "fileio.c".
* and lookup of disk files. All of details about the
* reading and writing of the disk are in "fileio.c". modified by Petri Kutvonen
*
* modified by Petri Kutvonen
*/ */
#include <assert.h> #include <assert.h>
@ -233,8 +231,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.
@ -287,7 +285,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 /* MAXNLINE Maximum # of lines from one file */ if( nline >= 10000000 /* 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. */
@ -327,12 +325,11 @@ 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
errmsg = "I/O ERROR, " ; || s == FIOMEM) {
curbp->b_flag |= BFTRUNC ; errmsg = (s == FIOERR) ? "I/O ERROR, " : "OUT OF MEMORY, " ;
} 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 = "" ;
@ -464,10 +461,8 @@ 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)
mloutfmt( "%B(Aborted)") ; return mloutfail( "(Aborted)") ;
return FALSE ;
}
return writeout( curbp->b_fname) ; return writeout( curbp->b_fname) ;
} }

46
input.c
View File

@ -15,9 +15,10 @@
#include "bind.h" #include "bind.h"
#include "estruct.h" #include "estruct.h"
#include "bindable.h" #include "bindable.h"
#include "display.h" #include "display.h" /* rubout(), echos(), echoc(), update() */
#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"
@ -38,12 +39,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 = CTRL | '[' ; /* current meta character */ int metac = CTL_ | '[' ; /* current meta character */
int ctlxc = CTRL | 'X' ; /* current control X prefix char */ int ctlxc = CTL_ | 'X' ; /* current control X prefix char */
int reptc = CTRL | 'U' ; /* current universal repeat char */ int reptc = CTL_ | 'U' ; /* current universal repeat char */
int abortc = CTRL | 'G' ; /* current abort command char */ int abortc = CTL_ | 'G' ; /* current abort command char */
const int nlc = CTRL | 'J' ; /* end of input char */ const int nlc = CTL_ | 'J' ; /* end of input char */
void ue_system( const char *cmd) { void ue_system( const char *cmd) {
@ -66,7 +67,7 @@ int mlyesno( const char *prompt)
for (;;) { for (;;) {
/* prompt the user */ /* prompt the user */
mlwrite( "%s (y/n)? ", prompt) ; mloutfmt( "%s (y/n)? ", prompt) ;
/* get the response */ /* get the response */
c = get1key() ; c = get1key() ;
@ -142,11 +143,11 @@ int newmlargt( char **outbufref, const char *prompt, int size) {
/* /*
* ectoc: * ectoc:
* expanded character to character * expanded character to character
* collapse the CTRL and SPEC flags back into an ascii code * collapse the CTL_ and SPEC flags back into an ascii code
*/ */
int ectoc( int c) { int ectoc( int c) {
if( c & CTRL) if( c & CTL_)
c ^= CTRL | 0x40 ; c ^= CTL_ | 0x40 ;
if( c & SPEC) if( c & SPEC)
c &= 255 ; c &= 255 ;
@ -190,7 +191,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, 0); ctrlg( FALSE, 1) ;
TTflush() ; TTflush() ;
return NULL ; return NULL ;
@ -322,7 +323,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 CTRL prefixes. */ and CTL_ prefixes. */
static int get1unicode( int *up) { static int get1unicode( int *up) {
/* Accept UTF-8 sequence */ /* Accept UTF-8 sequence */
int bytes ; int bytes ;
@ -343,7 +344,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 ^= CTRL | 0x40 ; c ^= CTL_ | 0x40 ;
*up = c ; *up = c ;
bytes = 1 ; bytes = 1 ;
@ -383,7 +384,7 @@ int getcmd( void) {
c = *(kptr++) = get1key() ; c = *(kptr++) = get1key() ;
if( c == 0x9B) if( c == 0x9B)
goto foundCSI ; goto foundCSI ;
else if( c == (CTRL | '[')) { else if( c == (CTL_ | '[')) {
/* fetch terminal sequence */ /* fetch terminal sequence */
c = *(kptr++) = get1key() ; c = *(kptr++) = get1key() ;
if( c == 'O') { /* F1 .. F4 */ if( c == 'O') { /* F1 .. F4 */
@ -407,7 +408,7 @@ int getcmd( void) {
mask = META ; mask = META ;
if( (v - 1) & 4) if( (v - 1) & 4)
mask |= CTRL ; mask |= CTL_ ;
v = v1 ; v = v1 ;
} }
@ -513,7 +514,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 */
mlwrite( "%s", prompt); mloutstr( prompt);
for (;;) { for (;;) {
#if COMPLC #if COMPLC
@ -538,23 +539,22 @@ 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 == (CTRL | 'M')) if( c == (CTL_ | 'M'))
c = CTRL | 0x40 | '\n' ; c = CTL_ | 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 */
mlwrite(""); mloutstr( "") ;
/* 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? */
ctrlg( FALSE, 0) ; retval = ctrlg( FALSE, 1) ;
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 */
mlwrite( "%s", prompt) ; mloutstr( 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;
mlwrite( "%s", prompt) ; mloutstr( prompt) ;
while( cpos != 0) { while( cpos != 0) {
c = buf[ --cpos] ; c = buf[ --cpos] ;
if( c == '*' || c == '?') { if( c == '*' || c == '?') {

View File

@ -1,8 +1,7 @@
/* isearch.c -- implements isearch.h */
#include "isearch.h" #include "isearch.h"
/* isearch.c /* The functions in this file implement commands that perform incremental
*
* 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
@ -24,7 +23,6 @@
* Modified by Petri Kutvonen * Modified by Petri Kutvonen
*/ */
#include <stdio.h>
#include <string.h> #include <string.h>
#include "basic.h" #include "basic.h"
@ -42,8 +40,6 @@
/* /*
* 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 */
@ -60,10 +56,7 @@
/* IS_QUIT is no longer used, the variable metac is used instead */ /* IS_QUIT is no longer used, the variable metac is used instead */
#endif static BINDABLE( isearch) ; /* internal use, not to be bound */
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) ;
@ -73,8 +66,6 @@ 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 */
@ -89,12 +80,10 @@ 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.
*/ */
int risearch(int f, int n) BINDABLE( risearch) {
{
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 */
@ -124,11 +113,10 @@ int risearch(int f, int n)
return TRUE; return TRUE;
} }
/*
* Again, but for the forward direction /* Again, but for the forward direction
*/ */
int fisearch(int f, int n) BINDABLE( fisearch) {
{
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 */
@ -156,8 +144,8 @@ int fisearch(int f, int n)
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.
@ -182,8 +170,7 @@ int fisearch(int f, int n)
* exists (or until the search is aborted). * exists (or until the search is aborted).
*/ */
static int isearch(int f, int n) static BINDABLE( isearch) {
{
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 */
@ -541,8 +528,6 @@ 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__
#define ISRCH 1 /* Incremental searches like ITS EMACS */ # include "names.h" /* BINDABLE */
#if ISRCH BINDABLE( risearch) ;
int risearch( int f, int n) ; BINDABLE( fisearch) ;
int fisearch( int f, int n) ;
#endif
#endif #endif
/* end of isearch */

6
line.c
View File

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

View File

@ -12,4 +12,9 @@ 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,9 +3,12 @@
#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, CTRL | 'G'} , {" abort-command", ctrlg, CTL_ | '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, CTRL | 'B'} , {" backward-character", (fnp_t) backchar, CTL_ | 'B'} ,
{" begin-macro", ctlxlp, CTLX | '('} , {" begin-macro", (fnp_t) ctlxlp, CTLX | '('} ,
{" beginning-of-file", (fnp_t) gotobob, META | '<'} , {" beginning-of-file", (fnp_t) gotobob, META | '<'} ,
{" beginning-of-line", (fnp_t) gotobol, CTRL | 'A'} , {" beginning-of-line", (fnp_t) gotobol, CTL_ | '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 | CTRL | 'L'} , {"!case-region-lower", lowerregion, CTLX | CTL_ | 'L'} ,
{"!case-region-upper", upperregion, CTLX | CTRL | 'U'} , {"!case-region-upper", upperregion, CTLX | CTL_ | '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 | CTRL | 'D'} , /* M^S */ {" change-screen-size", newsize, META | CTL_ | 'D'} , /* M^S */
{" change-screen-width", newwidth, META | CTRL | 'T'} , {" change-screen-width", newwidth, META | CTL_ | 'T'} ,
{" clear-and-redraw", redraw, CTRL | 'L'} , {" clear-and-redraw", (fnp_t) redraw, CTL_ | 'L'} ,
{" clear-message-line", clrmes, 0} , {" clear-message-line", (fnp_t) clrmes, 0} ,
{" copy-region", copyregion, META | 'W'} , {" copy-region", copyregion, META | 'W'} ,
{" count-words", wordcount, META | CTRL | 'C'} , {" count-words", wordcount, META | CTL_ | 'C'} ,
{" ctlx-prefix", cex, CTRL | 'X'} , {" ctlx-prefix", (fnp_t) cex, CTL_ | 'X'} ,
{"!delete-blank-lines", deblank, CTLX | CTRL | 'O'} , {"!delete-blank-lines", deblank, CTLX | CTL_ | 'O'} ,
{" delete-buffer", killbuffer, CTLX | 'K'} , {" delete-buffer", killbuffer, CTLX | 'K'} ,
{" delete-global-mode", delgmode, META | CTRL | 'M'} , {" delete-global-mode", delgmode, META | CTL_ | 'M'} ,
{" delete-mode", delmode, CTLX | CTRL | 'M'} , {" delete-mode", delmode, CTLX | CTL_ | 'M'} ,
{"!delete-next-character", forwdel, CTRL | 'D'} , {"!delete-next-character", forwdel, CTL_ | '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, CTRL | 'H'} , /* ^? */ {"!delete-previous-character", backdel, CTL_ | 'H'} , /* ^? */
{"!delete-previous-word", delbword, META | CTRL | 'H'} , /* M^? */ {"!delete-previous-word", delbword, META | CTL_ | '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 | CTRL | 'D'} , /* X^A */ {"!detab-line", detab, CTLX | CTL_ | 'D'} , /* X^A */
{" end-macro", ctlxrp, CTLX | ')'} , {" end-macro", (fnp_t) ctlxrp, CTLX | ')'} ,
{" end-of-file", (fnp_t) gotoeob, META | '>'} , {" end-of-file", (fnp_t) gotoeob, META | '>'} ,
{" end-of-line", (fnp_t) gotoeol, CTRL | 'E'} , {" end-of-line", (fnp_t) gotoeol, CTL_ | 'E'} ,
{"!entab-line", entab, CTLX | CTRL | 'E'} , {"!entab-line", entab, CTLX | CTL_ | 'E'} ,
{" exchange-point-and-mark", (fnp_t) swapmark, CTLX | CTRL | 'X'} , {" exchange-point-and-mark", (fnp_t) swapmark, CTLX | CTL_ | '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", ctlxe, CTLX | 'E'} , {" execute-macro", (fnp_t) 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,116 +119,106 @@ 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'} ,
#if PROC {" execute-procedure", execproc, META | CTL_ | 'E'} ,
{" execute-procedure", execproc, META | CTRL | 'E'} ,
#endif
{" execute-program", execprg, CTLX | '$'} , {" execute-program", execprg, CTLX | '$'} ,
{" exit-emacs", quit, CTLX | CTRL | 'C'} , {" exit-emacs", quit, CTLX | CTL_ | '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 | CTRL | 'F'} , {" find-file", filefind, CTLX | CTL_ | 'F'} ,
{" forward-character", (fnp_t) forwchar, CTRL | 'F'} , {" forward-character", (fnp_t) forwchar, CTL_ | 'F'} ,
{" goto-line", gotoline, META | 'G'} , {" goto-line", gotoline, META | 'G'} ,
#if CFENCE #if CFENCE
{" goto-matching-fence", getfence, META | CTRL | 'F'} , {" goto-matching-fence", getfence, META | CTL_ | 'F'} ,
#endif #endif
{" grow-window", enlargewind, CTLX | 'Z'} , /* X^ */ {" grow-window", enlargewind, CTLX | 'Z'} , /* X^ */
{"!handle-tab", insert_tab, CTRL | 'I'} , {"!handle-tab", insert_tab, CTL_ | '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'} ,
#endif {"!insert-file", insfile, CTLX | CTL_ | 'I'} ,
{"!insert-file", insfile, CTLX | CTRL | 'I'} , {"!insert-space", insspace, CTL_ | 'C'} ,
{"!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 | CTRL | 'W'} , {"!kill-paragraph", killpara, META | CTL_ | 'W'} ,
{"!kill-region", killregion, CTRL | 'W'} , {"!kill-region", killregion, CTL_ | 'W'} ,
{"!kill-to-end-of-line", killtext, CTRL | 'K'} , {"!kill-to-end-of-line", killtext, CTL_ | 'K'} ,
{" list-buffers", listbuffers, CTLX | CTRL | 'B'} , {" list-buffers", listbuffers, CTLX | CTL_ | 'B'} ,
{" meta-prefix", metafn, CTRL | '['} , {" meta-prefix", (fnp_t) metafn, CTL_ | '['} ,
{" move-window-down", mvdnwind, CTLX | CTRL | 'N'} , {" move-window-down", mvdnwind, CTLX | CTL_ | 'N'} ,
{" move-window-up", mvupwind, CTLX | CTRL | 'P'} , {" move-window-up", mvupwind, CTLX | CTL_ | 'P'} ,
{" name-buffer", namebuffer, META | CTRL | 'N'} , {" name-buffer", namebuffer, META | CTL_ | 'N'} ,
{"!newline", insert_newline, CTRL | 'M'} , {"!newline", insert_newline, CTL_ | 'M'} ,
{"!newline-and-indent", indent, CTRL | 'J'} , {"!newline-and-indent", indent, CTL_ | 'J'} ,
{" next-buffer", nextbuffer, CTLX | 'X'} , {" next-buffer", nextbuffer, CTLX | 'X'} ,
{" next-line", (fnp_t) forwline, CTRL | 'N'} , {" next-line", (fnp_t) forwline, CTL_ | 'N'} ,
{" next-page", (fnp_t) forwpage, CTRL | 'V'} , {" next-page", (fnp_t) forwpage, CTL_ | '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", nullproc, SPEC | META | 'C'}, /* hook */ {" nop", (fnp_t) nullproc, META | SPEC | 'C'}, /* hook */
{"!open-line", openline, CTRL | 'O'} , {"!open-line", openline, CTL_ | 'O'} ,
{"!overwrite-string", ovstring, 0} , {"!overwrite-string", ovstring, 0} ,
{" pipe-command", pipecmd, CTLX | '@'} , {" pipe-command", pipecmd, CTLX | '@'} ,
{" previous-line", (fnp_t) backline, CTRL | 'P'} , {" previous-line", (fnp_t) backline, CTL_ | 'P'} ,
{" previous-page", (fnp_t) backpage, CTRL | 'Z'} , /* MV */ {" previous-page", (fnp_t) backpage, CTL_ | '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 | CTRL | 'R'} , {"!query-replace-string", qreplace, META | CTL_ | 'R'} ,
{" quick-exit", quickexit, META | 'Z'} , {" quick-exit", quickexit, META | 'Z'} ,
{"!quote-character", quote, CTRL | 'Q'} , /* also XQ */ {"!quote-character", quote, CTL_ | 'Q'} ,
{"!read-file", fileread, CTLX | CTRL | 'R'} , {"!read-file", fileread, CTLX | CTL_ | 'R'} ,
{" redraw-display", reposition, META | CTRL | 'L'} , /* M! */ {" redraw-display", (fnp_t) reposition, META | CTL_ | 'L'} ,
{"!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'} ,
#endif {" run", execproc, 0} , /* alias of execute-procedure */
#if PROC {"!save-file", filesave, CTLX | CTL_ | 'S'} , /* also X^D */
{" 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 | CTRL | 'V'} , {" scroll-next-down", scrnextdw, META | CTL_ | 'V'} ,
{" scroll-next-up", scrnextup, META | CTRL | 'Z'} , {" scroll-next-up", scrnextup, META | CTL_ | 'Z'} ,
{" search-forward", forwsearch, CTRL | 'S'} , {" search-forward", forwsearch, CTL_ | 'S'} ,
{" search-reverse", backsearch, CTRL | 'R'} , {" search-reverse", backsearch, CTL_ | '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 | CTRL | 'Z'} , {" shrink-window", shrinkwind, CTLX | CTL_ | '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, CTRL | 'T'} , {"!transpose-characters", (fnp_t) twiddle, CTL_ | 'T'} ,
{"!trim-line", trim, CTLX | CTRL | 'T'} , {"!trim-line", trim, CTLX | CTL_ | 'T'} ,
{" unbind-key", unbindkey, META | CTRL | 'K'} , {" unbind-key", unbindkey, META | CTL_ | 'K'} ,
{" universal-argument", unarg, CTRL | 'U'} , {" universal-argument", (fnp_t) unarg, CTL_ | 'U'} ,
{" unmark-buffer", unmark, META | '~'} , {" unmark-buffer", unmark, META | '~'} ,
{" update-screen", upscreen, 0} , {" update-screen", upscreen, 0} ,
{" view-file", viewfile, CTLX | CTRL | 'V'} , {" view-file", viewfile, CTLX | CTL_ | 'V'} ,
{"!wrap-word", wrapword, SPEC | META | 'W'} , /* hook */ {"!wrap-word", wrapword, META | SPEC | 'W'} , /* hook */
{" write-file", filewrite, CTLX | CTRL | 'W'} , {" write-file", filewrite, CTLX | CTL_ | 'W'} ,
{" write-message", writemsg, 0} , {" write-message", writemsg, 0} ,
{"!yank", yank, CTRL | 'Y'} , {"!yank", yank, CTL_ | 'Y'} ,
{" ", NULL, 0}, {" ", NULL, 0},
/* extra key mapping */ /* extra key mapping */
// { NULL, newsize, META | CTRL | 'S'}, // { NULL, newsize, META | CTL_ | 'S'},
{ NULL, backdel, CTRL | '?'}, { NULL, backdel, CTL_ | '?'},
{ NULL, delbword, META | CTRL | '?'}, { NULL, delbword, META | CTL_ | '?'},
{ NULL, detab, CTLX | CTRL | 'A'}, { NULL, detab, CTLX | CTL_ | '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, reposition, META | '!'}, { NULL, (fnp_t) reposition, META | '!'},
//detab { NULL, filesave, CTLX | CTRL | 'D'}, //detab { NULL, filesave, CTLX | CTL_ | 'D'},
{ NULL, (fnp_t) setmark, META | '.'}, { NULL, (fnp_t) setmark, META | '.'},
// { NULL, bktoshell, META | 'S'}, // { NULL, bktoshell, META | 'S'},
@ -246,14 +236,14 @@ const name_bind names[] = {
{ NULL, help, SPEC | 'P'}, /* F1 */ { NULL, help, SPEC | 'P'}, /* F1 */
/* hooks */ /* hooks */
{ NULL, nullproc, SPEC | META | 'R'}, /* hook */ { NULL, (fnp_t) nullproc, META | SPEC | 'R'}, /* hook */
{ NULL, nullproc, SPEC | META | 'X'}, /* hook */ { NULL, (fnp_t) nullproc, META | SPEC | '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 */
@ -282,6 +272,9 @@ 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) ;
@ -293,14 +286,20 @@ 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 */ /* Check entry: a keycode and no name */
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) {
setkeybinding( nbp->n_keycode, fnbp) ; kbind_p ktp = 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 ;
} }
@ -370,8 +369,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
*/ */
@ -416,23 +415,26 @@ nbind_p fncmatch( char *name) {
} }
/* user function that does NOTHING */ /* user function that does NOTHING (bound to hooks) */
BINDABLE( nullproc) { TBINDABLE( nullproc) {
return TRUE ; return TRUE ;
} }
/* dummy function for binding to meta prefix */ /* dummy function for binding to meta prefix */
BINDABLE( metafn) { TBINDABLE( metafn) {
return TRUE ; return TRUE ;
} }
/* dummy function for binding to control-x prefix */ /* dummy function for binding to control-x prefix */
BINDABLE( cex) { TBINDABLE( cex) {
return TRUE ; return TRUE ;
} }
/* dummy function for binding to universal-argument */ /* dummy function for binding to universal-argument */
BINDABLE( unarg) { TBINDABLE( unarg) {
return TRUE ; return TRUE ;
} }

17
names.h
View File

@ -1,12 +1,10 @@
/* 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) */
@ -14,7 +12,9 @@
/* Bindable uEMACS function pointer type and definition template */ /* Bindable uEMACS function pointer type and definition template */
#define BINDABLE( fname) int fname( int f, int n) #define BINDABLE( fname) int fname( boolean f, int n)
#define BBINDABLE( fname) boolean fname( boolean f, int n)
#define TBINDABLE BBINDABLE
typedef BINDABLE( (*fnp_t)) ; typedef BINDABLE( (*fnp_t)) ;
@ -53,11 +53,10 @@ 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 */
BINDABLE( nullproc) ; TBINDABLE( nullproc) ;
BINDABLE( metafn) ; TBINDABLE( metafn) ;
BINDABLE( cex) ; TBINDABLE( cex) ;
BINDABLE( unarg) ; TBINDABLE( unarg) ;
#endif #endif
/* end of names.h */ /* end of names.h */

View File

@ -144,11 +144,9 @@ 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 ;
@ -167,9 +165,12 @@ 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 {
col += 1 ; int w = utf8_width( c) ; /* incomplete wc_width */
col += (w < 0) ? 2 : w ;
} }
}
return col ; return col ;
} }
@ -714,60 +715,40 @@ 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
*/ */
int setemode(int f, int n) BINDABLE( setemode) {
{
#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
*/ */
int delmode(int f, int n) BINDABLE( delmode) {
{
#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
*/ */
int setgmode(int f, int n) BINDABLE( setgmode) {
{
#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
*/ */
int delgmode(int f, int n) BINDABLE( delgmode) {
{
#if PKCODE
return adjustmode( FALSE, TRUE) ; return adjustmode( FALSE, TRUE) ;
#else
adjustmode(FALSE, TRUE);
#endif
} }
/* /*
@ -858,11 +839,10 @@ 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 */
status = newmlargt( &tstring, prompt, 0) ; /* grab as big a token as screen allow */ int status = newmlargt( &tstring, prompt, 0) ;
if( tstring == NULL) if( tstring == NULL)
return status ; return status ;

View File

@ -9,7 +9,7 @@
*/ */
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stddef.h>
#include "buffer.h" #include "buffer.h"
#include "estruct.h" #include "estruct.h"
@ -139,10 +139,9 @@ 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)
mloutstr( "No mark set in this window") ; return mloutfail( "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) {
@ -182,8 +181,8 @@ int getregion( region_p rp) {
} }
} }
} }
mloutstr( "Bug: lost mark") ;
return FALSE; return mloutfail( "Bug: lost mark") ;
} }
/* end of region.c */ /* end of region.c */

View File

@ -1,9 +1,7 @@
/* search.c -- implements search.h */ /* search.c -- implements search.h */
#include "search.h" #include "search.h"
/* search.c /* The functions in this file implement commands that search in the forward
*
* 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.
@ -177,15 +175,14 @@ 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
*/ */
int forwsearch(int f, int n) BINDABLE( forwsearch) {
{
int status = TRUE; int status = TRUE;
/* If n is negative, search backwards. /* If n is negative, search backwards.
@ -223,15 +220,14 @@ int forwsearch(int f, int n)
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
*/ */
int forwhunt(int f, int n) BINDABLE( forwhunt) {
{
int status = TRUE; int status = TRUE;
if (n < 0) /* search backwards */ if (n < 0) /* search backwards */
@ -276,16 +272,15 @@ int forwhunt(int f, int n)
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
*/ */
int backsearch(int f, int n) BINDABLE( backsearch) {
{
int status = TRUE; int status = TRUE;
/* If n is negative, search forwards. /* If n is negative, search forwards.
@ -324,16 +319,15 @@ int backsearch(int f, int n)
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
*/ */
int backhunt(int f, int n) BINDABLE( backhunt) {
{
int status = TRUE; int status = TRUE;
if (n < 0) if (n < 0)
@ -788,25 +782,23 @@ 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
*/ */
int sreplace(int f, int n) BINDABLE( sreplace) {
{
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
*/ */
int qreplace(int f, int n) BINDABLE( qreplace) {
{
return replaces( TRUE, f, n) ; return replaces( TRUE, f, n) ;
} }

39
spawn.c
View File

@ -1,9 +1,7 @@
/* spawn.c -- implements spawn.h */ /* spawn.c -- implements spawn.h */
#include "spawn.h" #include "spawn.h"
/* spawn.c /* Various operating system access commands.
*
* Various operating system access commands.
* *
* Modified by Petri Kutvonen * Modified by Petri Kutvonen
*/ */
@ -34,13 +32,11 @@
#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".
*/ */
int spawncli(int f, int n) BINDABLE( spawncli) {
{
#if USG | BSD #if USG | BSD
char *cp; char *cp;
#endif #endif
@ -81,9 +77,8 @@ int spawncli(int f, int n)
} }
#if BSD | SVR4 #if BSD | SVR4
/* suspend MicroEMACS and wait to wake up */
int bktoshell(int f, int n) BINDABLE( bktoshell) {
{ /* suspend MicroEMACS and wait to wake up */
vttidy(); vttidy();
/****************************** /******************************
int pid; int pid;
@ -103,12 +98,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 !".
*/ */
int spawn( int f, int n) { BINDABLE( spawn) {
int s ; int s ;
char *line ; char *line ;
@ -141,13 +136,13 @@ int spawn( int f, int n) {
#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 $".
*/ */
int execprg( int f, int n) { BINDABLE( execprg) {
int s ; int s ;
char *line ; char *line ;
@ -176,11 +171,11 @@ int execprg( int f, int n) {
#endif #endif
} }
/*
* Pipe a one line command into a window /* Pipe a one line command into a window
* Bound to ^X @ * Bound to ^X @
*/ */
int pipecmd( int f, int n) { BINDABLE( pipecmd) {
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 */
@ -271,11 +266,11 @@ int pipecmd( int f, int n) {
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 #
*/ */
int filter_buffer( int f, int n) { BINDABLE( filter_buffer) {
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,17 +1,20 @@
/* 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,3 +1,4 @@
/* util.h -- utility functions */
#ifndef UTIL_H_ #ifndef UTIL_H_
# define UTIL_H_ # define UTIL_H_
@ -5,3 +6,4 @@
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,54 +1,44 @@
/* window.c -- inplements window.h */ /* window.c -- inplements window.h */
#include "window.h" #include "window.h"
/* window.c /* Window management. Some of the functions are internal, and some are
* 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" #include "display.h" /* upmode() */
#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 */
struct window *curwp ; /* Current window */ static window_p savwindow = NULL ; /* saved window pointer */
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
* 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
* positive, it is that line. If it is negative it is that line from the bottom. If it is 0 the window is centered (this is what the standard
* 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-!.
* redisplay code does). With no argument it defaults to 0. Bound to M-!.
*/ */
int reposition(int f, int n) TBINDABLE( reposition) {
{ 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 an /* Refresh the screen. With no argument, it just does the refresh. With
* argument it recenters "." in the current window. Bound to "C-L". an argument it recenters "." in the current window. Bound to "C-L".
*/ */
int redraw(int f, int n) TBINDABLE( redraw) {
{
if( f == FALSE) if( f == FALSE)
sgarbf = TRUE ; sgarbf = TRUE ;
else { else {
@ -59,19 +49,17 @@ int redraw(int f, int n)
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
*
*/ */
int nextwind(int f, int n) BINDABLE( nextwind) {
{ window_p wp;
struct window *wp;
int nwindows; /* total number of windows */ int nwindows; /* total number of windows */
if (f) { if (f) {
@ -94,10 +82,8 @@ int nextwind(int f, int n)
wp = wheadp; wp = wheadp;
while (--n) while (--n)
wp = wp->w_wndp; wp = wp->w_wndp;
} else { } else
mlwrite("Window number out of range"); return mloutfail( "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;
@ -107,15 +93,14 @@ int nextwind(int f, int n)
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 do a current window. There arn't any errors, although the command does not
* lot if there is 1 window. do a lot if there is 1 window.
*/ */
int prevwind(int f, int n) BINDABLE( prevwind) {
{ window_p wp1;
struct window *wp1; window_p wp2;
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)
@ -137,28 +122,26 @@ int prevwind(int f, int n)
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".
*/ */
int mvdnwind(int f, int n) BINDABLE( mvdnwind) {
{
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".
*/ */
int mvupwind(int f, int n) BINDABLE( mvupwind) {
{ line_p lp;
struct line *lp;
int i; int i;
lp = curwp->w_linep; lp = curwp->w_linep;
@ -193,17 +176,16 @@ int mvupwind(int f, int n)
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.
*/ */
int onlywind(int f, int n) BINDABLE( onlywind) {
{ window_p wp;
struct window *wp; line_p lp;
struct line *lp;
int i; int i;
while (wheadp != curwp) { while (wheadp != curwp) {
@ -241,23 +223,20 @@ int onlywind(int f, int n)
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
*/ */
int delwind(int f, int n) BINDABLE( delwind) {
{ window_p wp; /* window to recieve deleted space */
struct window *wp; /* window to recieve deleted space */ window_p lwp; /* ptr window before curwp */
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)
mlwrite("Can not delete this window"); return mloutfail( "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;
@ -316,8 +295,8 @@ int delwind(int f, int n)
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
@ -325,21 +304,21 @@ int delwind(int f, int n)
* *
* int f, n; default flag and numeric argument * int f, n; default flag and numeric argument
*/ */
int splitwind(int f, int n) BINDABLE( splitwind) {
{ window_p wp;
struct window *wp; line_p lp;
struct line *lp;
int ntru; int ntru;
int ntrl; int ntrl;
int ntrd; int ntrd;
struct window *wp1; window_p wp1;
struct window *wp2; window_p wp2;
if( curwp->w_ntrows < 3) { if( curwp->w_ntrows < 3) {
mlwrite("Cannot split a %d line window", curwp->w_ntrows); mloutfmt( "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;
@ -398,33 +377,30 @@ int splitwind(int f, int n)
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".
*/ */
int enlargewind(int f, int n) BINDABLE( enlargewind) {
{ window_p adjwp;
struct window *adjwp; line_p lp;
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)
mlwrite("Only one window"); return mloutfail( "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)
mlwrite("Impossible change"); return mloutfail( "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)
@ -450,32 +426,29 @@ int enlargewind(int f, int n)
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".
*/ */
int shrinkwind(int f, int n) BINDABLE( shrinkwind) {
{ window_p adjwp;
struct window *adjwp; line_p lp;
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)
mlwrite("Only one window"); return mloutfail( "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)
mlwrite("Impossible change"); return mloutfail( "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;
@ -502,13 +475,12 @@ int shrinkwind(int f, int n)
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
*/ */
int resize(int f, int n) BINDABLE( resize) {
{
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 */
@ -525,14 +497,14 @@ int resize(int f, int n)
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.
*/ */
struct window *wpopup(void) window_p wpopup(void)
{ {
struct window *wp; window_p 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 */
@ -543,59 +515,57 @@ struct window *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 */
swindow = curwp; BINDABLE( savewnd) {
savwindow = curwp ;
return TRUE ; return TRUE ;
} }
int restwnd(int f, int n)
{ /* restore the saved screen */
struct window *wp;
/* find the window */ /* restore the saved screen */
wp = wheadp; BINDABLE( restwnd) {
while (wp != NULL) { /* check the saved window still exists */
if (wp == swindow) { for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) {
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;
} }
mlwrite("(No such window exists)"); return mloutfail( "(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
*/ */
int newsize(int f, int n) BINDABLE( newsize) {
{ window_p wp; /* current window being examined */
struct window *wp; /* current window being examined */ window_p nextwp; /* next window to scan */
struct window *nextwp; /* next window to scan */ window_p lastwp; /* last window scanned */
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 */
@ -603,10 +573,8 @@ int newsize(int f, int n)
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)
mlwrite("%%Screen size out of range"); return mloutfail( "%%Screen size out of range") ;
return FALSE;
}
if (term.t_nrow == n - 1) if (term.t_nrow == n - 1)
return TRUE; return TRUE;
@ -674,25 +642,22 @@ int newsize(int f, int n)
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
*/ */
int newwidth(int f, int n) BINDABLE( newwidth) {
{ 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)
mlwrite("%%Screen width out of range"); return mloutfail( "%%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;
@ -713,7 +678,7 @@ int newwidth(int f, int n)
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 */
struct line *lp; /* scannile line pointer */ line_p lp; /* scannile line pointer */
/* search down the line we want */ /* search down the line we want */
lp = curwp->w_linep; lp = curwp->w_linep;
@ -731,3 +696,5 @@ void cknewwindow(void)
{ {
execute(META | SPEC | 'X', FALSE, 1); execute(META | SPEC | 'X', FALSE, 1);
} }
/* end of window.c */

View File

@ -1,21 +1,22 @@
/* 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, line */ #include "buffer.h" /* buffer_p, line_p */
#include "names.h" /* BINDABLE() */
/* /* There is a window structure allocated for every active display window.
* There is a window structure allocated for every active display window. The The windows are kept in a big list, in top to bottom screen order, with
* windows are kept in a big list, in top to bottom screen order, with the the listhead at "wheadp". Each window contains its own values of dot
* listhead at "wheadp". Each window contains its own values of dot and mark. and mark. The flag field contains some bits that are set by commands to
* The flag field contains some bits that are set by commands to guide guide redisplay. Although this is a bit of a compromise in terms of
* redisplay. Although this is a bit of a compromise in terms of decoupling, decoupling, the full blown redisplay is just too expensive to run for
* the full blown redisplay is just too expensive to run for every input every input character.
* character.
*/ */
typedef struct window { typedef struct window {
struct window *w_wndp; /* Next window */ struct window *w_wndp; /* Next window */
struct buffer *w_bufp; /* Buffer displayed in window */ buffer_p 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" */
@ -49,26 +50,29 @@ extern window_p wheadp ; /* Head of list of windows */
# define WFINS 0x80 /* something was inserted */ # define WFINS 0x80 /* something was inserted */
# endif # endif
int reposition( int f, int n); /* Bindable functions */
int redraw( int f, int n) ; BINDABLE( delwind) ;
int nextwind( int f, int n) ; BINDABLE( enlargewind) ;
int prevwind( int f, int n) ; BINDABLE( mvdnwind) ;
int mvdnwind( int f, int n) ; BINDABLE( mvupwind) ;
int mvupwind( int f, int n) ; BINDABLE( newsize) ;
int onlywind( int f, int n) ; BINDABLE( newwidth) ;
int delwind( int f, int n) ; BINDABLE( nextwind) ;
int splitwind( int f, int n) ; BINDABLE( onlywind) ;
int enlargewind( int f, int n) ; BINDABLE( prevwind) ;
int shrinkwind( int f, int n) ; TBINDABLE( redraw) ;
int resize( int f, int n) ; TBINDABLE( reposition) ;
int scrnextup( int f, int n) ; BINDABLE( resize) ;
int scrnextdw( int f, int n) ; BINDABLE( restwnd) ;
int savewnd( int f, int n) ; BINDABLE( savewnd) ;
int restwnd( int f, int n) ; BINDABLE( scrnextdw) ;
int newsize( int f, int n) ; BINDABLE( scrnextup) ;
int newwidth( int f, int n) ; BINDABLE( shrinkwind) ;
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,13 +1,11 @@
/* word.c -- implements word.h */ /* word.c -- implements word.h */
#include "word.h" #include "word.h"
/* word.c /* 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
* The routines in this file implement commands that work word or a do any sentence mode commands, they are likely to be put in this file.
* 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. Modified by Petri Kutvonen
*
* Modified by Petri Kutvonen
*/ */
#include <assert.h> #include <assert.h>
@ -31,18 +29,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 current /* Word wrap on n-spaces. Back-over whatever precedes the point on the
* line and stop on the first word-break or the beginning of the line. If we current line and stop on the first word-break or the beginning of the
* reach the beginning of the line, jump back to the end of the word and start line. If we reach the beginning of the line, jump back to the end of
* a new line. Otherwise, break the line at the word-break, eat it, and jump the word and start a new line. Otherwise, break the line at the
* back to the end of the word. word-break, eat it, and jump back to the end of the word.
* Returns TRUE on success, FALSE on errors.
* Returns TRUE on success, FALSE on errors.
* @f: default flag.
* @n: numeric argument. @f: default flag.
@n: numeric argument.
*/ */
int wrapword(int f, int n) BINDABLE( wrapword) {
{
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 */
@ -81,11 +79,12 @@ int wrapword(int f, int n)
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 to performed by the "backchar" and "forwchar" routines. Error if you try
* move beyond the buffers. to move beyond the buffers.
*/ */
int backword( int f, int n) { BINDABLE( backword) {
if( n < 0) if( n < 0)
return forwword( f, -n) ; return forwword( f, -n) ;
@ -106,10 +105,12 @@ int backword( int f, int n) {
return forwchar( FALSE, 1) ; return forwchar( FALSE, 1) ;
} }
/* Move the cursor forward by the specified number of words. All of the motion
* is done by "forwchar". Error if you try and move beyond the buffer's end. /* Move the cursor forward by the specified number of words. All of the
motion is done by "forwchar". Error if you try and move beyond the
buffer's end.
*/ */
int forwword( int f, int n) { BINDABLE( forwword) {
if( n < 0) if( n < 0)
return backword( f, -n) ; return backword( f, -n) ;
@ -172,40 +173,41 @@ 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 the convert any characters to upper case. Error if you try and move beyond
* end of the buffer. Bound to "M-U". the end of the buffer. Bound to "M-U".
*/ */
int upperword( int f, int n) { BINDABLE( upperword) {
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 end of convert characters to lower case. Error if you try and move over the
* the buffer. Bound to "M-L". end of the buffer. Bound to "M-L".
*/ */
int lowerword( int f, int n) { BINDABLE( lowerword) {
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".
*/ */
int capword( int f, int n) { BINDABLE( capword) {
return capcapword( n, TRUE, FALSE) ; return capcapword( n, TRUE, FALSE) ;
} }
/*
* Kill forward by "n" words. Remember the location of dot. Move forward by /* Kill forward by "n" words. Remember the location of dot. Move forward
* the right number of words. Put dot back where it was and issue the kill by the right number of words. Put dot back where it was and issue the
* command for the right number of characters. With a zero argument, just kill command for the right number of characters. With a zero argument,
* kill one word and no whitespace. Bound to "M-D". just kill one word and no whitespace. Bound to "M-D".
*/ */
int delfword(int f, int n) BINDABLE( delfword) {
{
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 */
@ -285,13 +287,13 @@ int delfword(int f, int n)
return ldelete(size, TRUE); return ldelete(size, TRUE);
} }
/*
* Kill backwards by "n" words. Move backwards by the desired number of words, /* Kill backwards by "n" words. Move backwards by the desired number of
* counting the characters. When dot is finally moved to its resting place, words, counting the characters. When dot is finally moved to its
* fire off the kill command. Bound to "M-Rubout" and to "M-Backspace". resting place, fire off the kill command. Bound to "M-Rubout" and to
"M-Backspace".
*/ */
int delbword(int f, int n) BINDABLE( delbword) {
{
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 */
@ -352,17 +354,13 @@ 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 */
mloutstr( "No fill column set") ; return mloutfail( "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)
mloutstr( "Column too narrow") ; return mloutfail( "Column too narrow") ;
return FALSE;
}
justflag = justify_f ; justflag = justify_f ;
} }
@ -472,33 +470,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
*/ */
int fillpara( int f, int n) { BINDABLE( fillpara) {
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
*/ */
int justpara( int f, int n) { BINDABLE( justpara) {
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
*/ */
int killpara(int f, int n) BINDABLE( killpara) {
{
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 */
@ -525,15 +523,13 @@ int killpara(int f, int n)
} }
/* /* 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
*/ */
int wordcount(int f, int n) BINDABLE( wordcount) {
{
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 */
@ -591,15 +587,14 @@ int wordcount(int f, int n)
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
*/ */
int gotobop(int f, int n) BINDABLE( gotobop) {
{
if (n < 0) /* the other way... */ if (n < 0) /* the other way... */
return gotoeop(f, -n); return gotoeop(f, -n);
@ -629,15 +624,14 @@ int gotobop(int f, int n)
return TRUE; return TRUE;
} }
/*
* Go forward to the end of the current paragraph /* Go forward to the end of the current paragraph here we look for a
* here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE> <NL><NL> or <NL><TAB> or <NL><SPACE> combination to delimit the
* combination to delimit the beginning of a paragraph beginning of a paragraph
*
* int f, n; default Flag & Numeric argument int f, n; default Flag & Numeric argument
*/ */
int gotoeop(int f, int n) BINDABLE( gotoeop) {
{
if (n < 0) /* the other way... */ if (n < 0) /* the other way... */
return gotobop(f, -n); return gotobop(f, -n);