1
0
mirror of https://github.com/rfivet/uemacs.git synced 2024-12-17 23:06:25 -05:00

Compare commits

...

38 Commits

Author SHA1 Message Date
946c603a39 Merge branch 'viewmode' 2021-08-15 16:29:51 +08:00
731ea754bb Formatting and typos. 2021-08-15 16:05:31 +08:00
79c3dfa4d9 Refactoring display primitives. 2021-08-15 11:22:32 +08:00
109e330861 Consistent interface to deal with workaround on Cygwin when checking width of unicode character > 0xFFFF. 2021-08-15 09:41:35 +08:00
3bce7a4751 Rework file primitives. 2021-08-14 11:45:41 +08:00
b4d69118f5 Revise header files formatting.
Finish tagging BBINDABLE functions.
Modify forward-character to handle combined Unicode.
Bump up version number and set default program name as 'ue'.
2021-08-13 11:06:58 +08:00
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
893e34b740 Remove obsolete terminal implementations. 2021-08-07 21:54:09 +08:00
5c65613f03 Replace compilation check by estruct.h header inclusion. 2021-08-07 21:46:58 +08:00
1fbb2fc565 Merge common implementation of case-region-lower and case-region-upper. 2021-08-07 21:34:13 +08:00
1cdc889f6f Fix regression on key command input for M-^X and ^X^X. 2021-08-07 13:46:14 +08:00
c55a72ad26 Use explicit buffer name as output for the script. 2021-08-07 10:29:23 +08:00
3551d2b8d1 Simplify Makefile by removing obsolete rules (lint, splint, sparse, tags). 2021-08-07 10:28:20 +08:00
4b45ca231e Fix regression: CSI character instead of ^{[ in terminal special key sequence.
Remove terminal special key conditional compilation.
2021-08-06 15:21:00 +08:00
5002897705 Rewrite keycode command input from command line according to terminal sequence handling. 2021-08-05 12:09:21 +08:00
7f3f498f3f Rewrite terminal sequence handling while getting key sequence: getcmd(). 2021-08-04 10:54:39 +08:00
d890880a52 Revise bindable functions usage of struct to named types. 2021-08-03 13:37:06 +08:00
7730a4e730 Improve handling of UTF-8 interactive input of strings. 2021-08-01 15:07:06 +08:00
27f30e48d2 Name pointer type to struct. 2021-07-31 15:28:32 +08:00
486d01297d Improve keyboard input of UTF-8. 2021-07-31 14:45:35 +08:00
d48120a557 Improve support for Unicode in describe-key. 2021-07-31 12:35:39 +08:00
c4fab606d1 Revise keycode encoding.
Gather APROP and CFENCE conditional code.
2021-07-30 16:24:52 +08:00
22bbd0417c Revise types for names and keys bindings. 2021-07-30 09:30:12 +08:00
735aefc166 Manage key binding table dynamically.
Avoid deleting or binding to active prefix keys.
2021-07-24 16:34:54 +08:00
ba1bfcd0db Fix filename completion after prompt adaptation. 2021-07-24 13:57:51 +08:00
1aadb53956 Remove function pointer from key to bindable table.
Emphasize bindable functions in code.
Use function name based prompts.
2021-07-24 08:58:23 +08:00
f30ef38bc8 Merge name to function and key code to function table initialization. 2021-07-23 10:47:58 +08:00
521d96fbda Use binary search for name to function lookup. Fix name mapping table order. Rework test scripts. 2021-07-21 16:40:36 +08:00
6f7d89b1ac Fix regression: checking abort when prompting for command name. 2021-07-21 08:16:11 +08:00
c093b7064b Cache the result of function to name mapping lookup when doing keycode to function mapping lookup. 2021-07-20 17:34:35 +08:00
4f90e847f8 Tag uEMACS functions using first character of name string. 2021-07-20 11:24:32 +08:00
695b5d37da Tag most view mode incompatible functions in function names table. 2021-07-19 20:50:32 +08:00
f0fe1ec194 Avoid extra empty line at EOF. 2021-07-19 16:37:57 +08:00
00b85fab9f Fix warning triggered by enforcing const on function names table. 2021-07-19 16:36:14 +08:00
92c9208cd4 start tagging uEMACS functions that are not compatible with view mode. 2021-07-19 15:39:00 +08:00
78 changed files with 6061 additions and 8538 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text=auto

4
.gitignore vendored
View File

@ -1,2 +1,4 @@
em
depend.mak
ue
*.o
*.exe

View File

@ -1,5 +1,5 @@
# Makefile -- uEMACS
# Copyright (c) 2014-2021 Renaud Fivet
# Makefile -- µEMACS
# Copyright © 2013-2021 Renaud Fivet
# Make the build silent by default
V =
@ -25,7 +25,7 @@ WARNINGS=-pedantic -Wall -Wextra -Wstrict-prototypes -Wno-unused-parameter
CFLAGS=-O2 $(WARNINGS)
LDFLAGS=-s
LIBS=-lcurses
DEFINES=-DAUTOCONF -DPROGRAM=$(PROGRAM)
DEFINES=-DAUTOCONF -DPROGRAM=$(PROGRAM) # -DNDEBUG
ifeq ($(uname_S),Linux)
DEFINES += -DPOSIX -DUSG
else ifeq ($(uname_S),CYGWIN)
@ -38,18 +38,6 @@ else
$(error $(uname_S) needs configuration)
endif
#ifeq ($(uname_S),FreeBSD)
# DEFINES=-DAUTOCONF -DPOSIX -DSYSV -D_FREEBSD_C_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -D_XOPEN_SOURCE=600
#endif
#ifeq ($(uname_S),Darwin)
# DEFINES=-DAUTOCONF -DPOSIX -DSYSV -D_DARWIN_C_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -D_XOPEN_SOURCE=600
#endif
#LIBS=-ltermcap # BSD
#LIBS=-lcurses # SYSV
#LIBS=-ltermlib
#LIBS=-L/usr/lib/termcap -ltermcap
LFLAGS=-hbx
BINDIR=/usr/bin
LIBDIR=/usr/lib
@ -60,15 +48,9 @@ $(PROGRAM): $(OBJS)
$(E) " LINK " $@
$(Q) $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
SPARSE=sparse
SPARSE_FLAGS=-D__LITTLE_ENDIAN__ -D__x86_64__ -D__linux__ -D__unix__
sparse:
$(SPARSE) $(SPARSE_FLAGS) $(DEFINES) $(SRCS)
clean:
$(E) " CLEAN"
$(Q) rm -f $(PROGRAM) core lintout makeout tags *.o
$(Q) rm -f $(PROGRAM) depend.mak *.o
install: $(PROGRAM)
strip $(PROGRAM)
@ -78,22 +60,6 @@ install: $(PROGRAM)
chmod 755 ${BINDIR}/$(PROGRAM)
chmod 644 ${LIBDIR}/emacs.hlp ${LIBDIR}/.emacsrc
lint: ${SRC}
@rm -f lintout
lint ${LFLAGS} ${SRC} >lintout
cat lintout
splint:
splint -weak $(DEFINES) $(SRCS) -booltype boolean -booltrue TRUE -boolfalse FALSE +posixlib +matchanyintegral
errs:
@rm -f makeout
make $(PROGRAM) >makeout 2>&1
tags: ${SRC}
@rm -f tags
ctags ${SRC}
.c.o:
$(E) " CC " $@
$(Q) ${CC} ${CFLAGS} ${DEFINES} -c $*.c

301
basic.c
View File

@ -1,19 +1,16 @@
/* basic.c -- implements 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
* always updates the cursor location, so only moves between lines, or
* functions that adjust the top line in the window and invalidate the
* framing, are hard.
*
* modified by Petri Kutvonen
/* 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
always updates the cursor location, so only moves between lines, or
functions that adjust the top line in the window and invalidate the
framing, are hard.
modified by Petri Kutvonen
*/
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include "input.h"
@ -22,26 +19,20 @@
#include "terminal.h"
#include "window.h"
#define CVMVAS 1 /* arguments to page forward/back in pages */
int overlap = DEFAULT_OVERLAP ; /* line overlap in forw/back page */
int curgoal ; /* Goal for C-P, C-N */
int overlap = 0 ; /* $overlap: line overlap in forw/back page */
int curgoal ; /* $target: column goal for C-P, C-N */
/*
* This routine, given a pointer to a struct line, and the current cursor goal
* column, return the best choice for the offset. The offset is returned.
* Used by "C-N" and "C-P".
/* This routine, given a pointer to a struct line, and the current cursor
goal column, return the best choice for the offset. The offset is
returned. Used by "C-N" and "C-P".
*/
static unsigned getgoal( line_p dlp) {
int col ;
unsigned idx ;
int col = 0 ;
const unsigned len = llength( dlp) ;
col = 0 ;
idx = 0 ;
unsigned idx = 0 ;
while( idx < len) {
unicode_t c ;
unsigned width = utf8_to_unicode( dlp->l_text, idx, len, &c) ;
@ -49,183 +40,158 @@ static unsigned getgoal( line_p dlp) {
/* Take tabs, ^X and \xx hex characters into account */
if( c == '\t')
col += tabwidth - col % tabwidth ;
else if( c < 0x20 || c == 0x7F)
else if( c < 0x20 || c == 0x7F) /* ^x */
col += 2 ;
else if( c >= 0x80 && c <= 0xA0)
else if( c >= 0x80 && c <= 0xA0) /* \xx */
col += 3 ;
else
col += 1 ;
col += utf8_width( c) ;
if( col > curgoal)
break ;
else
idx += width ;
}
return idx ;
}
/*
* Move the cursor to the beginning of the current line of active window.
*/
boolean gotobol( int f, int n) {
/* Move the cursor to the beginning of the current line of active window. */
TBINDABLE( gotobol) {
curwp->w_doto = 0 ;
return TRUE ;
}
/*
* Move the cursor to the end of the current line of active window.
*/
boolean gotoeol( int f, int n) {
/* Move the cursor to the end of the current line of active window. */
TBINDABLE( gotoeol) {
curwp->w_doto = llength( curwp->w_dotp) ;
return TRUE ;
}
/*
* 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
* is the same as the new value of dot. Normally bound to "M-<".
/* 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 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_doto = 0 ;
curwp->w_flag |= WFHARD ;
return TRUE ;
}
/*
* 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.
* Bound to "M->".
/* 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.
Bound to "M->".
*/
boolean gotoeob( int f, int n) {
TBINDABLE( gotoeob) {
curwp->w_dotp = curbp->b_linep ;
curwp->w_doto = 0 ;
curwp->w_flag |= WFHARD ;
return TRUE ;
}
/*
* 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
* controls how the goal column is set. Bound to "C-N". No errors are
* possible.
/* 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 controls how the goal column is set. Bound to "C-N". No errors
are possible.
*/
boolean forwline( int f, int n) {
line_p dlp ;
BBINDABLE( forwline) {
assert( f == TRUE || n == 1) ;
if (n < 0)
return backline(f, -n);
/* if the last command was not a line move, reset the goal column */
if( (lastflag & CFCPCN) == 0)
curgoal = getccol( FALSE) ;
/* if we are on the last line as we start....fail the command */
if (curwp->w_dotp == curbp->b_linep)
return FALSE;
/* flag this command as a line move */
thisflag |= CFCPCN ;
/* 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 down */
dlp = curwp->w_dotp;
/* and move the point down */
if( n) {
line_p dlp = curwp->w_dotp ;
if( n > 0)
while( n && dlp != curbp->b_linep) {
dlp = lforw( dlp) ;
n -= 1 ;
}
/* reseting the current position */
curwp->w_dotp = dlp;
curwp->w_doto = getgoal(dlp);
curwp->w_flag |= WFMOVE;
return (n == 0) ? TRUE : FALSE ;
}
/*
* 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;
else {
while( n && lback( dlp) != curbp->b_linep) {
dlp = lback( dlp) ;
n -= 1 ;
n += 1 ;
}
}
/* resetting the current position */
curwp->w_dotp = dlp ;
curwp->w_doto = getgoal( dlp) ;
curwp->w_flag |= WFMOVE ;
}
/* reseting the current position */
curwp->w_dotp = dlp;
curwp->w_doto = getgoal(dlp);
curwp->w_flag |= WFMOVE;
return (n == 0) ? TRUE : FALSE ;
}
/*
* Move to a particular line.
/* 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.
*/
int gotoline( int f, int n) {
/* Get an argument if one doesnt exist. */
BINDABLE( gotoline) {
/* Get an argument if one doesn't exist. */
if( f == FALSE) {
int status ;
char *arg ; /* Buffer to hold argument. */
status = newmlarg( &arg, "Line to GOTO: ", 0) ;
if( status != TRUE) {
mloutstr( "(Aborted)") ;
int status = newmlarg( &arg, "goto-line: ", 0) ;
if( status != TRUE)
return status ;
}
n = atoi( arg) ;
free( arg) ;
f = TRUE ;
}
/* Handle the case where the user may be passed something like this:
* em filename +
/* Handle the case where the user may be passed something like this:
* ue filename +
* In this case we just go to the end of the buffer.
*/
if (n == 0)
return gotoeob(f, n);
if( n == 0)
return gotoeob( f, n) ;
/* If a bogus argument was passed, then returns false. */
if (n < 0)
return FALSE;
/* If a bogus argument was passed, then returns false. */
if( n < 0)
return FALSE ;
/* First, we go to the begin of the buffer. */
gotobob(f, n);
return (n == 1) ? TRUE : forwline( f, n - 1) ;
/* First, we go to the begin of the buffer. */
gotobob( f, n) ;
return (n == 1) ? TRUE : forwline( TRUE, n - 1) ;
}
/*
* 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
* the overlap; this value is the default overlap value in ITS EMACS. Because
* this zaps the top line in the display window, we have to do a hard update.
/* 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 the overlap; this value is the default overlap value in ITS EMACS.
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 ;
if (f == FALSE) {
if( f == FALSE) {
#if SCROLLCODE
if (term.t_scroll != NULL) /* $scroll == FALSE */
if (overlap == 0) /* $overlap == 0 */
@ -238,43 +204,41 @@ boolean forwpage( int f, int n) {
if (n <= 0) /* Forget the overlap. */
n = 1; /* If tiny window. */
} else if (n < 0)
return backpage(f, -n);
} else if( n < 0)
return backpage( f, -n) ;
#if CVMVAS
else /* Convert from pages. */
n *= curwp->w_ntrows; /* To lines. */
#endif
/* lp = curwp->w_linep; */
lp = curwp->w_dotp ;
while( n && lp != curbp->b_linep) {
lp = lforw( lp) ;
n -= 1 ;
}
/* curwp->w_linep = lp; */
curwp->w_dotp = lp;
curwp->w_doto = 0;
reposition( TRUE, 0) ;
curwp->w_dotp = lp ;
curwp->w_doto = 0 ;
reposition( TRUE, 0) ; /* center at dot, always succeed */
#if SCROLLCODE
curwp->w_flag |= WFHARD | WFKILLS;
#else
curwp->w_flag |= WFHARD;
#endif
return TRUE;
return TRUE ;
}
/*
* 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
* EMACS manual. Bound to "M-V". We do a hard update for exactly the same
* reason.
/* 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 EMACS manual. Bound to "M-V". We do a hard update for exactly the
same reason.
*/
boolean backpage( int f, int n) {
TBINDABLE( backpage) {
line_p lp ;
if (f == FALSE) { /* interactive, default n = 1 supplied */
if( f == FALSE) { /* interactive, default n = 1 supplied */
/* in interactive mode, first move dot to top of window */
if( curwp->w_dotp != curwp->w_linep) {
curwp->w_dotp = curwp->w_linep ;
@ -322,40 +286,33 @@ boolean backpage( int f, int n) {
return TRUE;
}
/*
* Set the mark in the current window to the value of "." in the window. No
* errors are possible. Bound to "M-.".
/* Set the mark in the current window to the value of "." in the window.
No errors are possible. Bound to M-. set-mark.
*/
boolean setmark( int f, int n) {
curwp->w_markp = curwp->w_dotp;
curwp->w_marko = curwp->w_doto;
TBINDABLE( setmark) {
curwp->w_markp = curwp->w_dotp ;
curwp->w_marko = curwp->w_doto ;
mloutstr( "(Mark set)") ;
return TRUE ;
}
/*
* Swap the values of "." and "mark" in the current window. This is pretty
* easy, because all of the hard work gets done by the standard routine
* that moves the mark about. The only possible error is "no mark". Bound to
* "C-X C-X".
*/
boolean swapmark( int f, int n) {
line_p odotp ;
int odoto;
if( curwp->w_markp == NULL) {
mloutstr( "No mark in this window") ;
return FALSE ;
/* Swap the values of "." and "mark" in the current window. If no mark as
been previously set, set it. Bound to C-X C-X exchange-point-and-mark.
*/
TBINDABLE( swapmark) {
line_p odotp = curwp->w_dotp ;
int odoto = curwp->w_doto ;
if( curwp->w_markp) {
curwp->w_dotp = curwp->w_markp ;
curwp->w_doto = curwp->w_marko ;
curwp->w_flag |= WFMOVE ;
}
odotp = curwp->w_dotp;
odoto = curwp->w_doto;
curwp->w_dotp = curwp->w_markp;
curwp->w_doto = curwp->w_marko;
curwp->w_markp = odotp;
curwp->w_marko = odoto;
curwp->w_flag |= WFMOVE;
return TRUE;
curwp->w_markp = odotp ;
curwp->w_marko = odoto ;
return TRUE ;
}
/* end of basic.c */

41
basic.h
View File

@ -1,35 +1,32 @@
/* basic.h -- basic commands for cursor movement in active window */
#ifndef _BASIC_H_
#define _BASIC_H_
#include "retcode.h"
#include "names.h" /* BINDABLE() */
/*
** $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)
** default to 0
*/
#define DEFAULT_OVERLAP 0
extern int overlap ; /* line overlap in forw/back page */
/* $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)
default to 0
*/
extern int overlap ; /* $overlap: line overlap in forw/back page */
/* $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) ;
boolean gotoeol( int f, int n) ;
int gotoline( int f, int n) ;
boolean gotobob( int f, int n) ;
boolean gotoeob( int f, int n) ;
boolean forwline( int f, int n) ;
boolean backline( int f, int n) ;
boolean forwpage( int f, int n) ;
boolean backpage( int f, int n) ;
boolean setmark( int f, int n) ;
boolean swapmark( int f, int n) ;
/* Bindable functions */
BBINDABLE( backline) ;
TBINDABLE( backpage) ;
BBINDABLE( forwline) ;
TBINDABLE( forwpage) ;
TBINDABLE( gotobob) ;
TBINDABLE( gotobol) ;
TBINDABLE( gotoeob) ;
TBINDABLE( gotoeol) ;
BINDABLE( gotoline) ;
TBINDABLE( setmark) ;
TBINDABLE( swapmark) ;
#endif
/* end of basic.h */

781
bind.c
View File

@ -1,409 +1,215 @@
/* bind.c -- implements bind.h */
#include "bind.h"
/* bind.c
*
* This file is for functions having to do with key bindings,
/* This file is for functions having to do with key bindings,
* descriptions, help commands and startup file.
*
* Written 11-feb-86 by Daniel Lawrence
* Modified by Petri Kutvonen
*/
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "estruct.h"
#include "bindable.h"
#include "buffer.h"
#include "display.h"
#include "ebind.h"
#include "display.h" /* upmode(), ostring() */
#include "exec.h"
#include "file.h"
#include "flook.h"
#include "input.h"
#include "line.h"
#include "mlout.h"
#include "names.h"
#include "util.h"
#include "window.h"
#if APROP
static int buildlist( char *mstring) ;
static int strinc( char *source, char *sub) ;
#endif
static void cmdstr( int c, char *seq) ;
static char *cmdstr( unsigned c, char *seq) ;
static unsigned int getckey( int mflag) ;
static unsigned int stock( char *keyname) ;
static int unbindchar( unsigned c) ;
static char *getfname( fn_t) ;
static const char *getfname( unsigned keycode, const char *failmsg) ;
int help(int f, int n)
{ /* give me some help!!!!
bring up a fake buffer and read the help file
into it with view mode */
struct buffer *bp; /* buffer pointer to help */
/* give me some help!!!! bring up a fake buffer and read the help file into
it with view mode
*/
BINDABLE( help) {
char *fname = NULL; /* ptr to file returned by flook() */
/* first check if we are already here */
bp = bfind( hlpfname, FALSE, BFINVS);
/* first check if we are already here */
buffer_p bp = bfind( hlpfname, FALSE, BFINVS);
if( bp == curbp)
return TRUE ;
if (bp == NULL) {
fname = flook( hlpfname, FALSE);
if (fname == NULL) {
mlwrite("(Help file is not online)");
return FALSE;
}
if( bp == NULL) {
fname = flook( hlpfname, FALSE) ;
if( fname == NULL)
return mloutfail( "(Help file is not online)") ;
}
/* split the current window to make room for the help stuff */
if (splitwind(FALSE, 1) == FALSE)
return FALSE;
/* split the current window to make room for the help stuff */
if( wheadp->w_wndp == NULL /* One window */
&& splitwind( FALSE, 1) == FALSE) /* Split it */
return FALSE ;
if (bp == NULL) {
if( bp == NULL) {
/* and read the stuff in */
if (getfile(fname, FALSE) == FALSE)
return FALSE;
if( getfile( fname, FALSE) == FALSE)
return FALSE ;
} else
swbuffer(bp);
swbuffer( bp) ;
/* make this window in VIEW mode, update all mode lines */
curwp->w_bufp->b_mode |= MDVIEW;
curwp->w_bufp->b_flag |= BFINVS;
upmode() ;
return TRUE;
return TRUE ;
}
int deskey(int f, int n)
{ /* describe the command for a certain key */
int c; /* key to describe */
char *ptr; /* string pointer to scan output strings */
char outseq[NSTRING]; /* output buffer for command sequence */
/* prompt the user to type us a key to describe */
mlwrite(": describe-key ");
/* get the command sequence to describe
change it to something we can print as well */
c = getckey( FALSE) ;
mlwrite( ": describe-key 0x%x, ", c) ;
cmdstr( c, &outseq[ 0]) ;
/* and dump it out */
ostring(outseq);
ostring(" ");
/* find the right ->function */
if ((ptr = getfname(getbind(c))) == NULL)
ptr = "Not Bound";
/* output the command sequence */
ostring(ptr);
return TRUE;
static boolean invalidkey( void) {
return mloutfail( "(Invalid key sequence)") ;
}
/*
* bindtokey:
/* describe the command for a certain key */
BINDABLE( deskey) {
const char cmdname[] = "describe-key" ;
char outseq[ 8] ; /* output buffer for keystroke sequence */
/* prompt the user to type a key to describe */
mloutfmt( "%s: ", cmdname) ;
/* get the command sequence to describe
* change it to something we can print as well */
unsigned keycode = getckey( FALSE) ;
if( keycode == (unsigned) ~0)
return invalidkey() ;
/* output the command sequence */
mloutfmt( "%s %s: 0x%x, %s", cmdname, cmdstr( keycode, outseq), keycode,
getfname( keycode, "Not Bound")) ;
return TRUE ;
}
/* bindtokey:
* add a new key to the key binding table
*
* int f, n; command arguments [IGNORED]
*/
int bindtokey(int f, int n)
{
unsigned int c; /* command key to bind */
fn_t kfunc; /* ptr to the requested function to bind to */
struct key_tab *ktp; /* pointer into the command table */
int found; /* matched command flag */
char outseq[80]; /* output buffer for keystroke sequence */
BINDABLE( bindtokey) {
kbind_p ktp ; /* pointer into the command table */
char outseq[ 8] ; /* output buffer for keystroke sequence */
/* prompt the user to type in a key to bind */
mlwrite(": bind-to-key ");
/* prompt the user to type in a key to bind */
mloutstr( "bind-to-key: ") ;
/* get the function name to bind it to */
kfunc = getname();
if (kfunc == NULL) {
mlwrite("(No such function)");
return FALSE;
}
ostring(" ");
/* get the function name to bind it to */
nbind_p nbp = getname() ;
if( nbp == NULL) /* abort */
return FALSE ;
/* get the command sequence to bind */
c = getckey((kfunc == metafn) || (kfunc == cex) ||
(kfunc == unarg) || (kfunc == ctrlg));
fnp_t kfunc = nbp->n_func ;
if( kfunc == NULL)
return mloutfail( "(No such function)") ;
/* change it to something we can print as well */
cmdstr(c, &outseq[0]);
mloutfmt( "bind-to-key %s: ", bind_name( nbp)) ;
/* and dump it out */
ostring(outseq);
/* get the command sequence to bind */
boolean prefix_f = (kfunc == (fnp_t) metafn) || (kfunc == (fnp_t) cex) ||
(kfunc == (fnp_t) unarg) || (kfunc == (fnp_t) ctrlg) ;
int c = getckey( prefix_f) ;
if( c == ~0)
return invalidkey() ;
/* if the function is a prefix key */
if (kfunc == metafn || kfunc == cex ||
kfunc == unarg || kfunc == ctrlg) {
/* change it to something we can print as well */
/* and dump it out */
ostring( cmdstr( c, outseq)) ;
/* search for an existing binding for the prefix key */
ktp = &keytab[0];
found = FALSE;
while (ktp->k_fp != NULL) {
if (ktp->k_fp == kfunc)
unbindchar(ktp->k_code);
++ktp;
/* key sequence can't be an active prefix key */
if( c == metac || c == ctlxc || c == reptc || c == abortc) {
if( (c == metac && kfunc == (fnp_t) metafn)
|| (c == ctlxc && kfunc == (fnp_t) cex)
|| (c == reptc && kfunc == (fnp_t) unarg)
|| (c == abortc && kfunc == (fnp_t) ctrlg))
return TRUE ; /* be silent if keep current */
return mloutfail( "(Can't bind to active prefix)") ;
}
/* reset the appropriate global prefix variable */
if (kfunc == metafn)
metac = c;
if (kfunc == cex)
ctlxc = c;
if (kfunc == unarg)
reptc = c;
if (kfunc == ctrlg)
abortc = c;
/* if the function is a prefix key */
if( prefix_f) {
/* remove existing binding for the prefix */
for( ktp = keytab ; ktp->k_code != 0 ; ktp++)
if( ktp->k_nbp == nbp) {
delkeybinding( ktp->k_code) ;
break ;
}
/* search the table to see if it exists */
ktp = &keytab[0];
found = FALSE;
while (ktp->k_fp != NULL) {
if (ktp->k_code == c) {
found = TRUE;
break;
}
++ktp;
/* set the appropriate global prefix variable */
if( kfunc == (fnp_t) metafn)
metac = c ;
else if( kfunc == (fnp_t) cex)
ctlxc = c ;
if( kfunc == (fnp_t) unarg)
reptc = c ;
if( kfunc == (fnp_t) ctrlg)
abortc = c ;
}
if (found) { /* it exists, just change it then */
ktp->k_fp = kfunc;
} else { /* otherwise we need to add it to the end */
/* if we run out of binding room, bitch */
if (ktp >= &keytab[NBINDS]) {
mlwrite("Binding table FULL!");
return FALSE;
}
ktp = setkeybinding( c, nbp) ;
if( ktp->k_code == 0)
return mloutfail( "Binding table FULL!") ;
ktp->k_code = c; /* add keycode */
ktp->k_fp = kfunc; /* and the function pointer */
++ktp; /* and make sure the next is null */
ktp->k_code = 0;
ktp->k_fp = NULL;
}
return TRUE;
return TRUE ;
}
/*
* unbindkey:
/* unbindkey:
* delete a key from the key binding table
*
* int f, n; command arguments [IGNORED]
*/
int unbindkey(int f, int n)
{
int c; /* command key to unbind */
char outseq[80]; /* output buffer for keystroke sequence */
BINDABLE( unbindkey) {
char outseq[ 8] ; /* output buffer for keystroke sequence */
/* prompt the user to type in a key to unbind */
mlwrite(": unbind-key ");
/* prompt the user to type in a key to unbind */
mloutstr( "unbind-key: ") ;
/* get the command sequence to unbind */
c = getckey(FALSE); /* get a command sequence */
/* get the command sequence to unbind */
int c = getckey( FALSE) ; /* get a command sequence */
if( c == ~0)
return invalidkey() ;
/* change it to something we can print as well */
cmdstr(c, &outseq[0]);
/* change it to something we can print as well */
/* and dump it out */
ostring( cmdstr( c, outseq)) ;
/* and dump it out */
ostring(outseq);
/* prefix key sequence can't be undound, just redefined */
if( c == reptc || c == abortc)
return mloutfail( "(Can't unbind prefix)") ;
/* if it isn't bound, bitch */
if (unbindchar(c) == FALSE) {
mlwrite("(Key not bound)");
return FALSE;
}
return TRUE;
/* if it isn't bound, bitch */
if( delkeybinding( c) == FALSE)
return mloutfail( "(Key not bound)") ;
return TRUE ;
}
/*
* unbindchar()
*
* int c; command key to unbind
*/
static int unbindchar( unsigned c) {
struct key_tab *ktp; /* pointer into the command table */
struct key_tab *sktp; /* saved pointer into the command table */
int found; /* matched command flag */
/* search the table to see if the key exists */
ktp = &keytab[0];
found = FALSE;
while (ktp->k_fp != NULL) {
if (ktp->k_code == c) {
found = TRUE;
break;
}
++ktp;
}
/* if it isn't bound, bitch */
if (!found)
return FALSE;
/* save the pointer and scan to the end of the table */
sktp = ktp;
while (ktp->k_fp != NULL)
++ktp;
--ktp; /* backup to the last legit entry */
/* copy the last entry to the current one */
sktp->k_code = ktp->k_code;
sktp->k_fp = ktp->k_fp;
/* null out the last one */
ktp->k_code = 0;
ktp->k_fp = NULL;
return TRUE;
}
/* describe bindings
* bring up a fake buffer and list the key bindings
* into it with view mode
*/
int desbind( int f, int n) {
#if APROP
return buildlist( "") ;
}
/* Apropos (List functions that match a substring) */
int apro( int f, int n) {
char *mstring ; /* string to match cmd names to */
int status ; /* status return */
status = newmlarg( &mstring, "Apropos string: ", 0) ;
if( status == TRUE) {
status = buildlist( mstring) ;
free( mstring) ;
} else if( status == FALSE)
status = buildlist( "") ; /* build list of all commands */
return status ;
}
/*
* build a binding list (limited or full)
*
* char *mstring; match string if a partial list, "" matches all
*/
static int buildlist( char *mstring) {
#endif
struct window *wp; /* scanning pointer to windows */
struct key_tab *ktp; /* pointer into the command table */
struct name_bind *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 */
if (splitwind(FALSE, 1) == FALSE)
return FALSE;
/* and get a buffer for it */
bp = bfind("*Binding list*", TRUE, 0);
if (bp == NULL || bclear(bp) == FALSE) {
mlwrite("Can not display binding list");
return FALSE;
}
/* let us know this is in progress */
mlwrite("(Building binding list)");
/* disconect the current buffer */
if (--curbp->b_nwnd == 0) { /* Last use. */
curbp->b_dotp = curwp->w_dotp;
curbp->b_doto = curwp->w_doto;
curbp->b_markp = curwp->w_markp;
curbp->b_marko = curwp->w_marko;
}
/* connect the current window to this buffer */
curbp = bp; /* make this buffer current in current window */
bp->b_mode = 0; /* no modes active in binding list */
bp->b_nwnd++; /* mark us as more in use */
wp = curwp;
wp->w_bufp = bp;
wp->w_linep = bp->b_linep;
wp->w_flag = WFHARD | WFFORCE;
wp->w_dotp = bp->b_dotp;
wp->w_doto = bp->b_doto;
wp->w_markp = NULL;
wp->w_marko = 0;
/* build the contents of this window, inserting it line by line */
for( nptr = &names[ 0] ; nptr->n_func != NULL ; nptr++) {
int cpos ; /* current position to use in outseq */
#if APROP
/* if we are executing an apropos command..... */
/* and current string doesn't include the search string */
if( *mstring && strinc( nptr->n_name, mstring) == FALSE)
continue ;
#endif
/* add in the command name */
mystrscpy( outseq, nptr->n_name, sizeof outseq) ;
cpos = strlen(outseq);
/* search down any keys bound to this */
ktp = &keytab[0];
while (ktp->k_fp != NULL) {
if (ktp->k_fp == nptr->n_func) {
/* padd out some spaces */
while (cpos < 28)
outseq[cpos++] = ' ';
/* add in the command sequence */
cmdstr(ktp->k_code, &outseq[cpos]);
strcat(outseq, "\n");
/* and add it as a line into the buffer */
if (linstr(outseq) != TRUE)
return FALSE;
cpos = 0; /* and clear the line */
}
++ktp;
}
/* if no key was bound, we need to dump it anyway */
if (cpos > 0) {
outseq[cpos++] = '\n';
outseq[cpos] = 0;
if (linstr(outseq) != TRUE)
return FALSE;
}
}
bp->b_mode |= MDVIEW; /* put this buffer view mode */
bp->b_flag &= ~BFCHG; /* don't flag this as a change */
wp->w_dotp = lforw(bp->b_linep); /* back to the beginning */
wp->w_doto = 0;
upmode() ; /* and update ALL mode lines */
mlwrite(""); /* clear the mode line */
return TRUE;
}
#if APROP
/*
* does source include sub?
/* does source include sub?
*
* char *source; string to search in
* char *sub; substring to look for
*/
static int strinc( char *source, char *sub) {
static boolean strinc( const char *source, const char *sub) {
/* for each character in the source string */
for( ; *source ; source++) {
char *nxtsp ; /* next ptr into source */
char *tp ; /* ptr into substring */
const char *nxtsp ; /* next ptr into source */
const char *tp ; /* ptr into substring */
nxtsp = source;
@ -419,23 +225,138 @@ static int strinc( char *source, char *sub) {
return FALSE ;
}
#endif
/*
* get a command key sequence from the keyboard
/* describe bindings
* bring up a fake buffer and list the key bindings
* into it with view mode
*/
BINDABLE( desbind) {
return buildlist( "") ;
}
/* Apropos (List functions that match a substring) */
BINDABLE( apro) {
char *mstring ; /* string to match cmd names to */
int status = newmlarg( &mstring, "apropos: ", 0) ;
if( status == TRUE) {
status = buildlist( mstring) ;
free( mstring) ;
} else if( status == FALSE)
status = buildlist( "") ; /* build list of all commands */
return status ;
}
/* build a binding list (limited or full)
*
* char *mstring; match string if a partial list, "" matches all
*/
static int buildlist( char *mstring) {
#define PADDING 28
char outseq[ PADDING + 8] ; /* output buffer for command + keystroke */
/* split the current window to make room for the binding list */
if( wheadp->w_wndp == NULL /* One window */
&& splitwind( FALSE, 1) == FALSE) /* Split it */
return FALSE ;
/* and get a buffer for it */
buffer_p bp = bfind( "*Binding list*", TRUE, 0) ;
if( bp == NULL || bclear( bp) == FALSE)
return mloutfail( "Can't display binding list") ;
/* let us know this is in progress */
mloutstr( "(Building binding list)") ;
/* disconnect the current buffer */
if( --curbp->b_nwnd == 0) { /* Last use. */
curbp->b_dotp = curwp->w_dotp ;
curbp->b_doto = curwp->w_doto ;
curbp->b_markp = curwp->w_markp ;
curbp->b_marko = curwp->w_marko ;
}
/* connect the current window to this buffer */
curbp = bp ; /* make this buffer current in current window */
bp->b_mode = 0 ; /* no modes active in binding list */
bp->b_nwnd++ ; /* mark us as more in use */
window_p wp = curwp ;
wp->w_bufp = bp ;
wp->w_linep = bp->b_linep ;
wp->w_flag = WFHARD | WFFORCE ;
wp->w_dotp = bp->b_dotp ;
wp->w_doto = bp->b_doto ;
wp->w_markp = NULL ;
wp->w_marko = 0 ;
/* build the contents of this window, inserting it line by line */
for( nbind_p nptr = names ; nptr->n_func != NULL ; nptr++) {
int cpos ; /* current position to use in outseq */
/* if we are executing an apropos command..... */
/* and current string doesn't include the search string */
if( *mstring && strinc( bind_name( nptr), mstring) == FALSE)
continue ;
/* add in the command name */
mystrscpy( outseq, bind_name( nptr), sizeof outseq) ;
cpos = strlen( outseq) ;
/* search down any keys bound to this */
for( kbind_p ktp = keytab ; ktp->k_code != 0 ; ktp++) {
if( ktp->k_nbp == nptr) {
/* padd out some spaces */
while( cpos < PADDING)
outseq[ cpos++] = ' ' ;
/* add in the command sequence */
cmdstr( ktp->k_code, &outseq[ cpos]) ;
strcat( outseq, "\n") ;
/* and add it as a line into the buffer */
if( linstr( outseq) != TRUE)
return FALSE ;
cpos = 0 ; /* and clear the line */
}
}
/* if no key was bound, we need to dump it anyway */
if( cpos > 0) {
outseq[ cpos++] = '\n';
outseq[ cpos] = 0;
if( linstr( outseq) != TRUE)
return FALSE ;
}
}
bp->b_mode |= MDVIEW ; /* put this buffer view mode */
bp->b_flag &= ~BFCHG ; /* don't flag this as a change */
wp->w_dotp = lforw( bp->b_linep) ; /* back to the beginning */
wp->w_doto = 0 ;
upmode() ; /* and update ALL mode lines */
mloutstr( "") ; /* clear the mode line */
return TRUE ;
}
/* get a command key sequence from the keyboard
*
* int mflag; going for a meta sequence?
* returns ~0 on failure
*/
static unsigned int getckey( int mflag) {
unsigned int c ; /* character fetched */
/* check to see if we are executing a command line */
if( clexec) {
char *tok ; /* command incoming */
tok = getnewtokval() ; /* get the next token */
char *tok = getnewtokval() ; /* get the next token */
if( tok == NULL)
c = 0 ; /* return dummy key on failure */
c = ~0 ; /* return invalid key on failure */
else {
c = stock( tok) ;
free( tok) ;
@ -450,8 +371,8 @@ static unsigned int getckey( int mflag) {
return c ;
}
/*
* execute the startup file
/* execute the startup file
*
* char *fname; name of startup file (null if default)
*/
@ -466,167 +387,121 @@ int startup( const char *fname) {
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
* char *seq; destination string for sequence
*/
static void cmdstr( int c, char *seq) {
char *ptr; /* pointer into current position in sequence */
static char *cmdstr( unsigned c, char *seq) {
char *ptr = seq ; /* pointer into current position in sequence */
ptr = seq;
/* apply meta sequence if needed */
if (c & META) {
/* apply meta sequence if needed */
if( c & META) {
*ptr++ = 'M';
*ptr++ = '-';
}
/* apply ^X sequence if needed */
if (c & CTLX) {
*ptr++ = '^';
*ptr++ = 'X';
/* apply ^X sequence if needed */
if( c & CTLX) {
if( ctlxc & CTL_)
*ptr++ = '^' ;
*ptr++ = ctlxc & ~PRFXMASK ;
}
/* apply SPEC sequence if needed */
if (c & SPEC) {
*ptr++ = 'F';
*ptr++ = 'N';
/* apply control sequence if needed */
if( c & CTL_)
*ptr++ = '^' ;
/* apply SPEC sequence if needed */
if( c & SPEC) {
*ptr++ = 'F' ;
*ptr++ = 'N' ;
}
/* apply control sequence if needed */
if (c & CONTROL) {
*ptr++ = '^';
}
/* and output the final sequence */
*ptr++ = c & 255; /* strip the prefixes */
*ptr = 0; /* terminate the string */
/* and output the final sequence */
ptr += unicode_to_utf8( c & ~PRFXMASK, ptr) ;
*ptr = 0 ; /* terminate the string */
return seq ;
}
/*
* This function looks a key binding up in the binding table
*
* int c; key to find what is bound to it
*/
fn_t getbind( unsigned c) {
struct key_tab *ktp;
ktp = &keytab[0]; /* Look in key table. */
while (ktp->k_fp != NULL) {
if (ktp->k_code == c)
return ktp->k_fp;
++ktp;
}
static const char *getfname( unsigned keycode, const char *failmsg) {
/* takes a key code and gets the name of the function bound to it */
kbind_p kbp = getkeybinding( keycode) ;
if( kbp->k_code == 0)
return failmsg ;
/* no such binding */
return NULL;
const char *found = bind_name( kbp->k_nbp) ;
assert( *found) ;
return found ;
}
/*
* getfname:
* This function takes a ptr to function and gets the name
* associated with it.
*/
static char *getfname(fn_t func)
{
struct name_bind *nptr; /* pointer into the name binding table */
/* skim through the table, looking for a match */
nptr = &names[0];
while (nptr->n_func != NULL) {
if (nptr->n_func == func)
return nptr->n_name;
++nptr;
}
return NULL;
}
/*
* match fname to a function in the names table
* and return any match or NULL if none
*
* char *fname; name to attempt to match
*/
int (*fncmatch(char *fname)) (int, int)
{
struct name_bind *ffp; /* pointer to entry in name binding table */
/* scan through the table, returning any match */
ffp = &names[0];
while (ffp->n_func != NULL) {
if (strcmp(fname, ffp->n_name) == 0)
return ffp->n_func;
++ffp;
}
return NULL;
}
/*
* stock:
/* stock:
* String key name TO Command Key
*
* char *keyname; name of key to translate to Command key form
* fmt: [M-|^X][^][FN]X
* returns ~0 on invalid sequence
*/
static unsigned int stock( char *keyname) {
unsigned int c; /* key sequence to return */
/* parse it up */
unsigned c = 0 ;
/* parse it up */
c = 0;
/* first, the META prefix */
if (*keyname == 'M' && *(keyname + 1) == '-') {
c = META;
keyname += 2;
/* first, the prefix META or ^X */
if( *keyname == 'M' && keyname[ 1] == '-') {
c = META ;
keyname += 2 ;
} else if( *keyname == '^' && keyname[ 1] == 'X') {
c = CTLX ;
keyname += 2 ;
}
/* next the function prefix */
if (*keyname == 'F' && *(keyname + 1) == 'N') {
c |= SPEC;
keyname += 2;
/* a control char? */
if( *keyname == '^' && keyname[ 1] != 0) {
c |= CTL_ ;
++keyname ;
}
/* control-x as well... (but not with FN) */
if (*keyname == '^' && *(keyname + 1) == 'X' && !(c & SPEC)) {
c |= CTLX;
keyname += 2;
}
/* a control char? */
if (*keyname == '^' && *(keyname + 1) != 0) {
c |= CONTROL;
++keyname;
}
if (*keyname < 32) {
c |= CONTROL;
*keyname += 'A';
/* next the function prefix */
if( *keyname == 'F' && keyname[ 1] == 'N') {
c |= SPEC ;
keyname += 2 ;
}
/* only one character left to parse */
if( !*keyname || keyname[1])
return ~0 ;
/* only way to redefine ^X is by quoting binary value */
if( *keyname < 32 || *keyname == 0x7F) {
c |= CTL_ ;
*keyname ^= 0x40 ;
} else if( c && !(c & SPEC)
&& *keyname >= 'a' && *keyname <= 'z')
/* make sure we are not lower case (not with function keys) */
if (*keyname >= 'a' && *keyname <= 'z' && !(c & SPEC))
*keyname -= 32;
*keyname -= 32 ;
/* the final sequence... */
/* the final sequence... */
c |= *keyname & 0xFFU ;
return c;
return c ;
}
/*
* string key name to binding name....
/* string key name to binding name....
*
* char *skey; name of keey to get binding for
* char *skey; name of key to get binding for
*/
char *transbind(char *skey)
{
char *bindname;
const char *transbind( char *skey) {
static const char failmsg[] = "ERROR" ;
bindname = getfname(getbind(stock(skey)));
if (bindname == NULL)
bindname = "ERROR";
return bindname;
unsigned c = stock( skey) ;
if( c == (unsigned) ~0)
return failmsg ;
else
return getfname( c, failmsg) ;
}
/* end of bind.c */

28
bind.h
View File

@ -1,23 +1,21 @@
/* bind.h -- bindable functions dealing with name and key bindings */
#ifndef _BIND_H_
#define _BIND_H_
#define APROP 1 /* Add code for Apropos command */
#include "names.h" /* BINDABLE() */
#if APROP
int apro( int f, int n) ;
#endif
/* Bindable uEMACS functions */
BINDABLE( apro) ;
BINDABLE( bindtokey) ;
BINDABLE( desbind) ;
BINDABLE( deskey) ;
BINDABLE( help) ;
BINDABLE( unbindkey) ;
/* Some global fuction declarations. */
typedef int (*fn_t)(int, int);
int help( int f, int n) ;
int deskey( int f, int n) ;
int bindtokey( int f, int n) ;
int unbindkey( int f, int n) ;
int desbind( int f, int n) ;
int startup( const char *fname) ;
fn_t getbind( unsigned keycode) ;
fn_t fncmatch( char *) ;
char *transbind( char *skey) ;
/* find a key to function association in the key to function mapping table */
const char *transbind( char *skey) ; /* by string representation of key */
#endif
/* end of bind.h */

View File

@ -1,170 +1,129 @@
/* bindable.h -- implements bindable.c */
/* bindable.c -- implements bindable.h */
#include "bindable.h"
#include <stdlib.h>
#include "defines.h"
#include "buffer.h"
#include "display.h"
#include "estruct.h"
#include "display.h" /* vttidy() */
#include "file.h"
#include "input.h"
#include "lock.h"
#include "mlout.h"
#include "terminal.h"
/*
* Fancy quit command, as implemented by Norm. If the any buffer has
* changed do a write on that buffer and exit emacs, otherwise simply exit.
/* Fancy quit command, as implemented by Norm. If any buffer has changed
do a write on that buffer and exit emacs, otherwise simply exit.
*/
int quickexit(int f, int n)
{
struct buffer *bp; /* scanning pointer to buffers */
struct buffer *oldcb; /* original current buffer */
int status;
oldcb = curbp; /* save in case we fail */
bp = bheadp;
while (bp != NULL) {
if ((bp->b_flag & BFCHG) != 0 /* Changed. */
&& (bp->b_flag & BFTRUNC) == 0 /* Not truncated P.K. */
&& (bp->b_flag & BFINVS) == 0) { /* Real. */
curbp = bp; /* make that buffer cur */
BINDABLE( quickexit) {
buffer_p oldcb = curbp ; /* save in case we fail */
for( buffer_p bp = bheadp ; bp != NULL ; bp = bp->b_bufp) {
if( (bp->b_flag & (BFCHG | BFTRUNC | BFINVS)) == BFCHG) {
/* Changed, Not truncated and real buffer */
curbp = bp ; /* make that buffer cur */
mloutfmt( "(Saving %s)", bp->b_fname) ;
#if PKCODE
#else
mloutstr( "\n") ;
#endif
if ((status = filesave(f, n)) != TRUE) {
curbp = oldcb; /* restore curbp */
return status;
int status = filesave( f, n) ;
if( status != TRUE) {
curbp = oldcb ; /* restore curbp */
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".
*/
int quit(int f, int n)
{
int s;
BINDABLE( quit) {
int s ; /* status of user query */
if (f != FALSE /* Argument forces it. */
if( f != FALSE /* Argument forces it. */
|| anycb() == FALSE /* All buffers clean. */
/* User says it's OK. */
|| (s =
mlyesno("Modified buffers exist. Leave anyway")) == TRUE) {
|| (s = mlyesno( "Modified buffers exist. Leave anyway")) == TRUE) {
#if (FILOCK && BSD) || SVR4
if (lockrel() != TRUE) {
TTputc('\n');
TTputc('\r');
TTclose();
TTkclose();
if( lockrel() != TRUE) {
TTputc('\n') ;
TTputc('\r') ;
TTclose() ;
TTkclose() ;
exit( EXIT_FAILURE) ;
}
#endif
vttidy();
if (f)
exit(n);
vttidy() ;
if( f)
exit( n) ;
else
exit( EXIT_SUCCESS) ;
}
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
* return.
*/
int ctlxlp(int f, int n)
{
if (kbdmode != STOP) {
mloutstr( "%Macro already active") ;
return FALSE;
}
BBINDABLE( ctlxlp) {
if( kbdmode != STOP)
return mloutfail( "%Macro already active") ;
mloutstr( "(Start macro)") ;
kbdptr = &kbdm[0];
kbdend = kbdptr;
kbdmode = RECORD;
return TRUE;
kbdptr = kbdm ;
kbdend = kbdptr ;
kbdmode = RECORD ;
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.
*/
int ctlxrp(int f, int n)
{
if (kbdmode == STOP) {
mloutstr( "%Macro not active") ;
return FALSE;
}
BBINDABLE( ctlxrp) {
if( kbdmode == STOP)
return mloutfail( "%Macro not active") ;
if (kbdmode == RECORD) {
mloutstr( "(End macro)") ;
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
* command gets an error. Return TRUE if all ok, else FALSE.
*/
int ctlxe(int f, int n)
{
if (kbdmode != STOP) {
mloutstr( "%Macro already active") ;
return FALSE;
}
if (n <= 0)
return TRUE;
kbdrep = n; /* remember how many times to execute */
kbdmode = PLAY; /* start us in play mode */
kbdptr = &kbdm[0]; /* at the beginning */
return TRUE;
BBINDABLE( ctlxe) {
if( kbdmode != STOP)
return mloutfail( "%Macro already active") ;
if( n <= 0)
return TRUE ;
kbdrep = n ; /* remember how many times to execute */
kbdmode = PLAY ; /* start us in play mode */
kbdptr = kbdm ; /* at the beginning */
return TRUE ;
}
/*
* Abort.
/* abort:
* Beep the beeper. Kill off any keyboard macro, etc., that is in progress.
* Sometimes called as a routine, to do general aborting of stuff.
*/
int ctrlg( int f, int n) {
BINDABLE( ctrlg) {
kbdmode = STOP ;
mloutfmt( "%B(Aborted)") ;
return ABORT ;
}
/* user function that does NOTHING */
int nullproc(int f, int n)
{
return TRUE;
}
/* dummy function for binding to meta prefix */
int metafn(int f, int n)
{
return TRUE;
}
/* dummy function for binding to control-x prefix */
int cex(int f, int n)
{
return TRUE;
}
/* dummy function for binding to universal-argument */
int unarg(int f, int n)
{
return TRUE;
}
/* end of bindable.c */

View File

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

View File

@ -67,3 +67,4 @@ set %D 0 # looking EAST
beginning-of-file
set $curline 3
set $curcol 1
unmark-buffer

499
buffer.c
View File

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

View File

@ -1,40 +1,43 @@
/* buffer.h -- buffer type and functions */
#ifndef _BUFFER_H_
#define _BUFFER_H_
#include "line.h"
#include "line.h" /* line_p */
#include "names.h" /* BINDABLE() */
/* 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 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.
*/
struct buffer {
struct buffer *b_bufp; /* Link to next struct buffer */
struct line *b_dotp; /* Link to "." struct line structure */
struct line *b_markp; /* The same as the above two, */
struct line *b_linep; /* Link to the header struct line */
int b_doto; /* Offset of "." in above struct line */
int b_marko; /* but for the "mark" */
int b_mode; /* editor mode of this buffer */
char b_active; /* window activated flag */
char b_nwnd; /* Count of windows on buffer */
char b_flag; /* Flags */
typedef struct buffer {
struct buffer *b_bufp ; /* Link to next struct buffer */
line_p b_dotp ; /* Link to "." struct line structure */
line_p b_markp ; /* The same as the above two, */
line_p b_linep ; /* Link to the header struct line */
int b_doto ; /* Offset of "." in above struct line */
int b_marko ; /* but for the "mark" */
int b_mode ; /* editor mode of this buffer */
char b_active ; /* window activated flag */
char b_nwnd ; /* Count of windows on buffer */
char b_flag ; /* Flags */
fname_t b_fname ; /* File name */
bname_t b_bname ; /* Buffer name */
};
} *buffer_p ;
extern struct buffer *curbp ; /* Current buffer */
extern struct buffer *bheadp ; /* Head of list of buffers */
extern struct buffer *blistp ; /* Buffer for C-X C-B */
extern buffer_p curbp ; /* Current buffer */
extern buffer_p bheadp ; /* Head of list of buffers */
extern buffer_p blistp ; /* Buffer for C-X C-B */
#define BFINVS 0x01 /* Internal invisable buffer */
#define BFCHG 0x02 /* Changed since last write */
@ -53,22 +56,27 @@ extern struct buffer *blistp ; /* Buffer for C-X C-B */
#define MDUTF8 0x0080 /* utf8 mode */
#define MDDOS 0x0100 /* CRLF eol mode */
extern const char *modename[] ; /* text names of modes */
extern const char *modename[ NUMMODES] ; /* text names of modes */
extern int gmode ; /* global editor mode */
int usebuffer( int f, int n) ;
int nextbuffer( int f, int n) ;
int swbuffer( struct buffer *bp) ;
int killbuffer( int f, int n) ;
int zotbuf( struct buffer *bp) ;
int namebuffer( int f, int n) ;
int listbuffers( int f, int n) ;
int anycb( void) ;
int bclear( struct buffer *bp) ;
int unmark( int f, int n) ;
/* Lookup a buffer by name. */
struct buffer *bfind( const char *bname, int cflag, int bflag) ;
/* Bindable functions */
BINDABLE( killbuffer) ;
BINDABLE( listbuffers) ;
BINDABLE( namebuffer) ;
BINDABLE( nextbuffer) ;
BINDABLE( unmark) ;
BINDABLE( usebuffer) ;
boolean anycb( void) ; /* Any changed buffer? */
int bclear( buffer_p bp) ; /* empty buffer */
int swbuffer( buffer_p bp) ; /* switch to buffer, make it current */
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
/* end of buffer.h */

View File

@ -1,9 +1,7 @@
/* defines.h -- */
#ifndef __DEFINES_H__
#define __DEFINES_H__
/* Must define one of
USG | BSD
*/
@ -15,11 +13,5 @@
#define NSTRING 128 /* # of bytes, string buffers */
#define CONTROL 0x01000000 /* Control flag, or'ed in */
#define META 0x02000000 /* Meta flag, or'ed in */
#define CTLX 0x04000000 /* ^X flag, or'ed in */
#define SPEC 0x08000000 /* special key (function keys) */
#endif
/* end of defines.h */

1441
display.c

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,12 @@
/* display.h -- display functionality */
#ifndef _DISPLAY_H_
#define _DISPLAY_H_
#include <stdarg.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 scrollcount ; /* number of lines to scroll */
@ -13,33 +15,32 @@ extern int disinp ; /* display input characters (echo) */
extern int gfcolor ; /* global forgrnd color (white) */
extern int gbcolor ; /* global backgrnd color (black) */
/* Bindable functions */
BINDABLE( upscreen) ;
void vtinit( void) ;
void vtfree( void) ;
void vttidy( void) ;
int upscreen( int f, int n) ;
int update( int force) ;
void updpos( void) ;
void upddex( void) ;
void updgar( void) ;
int updupd( int force) ;
boolean update( boolean force_f) ;
void upmode( void) ;
void movecursor( int row, int col) ;
void mlerase( void) ;
void vmlwrite( const char *fmt, va_list ap) ;
void mlwrite( const char *fmt, ...) ;
void ostring( char *s) ;
void ostring( const char *s) ;
void echoc( unicode_t c) ;
void echos( char *s) ;
void echos( const char *s) ;
void rubout( void) ;
void getscreensize( int *widthp, int *heightp) ;
#if UNIX
#include <signal.h>
#ifdef SIGWINCH
extern int chg_width, chg_height ;
# include <signal.h>
# ifdef SIGWINCH
extern int chg_width, chg_height ;
void sizesignal( int signr) ;
#endif
void sizesignal( int signr) ;
# endif
#endif
#endif
/* end of display.h */

363
ebind.c
View File

@ -1,363 +0,0 @@
/* ebind.c -- implements ebind.h */
#include "ebind.h"
/* ebind.c
*
* Initial default key to function bindings
*
* Modified by Petri Kutvonen
*/
#include <stdlib.h>
#include "basic.h"
#include "bind.h"
#include "estruct.h"
#include "bindable.h"
#include "buffer.h"
#include "eval.h"
#include "exec.h"
#include "file.h"
#include "isearch.h"
#include "line.h"
#include "random.h"
#include "region.h"
#include "search.h"
#include "spawn.h"
#include "window.h"
#include "word.h"
/*
* Command table.
* This table is *roughly* in ASCII order, left to right across the
* characters of the command. This explains the funny location of the
* control-X commands.
*/
struct key_tab keytab[NBINDS] = {
{CONTROL | '?', backdel},
{CONTROL | 'A', (fn_t) gotobol}
,
{CONTROL | 'B', (fn_t) backchar}
,
{CONTROL | 'C', insspace}
,
{CONTROL | 'D', forwdel}
,
{CONTROL | 'E', (fn_t) gotoeol}
,
{CONTROL | 'F', (fn_t) forwchar}
,
{CONTROL | 'G', ctrlg}
,
{CONTROL | 'H', backdel}
,
{CONTROL | 'I', insert_tab}
,
{CONTROL | 'J', indent}
,
{CONTROL | 'K', killtext}
,
{CONTROL | 'L', redraw}
,
{CONTROL | 'M', insert_newline}
,
{CONTROL | 'N', (fn_t) forwline}
,
{CONTROL | 'O', openline}
,
{CONTROL | 'P', (fn_t) backline}
,
{CONTROL | 'Q', quote}
,
{CONTROL | 'R', backsearch}
,
{CONTROL | 'S', forwsearch}
,
{CONTROL | 'T', (fn_t) twiddle}
,
{CONTROL | 'U', unarg}
,
{CONTROL | 'V', (fn_t) forwpage}
,
{CONTROL | 'W', killregion}
,
{CONTROL | 'X', cex}
,
{CONTROL | 'Y', yank}
,
{CONTROL | 'Z', (fn_t) backpage}
,
{CONTROL | ']', metafn}
,
{CTLX | CONTROL | 'B', listbuffers}
,
{CTLX | CONTROL | 'C', quit}
, /* Hard quit. */
#if PKCODE & AEDIT
{CTLX | CONTROL | 'A', detab}
,
#endif
#if PKCODE
{CTLX | CONTROL | 'D', filesave}
, /* alternative */
#else
#if AEDIT
{CTLX | CONTROL | 'D', detab}
,
#endif
#endif
#if AEDIT
{CTLX | CONTROL | 'E', entab}
,
#endif
{CTLX | CONTROL | 'F', filefind}
,
{CTLX | CONTROL | 'I', insfile}
,
{CTLX | CONTROL | 'L', lowerregion}
,
{CTLX | CONTROL | 'M', delmode}
,
{CTLX | CONTROL | 'N', mvdnwind}
,
{CTLX | CONTROL | 'O', deblank}
,
{CTLX | CONTROL | 'P', mvupwind}
,
{CTLX | CONTROL | 'R', fileread}
,
{CTLX | CONTROL | 'S', filesave}
,
#if AEDIT
{CTLX | CONTROL | 'T', trim}
,
#endif
{CTLX | CONTROL | 'U', upperregion}
,
{CTLX | CONTROL | 'V', viewfile}
,
{CTLX | CONTROL | 'W', filewrite}
,
{CTLX | CONTROL | 'X', (fn_t) swapmark}
,
{CTLX | CONTROL | 'Z', shrinkwind}
,
{CTLX | '?', deskey}
,
{CTLX | '!', spawn}
,
{CTLX | '@', pipecmd}
,
{CTLX | '#', filter_buffer}
,
{CTLX | '$', execprg}
,
{CTLX | '=', showcpos}
,
{CTLX | '(', ctlxlp}
,
{CTLX | ')', ctlxrp}
,
{CTLX | '^', enlargewind}
,
{CTLX | '0', delwind}
,
{CTLX | '1', onlywind}
,
{CTLX | '2', splitwind}
,
{CTLX | 'A', setvar}
,
{CTLX | 'B', usebuffer}
,
{CTLX | 'C', spawncli}
,
#if BSD | SVR4
{CTLX | 'D', bktoshell}
,
#endif
{CTLX | 'E', ctlxe}
,
{CTLX | 'F', setfillcol}
,
{CTLX | 'K', killbuffer}
,
{CTLX | 'M', setemode}
,
{CTLX | 'N', filename}
,
{CTLX | 'O', nextwind}
,
{CTLX | 'P', prevwind}
,
#if PKCODE
{CTLX | 'Q', quote}
, /* alternative */
#endif
#if ISRCH
{CTLX | 'R', risearch}
,
{CTLX | 'S', fisearch}
,
#endif
{CTLX | 'W', resize}
,
{CTLX | 'X', nextbuffer}
,
{CTLX | 'Z', enlargewind}
,
{META | CONTROL | '?', delbword},
#if WORDPRO
{META | CONTROL | 'C', wordcount}
,
#endif
#if PKCODE
{META | CONTROL | 'D', newsize}
,
#endif
#if PROC
{META | CONTROL | 'E', execproc}
,
#endif
#if CFENCE
{META | CONTROL | 'F', getfence}
,
#endif
{META | CONTROL | 'H', delbword}
,
{META | CONTROL | 'K', unbindkey}
,
{META | CONTROL | 'L', reposition}
,
{META | CONTROL | 'M', delgmode}
,
{META | CONTROL | 'N', namebuffer}
,
{META | CONTROL | 'R', qreplace}
,
{META | CONTROL | 'S', newsize}
,
{META | CONTROL | 'T', newwidth}
,
{META | CONTROL | 'V', scrnextdw}
,
#if WORDPRO
{META | CONTROL | 'W', killpara}
,
#endif
{META | CONTROL | 'Z', scrnextup}
,
{META | ' ', (fn_t) setmark}
,
{META | '?', help}
,
{META | '!', reposition}
,
{META | '.', (fn_t) setmark}
,
{META | '>', (fn_t) gotoeob}
,
{META | '<', (fn_t) gotobob}
,
{META | '~', unmark}
,
#if APROP
{META | 'A', apro}
,
#endif
{META | 'B', backword}
,
{META | 'C', capword}
,
{META | 'D', delfword}
,
{META | 'F', forwword}
,
{META | 'G', gotoline}
,
#if PKCODE
#if WORDPRO
{META | 'J', justpara}
,
#endif
#endif
{META | 'K', bindtokey}
,
{META | 'L', lowerword}
,
{META | 'M', setgmode}
,
#if WORDPRO
{META | 'N', gotoeop}
,
{META | 'P', gotobop}
,
{META | 'Q', fillpara}
,
#endif
{META | 'R', sreplace}
,
#if PKCODE
{META | 'S', forwhunt}
,
#else
#if BSD
{META | 'S', bktoshell}
,
#endif
#endif
{META | 'U', upperword}
,
{META | 'V', (fn_t) backpage}
,
{META | 'W', copyregion}
,
{META | 'X', namedcmd}
,
{META | 'Z', quickexit}
,
#if VT220
{SPEC | '1', (fn_t) gotobob /* fisearch */}
, /* VT220 keys */
{SPEC | '2', yank}
,
{SPEC | '3', forwdel /* killregion */}
,
{SPEC | '4', (fn_t) gotoeob /* setmark */}
,
{SPEC | '5', (fn_t) backpage}
,
{SPEC | '6', (fn_t) forwpage}
,
{SPEC | 'A', (fn_t) backline}
,
{SPEC | 'B', (fn_t) forwline}
,
{SPEC | 'C', (fn_t) forwchar}
,
{SPEC | 'D', (fn_t) backchar}
,
{SPEC | 'c', metafn}
,
{SPEC | 'd', (fn_t) backchar}
,
{SPEC | 'e', (fn_t) forwline}
,
{SPEC | 'f', (fn_t) gotobob}
,
{SPEC | 'h', help}
,
{SPEC | 'i', cex}
,
#endif
/* special internal bindings */
{ SPEC | META | 'W', wrapword }, /* called on word wrap */
{ SPEC | META | 'C', nullproc }, /* every command input */
{ SPEC | META | 'R', nullproc }, /* on file read */
{ SPEC | META | 'X', nullproc }, /* on window change P.K. */
{0, NULL}
};

View File

@ -1,9 +0,0 @@
/* Structure for the table of initial key bindings. */
struct key_tab {
unsigned k_code ; /* Key code */
int (*k_fp)( int, int) ; /* Routine to handle it */
} ;
#define NBINDS 256 /* max # of bound keys */
extern struct key_tab keytab[ NBINDS] ; /* key bind to functions table */

111
estruct.h
View File

@ -1,11 +1,8 @@
/* estruct.h -- */
#ifndef _ESTRUCT_H_
#define _ESTRUCT_H_
/* ESTRUCT.H
*
* Structure and preprocessor defines
/* Structure and preprocessor defines
*
* written by Dave G. Conroy
* modified by Steve Wilhite, George Jones
@ -13,9 +10,8 @@
* modified by Petri Kutvonen
*/
#ifdef MSDOS
#undef MSDOS
# undef MSDOS
#endif
/* Machine/OS definitions. */
@ -24,30 +20,30 @@
/* Make an intelligent guess about the target system. */
#if defined(BSD) || defined(sun) || defined(ultrix) || defined(__osf__)
#ifndef BSD
#define BSD 1 /* Berkeley UNIX */
#endif
#else
#define BSD 0
#endif
# if defined(BSD) || defined(sun) || defined(ultrix) || defined(__osf__)
# ifndef BSD
# define BSD 1 /* Berkeley UNIX */
# endif
# else
# define BSD 0
# endif
#if defined(SVR4) || defined(__linux__) /* ex. SunOS 5.3 */
#define SVR4 1
#define SYSV 1
#undef BSD
#endif
# if defined(SVR4) || defined(__linux__) /* ex. SunOS 5.3 */
# define SVR4 1
# define SYSV 1
# undef BSD
# endif
#if defined(SYSV) || defined(u3b2) || defined(_AIX) || (defined(i386) && defined(unix)) || defined( __unix__)
#define USG 1 /* System V UNIX */
#else
#define USG 0
#endif
# if defined(SYSV) || defined(u3b2) || defined(_AIX) || (defined(i386) && defined(unix)) || defined( __unix__)
# define USG 1 /* System V UNIX */
# else
# define USG 0
# endif
#else
# define BSD 0 /* UNIX BSD 4.2 and ULTRIX */
# define USG 1 /* UNIX system V */
#endif /*autoconf */
#endif /*autoconf || BSD || SYSV */
#define MSDOS 0 /* MS-DOS */
@ -62,54 +58,32 @@
#define RAMSIZE 0 /* dynamic RAM memory usage tracking */
#if RAMSIZE
#define RAMSHOW 1 /* auto dynamic RAM reporting */
# define RAMSHOW 1 /* auto dynamic RAM reporting */
#endif
#ifndef AUTOCONF
/* Special keyboard definitions */
#define VT220 0 /* Use keypad escapes P.K. */
#define VT100 0 /* Handle VT100 style keypad. */
/* Terminal Output definitions */
#define ANSI 0 /* ANSI escape sequences */
#define VT52 0 /* VT52 terminal (Zenith). */
#define TERMCAP 0 /* Use TERMCAP */
#define IBMPC 1 /* IBM-PC CGA/MONO/EGA driver */
# define TERMCAP 0 /* Use TERMCAP */
# define IBMPC 1 /* IBM-PC CGA/MONO/EGA driver */
#else
#define VT220 UNIX
#define VT100 0
#define ANSI 0
#define VT52 0
#define TERMCAP UNIX
#define IBMPC MSDOS
# define TERMCAP UNIX
# define IBMPC MSDOS
#endif /* Autoconf. */
/* Configuration options */
#define CFENCE 1 /* fench matching in CMODE */
#define VISMAC 0 /* update display during keyboard macros */
#ifndef AUTOCONF
#define COLOR 1 /* color commands and windows */
#define FILOCK 0 /* file locking under unix BSD 4.2 */
# define COLOR 1 /* color commands and windows */
# define FILOCK 0 /* file locking under unix BSD 4.2 */
#else
#define COLOR MSDOS
#ifdef SVR4
#define FILOCK 1
#else
#define FILOCK BSD
#endif
# define COLOR MSDOS
# ifdef SVR4
# define FILOCK 1
# else
# define FILOCK BSD
# endif
#endif /* Autoconf. */
#define CLEAN 0 /* de-alloc memory on exit */
@ -126,9 +100,9 @@
/* Define some ability flags. */
#if IBMPC
#define MEMMAP 1
# define MEMMAP 1
#else
#define MEMMAP 0
# define MEMMAP 0
#endif
#if USG | BSD
@ -140,11 +114,11 @@
/* Dynamic RAM tracking and reporting redefinitions */
#if RAMSIZE
#include <stdlib.h>
void *allocate( size_t size) ;
void release( void *ptr) ;
#define malloc allocate
#define free release
# include <stdlib.h>
void *allocate( size_t size) ;
void release( void *ptr) ;
# define malloc allocate
# define free release
#endif
/* De-allocate memory always on exit (if the operating system or
@ -152,11 +126,10 @@ void release( void *ptr) ;
*/
#if CLEAN
#define exit(a) cexit(a)
# define exit(a) cexit(a)
void cexit( int status) ;
void cexit( int status) ;
#endif
#endif
/* end of estruct.h */

38
eval.c
View File

@ -1,9 +1,7 @@
/* eval.c -- implements eval.h */
#include "eval.h"
/* eval.c
*
* Expression evaluation functions
/* Expression evaluation functions
*
* written 1986 by Daniel Lawrence
* modified by Petri Kutvonen
@ -35,8 +33,6 @@
#define MAXVARS 255
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
/* Macro argument token types */
#define TKNUL 0 /* end-of-string */
@ -212,7 +208,7 @@ static struct {
{ "and", UFAND | DYNAMIC }, /* logical and */
{ "asc", UFASCII | MONAMIC }, /* char to integer conversion */
{ "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 */
{ "bor", UFBOR | DYNAMIC }, /* bitwise or 9-10-87 jwm */
{ "bxo", UFBXOR | DYNAMIC }, /* bitwise xor 9-10-87 jwm */
@ -316,12 +312,12 @@ void varinit(void)
*
* @fname: name of function to evaluate.
*/
static char *gtfun( char *fname) {
static const char *gtfun( char *fname) {
unsigned fnum ; /* index to function to eval */
char *arg1 ; /* value of first argument */
char *arg2 ; /* value of second argument */
char *arg3 ; /* last argument */
char *retstr ; /* return value */
const char *retstr ; /* return value */
int low, high ; /* binary search indexes */
/* look the function up in the function table */
@ -799,14 +795,13 @@ static char *gtenv( char *vname) {
return errorm ;
}
/*
* set a variable
/* set a variable
*
* int f; default flag
* int n; numeric arg (can overide prompted value)
*/
int setvar(int f, int n)
{
BINDABLE( setvar) {
int status; /* status return */
struct variable_description vd; /* variable num/type */
char var[NVSIZE + 2]; /* name of variable to fetch %1234567890\0 */
@ -1206,7 +1201,7 @@ int is_it_cmd( char *token) {
*
* char *token; token to evaluate
*/
char *getval(char *token)
const char *getval(char *token)
{
int status; /* error return */
struct buffer *bp; /* temp buffer pointer */
@ -1468,28 +1463,25 @@ static void mlforce( char *s) {
discmd = oldcmd; /* and restore the original setting */
}
/*
* This function simply clears the message line,
* mainly for macro usage
/* This function simply clears the message line, mainly for macro usage
*
* int f, n; arguments ignored
*/
int clrmes( int f, int n) {
TBINDABLE( clrmes) {
mlforce( "") ;
return TRUE ;
}
/*
* This function writes a string on the message line
* mainly for macro usage
/* This function writes a string on the message line mainly for macro usage
*
* int f, n; arguments ignored
*/
int writemsg( int f, int n) {
int status ;
BINDABLE( writemsg) {
char *buf ; /* buffer to receive message into */
status = newmlarg( &buf, "Message to write: ", 0) ;
int status = newmlarg( &buf, "write-message: ", 0) ;
if( status == TRUE) {
/* write the message out */
mlforce( buf) ;

16
eval.h
View File

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

762
exec.c

File diff suppressed because it is too large Load Diff

109
exec.h
View File

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

117
execute.c
View File

@ -3,11 +3,11 @@
#define CLRMSG 0 /* space clears the message line with no insert */
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include "estruct.h"
#include "bind.h"
#include "random.h"
#include "display.h"
#include "file.h"
@ -78,7 +78,7 @@ static int insbrace( int n, int c) {
count = 1 ;
do {
if( boundry( curwp->w_dotp, curwp->w_doto, REVERSE)) {
if( boundary( curwp->w_dotp, curwp->w_doto, REVERSE)) {
/* at beginning of buffer, no match to be found */
curwp->w_dotp = oldlp ;
curwp->w_doto = oldoff ;
@ -166,7 +166,7 @@ static void fmatch( int ch) {
do {
/* At beginning of window or buffer, no match to be found */
if( curwp->w_dotp == toplp
|| boundry( curwp->w_dotp, curwp->w_doto, REVERSE))
|| boundary( curwp->w_dotp, curwp->w_doto, REVERSE))
break ;
backchar( FALSE, 1) ;
@ -202,21 +202,117 @@ static void fmatch( int ch) {
#endif
#if CFENCE
/*
* the cursor is moved to a matching fence
*
* int f, n; not used
*/
BINDABLE( getfence) {
struct line *oldlp; /* original line pointer */
int oldoff; /* and offset */
int sdir; /* direction of search (1/-1) */
int count; /* current fence level count */
char ch; /* fence type to match against */
char ofence; /* open fence */
char c; /* current character in scan */
/* save the original cursor position */
oldlp = curwp->w_dotp;
oldoff = curwp->w_doto;
/* get the current character */
if (oldoff == llength(oldlp))
ch = '\n';
else
ch = lgetc(oldlp, oldoff);
/* setup proper matching fence */
switch (ch) {
case '(':
ofence = ')';
sdir = FORWARD;
break;
case '{':
ofence = '}';
sdir = FORWARD;
break;
case '[':
ofence = ']';
sdir = FORWARD;
break;
case ')':
ofence = '(';
sdir = REVERSE;
break;
case '}':
ofence = '{';
sdir = REVERSE;
break;
case ']':
ofence = '[';
sdir = REVERSE;
break;
default:
TTbeep();
return FALSE;
}
/* scan until we find a match, or reach the end of file */
count = 1 ;
do {
if( boundary( curwp->w_dotp, curwp->w_doto, sdir)) {
/* at buffer limit, no match to be found */
/* restore the current position */
curwp->w_dotp = oldlp ;
curwp->w_doto = oldoff ;
TTbeep() ;
return FALSE ;
}
if( sdir == FORWARD)
forwchar( FALSE, 1) ;
else
backchar( FALSE, 1) ;
/* if no eol */
if( curwp->w_doto != llength(curwp->w_dotp)) {
c = curwbyte() ;
if( c == ch)
++count ;
else if( c == ofence)
--count ;
}
} while( count > 0) ;
/* we have a match, move the sucker */
curwp->w_flag |= WFMOVE ;
return TRUE ;
}
#endif
/*
* This is the general command execution routine. It handles the fake binding
* of all the keys to "self-insert". It also clears out the "thisflag" word,
* and arranges to move it to the "lastflag", so that the next command can
* look at it. Return the status of command.
*/
int execute( int c, int f, int n) {
int execute( unsigned c, int f, int n) {
int status ;
fn_t execfunc ;
/* if the keystroke is a bound function...do it */
execfunc = getbind( c) ;
if( execfunc != NULL) {
kbind_p ktp = getkeybinding( c) ;
if( ktp->k_code != 0) {
thisflag = 0 ;
assert( ktp->k_nbp != NULL) ;
char tag = bind_tag( ktp->k_nbp) ;
if( (tag & 1) && (curbp->b_mode & MDVIEW))
status = rdonly() ;
else {
fnp_t execfunc = ktp->k_nbp->n_func ;
status = execfunc( f, n) ;
}
lastflag = thisflag ;
return status ;
}
@ -330,11 +426,12 @@ void kbd_loop( void) {
newc = getcmd() ;
update( FALSE) ;
do {
fn_t execfunc ;
kbind_p ktp ;
fnp_t execfunc ;
if( c == newc
&& (execfunc = getbind( c)) != NULL
&& execfunc != insert_newline
&& (ktp = getkeybinding( c))->k_code == c
&& (execfunc = ktp->k_nbp->k_func) != insert_newline
&& execfunc != insert_tab)
newc = getcmd() ;
else

View File

@ -1,5 +1,19 @@
/* execute.h -- */
#ifndef _EXECUTE_H_
#define _EXECUTE_H_
#include "names.h" /* BINDABLE() */
extern int gasave ; /* global ASAVE size */
extern int gacount ; /* count until next ASAVE */
int execute( int c, int f, int n) ;
int execute( unsigned keycode, int f, int n) ;
void kbd_loop( void) ;
#define CFENCE 1 /* fence matching in CMODE */
#if CFENCE
BINDABLE( getfence) ;
#endif
#endif
/* end of execute.h */

312
file.c
View File

@ -1,16 +1,14 @@
/* file.c -- implements 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 "fileio.c".
*
* modified by Petri Kutvonen
/* 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
"fileio.c".
modified by Petri Kutvonen
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -64,21 +62,18 @@ boolean resterr( void) {
return FALSE ;
}
/*
* Read a file into the current
* buffer. This is really easy; all you do is
* find the name of the file, and call the standard
* "read a file into the current buffer" code.
* Bound to "C-X C-R".
/* Read a file into the current buffer. This is really easy; all you do is
* find the name of the file, and call the standard "read a file into the
* current buffer" code. Bound to C-X C-R read-file.
*/
int fileread( int f, int n) {
int status ;
BINDABLE( fileread) {
char *fname ;
if( restflag) /* don't allow this command if restricted */
return resterr() ;
status = newmlarg( &fname, "Read file: ", sizeof( fname_t)) ;
int status = newmlarg( &fname, "read-file: ", sizeof( fname_t)) ;
if( status == TRUE) {
status = readin( fname, TRUE) ;
free( fname) ;
@ -87,24 +82,20 @@ int fileread( int f, int n) {
return status ;
}
/*
* Insert a file into the current
* buffer. This is really easy; all you do is
* find the name of the file, and call the standard
* "insert a file into the current buffer" code.
* Bound to "C-X C-I".
/* Insert a file into the current buffer. This is really easy; all you do
* is find the name of the file, and call the standard "insert a file into
* the current buffer" code. Bound to C-X C-I insert-file.
*/
int insfile( int f, int n) {
int status ;
BINDABLE( insfile) {
char *fname ;
if( restflag) /* don't allow this command if restricted */
return resterr() ;
if( curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly() ; /* we are in read only mode */
assert( !(curbp->b_mode & MDVIEW)) ;
status = newmlarg( &fname, "Insert file: ", sizeof( fname_t)) ;
int status = newmlarg( &fname, "insert-file: ", sizeof( fname_t)) ;
if( status == TRUE) {
status = ifile( fname) ;
free( fname) ;
@ -116,23 +107,19 @@ int insfile( int f, int n) {
return reposition( TRUE, -1) ; /* Redraw with dot at bottom of window */
}
/*
* Select a file for editing.
* Look around to see if you can find the
* fine in another buffer; if you can find it
* just switch to the buffer. If you cannot find
* the file, create a new buffer, read in the
* text, and switch to the new buffer.
* Bound to C-X C-F.
/* Select a file for editing. Look around to see if you can find the file
* in another buffer; if you can find it just switch to the buffer. If you
* cannot find the file, create a new buffer, read in the text, and switch
* to the new buffer. Bound to C-X C-F find-file.
*/
int filefind( int f, int n) {
BINDABLE( filefind) {
char *fname ; /* file user wishes to find */
int status ; /* status return */
if( restflag) /* don't allow this command if restricted */
return resterr() ;
status = newmlarg( &fname, "Find file: ", sizeof( fname_t)) ;
int status = newmlarg( &fname, "find-file: ", sizeof( fname_t)) ;
if( status == TRUE) {
status = getfile( fname, TRUE) ;
free( fname) ;
@ -141,25 +128,24 @@ int filefind( int f, int n) {
return status ;
}
static void upd_mode( void) {
struct window *wp ;
/* Update mode lines */
for( wp = wheadp ; wp != NULL ; wp = wp->w_wndp)
/* Update mode lines of all windows displaying current buffer */
static void upd_mode( void) {
for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp)
if( wp->w_bufp == curbp)
wp->w_flag |= WFMODE ;
}
int viewfile( int f, int n) { /* visit a file in VIEW mode */
BINDABLE( viewfile) { /* visit a file in VIEW mode */
char *fname ; /* file user wishes to find */
int status ; /* status return */
if( restflag) /* don't allow this command if restricted */
return resterr() ;
status = newmlarg( &fname, "View file: ", sizeof( fname_t)) ;
int status = newmlarg( &fname, "view-file: ", sizeof( fname_t)) ;
if( status == TRUE) {
status = getfile(fname, FALSE) ;
status = getfile( fname, FALSE) ;
free( fname) ;
if( status == TRUE) { /* if we succeed, put it in view mode */
@ -171,14 +157,14 @@ int viewfile( int f, int n) { /* visit a file in VIEW mode */
return status ;
}
/*
* getfile()
/* getfile()
*
* char fname[]; file name to find
* boolean lockfl; check the file for locks?
*/
int getfile( const char *fname, boolean lockfl) {
struct buffer *bp;
buffer_p bp;
int s;
bname_t bname ; /* buffer name to put file */
@ -248,38 +234,34 @@ int getfile( const char *fname, boolean lockfl) {
return s;
}
/*
* Read file "fname" into the current buffer, blowing away any text
* found there. Called by both the read and find commands. Return
* the final status of the read. Also called by the mainline, to
* read in a file specified on the command line as an argument.
* The command bound to M-FNR is called after the buffer is set up
* and before it is read.
*
* char fname[]; name of file to read
* boolean lockfl; check for file locks?
/* Read file "fname" into the current buffer, blowing away any text found
there. Called by both the read and find commands. Return the final
status of the read. Also called by the mainline, to read in a file
specified on the command line as an argument. The command bound to
M-FNR is called after the buffer is set up and before it is read.
char fname[]; name of file to read
boolean lockfl; check for file locks?
*/
int readin(const char *fname, boolean lockfl)
{
struct window *wp;
struct buffer *bp;
int status ;
int readin( const char *fname, boolean lockfl) {
fio_code s ;
bp = curbp; /* Cheap. */
buffer_p bp = curbp ; /* Cheap. */
#if (FILOCK && BSD) || SVR4
if( lockfl && lockchk( fname) == ABORT) {
#if PKCODE
# if PKCODE
s = FIOFNF;
strcpy(bp->b_fname, "");
mloutstr( "(File in use)") ;
#else
# else
return ABORT;
#endif
# endif
} else
#endif
{
if( (status = bclear( bp)) != TRUE) /* Might be old. */
int status = bclear( bp) ;
if( status != TRUE) /* Might be old. */
return status ;
bp->b_flag &= ~(BFINVS | BFCHG);
@ -299,10 +281,10 @@ int readin(const char *fname, boolean lockfl)
/* read the file in */
mloutstr( "(Reading file)") ;
while ((s = ffgetline()) == FIOSUC) {
while( (s = ffgetline()) == FIOSUC) {
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) {
s = FIOMEM ; /* Keep message on the */
break ; /* display. */
@ -342,12 +324,11 @@ int readin(const char *fname, boolean lockfl)
if( fcode == FCODE_UTF_8)
curbp->b_mode |= MDUTF8 ;
if( s == FIOERR) {
errmsg = "I/O ERROR, " ;
curbp->b_flag |= BFTRUNC ;
} else if( s == FIOMEM) {
errmsg = "OUT OF MEMORY, " ;
if( s == FIOERR
|| s == FIOMEM) {
errmsg = (s == FIOERR) ? "I/O ERROR, " : "OUT OF MEMORY, " ;
curbp->b_flag |= BFTRUNC ;
curbp->b_mode |= MDVIEW ; /* force view mode as lost data */
} else
errmsg = "" ;
@ -355,52 +336,43 @@ int readin(const char *fname, boolean lockfl)
errmsg,
nline,
&"s"[ nline == 1],
codename[ fcode & (FCODE_MASK - 1)],
codename[ fcode],
eolname[ found_eol]) ;
ffclose() ; /* Ignore errors. */
}
}
for (wp = wheadp; wp != NULL; wp = wp->w_wndp) {
if (wp->w_bufp == curbp) {
wp->w_linep = lforw(curbp->b_linep);
wp->w_dotp = lforw(curbp->b_linep);
wp->w_doto = 0;
wp->w_markp = NULL;
wp->w_marko = 0;
wp->w_flag |= WFMODE | WFHARD;
for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) {
if( wp->w_bufp == curbp) {
wp->w_linep = lforw( curbp->b_linep) ;
wp->w_dotp = lforw(curbp->b_linep) ;
wp->w_doto = 0 ;
wp->w_markp = NULL ;
wp->w_marko = 0 ;
wp->w_flag |= WFMODE | WFHARD ;
}
}
return (s == FIOERR || s == FIOFNF) ? FALSE : TRUE ;
}
/*
* Take a file name, and from it
* fabricate a buffer name. This routine knows
* about the syntax of file names on the target system.
* I suppose that this information could be put in
* a better place than a line of code.
/* Take a file name, and from it fabricate a buffer name. This routine
knows about the syntax of file names on the target system. I suppose
that this information could be put in a better place than a line of
code.
*/
void makename( bname_t bname, const char *fname)
{
const char *cp1;
char *cp2;
void makename( bname_t bname, const char *fname) {
const char *cp1 = fname ;
for( const char *cp = cp1 ; *cp ; cp++)
if( *cp == '/')
cp1 = cp + 1 ;
cp1 = &fname[0];
while (*cp1 != 0)
++cp1;
while (cp1 != &fname[0] && cp1[-1] != '/')
--cp1;
cp2 = &bname[0];
char *cp2 = bname ;
while( *cp1 != 0 && *cp1 != ';') {
unicode_t c ;
int n ;
n = utf8_to_unicode( cp1, 0, 4, &c) ;
int n = utf8_to_unicode( cp1, 0, 4, &c) ;
if( cp2 + n <= &bname[ sizeof( bname_t) - 2]) /* 1 digit buffer name conflict [0..9] + EOS */
while( n--)
*cp2++ = *cp1++ ;
@ -408,50 +380,42 @@ void makename( bname_t bname, const char *fname)
break ;
}
*cp2 = 0;
*cp2 = 0 ;
}
/*
* make sure a buffer name is unique
/* make sure a buffer name is unique
*
* char *name; name to check on
*/
void unqname(char *name)
{
char *sp;
/* check to see if it is in the buffer list */
while (bfind(name, 0, FALSE) != NULL) {
void unqname( char *name) {
/* check to see if it is in the buffer list */
while( bfind( name, 0, FALSE) != NULL) {
/* go to the end of the name */
sp = name;
while (*sp)
++sp;
if (sp == name || (*(sp - 1) < '0' || *(sp - 1) > '8')) {
*sp++ = '0';
*sp = 0;
char *sp = name ;
while( *sp)
++sp ;
if( sp == name || (*(sp - 1) < '0' || *(sp - 1) > '8')) {
*sp++ = '0' ;
*sp = 0 ;
} else
*(--sp) += 1;
*(--sp) += 1 ;
}
}
/*
* Ask for a file name, and write the
* contents of the current buffer to that file.
* Update the remembered file name and clear the
* buffer changed flag. This handling of file names
* is different from the earlier versions, and
* is more compatible with Gosling EMACS than
* with ITS EMACS. Bound to "C-X C-W".
/* Ask for a file name, and write the content of the current buffer to that
* file. Update the remembered file name and clear the buffer changed
* flag. Bound to C-X C-W write-file.
*/
int filewrite( int f, int n) {
int status ;
BINDABLE( filewrite) {
char *fname ;
if( restflag) /* don't allow this command if restricted */
return resterr() ;
status = newmlarg( &fname, "Write file: ", sizeof( fname_t)) ;
int status = newmlarg( &fname, "write-file: ", sizeof( fname_t)) ;
if( status == TRUE) {
if( strlen( fname) > sizeof( fname_t) - 1)
status = FALSE ;
@ -467,42 +431,36 @@ int filewrite( int f, int n) {
return status ;
}
/*
* Save the contents of the current
* buffer in its associated file. Do nothing
* if nothing has changed (this may be a bug, not a
* feature). Error if there is no remembered file
* name for the buffer. Bound to "C-X C-S". May
* get called by "C-Z".
/* Save the content of the current buffer in its associated file. Do
nothing if nothing has changed (this may be a bug, not a feature).
Error if there is no remembered file name for the buffer. Bound to "C-X
C-S save-file". May get called by "M-Z quick-exit".
*/
int filesave( int f, int n) {
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
if ((curbp->b_flag & BFCHG) == 0) /* Return, no changes. */
return TRUE;
if (curbp->b_fname[0] == 0) { /* Must have a name. */
mloutstr( "No file name") ;
return FALSE;
BINDABLE( filesave) {
assert( !(curbp->b_mode & MDVIEW)) ;
if( (curbp->b_flag & BFCHG) == 0) /* Return, no changes. */
return TRUE ;
if( curbp->b_fname[0] == 0) { /* Must have a name. */
mloutfmt( "%BNo file name") ;
return FALSE ;
}
/* complain about truncated files */
if ((curbp->b_flag & BFTRUNC) != 0) {
if (mlyesno("Truncated file ... write it out") == FALSE) {
mloutstr( "(Aborted)") ;
return FALSE;
}
}
if( (curbp->b_flag & BFTRUNC) != 0
&& mlyesno( "Truncated file ... write it out") == FALSE)
return mloutfail( "(Aborted)") ;
return writeout( curbp->b_fname) ;
}
/*
* This function performs the details of file
* writing. Uses the file management routines in the
* "fileio.c" package. The number of lines written is
* displayed. Sadly, it looks inside a struct line; provide
* a macro for this. Most of the grief is error
* checking of some sort.
/* This function performs the details of file writing. Uses the file
management routines in the "fileio.c" package. The number of lines
written is displayed. Sadly, it looks inside a struct line; provide a
macro for this. Most of the grief is error checking of some sort.
*/
int writeout( const char *fn) {
fio_code s ;
@ -540,23 +498,20 @@ int writeout( const char *fn) {
return FALSE ;
}
/*
* The command allows the user
* to modify the file name associated with
* the current buffer. It is like the "f" command
* in UNIX "ed". The operation is simple; just zap
* the name in the buffer structure, and mark the windows
* as needing an update. You can type a blank line at the
* prompt if you wish.
/* The command allows the user to modify the file name associated with the
current buffer. It is like the "f" command in UNIX "ed". The operation
is simple; just zap the name in the buffer structure, and mark the
windows as needing an update. You can type a blank line at the prompt
if you wish. Bound to C-X N change-file-name.
*/
int filename( int f, int n) {
int status ;
BINDABLE( filename) {
char *fname ;
if( restflag) /* don't allow this command if restricted */
return resterr() ;
status = newmlarg( &fname, "Name: ", sizeof( fname_t)) ;
int status = newmlarg( &fname, "Name: ", sizeof( fname_t)) ;
if( status == ABORT)
return status ;
else if( status == FALSE)
@ -571,10 +526,9 @@ int filename( int f, int n) {
return TRUE ;
}
/*
* Insert file "fname" into the current
* buffer, Called by insert file command. Return the final
* status of the read.
/* Insert file "fname" into the current buffer, Called by insert file
command. Return the final status of the read.
*/
static int ifile( const char *fname) {
fio_code s ;
@ -649,3 +603,5 @@ static int ifile( const char *fname) {
return (s == FIOERR) ? FALSE : TRUE ;
}
/* end of file.c */

22
file.h
View File

@ -1,23 +1,27 @@
/* file.h -- file centric commands */
#ifndef _FILE_H_
#define _FILE_H_
#include "buffer.h"
#include "retcode.h"
#include "buffer.h" /* bname_t */
#include "names.h" /* BINDABLE() */
extern boolean restflag ; /* restricted use? */
boolean resterr( void) ; /* restricted error message */
int fileread( int f, int n) ;
int insfile( int f, int n) ;
int filefind( int f, int n) ;
int viewfile( int f, int n) ;
/* Bindable functions */
BINDABLE( filefind) ;
BINDABLE( fileread) ;
BINDABLE( filename) ;
BINDABLE( filesave) ;
BINDABLE( filewrite) ;
BINDABLE( insfile) ;
BINDABLE( viewfile) ;
int getfile( const char *fname, boolean lockfl) ;
int readin( const char *fname, boolean lockfl) ;
void makename( bname_t bname, const char *fname) ;
void unqname( char *name) ;
int filewrite( int f, int n) ;
int filesave( int f, int n) ;
int writeout( const char *fn) ;
int filename( int f, int n) ;
#endif
/* end of file.h */

View File

@ -1,13 +1,10 @@
/* fileio.c -- implements fileio.h */
#include "fileio.h"
/* FILEIO.C
*
* The routines in this file read and write ASCII files from the disk. All of
* the knowledge about files are here.
*
* modified by Petri Kutvonen
/* The routines in this file read and write ASCII files from the disk. All
of the knowledge about files are here.
modified by Petri Kutvonen
*/
#include <stdio.h>
@ -29,49 +26,45 @@ static FILE *ffp ; /* File pointer, all functions. */
static boolean eofflag ; /* end-of-file flag */
/*
* Open a file for reading.
*/
fio_code ffropen( const char *fn)
{
if ((ffp = fopen(fn, "r")) == NULL)
return FIOFNF;
eofflag = FALSE;
/* Open a file for reading. */
fio_code ffropen( const char *fn) {
eofflag = FALSE ;
ftype = FTYPE_NONE ;
fcode = FCODE_ASCII ;
return FIOSUC;
ffp = fopen( fn, "r") ;
return (ffp == NULL) ? FIOFNF : FIOSUC ;
}
/*
* Open a file for writing. Return TRUE if all is well, and FALSE on error
* (cannot create).
/* Open a file for writing. Return TRUE if all is well, and FALSE on error
(cannot create).
*/
fio_code ffwopen( const char *fn) {
ffp = fopen( fn, "w") ;
return (ffp == NULL) ? FIOERR : FIOSUC ;
}
/*
* Close a file. Should look at the status in all systems.
/* Close a file. Should look at the status in all systems.
*/
fio_code ffclose(void)
{
fio_code ffclose( void) {
/* free this since we do not need it anymore */
if (fline) {
free(fline);
fline = NULL;
if( fline) {
free( fline) ;
fline = NULL ;
}
eofflag = FALSE;
eofflag = FALSE ;
ftype = FTYPE_NONE ;
fcode = FCODE_ASCII ;
return (fclose( ffp) != FALSE) ? FIOERR : FIOSUC ;
}
/*
* Write a line to the already opened file. The "buf" points to the buffer,
* and the "nbuf" is its length, less the free newline. Return the status.
* Check only at the newline.
/* Write a line to the already opened file. The "buf" points to the
buffer, and the "nbuf" is its length, less the free newline. Return the
status. Check only at the newline.
*/
fio_code ffputline( char *buf, int nbuf, int dosflag) {
fwrite( buf, 1, nbuf, ffp) ;
@ -87,15 +80,13 @@ fio_code ffputline( char *buf, int nbuf, int dosflag) {
return FIOSUC ;
}
/*
* Read a line from a file, and store the bytes in the supplied buffer. The
* "nbuf" is the length of the buffer. Complain about long lines and lines
* at the end of the file that don't have a newline present. Check for I/O
* errors too. Return status.
/* Read a line from a file, and store the bytes in the supplied buffer.
The "nbuf" is the length of the buffer. Complain about long lines and
lines at the end of the file that don't have a newline present. Check
for I/O errors too. Return status.
*/
fio_code ffgetline( void) {
int c ; /* current character read */
int i ; /* current index into fline */
int lcode = FCODE_ASCII ; /* line encoding, defaults to ASCII */
/* if we are at the end...return it */
@ -114,7 +105,7 @@ fio_code ffgetline( void) {
return FIOMEM ;
/* read the line in */
i = 0 ;
int i = 0 ; /* current index into fline */
while( (c = fgetc( ffp)) != EOF && c != '\r' && c != '\n') {
/* if line is full, get more room */
if( i >= flen) {
@ -135,16 +126,15 @@ fio_code ffgetline( void) {
}
fpayload = i ;
lcode &= FCODE_MASK ;
if( lcode && (fcode != FCODE_MIXED)) { /* line contains extended chars */
if( lcode & 0x80 /* line contains extended chars */
&& (fcode != FCODE_MIXED)) {
/* Check if consistent UTF-8 encoding */
lcode = FCODE_ASCII ;
int pos = 0 ;
while( (pos < i) && (lcode != FCODE_MIXED)) {
unicode_t uc ;
int bytes ;
bytes = utf8_to_unicode( fline, pos, i, &uc) ;
int bytes = utf8_to_unicode( fline, pos, i, &uc) ;
pos += bytes ;
if( bytes > 1) /* Multi byte UTF-8 sequence */
lcode |= FCODE_UTF_8 ;
@ -176,3 +166,5 @@ fio_code ffgetline( void) {
return FIOSUC ;
}
/* end of fileio.c */

View File

@ -1,3 +1,4 @@
/* fileio.h -- file primitives */
#ifndef _FILEIO_H_
#define _FILEIO_H_
@ -16,10 +17,9 @@ typedef enum {
/* FTYPE_MIXED [ 3, 5, 6, 7] */
#define FCODE_ASCII 0
#define FCODE_MASK 0x80
#define FCODE_UTF_8 0x81
#define FCODE_EXTND 0x82
#define FCODE_MIXED 0x83
#define FCODE_UTF_8 1
#define FCODE_EXTND 2
#define FCODE_MIXED 3
extern char *fline ; /* dynamic return line */
extern int ftype ;
@ -33,3 +33,4 @@ fio_code ffropen( const char *fn) ;
fio_code ffwopen( const char *fn) ;
#endif
/* end of fileio.h */

View File

@ -61,3 +61,8 @@ set %NC &asc "█"
!endwhile
set $curline 3
set $curcol 1
select-buffer stack
unmark-buffer
select-buffer %thisbuf
unmark-buffer
delete-buffer stack

106
flook.c
View File

@ -1,85 +1,65 @@
/* flook.c -- implements flook.h */
#include "flook.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "defines.h"
#include "fileio.h"
/* possible names and paths of help files under different OSs */
/* possible names and paths of help files under different OSes */
const char *pathname[] = {
#if BSD | USG
".emacsrc",
"emacs.hlp",
#if PKCODE
# if PKCODE
"/usr/global/lib/", "/usr/local/bin/", "/usr/local/lib/",
#endif
# endif
"/usr/local/", "/usr/lib/", ""
#endif
} ;
#define PATHNAME_SIZE (sizeof pathname / sizeof pathname[ 0])
#define PATHTABLE_SIZE (sizeof pathname / sizeof pathname[ 0])
/*
* does <fname> exist on disk?
/* does <fname> exist on disk?
*
* char *fname; file to check for existance
*/
boolean fexist( const char *fname)
{
FILE *fp;
boolean fexist( const char *fname) {
FILE *fp = fopen( fname, "r") ;
if( fp == NULL)
return FALSE ;
else
fclose( fp) ;
/* try to open the file for reading */
fp = fopen(fname, "r");
/* if it fails, just return false! */
if (fp == NULL)
return FALSE;
/* otherwise, close it and report true */
fclose(fp);
return TRUE;
return TRUE ;
}
/*
* Look up the existance of a file along the normal or PATH
* environment variable. Look first in the HOME directory if
* asked and possible
*
* char *fname; base file name to search for
* boolean hflag; Look in the HOME environment variable first?
/* Look up the existence of a file along the normal or PATH environment
variable. Look first in the HOME directory if asked and possible.
char *fname; base file name to search for
boolean hflag; look in the HOME environment variable first?
*/
char *flook( const char *fname, boolean hflag)
{
unsigned i ; /* index */
int len ;
static char fspec[NSTRING]; /* full path spec to search */
char *flook( const char *fname, boolean hflag) {
static char fspec[ NSTRING] ; /* full path spec to search */
#if ENVFUNC
char *path; /* environmental PATH variable */
#endif
len = sizeof fspec - strlen( fname) - 1 ;
int len = sizeof fspec - strlen( fname) - 1 ;
if( len < 0)
return NULL ;
#if ENVFUNC
if (hflag) {
char *home; /* path to home directory */
home = getenv("HOME");
if (home != NULL) {
if( hflag) {
char *home = getenv( "HOME") ; /* path to home directory */
if( home != NULL) {
if( len > (int) strlen( home) + 1) {
/* build home dir file spec */
strcpy( fspec, home) ;
strcat(fspec, "/");
strcat(fspec, fname);
strcat( fspec, "/") ;
strcat( fspec, fname) ;
/* and try it out */
if( fexist( fspec))
@ -97,22 +77,19 @@ char *flook( const char *fname, boolean hflag)
}
#if ENVFUNC
#if USG | BSD
#define PATHCHR ':'
#else
#define PATHCHR ';'
#endif
# if USG | BSD
# define PATHCHR ':'
# else
# define PATHCHR ';'
# endif
/* get the PATH variable */
path = getenv("PATH");
if (path != NULL)
while (*path) {
char *sp; /* pointer into path spec */
int cnt ;
cnt = len ;
/* get the PATH variable */
char *path = getenv( "PATH") ; /* environmental PATH variable */
if( path != NULL)
while( *path) {
int cnt = len ;
/* build next possible file spec */
sp = fspec;
char *sp = fspec ; /* pointer into path spec */
while( *path && (*path != PATHCHR)) {
if( cnt-- > 0)
*sp++ = *path ;
@ -132,13 +109,13 @@ char *flook( const char *fname, boolean hflag)
return fspec ;
}
if (*path == PATHCHR)
++path;
if( *path == PATHCHR)
++path ;
}
#endif
/* look it up via the old table method */
for( i = 2; i < PATHNAME_SIZE ; i++)
for( unsigned i = 2 ; i < PATHTABLE_SIZE ; i++)
if( len >= (int) strlen( pathname[ i])) {
strcpy( fspec, pathname[ i]) ;
strcat( fspec, fname);
@ -148,6 +125,7 @@ char *flook( const char *fname, boolean hflag)
return fspec ;
}
return NULL; /* no such luck */
return NULL ; /* no such luck */
}
/* end of flook.c */

View File

@ -1,5 +1,8 @@
#include "retcode.h"
/* flook.h -- */
#ifndef _FLOOK_H_
#define _FLOOK_H_
#include "retcode.h" /* boolean */
#define rcfname pathname[ 0]
#define hlpfname pathname[ 1]
@ -10,3 +13,5 @@ extern const char *pathname[] ;
boolean fexist( const char *fname) ;
char *flook( const char *fname, boolean hflag) ;
#endif
/* end of flook.h */

View File

@ -1,241 +0,0 @@
/* ANSI.C
*
* The routines in this file provide support for ANSI style terminals
* over a serial line. The serial I/O services are provided by routines in
* "termio.c". It compiles into nothing if not an ANSI device.
*
* modified by Petri Kutvonen
*/
#define termdef 1 /* don't define "term" external */
#include <stdio.h>
#include "estruct.h"
#if ANSI
#define NROW 25 /* Screen size. */
#define NCOL 80 /* Edit if you want to. */
#if PKCODE
#define MROW 64
#endif
#define NPAUSE 100 /* # times thru update to pause */
#define MARGIN 8 /* size of minimim margin and */
#define SCRSIZ 64 /* scroll size for extended lines */
#define BEL 0x07 /* BEL character. */
#define ESC 0x1B /* ESC character. */
extern int ttopen(); /* Forward references. */
extern int ttgetc();
extern int ttputc();
extern int ttflush();
extern int ttclose();
extern int ansimove();
extern int ansieeol();
extern int ansieeop();
extern int ansibeep();
extern int ansiopen();
extern int ansirev();
extern int ansiclose();
extern int ansikopen();
extern int ansikclose();
extern int ansicres();
#if COLOR
extern int ansifcol();
extern int ansibcol();
int cfcolor = -1; /* current forground color */
int cbcolor = -1; /* current background color */
#endif
/*
* Standard terminal interface dispatch table. Most of the fields point into
* "termio" code.
*/
struct terminal term = {
#if PKCODE
MROW - 1,
#else
NROW - 1,
#endif
NROW - 1,
NCOL,
NCOL,
MARGIN,
SCRSIZ,
NPAUSE,
ansiopen,
ansiclose,
ansikopen,
ansikclose,
ttgetc,
ttputc,
ttflush,
ansimove,
ansieeol,
ansieeop,
ansibeep,
ansirev,
ansicres
#if COLOR
, ansifcol,
ansibcol
#endif
#if SCROLLCODE
, NULL
#endif
};
#if COLOR
ansifcol(color)
/* set the current output color */
int color; /* color to set */
{
if (color == cfcolor)
return;
ttputc(ESC);
ttputc('[');
ansiparm(color + 30);
ttputc('m');
cfcolor = color;
}
/* Set the current background color.
* color: color to set.
*/
void ansibcol(int color)
{
if (color == cbcolor)
return;
ttputc(ESC);
ttputc('[');
ansiparm(color + 40);
ttputc('m');
cbcolor = color;
}
#endif
ansimove(row, col)
{
ttputc(ESC);
ttputc('[');
ansiparm(row + 1);
ttputc(';');
ansiparm(col + 1);
ttputc('H');
}
void ansieeol(void)
{
ttputc(ESC);
ttputc('[');
ttputc('K');
}
void ansieeop(void)
{
#if COLOR
ansifcol(gfcolor);
ansibcol(gbcolor);
#endif
ttputc(ESC);
ttputc('[');
ttputc('J');
}
/* Change reverse video state.
* state: TRUE = reverse, FALSE = normal
*/
void ansirev(int state)
{
#if COLOR
int ftmp, btmp; /* temporaries for colors */
#endif
ttputc(ESC);
ttputc('[');
ttputc(state ? '7' : '0');
ttputc('m');
#if COLOR
if (state == FALSE) {
ftmp = cfcolor;
btmp = cbcolor;
cfcolor = -1;
cbcolor = -1;
ansifcol(ftmp);
ansibcol(btmp);
}
#endif
}
/* Change screen resolution. */
int ansicres()
{
return TRUE;
}
void ansibeep(void)
{
ttputc(BEL);
ttflush();
}
void ansiparm(int n)
{
int q, r;
q = n / 10;
if (q != 0) {
r = q / 10;
if (r != 0) {
ttputc((r % 10) + '0');
}
ttputc((q % 10) + '0');
}
ttputc((n % 10) + '0');
}
void ansiopen(void)
{
#if V7 | USG | BSD
char *cp;
if ((cp = getenv("TERM")) == NULL) {
puts("Shell variable TERM not defined!");
exit(1);
}
if (strcmp(cp, "vt100") != 0) {
puts("Terminal type not 'vt100'!");
exit(1);
}
#endif
strcpy(sres, "NORMAL");
revexist = TRUE;
ttopen();
}
void ansiclose(void)
{
#if COLOR
ansifcol(7);
ansibcol(0);
#endif
ttclose();
}
/* Open the keyboard (a noop here). */
void ansikopen(void)
{
}
/* Close the keyboard (a noop here). */
void ansikclose(void)
{
}
#endif

View File

@ -1,494 +0,0 @@
/* ibmpc.c
*
* The routines in this file provide support for the IBM-PC and other
* compatible terminals. It goes directly to the graphics RAM to do
* screen output. It compiles into nothing if not an IBM-PC driver
* Supported monitor cards include CGA, MONO and EGA.
*
* modified by Petri Kutvonen
*/
#define termdef 1 /* don't define "term" external */
#include <stdio.h>
#include "estruct.h"
#if IBMPC
#if PKCODE
#define NROW 50
#else
#define NROW 43 /* Max Screen size. */
#endif
#define NCOL 80 /* Edit if you want to. */
#define MARGIN 8 /* size of minimim margin and */
#define SCRSIZ 64 /* scroll size for extended lines */
#define NPAUSE 200 /* # times thru update to pause */
#define BEL 0x07 /* BEL character. */
#define ESC 0x1B /* ESC character. */
#define SPACE 32 /* space character */
#define SCADC 0xb8000000L /* CGA address of screen RAM */
#define SCADM 0xb0000000L /* MONO address of screen RAM */
#define SCADE 0xb8000000L /* EGA address of screen RAM */
#define MONOCRSR 0x0B0D /* monochrome cursor */
#define CGACRSR 0x0607 /* CGA cursor */
#define EGACRSR 0x0709 /* EGA cursor */
#define CDCGA 0 /* color graphics card */
#define CDMONO 1 /* monochrome text card */
#define CDEGA 2 /* EGA color adapter */
#if PKCODE
#define CDVGA 3
#endif
#define CDSENSE 9 /* detect the card type */
#if PKCODE
#define NDRIVE 4
#else
#define NDRIVE 3 /* number of screen drivers */
#endif
int dtype = -1; /* current display type */
char drvname[][8] = { /* screen resolution names */
"CGA", "MONO", "EGA"
#if PKCODE
, "VGA"
#endif
};
long scadd; /* address of screen ram */
int *scptr[NROW]; /* pointer to screen lines */
unsigned int sline[NCOL]; /* screen line image */
int egaexist = FALSE; /* is an EGA card available? */
extern union REGS rg; /* cpu register for use of DOS calls */
extern int ttopen(); /* Forward references. */
extern int ttgetc();
extern int ttputc();
extern int ttflush();
extern int ttclose();
extern int ibmmove();
extern int ibmeeol();
extern int ibmeeop();
extern int ibmbeep();
extern int ibmopen();
extern int ibmrev();
extern int ibmcres();
extern int ibmclose();
extern int ibmputc();
extern int ibmkopen();
extern int ibmkclose();
#if COLOR
extern int ibmfcol();
extern int ibmbcol();
extern int ibmscroll_reg();
int cfcolor = -1; /* current forground color */
int cbcolor = -1; /* current background color */
int ctrans[] = /* ansi to ibm color translation table */
#if PKCODE
{ 0, 4, 2, 6, 1, 5, 3, 7, 15 };
#else
{ 0, 4, 2, 6, 1, 5, 3, 7 };
#endif
#endif
/*
* Standard terminal interface dispatch table. Most of the fields point into
* "termio" code.
*/
struct terminal term = {
NROW - 1,
NROW - 1,
NCOL,
NCOL,
MARGIN,
SCRSIZ,
NPAUSE,
ibmopen,
ibmclose,
ibmkopen,
ibmkclose,
ttgetc,
ibmputc,
ttflush,
ibmmove,
ibmeeol,
ibmeeop,
ibmbeep,
ibmrev,
ibmcres
#if COLOR
, ibmfcol,
ibmbcol
#endif
#if SCROLLCODE
, ibmscroll_reg
#endif
};
#if COLOR
/* Set the current output color.
*
* @color: color to set.
*/
void ibmfcol(int color)
{
cfcolor = ctrans[color];
}
/* Set the current background color.
*
* @color: color to set.
*/
void ibmbcol(int color)
{
cbcolor = ctrans[color];
}
#endif
void ibmmove(int row, int col)
{
rg.h.ah = 2; /* set cursor position function code */
rg.h.dl = col;
rg.h.dh = row;
rg.h.bh = 0; /* set screen page number */
int86(0x10, &rg, &rg);
}
void ibmeeol(void)
{ /* erase to the end of the line */
unsigned int attr; /* attribute byte mask to place in RAM */
unsigned int *lnptr; /* pointer to the destination line */
int i;
int ccol; /* current column cursor lives */
int crow; /* row */
/* find the current cursor position */
rg.h.ah = 3; /* read cursor position function code */
rg.h.bh = 0; /* current video page */
int86(0x10, &rg, &rg);
ccol = rg.h.dl; /* record current column */
crow = rg.h.dh; /* and row */
/* build the attribute byte and setup the screen pointer */
#if COLOR
if (dtype != CDMONO)
attr = (((cbcolor & 15) << 4) | (cfcolor & 15)) << 8;
else
attr = 0x0700;
#else
attr = 0x0700;
#endif
lnptr = &sline[0];
for (i = 0; i < term.t_ncol; i++)
*lnptr++ = SPACE | attr;
if (flickcode && (dtype == CDCGA)) {
/* wait for vertical retrace to be off */
while ((inp(0x3da) & 8));
/* and to be back on */
while ((inp(0x3da) & 8) == 0);
}
/* and send the string out */
movmem(&sline[0], scptr[crow] + ccol, (term.t_ncol - ccol) * 2);
}
/* Put a character at the current position in the current colors */
void ibmputc(int ch)
{
rg.h.ah = 14; /* write char to screen with current attrs */
rg.h.al = ch;
#if COLOR
if (dtype != CDMONO)
rg.h.bl = cfcolor;
else
rg.h.bl = 0x07;
#else
rg.h.bl = 0x07;
#endif
int86(0x10, &rg, &rg);
}
void ibmeeop(void)
{
int attr; /* attribute to fill screen with */
rg.h.ah = 6; /* scroll page up function code */
rg.h.al = 0; /* # lines to scroll (clear it) */
rg.x.cx = 0; /* upper left corner of scroll */
rg.x.dx = (term.t_nrow << 8) | (term.t_ncol - 1);
/* lower right corner of scroll */
#if COLOR
if (dtype != CDMONO)
attr =
((ctrans[gbcolor] & 15) << 4) | (ctrans[gfcolor] & 15);
else
attr = 0;
#else
attr = 0;
#endif
rg.h.bh = attr;
int86(0x10, &rg, &rg);
}
/* Change reverse video state.
*
* @state: TRUE = reverse, FALSE = normal.
*/
void ibmrev(int state)
{
/* This never gets used under the IBM-PC driver */
}
/* Change screen resolution.
*
* @res: resolution to change to.
*/
void ibmcres(char *res)
{
int i;
for (i = 0; i < NDRIVE; i++) {
if (strcmp(res, drvname[i]) == 0) {
scinit(i);
return TRUE;
}
}
return FALSE;
}
#if SCROLLCODE
/* Move howmany lines starting at from to to. */
void ibmscroll_reg(from, to, howmany)
{
int i;
if (to < from) {
for (i = 0; i < howmany; i++) {
movmem(scptr[from + i], scptr[to + i],
term.t_ncol * 2);
}
}
else if (to > from) {
for (i = howmany - 1; i >= 0; i--) {
movmem(scptr[from + i], scptr[to + i],
term.t_ncol * 2);
}
}
}
#endif
void ibmbeep(void)
{
bdos(6, BEL, 0);
}
void ibmopen(void)
{
scinit(CDSENSE);
revexist = TRUE;
ttopen();
}
void ibmclose(void)
{
#if COLOR
ibmfcol(7);
ibmbcol(0);
#endif
/* if we had the EGA open... close it */
if (dtype == CDEGA)
egaclose();
#if PKCODE
if (dtype == CDVGA)
egaclose();
#endif
ttclose();
}
/* Open the keyboard. */
void ibmkopen(void)
{
}
/* Close the keyboard. */
void ibmkclose(void)
{
}
/* Initialize the screen head pointers.
*
* @type: type of adapter to init for.
*/
static int scinit(int type)
{
union {
long laddr; /* long form of address */
int *paddr; /* pointer form of address */
} addr;
int i;
/* if asked...find out what display is connected */
if (type == CDSENSE)
type = getboard();
/* if we have nothing to do....don't do it */
if (dtype == type)
return TRUE;
/* if we try to switch to EGA and there is none, don't */
if (type == CDEGA && egaexist != TRUE)
return FALSE;
/* if we had the EGA open... close it */
if (dtype == CDEGA)
egaclose();
#if PKCODE
if (dtype == CDVGA)
egaclose();
#endif
/* and set up the various parameters as needed */
switch (type) {
case CDMONO: /* Monochrome adapter */
scadd = SCADM;
newsize(TRUE, 25);
break;
case CDCGA: /* Color graphics adapter */
scadd = SCADC;
newsize(TRUE, 25);
break;
case CDEGA: /* Enhanced graphics adapter */
scadd = SCADE;
egaopen();
newsize(TRUE, 43);
break;
case CDVGA: /* Enhanced graphics adapter */
scadd = SCADE;
egaopen();
newsize(TRUE, 50);
break;
}
/* reset the $sres environment variable */
strcpy(sres, drvname[type]);
dtype = type;
/* initialize the screen pointer array */
for (i = 0; i < NROW; i++) {
addr.laddr = scadd + (long) (NCOL * i * 2);
scptr[i] = addr.paddr;
}
return TRUE;
}
/* getboard: Determine which type of display board is attached.
Current known types include:
CDMONO Monochrome graphics adapter
CDCGA Color Graphics Adapter
CDEGA Extended graphics Adapter
*/
/* getboard: Detect the current display adapter
if MONO set to MONO
CGA set to CGA EGAexist = FALSE
EGA set to CGA EGAexist = TRUE
*/
int getboard(void)
{
int type; /* board type to return */
type = CDCGA;
int86(0x11, &rg, &rg);
if ((((rg.x.ax >> 4) & 3) == 3))
type = CDMONO;
/* test if EGA present */
rg.x.ax = 0x1200;
rg.x.bx = 0xff10;
int86(0x10, &rg, &rg); /* If EGA, bh=0-1 and bl=0-3 */
egaexist = !(rg.x.bx & 0xfefc); /* Yes, it's EGA */
return type;
}
/* init the computer to work with the EGA */
void egaopen(void)
{
/* put the beast into EGA 43 row mode */
rg.x.ax = 3;
int86(16, &rg, &rg);
rg.h.ah = 17; /* set char. generator function code */
rg.h.al = 18; /* to 8 by 8 double dot ROM */
rg.h.bl = 0; /* block 0 */
int86(16, &rg, &rg);
rg.h.ah = 18; /* alternate select function code */
rg.h.al = 0; /* clear AL for no good reason */
rg.h.bl = 32; /* alt. print screen routine */
int86(16, &rg, &rg);
rg.h.ah = 1; /* set cursor size function code */
rg.x.cx = 0x0607; /* turn cursor on code */
int86(0x10, &rg, &rg);
outp(0x3d4, 10); /* video bios bug patch */
outp(0x3d5, 6);
}
void egaclose(void)
{
/* put the beast into 80 column mode */
rg.x.ax = 3;
int86(16, &rg, &rg);
}
/* Write a line out.
*
* @row: row of screen to place outstr on.
* @outstr: string to write out (must be term.t_ncol long).
* @forg: forground color of string to write.
* @bacg: background color.
*/
void scwrite(int row, char *outstr, int forg, int bacg)
{
unsigned int attr; /* attribute byte mask to place in RAM */
unsigned int *lnptr; /* pointer to the destination line */
int i;
/* build the attribute byte and setup the screen pointer */
#if COLOR
if (dtype != CDMONO)
attr = (((ctrans[bacg] & 15) << 4) | (ctrans[forg] & 15)) << 8;
else
attr = (((bacg & 15) << 4) | (forg & 15)) << 8;
#else
attr = (((bacg & 15) << 4) | (forg & 15)) << 8;
#endif
lnptr = &sline[0];
for (i = 0; i < term.t_ncol; i++)
*lnptr++ = (outstr[i] & 255) | attr;
if (flickcode && (dtype == CDCGA)) {
/* wait for vertical retrace to be off */
while ((inp(0x3da) & 8));
/* and to be back on */
while ((inp(0x3da) & 8) == 0);
}
/* and send the string out */
movmem(&sline[0], scptr[row], term.t_ncol * 2);
}
#endif

View File

@ -1,197 +0,0 @@
/* mingw32.c -- */
#ifdef MINGW32
#include "termio.h"
#include "terminal.h"
#include <errno.h>
#include <io.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include "utf8.h"
#include "wscreen.h"
static void vv( void) {}
static void vi( int i) {}
static int is( char *s) { return *s ; }
static void ttmove( int l, int c) ;
#define MARGIN 8
#define SCRSIZ 64
#define NPAUSE 10 /* # times thru update to pause. */
struct terminal term = {
24, /* These four values are set dynamically at open time. */
24,
80,
80,
MARGIN,
SCRSIZ,
NPAUSE,
ttopen,
#if PKCODE
ttclose,
#else
ttclose,
#endif
vv, /* ttkopen, */
vv, /* ttkclose, */
ttgetc,
ttputc,
ttflush,
ttmove,
vv, /* tteeol, */
vv, /* tteeop, */
vv, /* ttbeep, */
vi, /* ttrev, */
is /* ttcres */
#if COLOR
, iv, /* ttfcol, */
iv /* ttbcol */
#endif
#if SCROLLCODE
, NULL /* set dynamically at open time */
#endif
} ;
int ttrow ; /* Row location of HW cursor */
int ttcol ; /* Column location of HW cursor */
boolean eolexist = TRUE ; /* does clear to EOL exist? */
boolean revexist = FALSE ; /* does reverse video exist? */
boolean sgarbf = TRUE ; /* State of screen unknown */
char sres[ 16] ; /* Current screen resolution. */
/* NORMAL, CGA, EGA, VGA */
void ttopen( void) {
winit() ;
wcls() ;
term.t_mrow = term.t_nrow = wbottom() - wtop() ;
term.t_mcol = term.t_ncol = wright() - wleft() + 1 ;
wtitle( "uEMACS") ;
}
void ttclose( void) {
}
int ttputc( unicode_t c) {
char utf8[ 6] ;
int bytes ;
bytes = unicode_to_utf8( c, utf8) ;
fwrite( utf8, 1, bytes, stdout);
return 0 ;
}
void ttflush( void) {
int status ;
status = fflush( stdout);
while( status < 0 && errno == EAGAIN) {
_sleep( 1) ;
status = fflush( stdout) ;
}
if( status < 0)
exit( 15) ;
}
int ttgetc( void) {
static char buffer[ 32] ;
static int pending ;
unicode_t c ;
int count, bytes = 1, expected ;
count = pending ;
if( !count) {
count = read( 0, buffer, sizeof( buffer)) ;
if( count <= 0)
return 0 ;
pending = count ;
}
c = (unsigned char) buffer[ 0] ;
if( c >= 32 && c < 128)
goto done ;
/*
* Lazy. We don't bother calculating the exact
* expected length. We want at least two characters
* for the special character case (ESC+[) and for
* the normal short UTF8 sequence that starts with
* the 110xxxxx pattern.
*
* But if we have any of the other patterns, just
* try to get more characters. At worst, that will
* just result in a barely perceptible 0.1 second
* delay for some *very* unusual utf8 character
* input.
*/
expected = 2 ;
if( (c & 0xe0) == 0xe0)
expected = 6 ;
/* Special character - try to fill buffer */
if( count < expected) {
int n;
#if 0
ntermios.c_cc[VMIN] = 0;
ntermios.c_cc[VTIME] = 1; /* A .1 second lag */
tcsetattr(0, TCSANOW, &ntermios);
#endif
n = read(0, buffer + count, sizeof(buffer) - count);
/* Undo timeout */
#if 0
ntermios.c_cc[VMIN] = 1;
ntermios.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &ntermios);
#endif
if (n > 0)
pending += n;
}
if( pending > 1) {
unsigned char second = buffer[1];
/* Turn ESC+'[' into CSI */
if (c == 27 && second == '[') {
bytes = 2;
c = 128+27;
goto done;
}
}
bytes = utf8_to_unicode( buffer, 0, pending, &c) ;
done:
pending -= bytes ;
memmove( buffer, buffer+bytes, pending) ;
return c ;
}
int typahead( void) {
int x ; /* holds # of pending chars */
#ifdef FIONREAD
if( ioctl( 0, FIONREAD, &x) < 0)
#endif
x = 0 ;
return x ;
}
static void ttmove( int l, int c) {
wgoxy( c, l) ;
}
#else
typedef void _pedantic_empty_translation_unit ;
#endif
/* end of mingw32.c */

View File

@ -1,488 +0,0 @@
/* VMSVT.C
*
* Advanced VMS terminal driver
*
* Knows about any terminal defined in SMGTERMS.TXT and TERMTABLE.TXT
* located in SYS$SYSTEM.
*
* Author: Curtis Smith
* modified by Petri Kutvonen
*/
#include <stdio.h> /* Standard I/O package */
#include "estruct.h" /* Emacs' structures */
#if VMSVT
#include <descrip.h> /* Descriptor definitions */
/* These would normally come from iodef.h and ttdef.h */
#define IO$_SENSEMODE 0x27 /* Sense mode of terminal */
#define TT$_UNKNOWN 0x00 /* Unknown terminal */
#define TT$_VT100 96
/** Forward references **/
int vmsopen(), ttclose(), vmskopen(), vmskclose(), ttgetc(), ttputc();
int ttflush(), vmsmove(), vmseeol(), vmseeop(), vmsbeep(), vmsrev();
int vmscres();
extern int eolexist, revexist;
extern char sres[];
#if COLOR
int vmsfcol(), vmsbcol();
#endif
/** SMG stuff **/
static char *begin_reverse, *end_reverse, *erase_to_end_line;
static char *erase_whole_display;
static int termtype;
#define SMG$K_BEGIN_REVERSE 0x1bf
#define SMG$K_END_REVERSE 0x1d6
#define SMG$K_SET_CURSOR_ABS 0x23a
#define SMG$K_ERASE_WHOLE_DISPLAY 0x1da
#define SMG$K_ERASE_TO_END_LINE 0x1d9
#if SCROLLCODE
#define SMG$K_SCROLL_FORWARD 561 /* from sys$library:smgtrmptr.h */
#define SMG$K_SCROLL_REVERSE 562
#define SMG$K_SET_SCROLL_REGION 572
static char *scroll_forward, *scroll_reverse;
#endif
/* Dispatch table. All hard fields just point into the terminal I/O code. */
struct terminal term = {
#if PKCODE
MAXROW,
#else
24 - 1, /* Max number of rows allowable */
#endif
/* Filled in */ -1,
/* Current number of rows used */
MAXCOL, /* Max number of columns */
/* Filled in */ 0,
/* Current number of columns */
64, /* Min margin for extended lines */
8, /* Size of scroll region */
100, /* # times thru update to pause */
vmsopen, /* Open terminal at the start */
ttclose, /* Close terminal at end */
vmskopen, /* Open keyboard */
vmskclose, /* Close keyboard */
ttgetc, /* Get character from keyboard */
ttputc, /* Put character to display */
ttflush, /* Flush output buffers */
vmsmove, /* Move cursor, origin 0 */
vmseeol, /* Erase to end of line */
vmseeop, /* Erase to end of page */
vmsbeep, /* Beep */
vmsrev, /* Set reverse video state */
vmscres /* Change screen resolution */
#if COLOR
, vmsfcol, /* Set forground color */
vmsbcol /* Set background color */
#endif
#if SCROLLCODE
, NULL
#endif
};
/***
* ttputs - Send a string to ttputc
*
* Nothing returned
***/
ttputs(string)
char *string; /* String to write */
{
if (string)
while (*string != '\0')
ttputc(*string++);
}
/***
* vmsmove - Move the cursor (0 origin)
*
* Nothing returned
***/
vmsmove(row, col)
int row; /* Row position */
int col; /* Column position */
{
char buffer[32];
int ret_length;
static int request_code = SMG$K_SET_CURSOR_ABS;
static int max_buffer_length = sizeof(buffer);
static int arg_list[3] = { 2 };
char *cp;
int i;
/* Set the arguments into the arg_list array
* SMG assumes the row/column positions are 1 based (boo!)
*/
arg_list[1] = row + 1;
arg_list[2] = col + 1;
if ((smg$get_term_data( /* Get terminal data */
&termtype, /* Terminal table address */
&request_code, /* Request code */
&max_buffer_length, /* Maximum buffer length */
&ret_length, /* Return length */
buffer, /* Capability data buffer */
arg_list)
/* Argument list array */
/* We'll know soon enough if this doesn't work */
&1) == 0) {
ttputs("OOPS");
return;
}
/* Send out resulting sequence */
i = ret_length;
cp = buffer;
while (i-- > 0)
ttputc(*cp++);
}
#if SCROLLCODE
vmsscroll_reg(from, to, howmany)
{
int i;
if (to == from)
return;
if (to < from) {
vmsscrollregion(to, from + howmany - 1);
vmsmove(from + howmany - 1, 0);
for (i = from - to; i > 0; i--)
ttputs(scroll_forward);
} else { /* from < to */
vmsscrollregion(from, to + howmany - 1);
vmsmove(from, 0);
for (i = to - from; i > 0; i--)
ttputs(scroll_reverse);
}
vmsscrollregion(-1, -1);
}
vmsscrollregion(top, bot)
int top; /* Top position */
int bot; /* Bottom position */
{
char buffer[32];
int ret_length;
static int request_code = SMG$K_SET_SCROLL_REGION;
static int max_buffer_length = sizeof(buffer);
static int arg_list[3] = { 2 };
char *cp;
int i;
/* Set the arguments into the arg_list array
* SMG assumes the row/column positions are 1 based (boo!)
*/
arg_list[1] = top + 1;
arg_list[2] = bot + 1;
if ((smg$get_term_data( /* Get terminal data */
&termtype, /* Terminal table address */
&request_code, /* Request code */
&max_buffer_length, /* Maximum buffer length */
&ret_length, /* Return length */
buffer, /* Capability data buffer */
arg_list)
/* Argument list array */
/* We'll know soon enough if this doesn't work */
&1) == 0) {
ttputs("OOPS");
return;
}
ttputc(0);
/* Send out resulting sequence */
i = ret_length;
cp = buffer;
while (i-- > 0)
ttputc(*cp++);
}
#endif
/***
* vmsrev - Set the reverse video status
*
* Nothing returned
***/
vmsrev(status)
int status; /* TRUE if setting reverse */
{
if (status)
ttputs(begin_reverse);
else
ttputs(end_reverse);
}
/***
* vmscres - Change screen resolution (which it doesn't)
*
* Nothing returned
***/
vmscres()
{
/* But it could. For vt100/vt200s, one could switch from
80 and 132 columns modes */
}
#if COLOR
/***
* vmsfcol - Set the forground color (not implimented)
*
* Nothing returned
***/
vmsfcol()
{
}
/***
* vmsbcol - Set the background color (not implimented)
*
* Nothing returned
***/
vmsbcol()
{
}
#endif
/***
* vmseeol - Erase to end of line
*
* Nothing returned
***/
vmseeol()
{
ttputs(erase_to_end_line);
}
/***
* vmseeop - Erase to end of page (clear screen)
*
* Nothing returned
***/
vmseeop()
{
ttputs(erase_whole_display);
}
/***
* vmsbeep - Ring the bell
*
* Nothing returned
***/
vmsbeep()
{
ttputc('\007');
}
/***
* vmsgetstr - Get an SMG string capability by name
*
* Returns: Escape sequence
* NULL No escape sequence available
***/
char *vmsgetstr(request_code)
int request_code; /* Request code */
{
char *result;
static char seq_storage[1024];
static char *buffer = seq_storage;
static int arg_list[2] = { 1, 1 };
int max_buffer_length, ret_length;
/* Precompute buffer length */
max_buffer_length = (seq_storage + sizeof(seq_storage)) - buffer;
/* Get terminal commands sequence from master table */
if ((smg$get_term_data( /* Get terminal data */
&termtype, /* Terminal table address */
&request_code, /* Request code */
&max_buffer_length, /* Maximum buffer length */
&ret_length, /* Return length */
buffer, /* Capability data buffer */
arg_list)
/* Argument list array */
/* If this doesn't work, try again with no arguments */
&1) == 0 && (smg$get_term_data( /* Get terminal data */
&termtype, /* Terminal table address */
&request_code, /* Request code */
&max_buffer_length, /* Maximum buffer length */
&ret_length, /* Return length */
buffer)
/* Capability data buffer */
/* Return NULL pointer if capability is not available */
&1) == 0)
return NULL;
/* Check for empty result */
if (ret_length == 0)
return NULL;
/* Save current position so we can return it to caller */
result = buffer;
/* NIL terminate the sequence for return */
buffer[ret_length] = 0;
/* Advance buffer */
buffer += ret_length + 1;
/* Return capability to user */
return result;
}
/** I/O information block definitions **/
struct iosb { /* I/O status block */
short i_cond; /* Condition value */
short i_xfer; /* Transfer count */
long i_info; /* Device information */
};
struct termchar { /* Terminal characteristics */
char t_class; /* Terminal class */
char t_type; /* Terminal type */
short t_width; /* Terminal width in characters */
long t_mandl; /* Terminal's mode and length */
long t_extend; /* Extended terminal characteristics */
};
static struct termchar tc; /* Terminal characteristics */
/***
* vmsgtty - Get terminal type from system control block
*
* Nothing returned
***/
vmsgtty()
{
short fd;
int status;
struct iosb iostatus;
$DESCRIPTOR(devnam, "SYS$INPUT");
/* Assign input to a channel */
status = sys$assign(&devnam, &fd, 0, 0);
if ((status & 1) == 0)
exit(status);
/* Get terminal characteristics */
status = sys$qiow( /* Queue and wait */
0, /* Wait on event flag zero */
fd, /* Channel to input terminal */
IO$_SENSEMODE, /* Get current characteristic */
&iostatus, /* Status after operation */
0, 0, /* No AST service */
&tc, /* Terminal characteristics buf */
sizeof(tc), /* Size of the buffer */
0, 0, 0, 0); /* P3-P6 unused */
/* De-assign the input device */
if ((sys$dassgn(fd) & 1) == 0)
exit(status);
/* Jump out if bad status */
if ((status & 1) == 0)
exit(status);
if ((iostatus.i_cond & 1) == 0)
exit(iostatus.i_cond);
}
/***
* vmsopen - Get terminal type and open terminal
*
* Nothing returned
***/
vmsopen()
{
/* Get terminal type */
vmsgtty();
if (tc.t_type == TT$_UNKNOWN) {
printf("Terminal type is unknown!\n");
printf
("Try set your terminal type with SET TERMINAL/INQUIRE\n");
printf("Or get help on SET TERMINAL/DEVICE_TYPE\n");
exit(3);
}
/* Access the system terminal definition table for the */
/* information of the terminal type returned by IO$_SENSEMODE */
if ((smg$init_term_table_by_type(&tc.t_type, &termtype) & 1) == 0)
return -1;
/* Set sizes */
term.t_nrow = ((unsigned int) tc.t_mandl >> 24) - 1;
term.t_ncol = tc.t_width;
/* Get some capabilities */
begin_reverse = vmsgetstr(SMG$K_BEGIN_REVERSE);
end_reverse = vmsgetstr(SMG$K_END_REVERSE);
revexist = begin_reverse != NULL && end_reverse != NULL;
erase_to_end_line = vmsgetstr(SMG$K_ERASE_TO_END_LINE);
eolexist = erase_to_end_line != NULL;
erase_whole_display = vmsgetstr(SMG$K_ERASE_WHOLE_DISPLAY);
#if SCROLLCODE
scroll_forward = vmsgetstr(SMG$K_SCROLL_FORWARD);
scroll_reverse = vmsgetstr(SMG$K_SCROLL_REVERSE);
if (tc.t_type < TT$_VT100 || scroll_reverse == NULL ||
scroll_forward == NULL)
term.t_scroll = NULL;
else
term.t_scroll = vmsscroll_reg;
#endif
/* Set resolution */
strcpy(sres, "NORMAL");
/* Open terminal I/O drivers */
ttopen();
}
/***
* vmskopen - Open keyboard (not used)
*
* Nothing returned
***/
vmskopen()
{
}
/***
* vmskclose - Close keyboard (not used)
*
* Nothing returned
***/
vmskclose()
{
}
#endif

View File

@ -1,161 +0,0 @@
/* vt52.c
*
* The routines in this file
* provide support for VT52 style terminals
* over a serial line. The serial I/O services are
* provided by routines in "termio.c". It compiles
* into nothing if not a VT52 style device. The
* bell on the VT52 is terrible, so the "beep"
* routine is conditionalized on defining BEL.
*
* modified by Petri Kutvonen
*/
#define termdef 1 /* don't define "term" external */
#include <stdio.h>
#include "estruct.h"
#if VT52
#define NROW 24 /* Screen size. */
#define NCOL 80 /* Edit if you want to. */
#define MARGIN 8 /* size of minimim margin and */
#define SCRSIZ 64 /* scroll size for extended lines */
#define NPAUSE 100 /* # times thru update to pause */
#define BIAS 0x20 /* Origin 0 coordinate bias. */
#define ESC 0x1B /* ESC character. */
#define BEL 0x07 /* ascii bell character */
extern int ttopen(); /* Forward references. */
extern int ttgetc();
extern int ttputc();
extern int ttflush();
extern int ttclose();
extern int vt52move();
extern int vt52eeol();
extern int vt52eeop();
extern int vt52beep();
extern int vt52open();
extern int vt52rev();
extern int vt52cres();
extern int vt52kopen();
extern int vt52kclose();
#if COLOR
extern int vt52fcol();
extern int vt52bcol();
#endif
/*
* Dispatch table.
* All the hard fields just point into the terminal I/O code.
*/
struct terminal term = {
NROW - 1,
NROW - 1,
NCOL,
NCOL,
MARGIN,
SCRSIZ,
NPAUSE,
&vt52open,
&ttclose,
&vt52kopen,
&vt52kclose,
&ttgetc,
&ttputc,
&ttflush,
&vt52move,
&vt52eeol,
&vt52eeop,
&vt52beep,
&vt52rev,
&vt52cres
#if COLOR
, &vt52fcol,
&vt52bcol
#endif
#if SCROLLCODE
, NULL
#endif
};
vt52move(row, col)
{
ttputc(ESC);
ttputc('Y');
ttputc(row + BIAS);
ttputc(col + BIAS);
}
vt52eeol()
{
ttputc(ESC);
ttputc('K');
}
vt52eeop()
{
ttputc(ESC);
ttputc('J');
}
vt52rev(status)
/* set the reverse video state */
int status; /* TRUE = reverse video, FALSE = normal video */
{
/* can't do this here, so we won't */
}
vt52cres()
{ /* change screen resolution - (not here though) */
return TRUE;
}
#if COLOR
vt52fcol()
{ /* set the forground color [NOT IMPLIMENTED] */
}
vt52bcol()
{ /* set the background color [NOT IMPLIMENTED] */
}
#endif
vt52beep()
{
#ifdef BEL
ttputc(BEL);
ttflush();
#endif
}
vt52open()
{
#if V7 | BSD
char *cp;
char *getenv();
if ((cp = getenv("TERM")) == NULL) {
puts("Shell variable TERM not defined!");
exit(1);
}
if (strcmp(cp, "vt52") != 0 && strcmp(cp, "z19") != 0) {
puts("Terminal type not 'vt52'or 'z19' !");
exit(1);
}
#endif
ttopen();
}
vt52kopen()
{
}
vt52kclose()
{
}
#endif

View File

@ -1,117 +0,0 @@
/* wscreen.c -- windows screen console for MINGW32 */
#include "wscreen.h"
#ifdef MINGW32
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
/* Standard error macro for reporting API errors */
#define PERR(bSuccess, api){if(!(bSuccess)) printf("%s:Error %ld from %s \
on line %d\n", __FILE__, GetLastError(), api, __LINE__);}
static void cls( HANDLE hConsole )
{
COORD coordScreen = { 0, 0 }; /* here's where we'll home the
cursor */
BOOL bSuccess;
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
DWORD dwConSize; /* number of character cells in
the current buffer */
/* get the number of character cells in the current buffer */
bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi );
PERR( bSuccess, "GetConsoleScreenBufferInfo" );
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
/* fill the entire screen with blanks */
bSuccess = FillConsoleOutputCharacter( hConsole, (TCHAR) ' ',
dwConSize, coordScreen, &cCharsWritten );
PERR( bSuccess, "FillConsoleOutputCharacter" );
/* get the current text attribute */
bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi );
PERR( bSuccess, "ConsoleScreenBufferInfo" );
/* now set the buffer's attributes accordingly */
bSuccess = FillConsoleOutputAttribute( hConsole, csbi.wAttributes,
dwConSize, coordScreen, &cCharsWritten );
PERR( bSuccess, "FillConsoleOutputAttribute" );
/* put the cursor at (0, 0) */
bSuccess = SetConsoleCursorPosition( hConsole, coordScreen );
PERR( bSuccess, "SetConsoleCursorPosition" );
return;
}
void wcls( void) {
cls( GetStdHandle( STD_OUTPUT_HANDLE)) ;
}
static struct {
int width ;
int height ;
int curTop, curBot, curRight, curLeft ;
} Screen ;
void winit( void) {
CONSOLE_SCREEN_BUFFER_INFO csbInfo ;
wcls() ;
if( GetConsoleScreenBufferInfo(
GetStdHandle( STD_OUTPUT_HANDLE), &csbInfo)) {
Screen.width = csbInfo.dwSize.X ;
Screen.height = csbInfo.dwSize.Y ;
Screen.curLeft = csbInfo.srWindow.Left ;
Screen.curTop = csbInfo.srWindow.Top ;
Screen.curRight = csbInfo.srWindow.Right ;
Screen.curBot = csbInfo.srWindow.Bottom ;
}
}
int wwidth( void) {
return Screen.width ;
}
int wheight( void) {
return Screen.height ;
}
int wleft( void) {
return Screen.curLeft ;
}
int wtop( void) {
return Screen.curTop ;
}
int wright( void) {
return Screen.curRight ;
}
int wbottom( void) {
return Screen.curBot ;
}
void wgoxy( int x, int y) {
COORD coord ;
coord.X = x ;
coord.Y = y ;
SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE), coord );
}
void wtitle( const char *title) {
SetConsoleTitle( title) ;
}
#endif /* MINGW32 */
/* end of wscreen.c */

View File

@ -1,14 +0,0 @@
/* wscreen.h -- character screen drawing */
void winit( void) ;
void wcls( void) ;
void wgoxy( int x, int y) ;
void wtitle( const char *title) ;
int wwidth( void) ;
int wheight( void) ;
int wleft( void) ;
int wright( void) ;
int wtop( void) ;
int wbottom( void) ;
/* end of wscreen.h */

404
input.c
View File

@ -1,10 +1,7 @@
/* input.c -- implements input.h */
#include "input.h"
/* input.c
*
* Various input routines
/* Various input routines
*
* written by Daniel Lawrence 5/9/86
* modified by Petri Kutvonen
@ -18,9 +15,10 @@
#include "bind.h"
#include "estruct.h"
#include "bindable.h"
#include "display.h"
#include "display.h" /* rubout(), echos(), echoc(), update() */
#include "exec.h"
#include "isa.h"
#include "mlout.h"
#include "names.h"
#include "terminal.h"
#include "utf8.h"
@ -41,12 +39,12 @@ kbdstate kbdmode = STOP ; /* current keyboard macro mode */
int lastkey = 0 ; /* last keystoke */
int kbdrep = 0 ; /* number of repetitions */
int metac = CONTROL | '[' ; /* current meta character */
int ctlxc = CONTROL | 'X' ; /* current control X prefix char */
int reptc = CONTROL | 'U' ; /* current universal repeat char */
int abortc = CONTROL | 'G' ; /* current abort command char */
int metac = CTL_ | '[' ; /* current meta character */
int ctlxc = CTL_ | 'X' ; /* current control X prefix char */
int reptc = CTL_ | 'U' ; /* current universal repeat char */
int abortc = CTL_ | 'G' ; /* current abort command char */
const int nlc = CONTROL | 'J' ; /* end of input char */
const int nlc = CTL_ | 'J' ; /* end of input char */
void ue_system( const char *cmd) {
@ -69,7 +67,7 @@ int mlyesno( const char *prompt)
for (;;) {
/* prompt the user */
mlwrite( "%s (y/n)? ", prompt) ;
mloutfmt( "%s (y/n)? ", prompt) ;
/* get the response */
c = get1key() ;
@ -145,11 +143,11 @@ int newmlargt( char **outbufref, const char *prompt, int size) {
/*
* ectoc:
* expanded character to character
* collapse the CONTROL and SPEC flags back into an ascii code
* collapse the CTL_ and SPEC flags back into an ascii code
*/
int ectoc( int c) {
if( c & CONTROL)
c ^= CONTROL | 0x40 ;
if( c & CTL_)
c ^= CTL_ | 0x40 ;
if( c & SPEC)
c &= 255 ;
@ -162,12 +160,11 @@ int ectoc( int c) {
* that pressing a <SPACE> will attempt to complete an unfinished command
* name if it is unique.
*/
fn_t getname(void)
{
nbind_p getname( void) {
int cpos; /* current column on screen output */
struct name_bind *ffp; /* first ptr to entry in name binding table */
struct name_bind *cffp; /* current ptr to entry in name binding table */
struct name_bind *lffp; /* last ptr to entry in name binding table */
nbind_p ffp; /* first ptr to entry in name binding table */
nbind_p cffp; /* current ptr to entry in name binding table */
nbind_p lffp; /* last ptr to entry in name binding table */
char buf[NSTRING]; /* buffer to hold tentative command name */
/* starting at the beginning of the string buffer */
@ -177,7 +174,7 @@ fn_t getname(void)
if (clexec) {
if( TRUE != gettokval( buf, sizeof buf))
return NULL;
return fncmatch(&buf[0]);
return fncmatch( buf) ;
}
/* build a name string from the keyboard */
@ -191,12 +188,12 @@ fn_t getname(void)
buf[cpos] = 0;
/* and match it off */
return fncmatch(&buf[0]);
return fncmatch( buf) ;
} else if (c == ectoc(abortc)) { /* Bell, abort */
ctrlg(FALSE, 0);
TTflush();
return NULL;
} else if( c == ectoc(abortc)) { /* Bell, abort */
ctrlg( FALSE, 1) ;
TTflush() ;
return NULL ;
} else if (c == 0x7F || c == 0x08) { /* rubout/erase */
if (cpos != 0) {
@ -216,59 +213,40 @@ fn_t getname(void)
} else if (c == ' ' || c == 0x1b || c == 0x09) {
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
/* attempt a completion */
buf[cpos] = 0; /* terminate it for us */
ffp = &names[0]; /* scan for matches */
while (ffp->n_func != NULL) {
if (strncmp(buf, ffp->n_name, strlen(buf))
== 0) {
buf[ cpos] = 0 ; /* terminate it for us */
int buflen = strlen( buf) ;
/* scan for matches */
for( ffp = names ; ffp->n_func != NULL ; ffp++) {
if( strncmp( buf, bind_name( ffp), buflen) == 0) {
/* a possible match! More than one? */
if ((ffp + 1)->n_func == NULL ||
(strncmp
(buf, (ffp + 1)->n_name,
strlen(buf)) != 0)) {
if( (ffp + 1)->n_func == NULL ||
(strncmp( buf, bind_name( ffp + 1), buflen) != 0)) {
/* no...we match, print it */
echos( ffp->n_name + cpos) ;
TTflush();
return ffp->n_func;
echos( &bind_name( ffp)[ cpos]) ;
TTflush() ;
return ffp ;
} else {
/* << << << << << << << << << << << << << << << << << */
/* try for a partial match against the list */
/* first scan down until we no longer match the current input */
lffp = (ffp + 1);
while ((lffp +
1)->n_func !=
NULL) {
if (strncmp
(buf,
(lffp +
1)->n_name,
strlen(buf))
!= 0)
break;
++lffp;
}
/* first scan down until we no longer match the
* current input */
for( lffp = ffp + 1 ; (lffp + 1)->n_func != NULL ;
lffp++)
if( strncmp( buf, bind_name( lffp + 1),
buflen) != 0)
break ;
/* and now, attempt to partial complete the string, char at a time */
/* and now, attempt to partial complete the string,
* one char at a time */
while (TRUE) {
/* add the next char in */
buf[cpos] =
ffp->
n_name[cpos];
buf[ cpos] = bind_name( ffp)[ cpos] ;
/* scan through the candidates */
cffp = ffp + 1;
while (cffp <=
lffp) {
if (cffp->
n_name
[cpos]
!=
buf
[cpos])
goto onward;
++cffp;
}
for( cffp = ffp + 1 ; cffp <= lffp ; cffp++)
if( bind_name( cffp)[ cpos] != buf[ cpos])
goto onward ;
/* add the character */
echoc( buf[ cpos++]) ;
@ -276,12 +254,11 @@ fn_t getname(void)
/* << << << << << << << << << << << << << << << << << */
}
}
++ffp;
}
/* no match.....beep and onward */
TTbeep();
onward:;
onward:
TTflush();
/* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
} else {
@ -345,152 +322,138 @@ int tgetc(void)
return c;
}
/* GET1KEY: Get one keystroke. The only prefixs legal here are the SPEC
and CONTROL prefixes. */
int get1key( void) {
int c ;
/* get a keystroke */
c = tgetc();
if( (c >= 0x00 && c <= 0x1F) || c == 0x7F) /* C0 control -> C- */
c ^= CONTROL | 0x40 ;
return c ;
}
/* GETCMD: Get a command from the keyboard. Process all applicable
prefix keys */
static int get1unicode( int *k) {
/* GET1KEY: Get one keystroke. The only prefixes legal here are the SPEC
and CTL_ prefixes. */
static int get1unicode( int *up) {
/* Accept UTF-8 sequence */
int c = *k ;
int bytes ;
int c = tgetc() ;
if( c > 0xC1 && c <= 0xF4) {
char utf[ 4] ;
char cc ;
utf[ 0] = c ;
utf[ 1] = cc = get1key() ;
utf[ 1] = cc = tgetc() ;
if( (c & 0x20) && ((cc & 0xC0) == 0x80)) { /* at least 3 bytes and a valid encoded char */
utf[ 2] = cc = get1key() ;
utf[ 2] = cc = tgetc() ;
if( (c & 0x10) && ((cc & 0xC0) == 0x80)) /* at least 4 bytes and a valid encoded char */
utf[ 3] = get1key() ;
utf[ 3] = tgetc() ;
}
return utf8_to_unicode( utf, 0, sizeof utf, (unicode_t *) k) ;
} else
return 1 ;
bytes = utf8_to_unicode( utf, 0, sizeof utf, (unicode_t *) up) ;
} else {
if( (c >= 0x00 && c <= 0x1F) || c == 0x7F) /* C0 control -> C- */
c ^= CTL_ | 0x40 ;
*up = c ;
bytes = 1 ;
}
return bytes ;
}
int getcmd(void)
{
int c; /* fetched keystroke */
#if VT220
int d; /* second character P.K. */
int cmask = 0;
#endif
/* get initial character */
c = get1key();
/* Terminal sequences need up to 7 read ahead characters */
#define STACKSIZE 7
static int keystack[ STACKSIZE] ;
static int *stackptr = &keystack[ STACKSIZE] ;
#define KPUSH( c) *(--stackptr) = (c)
#if VT220
proc_metac:
#endif
if (c == 128+27) /* CSI */
goto handle_CSI;
/* process META prefix */
if (c == (CONTROL | '[')) {
c = get1key();
#if VT220
if (c == '[' || c == 'O') { /* CSI P.K. */
handle_CSI:
c = get1key();
if (c >= 'A' && c <= 'D')
return SPEC | c | cmask;
if (c >= 'E' && c <= 'z' && c != 'i' && c != 'c')
return SPEC | c | cmask;
d = get1key();
if (d == '~') /* ESC [ n ~ P.K. */
return SPEC | c | cmask;
switch (c) { /* ESC [ n n ~ P.K. */
case '1':
c = d + 32;
break;
case '2':
c = d + 48;
break;
case '3':
c = d + 64;
break;
default:
c = '?';
break;
}
if (d != '~') /* eat tilde P.K. */
get1key();
if (c == 'i') { /* DO key P.K. */
c = ctlxc;
goto proc_ctlxc;
} else if (c == 'c') /* ESC key P.K. */
c = get1key();
else
return SPEC | c | cmask;
}
#endif
#if VT220
if (c == (CONTROL | '[')) {
cmask = META;
goto proc_metac;
}
#endif
if( islower( c)) /* Force to upper */
c = flipcase( c) ;
else if( c >= 0x00 && c <= 0x1F) /* control key */
c = CONTROL | (c + '@');
return META | c;
}
#if PKCODE
else if (c == metac) {
c = get1key();
#if VT220
if (c == (CONTROL | '[')) {
cmask = META;
goto proc_metac;
}
#endif
if( islower( c)) /* Force to upper */
c = flipcase( c) ;
else if( c >= 0x00 && c <= 0x1F) /* control key */
c = CONTROL | (c + '@');
return META | c;
}
#endif
int get1key( void) {
int c ;
/* fetch from queue if any were pushed back */
if( stackptr != &keystack[ STACKSIZE])
return *(stackptr++) ;
#if VT220
proc_ctlxc:
#endif
/* process CTLX prefix */
if (c == ctlxc) {
c = get1key();
#if VT220
if (c == (CONTROL | '[')) {
cmask = CTLX;
goto proc_metac;
}
#endif
if (c >= 'a' && c <= 'z') /* Force to upper */
c -= 0x20;
if (c >= 0x00 && c <= 0x1F) /* control key */
c = CONTROL | (c + '@');
return CTLX | c;
}
#ifdef CYGWIN
/* fetch from keyboard */
get1unicode( &c) ;
#endif
return c ;
}
/* otherwise, just return it */
return c;
/* GETCMD: Get a command from the keyboard. Process all applicable prefix
keys. Handle alted and controlled FNx, not shifted.
*/
int getcmd( void) {
int prefix = 0 ; /* prefixes M- or ^X */
int keyread[ STACKSIZE] ; /* room to process sequences like ^[[24;2~ */
int *kptr = keyread ;
int c ;
for( ;;) {
c = *(kptr++) = get1key() ;
if( c == 0x9B)
goto foundCSI ;
else if( c == (CTL_ | '[')) {
/* fetch terminal sequence */
c = *(kptr++) = get1key() ;
if( c == 'O') { /* F1 .. F4 */
c = *(kptr++) = get1key() ;
if( c >= 'P' && c <= 'S')
return c | SPEC | prefix ;
} else if( c == '[') {
int v1, v ; /* ^[[v1;v~ or ^[[v~ */
foundCSI:
v1 = v = 0 ;
while( kptr < &keyread[ STACKSIZE]) {
c = *(kptr++) = get1key() ;
if( (c == '~')
|| (c >= 'A' && c <= 'Z')
|| (c >= 'a' && c <= 'z')) {
/* Found end of sequence */
int mask = prefix ;
if( v1) { /* Handle ALT/CTL, not SHFT */
if( (v - 1) & 2)
mask = META ;
if( (v - 1) & 4)
mask |= CTL_ ;
v = v1 ;
}
if( c == '~') {
if( v)
c = v + ((v <= 9) ? '0' : 'a' - 10) ;
else
break ;
}
return c | SPEC | mask ;
} else if( c == ';') { /* Start of SHFT/ALT/CTL state */
v1 = v ;
v = 0 ;
} else if( c >= '0' && c <= '9')
v = v * 10 + c - '0' ;
else
break ;
}
}
/* not a match, unget the keys read so far */
while( kptr > keyread)
KPUSH( *(--kptr)) ;
c = get1key() ;
} else
kptr-- ;
if( c == metac) {
prefix = META ;
} else if( c == ctlxc) {
if( prefix)
break ; /* ^X^X or M-^X */
else
prefix = CTLX ;
} else
break ;
}
if( prefix && islower( c))
c = flipcase( c) ;
return c | prefix ;
}
/* A more generalized prompt/reply function allowing the caller
@ -512,16 +475,17 @@ static void echov( int c) {
}
}
static void rubc( char c) {
static void rubc( int c) {
rubout() ;
if( (c >= 0 && c < ' ') || c == 0x7F) {
/* ^x range */
rubout() ;
if( c == '\n') {
if( c == '\n') { /* <NL> */
rubout() ;
rubout() ;
}
}
} else if( utf8_width( c) == 2)
rubout() ;
}
int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
@ -541,16 +505,16 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
static char tmp[] = "/tmp/meXXXXXX";
FILE *tmpf = NULL;
#endif
/* Look for "Find file: ", "View file: ", "Insert file: ", "Write file: ",
/* Look for "find-file: ", "View file: ", "Insert file: ", "Write file: ",
** "Read file: ", "Execute file: " */
file_f = NULL != strstr( prompt, " file: ") ;
file_f = NULL != strstr( prompt, "file: ") ;
#endif
cpos = 0;
quote_f = FALSE;
/* prompt the user for the input string */
mlwrite( "%s", prompt);
mloutstr( prompt);
for (;;) {
#if COMPLC
@ -559,14 +523,14 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
didtry = 0;
#endif
/* get a character from the user */
c = get1key();
int bytes = get1unicode( &c) ;
/* Quoting? Store as it is */
if( quote_f == TRUE) {
quote_f = FALSE ;
if( cpos < nbuf - 1) {
if( cpos < nbuf - bytes) {
c = ectoc( c) ;
buf[ cpos++] = c ;
cpos += unicode_to_utf8( c, &buf[ cpos]) ;
echov( c) ;
TTflush() ;
}
@ -575,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( c == (CONTROL | 'M'))
c = CONTROL | 0x40 | '\n' ;
if( c == (CTL_ | 'M'))
c = CTL_ | 0x40 | '\n' ;
if( c == eolchar) {
/* if they hit the line terminator, wrap it up */
buf[ cpos] = 0 ;
/* clear the message line */
mlwrite("");
mloutstr( "") ;
/* if we default the buffer, return FALSE */
retval = cpos != 0 ;
break ;
} else if( c == abortc) {
/* Abort the input? */
ctrlg( FALSE, 0) ;
retval = ABORT ;
retval = ctrlg( FALSE, 1) ;
break ;
}
@ -601,13 +564,17 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
if( c == 0x7F || c == 0x08) {
/* rubout/erase */
if (cpos != 0) {
rubc( buf[ --cpos]) ;
int c ;
cpos -= 1 ;
cpos -= utf8_revdelta( (unsigned char *) &buf[ cpos], cpos) ;
utf8_to_unicode( &buf[ cpos], 0, 4, (unicode_t *) &c) ;
rubc( c) ;
TTflush();
}
} else if( c == 0x15) {
/* C-U, kill */
mlwrite( "%s", prompt) ;
mloutstr( prompt) ;
cpos = 0 ;
#if COMPLC
} else if( (c == 0x09 || c == ' ') && file_f) {
@ -621,7 +588,7 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
didtry = 1;
ocpos = cpos;
mlwrite( "%s", prompt) ;
mloutstr( prompt) ;
while( cpos != 0) {
c = buf[ --cpos] ;
if( c == '*' || c == '?') {
@ -717,10 +684,7 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
quote_f = TRUE ;
else {
/* store as it is */
int n ;
n = get1unicode( &c) ; /* fetch multiple bytes */
if( cpos + n < nbuf) {
if( cpos + bytes < nbuf) {
cpos += unicode_to_utf8( c, &buf[ cpos]) ;
echov( c) ;
TTflush() ;
@ -736,3 +700,5 @@ int getstring( const char *prompt, char *buf, int nbuf, int eolchar)
return retval ;
}
/* end of input.c */

20
input.h
View File

@ -1,12 +1,14 @@
/* input.h -- */
#ifndef _INPUT_H_
#define _INPUT_H_
#include "bind.h"
#include "names.h" /* nbind_p */
typedef enum {
STOP, PLAY, RECORD
} kbdstate ;
extern kbdstate kbdmode ; /* current keyboard macro mode */
extern int lastkey ; /* last keystoke */
extern int kbdrep ; /* number of repetitions */
@ -14,10 +16,10 @@ extern int kbdm[] ; /* Holds kayboard macro data */
extern int *kbdptr ; /* current position in keyboard buf */
extern int *kbdend ; /* ptr to end of the keyboard */
extern int metac; /* current meta character */
extern int ctlxc; /* current control X prefix char */
extern int reptc; /* current universal repeat char */
extern int abortc; /* current abort command char */
extern int metac ; /* current meta character */
extern int ctlxc ; /* current control X prefix char */
extern int reptc ; /* current universal repeat char */
extern int abortc ; /* current abort command char */
extern const int nlc ; /* end of input char */
@ -26,10 +28,14 @@ int mlyesno( const char *prompt) ;
int newmlarg( char **outbufref, const char *prompt, int size) ;
int newmlargt( char **outbufref, const char *prompt, int size) ;
int ectoc( int c) ;
fn_t getname( void) ;
/* Get a command binding from the command line or interactively */
nbind_p getname( void) ;
int tgetc( void) ;
int get1key( void) ;
int getcmd( void) ;
int getstring( const char *prompt, char *buf, int nbuf, int eolchar) ;
#endif
/* end of input.h */

23
isa.h
View File

@ -1,32 +1,30 @@
/* isa.h -- isletter, islower, isupper, flipcase */
#ifndef __ISA_H__
#define __ISA_H__
#define NATIONL 0 /* if 1, interpret [,],\,{,},| as characters P.K. */
#ifdef islower
#undef islower
# undef islower
#endif
#ifdef isupper
#undef isupper
# undef isupper
#endif
#define NATIONL 0 /* if 1, interpret [,],\,{,},| as characters P.K. */
#if NATIONL
#define LASTUL ']'
#define LASTLL '}'
# define LASTUL ']'
# define LASTLL '}'
#else
#define LASTUL 'Z'
#define LASTLL 'z'
# define LASTUL 'Z'
# define LASTLL 'z'
#endif
#define isletter(c) __isxletter((0xFF & (c)))
#define islower(c) isxlower((0xFF & (c)))
#define isupper(c) isxupper((0xFF & (c)))
#define __isxletter(c) (('a' <= c && LASTLL >= c) || ('A' <= c && LASTUL >= c) || (192<=c /* && c<=255 */))
#define __isxletter(c) (('a' <= c && LASTLL >= c) || \
('A' <= c && LASTUL >= c) || (192<=c /* && c<=255 */))
#define isxlower(c) (('a' <= c && LASTLL >= c) || (224 <= c && 252 >= c))
#define isxupper(c) (('A' <= c && LASTUL >= c) || (192 <= c && 220 >= c))
@ -39,6 +37,5 @@
#define DIFCASE 0x20 /* ASCII 'a' - 'A' */
#define flipcase( c) ((c) ^ DIFCASE) /* Toggle the case of a letter. */
#endif /* __ISA_H__ */
#endif
/* end of isa.h */

View File

@ -1,8 +1,7 @@
/* isearch.c -- implements 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
* is intended to emulate the same command from the original EMACS
* implementation (ITS). Contains references to routines internal to
@ -24,7 +23,6 @@
* Modified by Petri Kutvonen
*/
#include <stdio.h>
#include <string.h>
#include "basic.h"
@ -42,8 +40,6 @@
/*
* Incremental search defines.
*/
#if ISRCH
#define CMDBUFLEN 256 /* Length of our command buffer */
#define IS_ABORT 0x07 /* Abort the isearch */
@ -60,10 +56,7 @@
/* IS_QUIT is no longer used, the variable metac is used instead */
#endif
static int isearch( int f, int n) ;
static BINDABLE( isearch) ; /* internal use, not to be bound */
static int checknext( char chr, char *patrn, int dir) ;
static int scanmore( char *patrn, int dir) ;
static int match_pat( char *patrn) ;
@ -73,8 +66,6 @@ static int uneat( void) ;
static void reeat( int c) ;
#if ISRCH
static int echo_char(int c, int col);
/* 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 */
/*
* 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.
*/
int risearch(int f, int n)
{
BINDABLE( risearch) {
struct line *curline; /* Current line on entry */
int curoff; /* Current offset on entry */
@ -124,11 +113,10 @@ int risearch(int f, int n)
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 */
int curoff; /* Current offset on entry */
@ -156,8 +144,8 @@ int fisearch(int f, int n)
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
* as each character is typed, with the screen and cursor updated with each
* new search character.
@ -182,8 +170,7 @@ int fisearch(int f, int n)
* exists (or until the search is aborted).
*/
static int isearch(int f, int n)
{
static BINDABLE( isearch) {
int status; /* Search status */
int col; /* prompt column */
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 */
term.t_getchar = uneat; /* Replace it with ours */
}
#else
int isearch(int f, int n)
{
}
#endif
/* end of isearch.c */

View File

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

236
line.c
View File

@ -1,6 +1,7 @@
/* line.c
*
* The functions in this file are a general set of line management utilities.
/* line.c -- implements line.h */
#include "line.h"
/* The functions in this file are a general set of line management utilities.
* They are the only routines that touch the text. They also touch the buffer
* and window structures, to make sure that the necessary updating gets done.
* There are routines in this file that handle the kill buffer too. It isn't
@ -13,12 +14,9 @@
*
*/
#include "line.h"
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h> /* NULL, offsetof() */
#include <stdlib.h> /* malloc(), free() */
#include <string.h>
#include "buffer.h"
@ -41,13 +39,13 @@ static int ldelnewline( void) ;
#define KBLOCK 250 /* sizeof kill buffer chunks */
struct kill {
typedef struct kill {
struct kill *d_next; /* Link to next chunk, NULL if last. */
char d_chunk[KBLOCK]; /* Deleted text. */
};
} *kill_p ;
static struct kill *kbufp = NULL ; /* current kill buffer chunk pointer */
static struct kill *kbufh = NULL ; /* kill buffer header pointer */
static kill_p kbufp = NULL ; /* current kill buffer chunk pointer */
static kill_p kbufh = NULL ; /* kill buffer header pointer */
static int kused = KBLOCK ; /* # of bytes used in kill buffer */
static int klen ; /* length of kill buffer content */
static char *value = NULL ; /* temp buffer for value */
@ -56,7 +54,7 @@ static char *value = NULL ; /* temp buffer for value */
* return some of the contents of the kill buffer
*/
char *getkill( void) {
struct kill *kp ;
kill_p kp ;
char *cp ;
if (kbufh == NULL)
@ -86,22 +84,20 @@ char *getkill( void) {
return value;
}
/*
* Move the cursor backwards by "n" characters. If "n" is less than zero call
* "forwchar" to actually do the move. Otherwise compute the new cursor
* location. Error if you try and move out of the buffer. Set the flag if the
* line pointer for dot changes.
/* Move the cursor backwards by "n" characters. If "n" is less than zero
call "forwchar" to actually do the move. Otherwise compute the new
cursor location. Error if you try and move out of the buffer. Set the
flag if the line pointer for dot changes.
*/
boolean backchar( int f, int n) {
assert( f == TRUE || (f == FALSE && n == 1)) ;
BBINDABLE( backchar) {
assert( f == TRUE || n == 1) ;
if( n < 0)
return forwchar( f, -n) ;
while( n--) {
if( curwp->w_doto == 0) { /* at beginning of line */
line_p lp ;
lp = lback( curwp->w_dotp) ;
line_p lp = lback( curwp->w_dotp) ;
if( lp == curbp->b_linep) /* at beginning of buffer */
return FALSE ;
@ -109,9 +105,7 @@ boolean backchar( int f, int n) {
curwp->w_doto = llength( lp) ;
curwp->w_flag |= WFMOVE ;
} else {
unsigned pos ;
pos = curwp->w_doto -= 1 ;
unsigned pos = curwp->w_doto -= 1 ;
if( pos > 0)
curwp->w_doto -= utf8_revdelta( (unsigned char *) &( (curwp->w_dotp)->l_text[ pos]), pos) ;
}
@ -120,14 +114,14 @@ boolean backchar( int f, int n) {
return TRUE ;
}
/*
* Move the cursor forwards by "n" characters. If "n" is less than zero call
* "backchar" to actually do the move. Otherwise compute the new cursor
* location, and move ".". Error if you try and move off the end of the
* buffer. Set the flag if the line pointer for dot changes.
/* Move the cursor forwards by "n" characters. If "n" is less than zero
call "backchar" to actually do the move. Otherwise compute the new
cursor location, and move ".". Error if you try and move off the end of
the buffer. Set the flag if the line pointer for dot changes.
*/
boolean forwchar( int f, int n) {
assert( f == TRUE || (f == FALSE && n == 1)) ;
BBINDABLE( forwchar) {
assert( f == TRUE || n == 1) ;
if( n < 0)
return backchar( f, -n) ;
@ -142,10 +136,18 @@ boolean forwchar( int f, int n) {
curwp->w_flag |= WFMOVE ;
} else {
unicode_t unc ;
unsigned bytes ;
bytes = utf8_to_unicode( curwp->w_dotp->l_text, curwp->w_doto, len, &unc) ;
curwp->w_doto += utf8_to_unicode( curwp->w_dotp->l_text,
curwp->w_doto, len, &unc) ;
/* check if next char is null width unicode */
while( curwp->w_doto != len) {
unsigned bytes = utf8_to_unicode( curwp->w_dotp->l_text,
curwp->w_doto, len, &unc) ;
if( utf8_width( unc) == 0)
curwp->w_doto += bytes ;
else
break ;
}
}
}
@ -160,12 +162,14 @@ boolean forwchar( int f, int n) {
*/
line_p lalloc( int used) {
#define BLOCK_SIZE 16 /* Line block chunk size. */
line_p lp ;
int size ;
/* size = used + BLOCK_SIZE - used % BLOCK_SIZE ; */
size = (used + BLOCK_SIZE) & ~(BLOCK_SIZE - 1) ; /* as BLOCK_SIZE is power of 2 */
lp = (line_p) malloc( offsetof( struct line, l_text) + size) ;
/* rounding down use masking instead or modulo when BLOCK_SIZE is power of 2 */
#if (BLOCK_SIZE & -BLOCK_SIZE) == BLOCK_SIZE
int size = (used + BLOCK_SIZE) & ~(BLOCK_SIZE - 1) ;
#else
int size = used + BLOCK_SIZE - used % BLOCK_SIZE ;
#endif
line_p lp = (line_p) malloc( offsetof( struct line, l_text) + size) ;
if( lp == NULL)
mloutstr( "(OUT OF MEMORY)") ;
else {
@ -183,7 +187,7 @@ line_p lalloc( int used) {
* conditions described in the above comments don't hold here.
*/
void lfree( line_p lp) {
struct buffer *bp;
buffer_p bp;
struct window *wp;
wp = wheadp;
@ -249,11 +253,11 @@ void lchange(int flag)
*
* int f, n; default flag and numeric argument
*/
int insspace(int f, int n)
{
linsert(n, ' ');
backchar(f, n);
return TRUE;
BINDABLE( insspace) {
assert( !(curbp->b_mode & MDVIEW)) ;
linsert( n, ' ') ;
backchar( f, n) ;
return TRUE ;
}
/*
@ -294,18 +298,13 @@ int linstr( char *instr) {
boolean linsert_byte( int n, int c) {
char *cp1;
char *cp2;
struct line *lp1;
struct line *lp2;
struct line *lp3;
line_p lp1, lp2, lp3 ;
int doto;
int i;
struct window *wp;
assert( (curbp->b_mode & MDVIEW) == 0) ;
#if 0
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
#endif
lchange(WFEDIT);
lp1 = curwp->w_dotp; /* Current line */
if (lp1 == curbp->b_linep) { /* At the end: special */
@ -313,8 +312,11 @@ boolean linsert_byte( int n, int c) {
mloutstr( "bug: linsert") ;
return FALSE;
}
if ((lp2 = lalloc(n)) == NULL) /* Allocate new line */
return FALSE;
lp2 = lalloc( n) ; /* Allocate new line */
if( lp2 == NULL)
return FALSE ;
lp3 = lp1->l_bp; /* Previous line */
lp3->l_fp = lp2; /* Link in */
lp2->l_fp = lp1;
@ -328,8 +330,10 @@ boolean linsert_byte( int n, int c) {
}
doto = curwp->w_doto; /* Save for later. */
if (lp1->l_used + n > lp1->l_size) { /* Hard: reallocate */
if ((lp2 = lalloc(lp1->l_used + n)) == NULL)
return FALSE;
lp2 = lalloc( lp1->l_used + n) ;
if( lp2 == NULL)
return FALSE ;
cp1 = &lp1->l_text[0];
cp2 = &lp2->l_text[0];
while (cp1 != &lp1->l_text[doto])
@ -373,8 +377,7 @@ boolean linsert_byte( int n, int c) {
int linsert( int n, unicode_t c) {
assert( n >= 0) ;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
assert( !(curbp->b_mode & MDVIEW)) ;
if( n > 0) {
char utf8[ 4] ;
@ -396,16 +399,14 @@ int linsert( int n, unicode_t c) {
return TRUE;
}
/*
* Overwrite a character into the current line at the current position
/* Overwrite a character into the current line at the current position
*
* int c; character to overwrite on current position
* int c ; character to overwrite on current position
*/
static int lowrite( int c) {
if( curwp->w_doto < curwp->w_dotp->l_used
&& (
lgetc(curwp->w_dotp, curwp->w_doto) != '\t' ||
((curwp->w_doto) % tabwidth) == (tabwidth - 1)
&& ( lgetc( curwp->w_dotp, curwp->w_doto) != '\t'
|| (curwp->w_doto % tabwidth) == (tabwidth - 1)
))
ldelchar( 1, FALSE) ;
@ -418,15 +419,12 @@ static int lowrite( int c) {
int lover( char *ostr) {
int status = TRUE ;
if (ostr != NULL) {
if( ostr != NULL) {
char tmpc ;
while( (tmpc = *ostr++)) {
status =
(tmpc == '\n' ? lnewline() : lowrite(tmpc));
/* Insertion error? */
if( status != TRUE) {
status = (tmpc == '\n' ? lnewline() : lowrite( tmpc)) ;
if( status != TRUE) { /* Insertion error? */
mloutstr( "%Out of memory while overwriting") ;
return status ;
}
@ -444,17 +442,15 @@ int lover( char *ostr) {
* update of dot and mark is a bit easier then in the above case, because the
* split forces more updating.
*/
int lnewline(void)
{
int lnewline( void) {
char *cp1;
char *cp2;
struct line *lp1;
struct line *lp2;
line_p lp1, lp2 ;
int doto;
struct window *wp;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
assert( !(curbp->b_mode & MDVIEW)) ;
#if SCROLLCODE
lchange(WFHARD | WFINS);
#else
@ -462,8 +458,10 @@ int lnewline(void)
#endif
lp1 = curwp->w_dotp; /* Get the address and */
doto = curwp->w_doto; /* offset of "." */
if ((lp2 = lalloc(doto)) == NULL) /* New first half line */
return FALSE;
lp2 = lalloc( doto) ; /* New first half line */
if( lp2 == NULL)
return FALSE ;
cp1 = &lp1->l_text[0]; /* Shuffle text around */
cp2 = &lp2->l_text[0];
while (cp1 != &lp1->l_text[doto])
@ -515,12 +513,14 @@ int lgetchar( unicode_t *c) {
*/
boolean ldelchar( long n, boolean kflag) {
/* testing for read only mode is done by ldelete() */
while (n-- > 0) {
while( n-- > 0) {
unicode_t c;
if (!ldelete(lgetchar(&c), kflag))
return FALSE;
if( !ldelete( lgetchar( &c), kflag))
return FALSE ;
}
return TRUE;
return TRUE ;
}
/*
@ -535,13 +535,12 @@ boolean ldelchar( long n, boolean kflag) {
boolean ldelete( long n, boolean kflag) {
char *cp1;
char *cp2;
struct line *dotp;
line_p dotp;
int doto;
int chunk;
struct window *wp;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
assert( !(curbp->b_mode & MDVIEW)) ;
while( n > 0) {
dotp = curwp->w_dotp;
@ -636,20 +635,14 @@ char *getctext( void) {
* about in memory. Return FALSE on error and TRUE if all looks ok. Called by
* "ldelete" only.
*/
static int ldelnewline(void)
{
static int ldelnewline( void) {
char *cp1;
char *cp2;
struct line *lp1;
struct line *lp2;
struct line *lp3;
line_p lp1, lp2, lp3 ;
struct window *wp;
assert( (curbp->b_mode & MDVIEW) == 0) ;
#if 0
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
#endif
lp1 = curwp->w_dotp;
lp2 = lp1->l_fp;
if (lp2 == curbp->b_linep) { /* At the buffer end. */
@ -682,8 +675,11 @@ static int ldelnewline(void)
free((char *) lp2);
return TRUE;
}
if ((lp3 = lalloc(lp1->l_used + lp2->l_used)) == NULL)
return FALSE;
lp3 = lalloc( lp1->l_used + lp2->l_used) ;
if( lp3 == NULL)
return FALSE ;
cp1 = &lp1->l_text[0];
cp2 = &lp3->l_text[0];
while (cp1 != &lp1->l_text[lp1->l_used])
@ -725,7 +721,7 @@ static int ldelnewline(void)
*/
void kdelete(void)
{
struct kill *kp; /* ptr to scan kill buffer chunk list */
kill_p kp; /* ptr to scan kill buffer chunk list */
if (kbufh != NULL) {
@ -754,30 +750,30 @@ void kdelete(void)
*
* int c; character to insert in the kill buffer
*/
int kinsert(int c)
{
struct kill *nchunk; /* ptr to newly malloced chunk */
int kinsert( int c) {
/* check to see if we need a new chunk */
if (kused >= KBLOCK) {
if ((nchunk = (struct kill *)malloc(sizeof(struct kill))) == NULL)
return FALSE;
if( kused >= KBLOCK) {
kill_p nchunk = malloc( sizeof *nchunk) ;
if( nchunk == NULL)
return FALSE ;
if( kbufh == NULL) { /* set head ptr if first time */
kbufh = nchunk;
kbufh = nchunk ;
klen = 0 ;
}
if (kbufp != NULL) /* point the current to this new one */
kbufp->d_next = nchunk;
kbufp = nchunk;
kbufp->d_next = NULL;
kused = 0;
if( kbufp != NULL) /* point the current to this new one */
kbufp->d_next = nchunk ;
kbufp = nchunk ;
kbufp->d_next = NULL ;
kused = 0 ;
}
/* and now insert the character */
kbufp->d_chunk[kused++] = c;
kbufp->d_chunk[ kused++] = c ;
klen += 1 ;
return TRUE;
return TRUE ;
}
/*
@ -785,15 +781,14 @@ int kinsert(int c)
* is done by the standard insert routines. All you do is run the loop, and
* check for errors. Bound to "C-Y".
*/
int yank(int f, int n)
{
BINDABLE( yank) {
int c;
int i;
char *sp; /* pointer into string to insert */
struct kill *kp; /* pointer into kill buffer */
kill_p kp; /* pointer into kill buffer */
assert( !(curbp->b_mode & MDVIEW)) ;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
if (n < 0)
return FALSE;
/* make sure there is something to yank */
@ -829,6 +824,7 @@ int yank(int f, int n)
* VIEW (read-only) mode
*/
boolean rdonly( void) {
mloutfmt( "%B(Key illegal in VIEW mode)") ;
return FALSE ;
return mloutfail( "(Key illegal in VIEW mode)") ;
}
/* end of line.c */

35
line.h
View File

@ -1,16 +1,17 @@
#ifndef LINE_H_
#define LINE_H_
/* line.h -- line centric interface */
#ifndef _LINE_H_
#define _LINE_H_
#include "retcode.h"
#include "names.h"
#include "utf8.h"
/*
* All text is kept in circularly linked lists of "struct line" structures.
* These begin at the header line (which is the blank line beyond the end of the
* buffer). This line is pointed to by the "struct buffer". Each line contains a
* number of bytes in the line (the "used" size), the size of the text array,
* and the text. The end of line is not stored as a byte; it's implied. Future
* additions will include update hints, and a list of marks into the line.
/* All text is kept in circularly linked lists of "struct line" structures.
These begin at the header line (which is the blank line beyond the end
of the buffer). This line is pointed to by the "struct buffer". Each
line contains a number of bytes in the line (the "used" size), the size
of the text array, and the text. The end of line is not stored as a
byte; it's implied. Future additions will include update hints, and a
list of marks into the line.
*/
typedef struct line {
struct line *l_fp ; /* Forward link to the next line */
@ -30,12 +31,14 @@ extern int tabwidth ; /* Map to $tab, default to 8, can be set to [1, .. */
char *getkill( void) ;
boolean backchar( int f, int n) ;
boolean forwchar( int f, int n) ;
/* Bindable functions */
BBINDABLE( backchar) ;
BBINDABLE( forwchar) ;
BINDABLE( insspace) ;
BINDABLE( yank) ;
void lfree( line_p lp) ;
void lchange( int flag) ;
int insspace( int f, int n) ;
int linstr( char *instr) ;
int linsert( int n, unicode_t c) ;
boolean linsert_byte( int n, int c) ;
@ -43,13 +46,13 @@ int lover( char *ostr) ;
int lnewline( void) ;
boolean ldelete( long n, boolean kflag) ;
boolean ldelchar( long n, boolean kflag) ;
int lgetchar( unicode_t *) ;
int lgetchar( unicode_t *cref) ;
char *getctext( void) ;
void kdelete( void) ;
int kinsert( int c) ;
int yank( int f, int n) ;
line_p lalloc( int minsize) ; /* Allocate a line of at least minsize chars. */
boolean rdonly( void) ; /* Read Only error message */
#endif /* LINE_H_ */
#endif
/* end of line.h */

2
lock.c
View File

@ -1,6 +1,4 @@
/* lock.c -- implements lock.h */
#include "estruct.h"
#include "lock.h"
/* LOCK.C

9
lock.h
View File

@ -1,16 +1,15 @@
/* lock.h -- */
#ifndef _LOCK_H_
#define _LOCK_H_
#ifndef _ESTRUCT_H_
#error uEmacs compilation settings needs to be done!
#endif
#include "estruct.h"
#if BSD | SVR4
int lockchk( const char *fname) ;
int lockrel( void) ;
int lock( const char *fname) ;
int unlock( const char *fname) ;
#endif
#endif
#endif
/* end of lock.h */

28
main.c
View File

@ -1,9 +1,6 @@
/* main.c -- */
/*
* main.c
*
* µEMACS 4.2
/* µEMACS 4.2
*
* Based on:
*
@ -164,11 +161,10 @@ int main(int argc, char **argv)
}
}
/* Initialize the editor. */
vtinit(); /* Display */
vtinit() ; /* Display */
mloutfmt = mlwrite ;
edinit("main"); /* Buffers, windows */
varinit(); /* user variables */
edinit( "main") ; /* Bindings, buffers, windows */
varinit() ; /* user variables */
viewflag = FALSE; /* view mode defaults off in command line */
gotoflag = FALSE; /* set to off to begin with */
@ -327,14 +323,14 @@ int main(int argc, char **argv)
* as an argument, because the main routine may have been told to read in a
* file by default, and we want the buffer name to be right.
*/
static void edinit(char *bname)
{
struct buffer *bp;
static void edinit( char *bname) {
buffer_p bp;
struct window *wp;
if( NULL == (bp = bfind( bname, TRUE, 0)) /* First buffer */
|| NULL == (blistp = bfind( "*List*", TRUE, BFINVS)) /* Buffer list buffer */
|| NULL == (wp = (struct window *) malloc( sizeof( struct window)))) { /* First window */
if( !init_bindings() /* initialize mapping of function to name and key */
|| NULL == (bp = bfind( bname, TRUE, 0)) /* First buffer */
|| NULL == (blistp = bfind( "*List*", TRUE, BFINVS)) /* Buffer list */
|| NULL == (wp = malloc( sizeof *wp))) { /* First window */
fputs( "First initialisation failed!\n", stderr) ;
exit( EXIT_FAILURE) ;
}
@ -439,7 +435,7 @@ static void dspram( void)
#endif
#endif
/* On some primitave operation systems, and when emacs is used as
/* On some primitive operation systems, and when emacs is used as
a subprogram to a larger project, emacs needs to de-alloc its
own used memory
*/
@ -484,3 +480,5 @@ void cexit( int status) {
exit(status);
}
#endif
/* end of main.c */

View File

@ -9,6 +9,8 @@ set %D3 0
set %D4 -1
set %D5 0
select-buffer maze
# draw the maze layout
$curwidth insert-string " "
newline
@ -98,3 +100,5 @@ write-message $line
set $curline 3
set $curcol 1
set $curchar 32
unmark-buffer

View File

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

View File

@ -1,12 +1,13 @@
/* mlout.h -- message line output interface */
#ifndef __MLOUT_H__
#define __MLOUT_H__
#include "retcode.h"
extern void (*mloutfmt)( const char *, ...) ;
void mloutstr( const char *str) ;
boolean mloutfail( const char *msg) ; /* output with BELL and return FALSE */
#endif /* __MLOUT_H__ */
#endif
/* end of mlout.h */

624
names.c
View File

@ -3,12 +3,14 @@
/* Name to function binding table.
*
* This table gives the names of all the bindable functions
* and their C function address. These are used for the bind-to-key
* function.
*/
* This table gives the names of all the bindable functions and their C
* function address. These are used for the bind-to-key function and
* command line parsing.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "basic.h"
#include "bind.h"
@ -17,6 +19,7 @@
#include "display.h"
#include "eval.h"
#include "exec.h"
#include "execute.h"
#include "file.h"
#include "isearch.h"
#include "line.h"
@ -24,212 +27,415 @@
#include "random.h"
#include "search.h"
#include "spawn.h"
#include "util.h"
#include "window.h"
#include "word.h"
struct name_bind names[] = {
{"abort-command", ctrlg},
{"add-mode", setemode},
{"add-global-mode", setgmode},
#if APROP
{"apropos", apro},
#endif
{"backward-character", (fn_t) backchar},
{"begin-macro", ctlxlp},
{"beginning-of-file", (fn_t) gotobob},
{"beginning-of-line", (fn_t) gotobol},
{"bind-to-key", bindtokey},
{"buffer-position", showcpos},
{"case-region-lower", lowerregion},
{"case-region-upper", upperregion},
{"case-word-capitalize", capword},
{"case-word-lower", lowerword},
{"case-word-upper", upperword},
{"change-file-name", filename},
{"change-screen-size", newsize},
{"change-screen-width", newwidth},
{"clear-and-redraw", redraw},
{"clear-message-line", clrmes},
{"copy-region", copyregion},
#if WORDPRO
{"count-words", wordcount},
#endif
{"ctlx-prefix", cex},
{"delete-blank-lines", deblank},
{"delete-buffer", killbuffer},
{"delete-mode", delmode},
{"delete-global-mode", delgmode},
{"delete-next-character", forwdel},
{"delete-next-word", delfword},
{"delete-other-windows", onlywind},
{"delete-previous-character", backdel},
{"delete-previous-word", delbword},
{"delete-window", delwind},
{"describe-bindings", desbind},
{"describe-key", deskey},
#if AEDIT
{"detab-line", detab},
#endif
{"end-macro", ctlxrp},
{"end-of-file", (fn_t) gotoeob},
{"end-of-line", (fn_t) gotoeol},
#if AEDIT
{"entab-line", entab},
#endif
{"exchange-point-and-mark", (fn_t) swapmark},
{"execute-buffer", execbuf},
{"execute-command-line", execcmd},
{"execute-file", execfile},
{"execute-macro", ctlxe},
{"execute-macro-1", cbuf1},
{"execute-macro-2", cbuf2},
{"execute-macro-3", cbuf3},
{"execute-macro-4", cbuf4},
{"execute-macro-5", cbuf5},
{"execute-macro-6", cbuf6},
{"execute-macro-7", cbuf7},
{"execute-macro-8", cbuf8},
{"execute-macro-9", cbuf9},
{"execute-macro-10", cbuf10},
{"execute-macro-11", cbuf11},
{"execute-macro-12", cbuf12},
{"execute-macro-13", cbuf13},
{"execute-macro-14", cbuf14},
{"execute-macro-15", cbuf15},
{"execute-macro-16", cbuf16},
{"execute-macro-17", cbuf17},
{"execute-macro-18", cbuf18},
{"execute-macro-19", cbuf19},
{"execute-macro-20", cbuf20},
{"execute-macro-21", cbuf21},
{"execute-macro-22", cbuf22},
{"execute-macro-23", cbuf23},
{"execute-macro-24", cbuf24},
{"execute-macro-25", cbuf25},
{"execute-macro-26", cbuf26},
{"execute-macro-27", cbuf27},
{"execute-macro-28", cbuf28},
{"execute-macro-29", cbuf29},
{"execute-macro-30", cbuf30},
{"execute-macro-31", cbuf31},
{"execute-macro-32", cbuf32},
{"execute-macro-33", cbuf33},
{"execute-macro-34", cbuf34},
{"execute-macro-35", cbuf35},
{"execute-macro-36", cbuf36},
{"execute-macro-37", cbuf37},
{"execute-macro-38", cbuf38},
{"execute-macro-39", cbuf39},
{"execute-macro-40", cbuf40},
{"execute-named-command", namedcmd},
#if PROC
{"execute-procedure", execproc},
#endif
{"execute-program", execprg},
{"exit-emacs", quit},
#if WORDPRO
{"fill-paragraph", fillpara},
#endif
{"filter-buffer", filter_buffer},
{"find-file", filefind},
{"forward-character", (fn_t) forwchar},
{"goto-line", gotoline},
#if CFENCE
{"goto-matching-fence", getfence},
#endif
{"grow-window", enlargewind},
{"handle-tab", insert_tab},
{"hunt-forward", forwhunt},
{"hunt-backward", backhunt},
{"help", help},
{"i-shell", spawncli},
#if ISRCH
{"incremental-search", fisearch},
#endif
{"insert-file", insfile},
{"insert-space", insspace},
{"insert-string", istring},
#if WORDPRO
#if PKCODE
{"justify-paragraph", justpara},
#endif
{"kill-paragraph", killpara},
#endif
{"kill-region", killregion},
{"kill-to-end-of-line", killtext},
{"list-buffers", listbuffers},
{"meta-prefix", metafn},
{"move-window-down", mvdnwind},
{"move-window-up", mvupwind},
{"name-buffer", namebuffer},
{"newline", insert_newline},
{"newline-and-indent", indent},
{"next-buffer", nextbuffer},
{"next-line", (fn_t) forwline},
{"next-page", (fn_t) forwpage},
#if WORDPRO
{"next-paragraph", gotoeop},
#endif
{"next-window", nextwind},
{"next-word", forwword},
{"nop", nullproc},
{"open-line", openline},
{"overwrite-string", ovstring},
{"pipe-command", pipecmd},
{"previous-line", (fn_t) backline},
{"previous-page", (fn_t) backpage},
#if WORDPRO
{"previous-paragraph", gotobop},
#endif
{"previous-window", prevwind},
{"previous-word", backword},
{"query-replace-string", qreplace},
{"quick-exit", quickexit},
{"quote-character", quote},
{"read-file", fileread},
{"redraw-display", reposition},
{"resize-window", resize},
{"restore-window", restwnd},
{"replace-string", sreplace},
#if ISRCH
{"reverse-incremental-search", risearch},
#endif
#if PROC
{"run", execproc},
#endif
{"save-file", filesave},
{"save-window", savewnd},
{"scroll-next-up", scrnextup},
{"scroll-next-down", scrnextdw},
{"search-forward", forwsearch},
{"search-reverse", backsearch},
{"select-buffer", usebuffer},
{"set", setvar},
{"set-fill-column", setfillcol},
{"set-mark", (fn_t) setmark},
{"shell-command", spawn},
{"shrink-window", shrinkwind},
{"split-current-window", splitwind},
{"store-macro", storemac},
#if PROC
{"store-procedure", storeproc},
#endif
#if BSD | SVR4
{"suspend-emacs", bktoshell},
#endif
{"transpose-characters", (fn_t) twiddle},
#if AEDIT
{"trim-line", trim},
#endif
{"unbind-key", unbindkey},
{"universal-argument", unarg},
{"unmark-buffer", unmark},
{"update-screen", upscreen},
{"view-file", viewfile},
{"wrap-word", wrapword},
{"write-file", filewrite},
{"write-message", writemsg},
{"yank", yank},
{"", NULL}
};
const name_bind names[] = {
{" abort-command", ctrlg, CTL_ | 'G'} ,
{" add-global-mode", setgmode, META | 'M'} ,
{" add-mode", setemode, CTLX | 'M'} ,
{" apropos", apro, META | 'A'} ,
{" backward-character", (fnp_t) backchar, CTL_ | 'B'} ,
{" begin-macro", (fnp_t) ctlxlp, CTLX | '('} ,
{" beginning-of-file", (fnp_t) gotobob, META | '<'} ,
{" beginning-of-line", (fnp_t) gotobol, CTL_ | 'A'} ,
{" bind-to-key", bindtokey, META | 'K'} ,
{" buffer-position", showcpos, CTLX | '='} ,
{"!case-region-lower", lowerregion, CTLX | CTL_ | 'L'} ,
{"!case-region-upper", upperregion, CTLX | CTL_ | 'U'} ,
{"!case-word-capitalize", capword, META | 'C'} ,
{"!case-word-lower", lowerword, META | 'L'} ,
{"!case-word-upper", upperword, META | 'U'} ,
{" change-file-name", filename, CTLX | 'N'} ,
{" change-screen-size", newsize, META | CTL_ | 'D'} , /* M^S */
{" change-screen-width", newwidth, META | CTL_ | 'T'} ,
{" clear-and-redraw", (fnp_t) redraw, CTL_ | 'L'} ,
{" clear-message-line", (fnp_t) clrmes, 0} ,
{" copy-region", copyregion, META | 'W'} ,
{" count-words", wordcount, META | CTL_ | 'C'} ,
{" ctlx-prefix", (fnp_t) cex, CTL_ | 'X'} ,
{"!delete-blank-lines", deblank, CTLX | CTL_ | 'O'} ,
{" delete-buffer", killbuffer, CTLX | 'K'} ,
{" delete-global-mode", delgmode, META | CTL_ | 'M'} ,
{" delete-mode", delmode, CTLX | CTL_ | 'M'} ,
{"!delete-next-character", forwdel, CTL_ | 'D'} ,
{"!delete-next-word", delfword, META | 'D'} ,
{" delete-other-windows", onlywind, CTLX | '1'} ,
{"!delete-previous-character", backdel, CTL_ | 'H'} , /* ^? */
{"!delete-previous-word", delbword, META | CTL_ | 'H'} , /* M^? */
{" delete-window", delwind, CTLX | '0'} ,
{" describe-bindings", desbind, 0} ,
{" describe-key", deskey, CTLX | '?'} ,
{"!detab-line", detab, CTLX | CTL_ | 'D'} , /* X^A */
{" end-macro", (fnp_t) ctlxrp, CTLX | ')'} ,
{" end-of-file", (fnp_t) gotoeob, META | '>'} ,
{" end-of-line", (fnp_t) gotoeol, CTL_ | 'E'} ,
{"!entab-line", entab, CTLX | CTL_ | 'E'} ,
{" exchange-point-and-mark", (fnp_t) swapmark, CTLX | CTL_ | 'X'} ,
{" execute-buffer", execbuf, 0} ,
{" execute-command-line", execcmd, 0} ,
{" execute-file", execfile, 0} ,
{" execute-macro", (fnp_t) ctlxe, CTLX | 'E'} ,
{" execute-macro-1", cbuf1, 0} ,
{" execute-macro-10", cbuf10, 0} ,
{" execute-macro-11", cbuf11, 0} ,
{" execute-macro-12", cbuf12, 0} ,
{" execute-macro-13", cbuf13, 0} ,
{" execute-macro-14", cbuf14, 0} ,
{" execute-macro-15", cbuf15, 0} ,
{" execute-macro-16", cbuf16, 0} ,
{" execute-macro-17", cbuf17, 0} ,
{" execute-macro-18", cbuf18, 0} ,
{" execute-macro-19", cbuf19, 0} ,
{" execute-macro-2", cbuf2, 0} ,
{" execute-macro-20", cbuf20, 0} ,
{" execute-macro-21", cbuf21, 0} ,
{" execute-macro-22", cbuf22, 0} ,
{" execute-macro-23", cbuf23, 0} ,
{" execute-macro-24", cbuf24, 0} ,
{" execute-macro-25", cbuf25, 0} ,
{" execute-macro-26", cbuf26, 0} ,
{" execute-macro-27", cbuf27, 0} ,
{" execute-macro-28", cbuf28, 0} ,
{" execute-macro-29", cbuf29, 0} ,
{" execute-macro-3", cbuf3, 0} ,
{" execute-macro-30", cbuf30, 0} ,
{" execute-macro-31", cbuf31, 0} ,
{" execute-macro-32", cbuf32, 0} ,
{" execute-macro-33", cbuf33, 0} ,
{" execute-macro-34", cbuf34, 0} ,
{" execute-macro-35", cbuf35, 0} ,
{" execute-macro-36", cbuf36, 0} ,
{" execute-macro-37", cbuf37, 0} ,
{" execute-macro-38", cbuf38, 0} ,
{" execute-macro-39", cbuf39, 0} ,
{" execute-macro-4", cbuf4, 0} ,
{" execute-macro-40", cbuf40, 0} ,
{" execute-macro-5", cbuf5, 0} ,
{" execute-macro-6", cbuf6, 0} ,
{" execute-macro-7", cbuf7, 0} ,
{" execute-macro-8", cbuf8, 0} ,
{" execute-macro-9", cbuf9, 0} ,
{" execute-named-command", namedcmd, META | 'X'} ,
{" execute-procedure", execproc, META | CTL_ | 'E'} ,
{" execute-program", execprg, CTLX | '$'} ,
{" exit-emacs", quit, CTLX | CTL_ | 'C'} ,
{"!fill-paragraph", fillpara, META | 'Q'} ,
{"!filter-buffer", filter_buffer, CTLX | '#'} ,
{" find-file", filefind, CTLX | CTL_ | 'F'} ,
{" forward-character", (fnp_t) forwchar, CTL_ | 'F'} ,
{" goto-line", gotoline, META | 'G'} ,
#if CFENCE
{" goto-matching-fence", getfence, META | CTL_ | 'F'} ,
#endif
{" grow-window", enlargewind, CTLX | 'Z'} , /* X^ */
{"!handle-tab", insert_tab, CTL_ | 'I'} ,
{" help", help, META | '?'} ,
{" hunt-backward", backhunt, 0} ,
{" hunt-forward", forwhunt, META | 'S'} ,
{" i-shell", spawncli, CTLX | 'C'} ,
{" incremental-search", fisearch, CTLX | 'S'} ,
{"!insert-file", insfile, CTLX | CTL_ | 'I'} ,
{"!insert-space", insspace, CTL_ | 'C'} ,
{"!insert-string", istring, 0} ,
#if PKCODE
{"!justify-paragraph", justpara, META | 'J'} ,
#endif
{"!kill-paragraph", killpara, META | CTL_ | 'W'} ,
{"!kill-region", killregion, CTL_ | 'W'} ,
{"!kill-to-end-of-line", killtext, CTL_ | 'K'} ,
{" list-buffers", listbuffers, CTLX | CTL_ | 'B'} ,
{" meta-prefix", (fnp_t) metafn, CTL_ | '['} ,
{" move-window-down", mvdnwind, CTLX | CTL_ | 'N'} ,
{" move-window-up", mvupwind, CTLX | CTL_ | 'P'} ,
{" name-buffer", namebuffer, META | CTL_ | 'N'} ,
{"!newline", insert_newline, CTL_ | 'M'} ,
{"!newline-and-indent", indent, CTL_ | 'J'} ,
{" next-buffer", nextbuffer, CTLX | 'X'} ,
{" next-line", (fnp_t) forwline, CTL_ | 'N'} ,
{" next-page", (fnp_t) forwpage, CTL_ | 'V'} ,
{" next-paragraph", gotoeop, META | 'N'} ,
{" next-window", nextwind, CTLX | 'O'} ,
{" next-word", forwword, META | 'F'} ,
{" nop", (fnp_t) nullproc, META | SPEC | 'C'}, /* hook */
{"!open-line", openline, CTL_ | 'O'} ,
{"!overwrite-string", ovstring, 0} ,
{" pipe-command", pipecmd, CTLX | '@'} ,
{" previous-line", (fnp_t) backline, CTL_ | 'P'} ,
{" previous-page", (fnp_t) backpage, CTL_ | 'Z'} , /* MV */
{" previous-paragraph", gotobop, META | 'P'} ,
{" previous-window", prevwind, CTLX | 'P'} ,
{" previous-word", backword, META | 'B'} ,
{"!query-replace-string", qreplace, META | CTL_ | 'R'} ,
{" quick-exit", quickexit, META | 'Z'} ,
{"!quote-character", quote, CTL_ | 'Q'} ,
{"!read-file", fileread, CTLX | CTL_ | 'R'} ,
{" redraw-display", (fnp_t) reposition, META | CTL_ | 'L'} ,
{"!replace-string", sreplace, META | 'R'} ,
{" resize-window", resize, CTLX | 'W'} ,
{" restore-window", restwnd, 0} ,
{" reverse-incremental-search", risearch, CTLX | 'R'} ,
{" run", execproc, 0} , /* alias of execute-procedure */
{"!save-file", filesave, CTLX | CTL_ | 'S'} , /* also X^D */
{" save-window", savewnd, 0} ,
{" scroll-next-down", scrnextdw, META | CTL_ | 'V'} ,
{" scroll-next-up", scrnextup, META | CTL_ | 'Z'} ,
{" search-forward", forwsearch, CTL_ | 'S'} ,
{" search-reverse", backsearch, CTL_ | 'R'} ,
{" select-buffer", usebuffer, CTLX | 'B'} ,
{" set", setvar, CTLX | 'A'} ,
{" set-fill-column", setfillcol, CTLX | 'F'} ,
{" set-mark", (fnp_t) setmark, META | ' '} , /* M. */
{" shell-command", spawn, CTLX | '!'} ,
{" shrink-window", shrinkwind, CTLX | CTL_ | 'Z'} ,
{" split-current-window", splitwind, CTLX | '2'} ,
{" store-macro", storemac, 0} ,
{" store-procedure", storeproc, 0} ,
#if BSD | SVR4
{" suspend-emacs", bktoshell, CTLX | 'D'} , /* BSD MS */
#endif
{"!transpose-characters", (fnp_t) twiddle, CTL_ | 'T'} ,
{"!trim-line", trim, CTLX | CTL_ | 'T'} ,
{" unbind-key", unbindkey, META | CTL_ | 'K'} ,
{" universal-argument", (fnp_t) unarg, CTL_ | 'U'} ,
{" unmark-buffer", unmark, META | '~'} ,
{" update-screen", upscreen, 0} ,
{" view-file", viewfile, CTLX | CTL_ | 'V'} ,
{"!wrap-word", wrapword, META | SPEC | 'W'} , /* hook */
{" write-file", filewrite, CTLX | CTL_ | 'W'} ,
{" write-message", writemsg, 0} ,
{"!yank", yank, CTL_ | 'Y'} ,
{" ", NULL, 0},
/* extra key mapping */
// { NULL, newsize, META | CTL_ | 'S'},
{ NULL, backdel, CTL_ | '?'},
{ NULL, delbword, META | CTL_ | '?'},
{ NULL, detab, CTLX | CTL_ | 'A'},
{ NULL, enlargewind, CTLX | '^'},
{ NULL, (fnp_t) backpage, META | 'V'},
{ NULL, quote, CTLX | 'Q'},
{ NULL, (fnp_t) reposition, META | '!'},
//detab { NULL, filesave, CTLX | CTL_ | 'D'},
{ NULL, (fnp_t) setmark, META | '.'},
// { NULL, bktoshell, META | 'S'},
/* special key mapping */
{ NULL, yank, SPEC | '2'}, /* Insert */
{ NULL, forwdel /* killregion */, SPEC | '3'}, /* Delete */
{ NULL, (fnp_t) backpage, SPEC | '5'}, /* Page Up */
{ NULL, (fnp_t) forwpage, SPEC | '6'}, /* Page Down */
{ NULL, (fnp_t) backline, SPEC | 'A'}, /* Up */
{ NULL, (fnp_t) forwline, SPEC | 'B'}, /* Down */
{ NULL, (fnp_t) forwchar, SPEC | 'C'}, /* Right */
{ NULL, (fnp_t) backchar, SPEC | 'D'}, /* Left */
{ NULL, (fnp_t) gotoeob, SPEC | 'F'}, /* End */
{ NULL, (fnp_t) gotobob, SPEC | 'H'}, /* Home */
{ NULL, help, SPEC | 'P'}, /* F1 */
/* hooks */
{ NULL, (fnp_t) nullproc, META | SPEC | 'R'}, /* hook */
{ NULL, (fnp_t) nullproc, META | SPEC | 'X'}, /* hook */
{ NULL, NULL, 0}
} ;
static int lastnmidx = 0 ; /* index of last name entry */
kbind_p keytab ;
static int ktsize = 140 ; /* last check: need at least 133 + 1 */
boolean init_bindings( void) {
/* allocate table */
keytab = malloc( ktsize * sizeof *keytab) ;
if( keytab == NULL)
return FALSE ;
/* insert end of table mark */
keytab->k_code = 0 ;
keytab->k_nbp = NULL ;
/* Add default key bindings */
nbind_p nbp ;
for( nbp = names ; nbp->n_func != NULL ; nbp++) {
/* Check entries and strict order */
assert( (nbp->n_name != NULL) &&
((nbp == names) ||
(0 > strcmp( bind_name( nbp - 1), bind_name( nbp)))
)
) ;
/* Add key definition */
if( nbp->n_keycode) {
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
* key code re-definition */
assert( (++ktp)->k_code == 0) ;
}
}
/* memorize position after last valid function entry */
lastnmidx = nbp - names ;
/* Process extra key bindings if any */
for( nbp++ ; nbp->n_func != NULL ; nbp++) {
/* Check entry: a keycode and no name */
assert( nbp->n_keycode && (nbp->n_name == NULL)) ;
/* Look for corresponding function and add extra key binding */
nbind_p fnbp ;
for( fnbp = names ; fnbp->n_func != NULL ; fnbp++)
if( fnbp->n_func == nbp->n_func) {
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 ;
}
/* Insure there is a name entry for the keycode */
assert( fnbp->n_func != NULL) ;
}
return TRUE ;
}
kbind_p setkeybinding( unsigned key, nbind_p nbp) {
kbind_p ktp ;
/* search the table to see if it exists */
for( ktp = keytab ; ktp->k_code != 0 ; ktp++)
if( ktp->k_code == key) {
/* it exists, just change it then */
ktp->k_nbp = nbp ;
return ktp ;
}
/* otherwise we need to add it to the end */
/* check if the end marker is at the end of the table */
if( ktp == &keytab[ ktsize - 1]) {
/* out of binding room */
int newsize = ktsize + 10 ;
kbind_p newkeytab = realloc( keytab, newsize * sizeof *keytab) ;
if( newkeytab == NULL)
/* out of space */
return ktp ;
keytab = newkeytab ;
ktp = &keytab[ ktsize - 1] ;
ktsize = newsize ;
}
ktp->k_code = key ; /* add keycode */
ktp->k_nbp = nbp ;
++ktp ; /* and make sure the next is null */
ktp->k_code = 0 ;
ktp->k_nbp = NULL ;
return ktp - 1 ;
}
boolean delkeybinding( unsigned key) {
kbind_p ktp ; /* pointer into the key binding table */
/* search the table to see if the key exists */
for( ktp = keytab ; ktp->k_code != 0 ; ktp++) {
if( ktp->k_code == key) {
/* save the pointer and scan to the end of the table */
kbind_p sav_ktp = ktp ;
while( (++ktp)->k_code != 0) ;
ktp -= 1 ; /* backup to the last legit entry */
/* copy the last entry to the current one */
sav_ktp->k_code = ktp->k_code ;
sav_ktp->k_nbp = ktp->k_nbp ;
/* null out the last one */
ktp->k_code = 0 ;
ktp->k_nbp = NULL ;
return TRUE ;
}
}
return FALSE ;
}
/* This function looks a key binding up in the binding table
*
* int c; key to find what is bound to it
*/
kbind_p getkeybinding( unsigned c) {
kbind_p ktp ;
for( ktp = keytab ; ktp->k_code != 0 ; ktp++)
if (ktp->k_code == c)
break ;
return ktp ;
}
#define BINARY 1
nbind_p fncmatch( char *name) {
#ifdef BINARY
int found = lastnmidx ;
int low = 0 ;
int high = found - 1 ;
do {
int cur = (high + low) / 2 ;
int s = strcmp( name, bind_name( &names[ cur])) ;
if( s < 0)
high = cur - 1 ;
else if( s == 0) {
found = cur ;
break ;
} else
low = cur + 1 ;
} while( low <= high) ;
return &names[ found] ;
#else
nbind_p nbp ;
for( nbp = names ; nbp->n_func != NULL ; nbp++)
if( !strcmp( name, bind_name( nbp)))
break ;
return nbp ;
#endif
}
/* user function that does NOTHING (bound to hooks) */
TBINDABLE( nullproc) {
return TRUE ;
}
/* dummy function for binding to meta prefix */
TBINDABLE( metafn) {
return TRUE ;
}
/* dummy function for binding to control-x prefix */
TBINDABLE( cex) {
return TRUE ;
}
/* dummy function for binding to universal-argument */
TBINDABLE( unarg) {
return TRUE ;
}
/* end of names.c */

64
names.h
View File

@ -1,8 +1,62 @@
/* names.h -- mapping of functions to names and keys */
#ifndef _NAMES_H_
#define _NAMES_H_
#include "retcode.h"
#define CTL_ 0x01000000 /* Control flag, or'ed in */
#define META 0x02000000 /* Meta flag, or'ed in */
#define CTLX 0x04000000 /* ^X flag, or'ed in */
#define SPEC 0x08000000 /* special key (function keys) */
#define PRFXMASK 0x0F000000 /* prefix mask */
/* Bindable uEMACS function pointer type and definition template */
#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)) ;
/* Structure for the name binding table. */
struct name_bind {
char *n_name; /* name of function key */
int (*n_func)(int, int); /* function name is bound to */
};
typedef struct {
const char *n_name ; /* name starting with one tag character */
fnp_t n_func ; /* function the name is bound to */
unsigned n_keycode ; /* default key assignment, 0 when none */
} name_bind ;
extern struct name_bind names[];/* name to function table */
typedef const name_bind *nbind_p ;
#define bind_name( p) (&( p)->n_name[ 1])
#define bind_tag( p) ( p)->n_name[ 0]
/* Structure for the key bindings table. */
typedef struct {
unsigned k_code ; /* Key code */
nbind_p k_nbp ; /* entry in name to function map table */
} *kbind_p ;
extern const name_bind names[] ; /* name to function mapping table */
extern kbind_p keytab ; /* key bind to functions table */
boolean init_bindings( void) ;
kbind_p setkeybinding( unsigned key, nbind_p nbp) ;
boolean delkeybinding( unsigned key) ;
kbind_p getkeybinding( unsigned key) ; /* look up by key code */
/* find a name to function association in the name to function mapping table */
nbind_p fncmatch( char *name) ; /* look up by name */
/* bindable functions mapped to prefix keys and hooks */
TBINDABLE( nullproc) ;
TBINDABLE( metafn) ;
TBINDABLE( cex) ;
TBINDABLE( unarg) ;
#endif
/* end of names.h */

View File

@ -1,5 +1,4 @@
/* pklock.c -- implements pklock.h */
#include "estruct.h"
#include "pklock.h"
/* PKLOCK.C

View File

@ -1,15 +1,13 @@
/* pklock.h -- */
#ifndef _PKLOCK_H_
#define _PKLOCK_H_
#ifndef _ESTRUCT_H_
#error uEmacs compilation settings needs to be done!
#endif
#include "estruct.h"
#if (FILOCK && BSD) || SVR4
char *dolock( const char *fname) ;
char *undolock( const char *fname) ;
#endif
#endif
/* end of pklock.h */

483
random.c
View File

@ -1,14 +1,13 @@
/* random.c -- implements random.h */
#include "random.h"
/* random.c
*
* This file contains the command processing functions for a number of
* random commands. There is no functional grouping here, for sure.
*
* Modified by Petri Kutvonen
/* This file contains the command processing functions for a number of
random commands. There is no functional grouping here, for sure.
Modified by Petri Kutvonen
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -50,26 +49,22 @@ int lastflag ; /* Flags, last command */
static int adjustmode( int kind, int global) ;
static int cinsert( void) ;
/*
* Set fill column to n.
/* Set fill column to n. Bound to C-X F set-fill-column.
*/
int setfillcol(int f, int n)
{
fillcol = n;
mlwrite("(Fill column is %d)", n);
return TRUE;
BINDABLE( setfillcol) {
fillcol = n ;
mlwrite( "(Fill column is %d)", n) ;
return TRUE ;
}
/*
* Display the current position of the cursor, in origin 1 X-Y coordinates,
* the character that is under the cursor (in hex), and the fraction of the
* text that is before the cursor. The displayed column is not the current
* column, but the column that would be used on an infinite width display.
* Normally this is bound to "C-X =".
/* Display the current position of the cursor, in origin 1 X-Y coordinates,
the character that is under the cursor (in hex), and the fraction of the
text that is before the cursor. The displayed column is not the current
column, but the column that would be used on an infinite width display.
Normally this is bound to C-X = buffer-position.
*/
int showcpos(int f, int n)
{
struct line *lp; /* current line */
BINDABLE( showcpos) {
line_p lp ; /* current line */
long numchars; /* # of chars in file */
int numlines; /* # of lines in file */
long predchars; /* # chars preceding point */
@ -127,7 +122,7 @@ int showcpos(int f, int n)
int getcline(void)
{ /* get the current line number */
struct line *lp; /* current line */
line_p lp ; /* current line */
int numlines; /* # of lines before point */
/* starting at the beginning of the buffer */
@ -147,15 +142,13 @@ int getcline(void)
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 i, col;
struct line *dlp = curwp->w_dotp;
int byte_offset = curwp->w_doto;
int len = llength(dlp);
int getccol( int bflg) {
int i, col ;
line_p dlp = curwp->w_dotp ;
int byte_offset = curwp->w_doto ;
int len = llength( dlp) ;
col = i = 0;
while (i < byte_offset) {
@ -163,17 +156,19 @@ int getccol(int bflg)
i += utf8_to_unicode(dlp->l_text, i, len, &c);
if( bflg && c != ' ' && c != '\t') /* Request Stop at first non-blank */
break;
break ;
if (c == '\t')
col += tabwidth - col % tabwidth ;
else if (c < 0x20 || c == 0x7F) /* displayed as ^c */
col += 2 ;
else if (c >= 0x80 && c <= 0xa0) /* displayed as \xx */
col += 3 ;
else
col += 1 ;
else {
col += utf8_width( c) ;
}
return col;
}
return col ;
}
/*
@ -214,22 +209,21 @@ boolean setccol( int pos) {
return col >= pos;
}
/*
* Twiddle the two characters on either side of dot. If dot is at the end of
* the line twiddle the two characters before it. Return with an error if dot
* is at the beginning of line; it seems to be a bit pointless to make this
* work. This fixes up a very common typo with a single stroke. Normally bound
* to "C-T". This always works within a line, so "WFEDIT" is good enough.
/* Twiddle the two characters on either side of dot. If dot is at the end
of the line twiddle the two characters before it. Return with an error
if dot is at the beginning of line; it seems to be a bit pointless to
make this work. This fixes up a very common typo with a single stroke.
Normally bound to "C-T". This always works within a line, so "WFEDIT"
is good enough.
*/
boolean twiddle( int f, int n) {
BBINDABLE( twiddle) {
unicode_t c ;
int len ;
boolean eof_f = FALSE ;
if( curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly() ; /* we are in read only mode */
assert( !(curbp->b_mode & MDVIEW)) ;
len = llength( curwp->w_dotp) ;
int len = llength( curwp->w_dotp) ;
if( len < 2 || curwp->w_doto == 0) /* at least 2 chars & not bol */
return FALSE ;
@ -253,42 +247,36 @@ boolean twiddle( int f, int n) {
return TRUE ;
}
/*
* Quote the next character, and insert it into the buffer. All the characters
* are taken literally, with the exception of the newline, which always has
* its line splitting meaning. The character is always read, even if it is
* inserted 0 times, for regularity. Bound to "C-Q"
/* Quote the next character, and insert it into the buffer. All the
characters are taken literally, with the exception of the newline, which
always has its line splitting meaning. The character is always read,
even if it is inserted 0 times, for regularity. Bound to C-Q
quote-character.
*/
int quote(int f, int n)
{
int c;
BINDABLE( quote) {
int ret ;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
c = tgetc();
if (n < 0)
return FALSE;
if (n == 0)
return TRUE;
if (c == '\n') {
int s ;
assert( !(curbp->b_mode & MDVIEW)) ;
do {
s = lnewline();
} while (s == TRUE && --n);
return s;
}
return linsert(n, c);
int c = ectoc( get1key()) ;
if( n < 0)
ret = FALSE ;
else if( n == 0)
ret = TRUE ;
else if( c == '\n')
do
ret = lnewline() ;
while( ret == TRUE && --n) ;
else
ret = linsert( n, c) ;
return ret ;
}
/*
* Set tab size if given non-default argument (n <> 1). Otherwise, insert a
* tab into file. If given argument, n, of zero, change to true tabs.
* If n > 1, simulate tab stop every n-characters using spaces. This has to be
* done in this slightly funny way because the tab (in ASCII) has been turned
* into "C-I" (in 10 bit code) already. Bound to "C-I".
/* Insert tab/blank/space up to nth next tabulation according to hard/soft
tab current state and tab width. Bound to C-I handle-tab.
*/
int insert_tab( int f, int n) {
BINDABLE( insert_tab) {
int status ;
if( n < 0)
@ -305,25 +293,20 @@ int insert_tab( int f, int n) {
return status ;
}
#if AEDIT
/*
* change tabs to spaces
*
* int f, n; default flag and numeric repeat count
*/
int detab(int f, int n)
{
int inc; /* increment to next line [sgn(n)] */
BINDABLE( detab) {
assert( !(curbp->b_mode & MDVIEW)) ;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
if (f == FALSE)
n = 1;
if( f == FALSE)
n = 1 ;
/* loop thru detabbing n lines */
inc = ((n > 0) ? 1 : -1);
while (n) {
int inc = (n > 0) ? 1 : -1 ; /* increment to next line [sgn(n)] */
for( ; n ; n -= inc) {
curwp->w_doto = 0; /* start at the beginning */
/* detab the entire current line */
@ -343,9 +326,8 @@ int detab(int f, int n)
/* advance/or back to the next line */
if( forwline( TRUE, inc) == FALSE)
break ;
n -= inc;
}
curwp->w_doto = 0; /* to the begining of the line */
thisflag &= ~CFCPCN; /* flag that this resets the goal column */
lchange(WFEDIT); /* yes, we have made at least an edit */
@ -353,25 +335,21 @@ int detab(int f, int n)
}
/*
* change spaces to tabs where posible
* change spaces to tabs where possible
*
* int f, n; default flag and numeric repeat count
*/
int entab(int f, int n)
{
BINDABLE( entab) {
#define nextab(a) (a + tabwidth - a % tabwidth)
int inc; /* increment to next line [sgn(n)] */
assert( !(curbp->b_mode & MDVIEW)) ;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
if (f == FALSE)
n = 1;
if( f == FALSE)
n = 1 ;
/* loop thru entabbing n lines */
inc = ((n > 0) ? 1 : -1);
while (n) {
int inc = (n > 0) ? 1 : -1 ; /* increment to next line [sgn(n)] */
for( ; n ; n -= inc) {
int fspace ; /* pointer to first space if in a run */
int ccol ; /* current cursor column */
@ -418,9 +396,8 @@ int entab(int f, int n)
/* advance/or back to the next line */
if( forwline( TRUE, inc) == FALSE)
break ;
n -= inc;
}
curwp->w_doto = 0; /* to the begining of the line */
thisflag &= ~CFCPCN; /* flag that this resets the goal column */
lchange(WFEDIT); /* yes, we have made at least an edit */
@ -432,19 +409,15 @@ int entab(int f, int n)
*
* int f, n; default flag and numeric repeat count
*/
int trim(int f, int n)
{
int inc; /* increment to next line [sgn(n)] */
BINDABLE( trim) {
assert( !(curbp->b_mode & MDVIEW)) ;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
if (f == FALSE)
n = 1;
if( f == FALSE)
n = 1 ;
/* loop thru trimming n lines */
inc = ((n > 0) ? 1 : -1);
while (n) {
int inc = (n > 0) ? 1 : -1 ; /* increment to next line [sgn(n)] */
for( ; n ; n -= inc) {
line_p lp ; /* current line pointer */
int offset ; /* original line offset position */
int length ; /* current length */
@ -464,50 +437,40 @@ int trim(int f, int n)
/* advance/or back to the next line */
if( forwline( TRUE, inc) == FALSE)
break ;
n -= inc;
}
lchange(WFEDIT);
thisflag &= ~CFCPCN; /* flag that this resets the goal column */
return (n == 0) ? TRUE : FALSE ;
}
#endif
/*
* Open up some blank space. The basic plan is to insert a bunch of newlines,
* and then back up over them. Everything is done by the subcommand
* procerssors. They even handle the looping. Normally this is bound to "C-O".
*/
int openline(int f, int n)
{
int i;
int s;
BINDABLE( openline) {
assert( !(curbp->b_mode & MDVIEW)) ;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
if (n < 0)
return FALSE;
if (n == 0)
return TRUE;
i = n; /* Insert newlines. */
do {
s = lnewline();
} while (s == TRUE && --i);
if (s == TRUE) /* Then back up overtop */
s = backchar(f, n); /* of them all. */
return s;
int ret = (n < 0) ? FALSE : TRUE ;
for( int i = n ; ret == TRUE && i ; i--) /* Insert newlines. */
ret = lnewline() ;
if( ret == TRUE) /* Then back up overtop */
ret = backchar( f, n) ; /* of them all. */
return ret ;
}
/*
* Insert a newline. Bound to "C-M". If we are in CMODE, do automatic
* indentation as specified.
*/
int insert_newline(int f, int n)
{
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
if (n < 0)
return FALSE;
BINDABLE( insert_newline) {
assert( !(curbp->b_mode & MDVIEW)) ;
if( n < 0)
return FALSE ;
/* if we are in C mode and this is a default <NL> */
if (n == 1 && (curbp->b_mode & MDCMOD) &&
@ -596,22 +559,19 @@ static int cinsert(void)
}
/*
* Delete blank lines around dot. What this command does depends if dot is
* sitting on a blank line. If dot is sitting on a blank line, this command
* deletes all the blank lines above and below the current line. If it is
* sitting on a non blank line then it deletes all of the blank lines after
* the line. Normally this command is bound to "C-X C-O". Any argument is
* ignored.
/* Delete blank lines around dot. What this command does depends if dot is
* sitting on a blank line. If dot is sitting on a blank line, this
* command deletes all the blank lines above and below the current line.
* If it is sitting on a non blank line then it deletes all of the blank
* lines after the line. Normally this command is bound to C-X C-O
* delete-blank-lines. Any argument is ignored.
*/
int deblank(int f, int n)
{
struct line *lp1;
struct line *lp2;
long nld;
BINDABLE( deblank) {
line_p lp1, lp2 ;
long nld ;
assert( !(curbp->b_mode & MDVIEW)) ;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
lp1 = curwp->w_dotp;
while (llength(lp1) == 0 && (lp2 = lback(lp1)) != curbp->b_linep)
lp1 = lp2;
@ -626,26 +586,24 @@ int deblank(int f, int n)
return ldelete(nld, FALSE);
}
/*
* Insert a newline, then enough tabs and spaces to duplicate the indentation
* of the previous line. Assumes tabs are every tabwidth characters.
* Figure out the indentation of the current line. Insert a newline by calling
* the standard routine. Insert the indentation by inserting the right number
* of tabs and spaces. Return TRUE if all ok. Return FALSE if one of the
* subcomands failed. Normally bound to "C-J".
/* Insert a newline, then enough tabs and spaces to duplicate the
* indentation of the previous line. Assumes tabs are every tabwidth
* characters. Figure out the indentation of the current line. Insert a
* newline by calling the standard routine. Insert the indentation by
* inserting the right number of tabs and spaces. Return TRUE if all ok.
* Return FALSE if one of the subcomands failed. Normally bound to C-J
* newline-and-indent.
*/
int indent( int f, int n) {
int nicol ;
BINDABLE( indent) {
int i ;
if( curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly() ; /* we are in read only mode */
assert( !(curbp->b_mode & MDVIEW)) ;
if( n < 0)
return FALSE ;
/* number of columns to indent */
nicol = 0 ;
int nicol = 0 ;
for( i = 0 ; i < llength( curwp->w_dotp) ; i += 1) {
int c ;
@ -675,9 +633,8 @@ int indent( int f, int n) {
* If any argument is present, it kills rather than deletes, to prevent loss
* of text if typed with a big argument. Normally bound to "C-D".
*/
int forwdel( int f, int n) {
if( curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly() ; /* we are in read only mode */
BINDABLE( forwdel) {
assert( !(curbp->b_mode & MDVIEW)) ;
if( n == 0)
return TRUE ;
@ -699,9 +656,8 @@ int forwdel( int f, int n) {
* forward, this actually does a kill if presented with an argument. Bound to
* both "RUBOUT" and "C-H".
*/
int backdel( int f, int n) {
if( curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly() ; /* we are in read only mode */
BINDABLE( backdel) {
assert( !(curbp->b_mode & MDVIEW)) ;
if( n == 0)
return TRUE ;
@ -725,13 +681,12 @@ int backdel( int f, int n) {
* number of newlines. If called with a negative argument it kills backwards
* that number of newlines. Normally bound to "C-K".
*/
int killtext(int f, int n)
{
struct line *nextp;
BINDABLE( killtext) {
line_p nextp ;
long chunk;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
assert( !(curbp->b_mode & MDVIEW)) ;
if ((lastflag & CFKILL) == 0) /* Clear kill buffer if */
kdelete(); /* last wasn't a kill. */
thisflag |= CFKILL;
@ -758,64 +713,44 @@ int killtext(int f, int n)
return ldelete(chunk, TRUE);
}
/*
* prompt and set an editor mode
/* prompt and set an editor mode
*
* int f, n; default and argument
*/
int setemode(int f, int n)
{
#if PKCODE
return adjustmode(TRUE, FALSE);
#else
adjustmode(TRUE, FALSE);
#endif
BINDABLE( setemode) {
return adjustmode( TRUE, FALSE) ;
}
/*
* prompt and delete an editor mode
/* prompt and delete an editor mode
*
* int f, n; default and argument
*/
int delmode(int f, int n)
{
#if PKCODE
return adjustmode(FALSE, FALSE);
#else
adjustmode(FALSE, FALSE);
#endif
BINDABLE( delmode) {
return adjustmode( FALSE, FALSE) ;
}
/*
* prompt and set a global editor mode
/* prompt and set a global editor mode
*
* int f, n; default and argument
*/
int setgmode(int f, int n)
{
#if PKCODE
return adjustmode(TRUE, TRUE);
#else
adjustmode(TRUE, TRUE);
#endif
BINDABLE( setgmode) {
return adjustmode( TRUE, TRUE) ;
}
/*
* prompt and delete a global editor mode
/* prompt and delete a global editor mode
*
* int f, n; default and argument
*/
int delgmode(int f, int n)
{
#if PKCODE
return adjustmode(FALSE, TRUE);
#else
adjustmode(FALSE, TRUE);
#endif
BINDABLE( delgmode) {
return adjustmode( FALSE, TRUE) ;
}
/*
* change the editor mode status
/* change the editor mode status
*
* int kind; true = set, false = delete
* int global; true = global flag, false = current buffer flag
@ -900,103 +835,12 @@ static int adjustmode( int kind, int global) {
return FALSE;
}
#if CFENCE
/*
* the cursor is moved to a matching fence
*
* int f, n; not used
*/
int getfence(int f, int n)
{
struct line *oldlp; /* original line pointer */
int oldoff; /* and offset */
int sdir; /* direction of search (1/-1) */
int count; /* current fence level count */
char ch; /* fence type to match against */
char ofence; /* open fence */
char c; /* current character in scan */
/* save the original cursor position */
oldlp = curwp->w_dotp;
oldoff = curwp->w_doto;
/* get the current character */
if (oldoff == llength(oldlp))
ch = '\n';
else
ch = lgetc(oldlp, oldoff);
/* setup proper matching fence */
switch (ch) {
case '(':
ofence = ')';
sdir = FORWARD;
break;
case '{':
ofence = '}';
sdir = FORWARD;
break;
case '[':
ofence = ']';
sdir = FORWARD;
break;
case ')':
ofence = '(';
sdir = REVERSE;
break;
case '}':
ofence = '{';
sdir = REVERSE;
break;
case ']':
ofence = '[';
sdir = REVERSE;
break;
default:
TTbeep();
return FALSE;
}
/* scan until we find a match, or reach the end of file */
count = 1 ;
do {
if( boundry( curwp->w_dotp, curwp->w_doto, sdir)) {
/* at buffer limit, no match to be found */
/* restore the current position */
curwp->w_dotp = oldlp ;
curwp->w_doto = oldoff ;
TTbeep() ;
return FALSE ;
}
if( sdir == FORWARD)
forwchar( FALSE, 1) ;
else
backchar( FALSE, 1) ;
/* if no eol */
if( curwp->w_doto != llength(curwp->w_dotp)) {
c = curwbyte() ;
if( c == ch)
++count ;
else if( c == ofence)
--count ;
}
} while( count > 0) ;
/* we have a match, move the sucker */
curwp->w_flag |= WFMOVE ;
return TRUE ;
}
#endif
static int iovstring( int f, int n, const char *prompt, int (*fun)( char *)) {
int status ; /* status return code */
char *tstring ; /* string to add */
/* ask for string to insert */
status = newmlargt( &tstring, prompt, 0) ; /* grab as big a token as screen allow */
/* ask for string to insert */
int status = newmlargt( &tstring, prompt, 0) ;
if( tstring == NULL)
return status ;
@ -1013,24 +857,23 @@ static int iovstring( int f, int n, const char *prompt, int (*fun)( char *)) {
return status ;
}
/*
* ask for and insert a string into the current
* buffer at the current point
*
* int f, n; ignored arguments
/* ask for and insert a string into the current buffer at the current point
int f, n; ignored arguments
*/
int istring( int f, int n) {
return iovstring( f, n, "String to insert<META>: ", linstr) ;
BINDABLE( istring) {
return iovstring( f, n, "insert-string<META>: ", linstr) ;
}
/*
* ask for and overwite a string into the current
* buffer at the current point
*
* int f, n; ignored arguments
/* ask for and overwite a string into the current buffer at the current
point
int f, n; ignored arguments
*/
int ovstring( int f, int n) {
return iovstring( f, n, "String to overwrite<META>: ", lover) ;
BINDABLE( ovstring) {
return iovstring( f, n, "overwrite-string<META>: ", lover) ;
}
/* end of random.c */

View File

@ -1,50 +1,46 @@
/* random.h -- various commands */
#ifndef _RANDOM_H_
#define _RANDOM_H_
#include "names.h"
#include "retcode.h"
/* Command flags */
#define CFCPCN 0x0001 /* Flag that last command was C-P, C-N */
#define CFKILL 0x0002 /* Flag that last command was a kill */
#define AEDIT 1
extern int thisflag ; /* Flags, this command */
extern int lastflag ; /* Flags, last command */
extern int fillcol ; /* Fill column */
extern boolean hardtab ; /* Use hard tab instead of soft tab */
/* Uninitialized global external declarations. */
#define CFCPCN 0x0001 /* Last command was C-P, C-N */
#define CFKILL 0x0002 /* Last command was a kill */
extern int thisflag ; /* Flags, this command */
extern int lastflag ; /* Flags, last command */
int setfillcol( int f, int n) ;
int showcpos( int f, int n) ;
int getcline( void) ;
int getccol( int bflg) ;
boolean setccol( int pos) ;
boolean twiddle( int f, int n) ;
int quote( int f, int n) ;
int insert_tab( int f, int n) ;
#if AEDIT
int detab( int f, int n) ;
int entab( int f, int n) ;
int trim( int f, int n) ;
#endif
int openline( int f, int n) ;
int insert_newline( int f, int n) ;
int deblank( int f, int n) ;
int indent( int f, int n) ;
int forwdel( int f, int n) ;
int backdel( int f, int n) ;
int killtext( int f, int n) ;
int setemode( int f, int n) ;
int delmode( int f, int n) ;
int setgmode( int f, int n) ;
int delgmode( int f, int n) ;
int getfence( int f, int n) ;
int istring( int f, int n) ;
int ovstring( int f, int n) ;
/* Bindable functions */
BINDABLE( setfillcol) ;
BINDABLE( showcpos) ;
BBINDABLE( twiddle) ;
BINDABLE( quote) ;
BINDABLE( insert_tab) ;
BINDABLE( detab) ;
BINDABLE( entab) ;
BINDABLE( trim) ;
BINDABLE( openline) ;
BINDABLE( insert_newline) ;
BINDABLE( deblank) ;
BINDABLE( indent) ;
BINDABLE( forwdel) ;
BINDABLE( backdel) ;
BINDABLE( killtext) ;
BINDABLE( setemode) ;
BINDABLE( delmode) ;
BINDABLE( setgmode) ;
BINDABLE( delgmode) ;
BINDABLE( istring) ;
BINDABLE( ovstring) ;
#endif
/* end of random.h */

256
region.c
View File

@ -1,16 +1,15 @@
/* region.c -- implements region.h */
#include "region.h"
/* region.c
*
* The routines in this file deal with the region, that magic space
* between "." and mark. Some functions are commands. Some functions are
* just for internal use.
*
* Modified by Petri Kutvonen
/* The routines in this file deal with the region, that magic space between
"." and mark. Some functions are commands. Some functions are just for
internal use.
Modified by Petri Kutvonen
*/
#include <stdio.h>
#include <assert.h>
#include <stddef.h>
#include "buffer.h"
#include "estruct.h"
@ -19,161 +18,130 @@
#include "random.h"
#include "window.h"
/*
* Kill the region. Ask "getregion"
* to figure out the bounds of the region.
* Move "." to the start, and kill the characters.
* Bound to "C-W".
/* Kill the region. Ask getregion() to figure out the bounds of the
region. Move "." to the start, and kill the characters. Bound to C-W
kill-region.
*/
int killregion(int f, int n)
{
int s;
struct region region;
BINDABLE( killregion) {
region_t region ;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
if ((s = getregion(&region)) != TRUE)
return s;
if ((lastflag & CFKILL) == 0) /* This is a kill type */
kdelete(); /* command, so do magic */
thisflag |= CFKILL; /* kill buffer stuff. */
curwp->w_dotp = region.r_linep;
curwp->w_doto = region.r_offset;
return ldelete(region.r_size, TRUE);
assert( !(curbp->b_mode & MDVIEW)) ;
int ret = getregion( &region) ;
if( ret != TRUE)
return ret ;
if( (lastflag & CFKILL) == 0) /* This is a kill type */
kdelete() ; /* command, so do magic */
thisflag |= CFKILL ; /* kill buffer stuff. */
curwp->w_dotp = region.r_linep ;
curwp->w_doto = region.r_offset ;
return ldelete( region.r_size, TRUE) ;
}
/*
* Copy all of the characters in the
* region to the kill buffer. Don't move dot
* at all. This is a bit like a kill region followed
* by a yank. Bound to "M-W".
/* Copy all of the characters in the region to the kill buffer. Don't move
dot at all. This is a bit like a kill region followed by a yank. Bound
to M-W copy-region.
*/
int copyregion(int f, int n)
{
struct line *linep;
int loffs;
int s;
struct region region;
BINDABLE( copyregion) {
region_t region ;
if ((s = getregion(&region)) != TRUE)
return s;
if ((lastflag & CFKILL) == 0) /* Kill type command. */
kdelete();
thisflag |= CFKILL;
linep = region.r_linep; /* Current line. */
loffs = region.r_offset; /* Current offset. */
while (region.r_size--) {
if (loffs == llength(linep)) { /* End of line. */
if ((s = kinsert('\n')) != TRUE)
return s;
linep = lforw(linep);
loffs = 0;
int ret = getregion( &region) ;
if( ret != TRUE)
return ret ;
if( (lastflag & CFKILL) == 0) /* Kill type command. */
kdelete() ;
thisflag |= CFKILL ;
line_p linep = region.r_linep ; /* Current line. */
int loffs = region.r_offset ; /* Current offset. */
while( region.r_size--) {
if( loffs == llength( linep)) { /* End of line. */
ret = kinsert( '\n') ;
if( ret != TRUE)
return ret ;
linep = lforw( linep) ;
loffs = 0 ;
} else { /* Middle of line. */
if ((s = kinsert(lgetc(linep, loffs))) != TRUE)
return s;
++loffs;
ret = kinsert( lgetc( linep, loffs)) ;
if( ret != TRUE)
return ret ;
++loffs ;
}
}
mloutstr( "(region copied)") ;
return TRUE;
return TRUE ;
}
/*
* Lower case region. Zap all of the upper
* case characters in the region to lower case. Use
* the region code to set the limits. Scan the buffer,
* doing the changes. Call "lchange" to ensure that
* redisplay is done in all buffers. Bound to
* "C-X C-L".
/* Lower case region & Upper case region. Zap all of the upper/lower case
characters in the region to lower/upper case. Use the region code to
set the limits. Scan the buffer, doing the changes. Call "lchange" to
ensure that redisplay is done in all buffers. Bound to C-X C-L
case-region-lower and C-X C-U case-region-upper.
*/
int lowerregion(int f, int n)
{
struct line *linep;
int loffs;
int c;
int s;
struct region region;
static int utol( int c) {
return (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : -1 ;
}
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
if ((s = getregion(&region)) != TRUE)
return s;
lchange(WFHARD);
linep = region.r_linep;
loffs = region.r_offset;
while (region.r_size--) {
if (loffs == llength(linep)) {
linep = lforw(linep);
loffs = 0;
static int ltou( int c) {
return (c >= 'a' && c <= 'z') ? c + 'A' - 'a' : -1 ;
}
static int caseregion( int (* cconv)( int)) {
region_t region ;
assert( !(curbp->b_mode & MDVIEW)) ;
int ret = getregion( &region) ;
if( ret != TRUE)
return ret ;
lchange( WFHARD) ;
line_p linep = region.r_linep ;
int loffs = region.r_offset ;
while( region.r_size--) {
if( loffs == llength( linep)) {
linep = lforw( linep) ;
loffs = 0 ;
} else {
c = lgetc(linep, loffs);
if (c >= 'A' && c <= 'Z')
lputc(linep, loffs, c + 'a' - 'A');
++loffs;
int c = cconv( lgetc( linep, loffs)) ;
if( c != -1)
lputc( linep, loffs, c) ;
++loffs ;
}
}
return TRUE;
return TRUE ;
}
/*
* Upper case region. Zap all of the lower
* case characters in the region to upper case. Use
* the region code to set the limits. Scan the buffer,
* doing the changes. Call "lchange" to ensure that
* redisplay is done in all buffers. Bound to
* "C-X C-L".
*/
int upperregion(int f, int n)
{
struct line *linep;
int loffs;
int c;
int s;
struct region region;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
if ((s = getregion(&region)) != TRUE)
return s;
lchange(WFHARD);
linep = region.r_linep;
loffs = region.r_offset;
while (region.r_size--) {
if (loffs == llength(linep)) {
linep = lforw(linep);
loffs = 0;
} else {
c = lgetc(linep, loffs);
if (c >= 'a' && c <= 'z')
lputc(linep, loffs, c - 'a' + 'A');
++loffs;
}
}
return TRUE;
BINDABLE( lowerregion) {
return caseregion( utol) ;
}
/*
* This routine figures out the
* bounds of the region in the current window, and
* fills in the fields of the "struct region" structure pointed
* to by "rp". Because the dot and mark are usually very
* close together, we scan outward from dot looking for
* mark. This should save time. Return a standard code.
* Callers of this routine should be prepared to get
* an "ABORT" status; we might make this have the
* conform thing later.
*/
int getregion(struct region *rp)
{
struct line *flp;
struct line *blp;
long fsize;
long bsize;
BINDABLE( upperregion) {
return caseregion( ltou) ;
}
/* This routine figures out the bounds of the region in the current window,
* and fills in the fields of the "region_t" structure pointed to by "rp".
* Because the dot and mark are usually very close together, we scan
* outward from dot looking for mark. This should save time. Return a
* standard code. Callers of this routine should be prepared to get an
* "ABORT" status; we might make this have the conform thing later.
*/
int getregion( region_p rp) {
line_p flp, blp ;
long fsize, bsize ;
if (curwp->w_markp == NULL)
return mloutfail( "No mark set in this window") ;
if (curwp->w_markp == NULL) {
mloutstr( "No mark set in this window") ;
return FALSE;
}
if (curwp->w_dotp == curwp->w_markp) {
rp->r_linep = curwp->w_dotp;
if (curwp->w_doto < curwp->w_marko) {
@ -213,6 +181,8 @@ int getregion(struct region *rp)
}
}
}
mloutstr( "Bug: lost mark") ;
return FALSE;
return mloutfail( "Bug: lost mark") ;
}
/* end of region.c */

View File

@ -1,22 +1,27 @@
/* region.h -- a region starts at the mark and end at the dot */
#ifndef _REGION_H_
#define _REGION_H_
#include "line.h"
/*
* The starting position of a region, and the size of the region in
* characters, is kept in a region structure. Used by the region commands.
/* The starting position of a region, and the size of the region in
characters, is kept in a region structure. Used by the region commands.
*/
struct region {
struct line *r_linep; /* Origin struct line address. */
int r_offset; /* Origin struct line offset. */
long r_size; /* Length in characters. */
};
typedef struct {
line_p r_linep ; /* Origin struct line address. */
int r_offset ; /* Origin struct line offset. */
long r_size ; /* Length in characters. */
} region_t ;
int killregion( int f, int n) ;
int copyregion( int f, int n) ;
int lowerregion( int f, int n) ;
int upperregion( int f, int n) ;
int getregion( struct region *rp) ;
typedef region_t *region_p ;
/* Bindable functions */
BINDABLE( killregion) ;
BINDABLE( copyregion) ;
BINDABLE( lowerregion) ;
BINDABLE( upperregion) ;
int getregion( region_p rp) ;
#endif
/* end of region.h */

View File

@ -1,13 +1,15 @@
/* retcode.h -- */
#ifndef __RETCODE_H__
#define __RETCODE_H__
#ifdef FALSE
#error "FALSE shouldn't be defined"
#undef FALSE
# error "FALSE shouldn't be defined"
# undef FALSE
#endif
#ifdef TRUE
#error "TRUE shouldn't be defined"
#undef TRUE
# error "TRUE shouldn't be defined"
# undef TRUE
#endif
typedef enum {
@ -18,3 +20,4 @@ typedef enum {
#define ABORT 2 /* 2, death, ^G, abort, etc. */
#endif
/* end of retcode.h */

View File

@ -1,10 +1,10 @@
# Visualize Screen Dimensions
select-buffer screensize
insert-string &cat $curwidth &cat "x" $pagelen
insert-string &rig "---------+" &sub 10 $curcol
&sub &div $curwidth 10 1 insert-string "---------+"
insert-string &lef "1234567890" &mod $curwidth 10
end-of-file
&sub $pagelen 3 execute-command-line "insert-string &cat $curline ~n"
&sub $pagelen 3 execute-command-line "insert-string &cat ~n &add $curline 1"
beginning-of-file
unmark-buffer
write-message $line

124
search.c
View File

@ -1,9 +1,7 @@
/* search.c -- implements 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
* strings. Probably should have a regular expression search, or something
* like that.
@ -60,6 +58,7 @@
* Modified by Petri Kutvonen
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -86,7 +85,7 @@
unsigned int matchlen = 0 ;
static unsigned int mlenold = 0 ;
char *patmatch = NULL ;
static struct line *matchline = NULL;
static line_p matchline = NULL;
static int matchoff = 0;
spat_t pat ; /* Search pattern */
@ -164,10 +163,10 @@ static struct magic_replacement rmcpat[NPAT]; /* The replacement magic array. */
static int mcscanner( struct magic *mcpatrn, int direct, int beg_or_end) ;
#endif
static int amatch(struct magic *mcptr, int direct, struct line **pcwline, int *pcwoff);
static int amatch(struct magic *mcptr, int direct, line_p *pcwline, int *pcwoff);
static int readpattern(char *prompt, char *apat, int srch);
static int replaces(int kind, int f, int n);
static int nextch(struct line **pcurline, int *pcuroff, int dir);
static int nextch( line_p *pcurline, int *pcuroff, int dir);
static int mcstr(void);
static int rmcstr(void);
static int mceq(int bc, struct magic *mt);
@ -176,15 +175,14 @@ static int biteq(int bc, char *cclmap);
static char *clearbits(void);
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
* the match string, and (perhaps) repaint the display.
*
* int f, n; default flag / numeric argument
*/
int forwsearch(int f, int n)
{
BINDABLE( forwsearch) {
int status = TRUE;
/* If n is negative, search backwards.
@ -222,15 +220,14 @@ int forwsearch(int f, int n)
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,
* and (perhaps) repaint the display.
*
* int f, n; default flag / numeric argument
*/
int forwhunt(int f, int n)
{
BINDABLE( forwhunt) {
int status = TRUE;
if (n < 0) /* search backwards */
@ -275,16 +272,15 @@ int forwhunt(int f, int n)
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.
* If found "." is left pointing at the first character of the pattern
* (the last character that was matched).
*
* int f, n; default flag / numeric argument
*/
int backsearch(int f, int n)
{
BINDABLE( backsearch) {
int status = TRUE;
/* If n is negative, search forwards.
@ -323,16 +319,15 @@ int backsearch(int f, int n)
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.
* If found "." is left pointing at the first character of the pattern
* (the last character that was matched).
*
* int f, n; default flag / numeric argument
*/
int backhunt(int f, int n)
{
BINDABLE( backhunt) {
int status = TRUE;
if (n < 0)
@ -389,7 +384,7 @@ int backhunt(int f, int n)
*/
static int mcscanner(struct magic *mcpatrn, int direct, int beg_or_end)
{
struct line *curline; /* current line during scan */
line_p curline; /* current line during scan */
int curoff; /* position within current line */
/* If we are going in reverse, then the 'end' is actually
@ -412,7 +407,7 @@ static int mcscanner(struct magic *mcpatrn, int direct, int beg_or_end)
/* Scan each character until we hit the head link record.
*/
while (!boundry(curline, curoff, direct)) {
while (!boundary(curline, curoff, direct)) {
/* Save the current position in case we need to
* restore it on a match, and initialize matchlen to
* zero in case we are doing a search for replacement.
@ -453,13 +448,13 @@ static int mcscanner(struct magic *mcpatrn, int direct, int beg_or_end)
*
* struct magic *mcptr; string to scan for
* int direct; which way to go.
* struct line **pcwline; current line during scan
* line_p *pcwline; current line during scan
* int *pcwoff; position within current line
*/
static int amatch(struct magic *mcptr, int direct, struct line **pcwline, int *pcwoff)
static int amatch(struct magic *mcptr, int direct, line_p *pcwline, int *pcwoff)
{
int c; /* character at current position */
struct line *curline; /* current line during scan */
line_p curline; /* current line during scan */
int curoff; /* position within current line */
int nchars;
@ -599,9 +594,9 @@ int scanner(const char *patrn, int direct, int beg_or_end)
{
int c; /* character at current position */
const char *patptr; /* pointer into pattern */
struct line *curline; /* current line during scan */
line_p curline; /* current line during scan */
int curoff; /* position within current line */
struct line *scanline; /* current line during scanning */
line_p scanline; /* current line during scanning */
int scanoff; /* position in scanned line */
/* If we are going in reverse, then the 'end' is actually
@ -616,7 +611,7 @@ int scanner(const char *patrn, int direct, int beg_or_end)
/* Scan each character until we hit the head link record.
*/
while (!boundry(curline, curoff, direct)) {
while (!boundary(curline, curoff, direct)) {
/* Save the current position in case we match
* the search string at this point.
*/
@ -748,7 +743,7 @@ static int readpattern(char *prompt, char *apat, int srch)
void savematch(void)
{
char *ptr; /* pointer to last match string */
struct line *curline; /* line of last match */
line_p curline; /* line of last match */
int curoff; /* offset " " */
/* Free any existing match string, then
@ -787,26 +782,24 @@ void rvstrcpy(char *rvstr, char *str)
*rvstr = '\0';
}
/*
* sreplace -- Search and replace.
/* sreplace -- Search and replace.
*
* int f; default flag
* int n; # of repetitions wanted
*/
int sreplace(int f, int n)
{
return replaces(FALSE, f, n);
BINDABLE( sreplace) {
return replaces( FALSE, f, n) ;
}
/*
* qreplace -- search and replace with query.
/* qreplace -- search and replace with query.
*
* int f; default flag
* int n; # of repetitions wanted
*/
int qreplace(int f, int n)
{
return replaces(TRUE, f, n);
BINDABLE( qreplace) {
return replaces( TRUE, f, n) ;
}
/*
@ -827,17 +820,16 @@ static int replaces(int kind, int f, int n)
int nlrepl; /* was a replace done on the last line? */
char c; /* input char for query */
spat_t tpat ; /* temporary to hold search pattern */
struct line *origline; /* original "." position */
line_p origline; /* original "." position */
int origoff; /* and offset (for . query option) */
struct line *lastline; /* position of last replace and */
line_p lastline; /* position of last replace and */
int lastoff; /* offset (for 'u' query option) */
/* rfi */
///* rfi */
lastline = NULL ;
lastoff = 0 ;
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
assert( !(curbp->b_mode & MDVIEW)) ;
/* Check for negative repetitions.
*/
@ -1114,25 +1106,23 @@ int expandp(char *srcstr, char *deststr, int maxlength)
return TRUE;
}
/*
* boundry -- Return information depending on whether we may search no
* further. Beginning of file and end of file are the obvious
* cases, but we may want to add further optional boundry restrictions
* in future, a' la VMS EDT. At the moment, just return TRUE or
* FALSE depending on if a boundry is hit (ouch).
*/
int boundry(struct line *curline, int curoff, int dir)
{
int border;
if (dir == FORWARD) {
border = (curoff == llength(curline)) &&
(lforw(curline) == curbp->b_linep);
} else {
border = (curoff == 0) &&
(lback(curline) == curbp->b_linep);
}
return border;
/* boundary -- Returns information depending on whether we may search no
further. Beginning of file and end of file are the obvious cases, but
we may want to add further optional boundary restrictions in future, a'
la VMS EDT. At the moment, just return TRUE or FALSE depending on if a
boundary is hit (ouch).
*/
int boundary( line_p curline, int curoff, int dir) {
int border ;
if( dir == FORWARD)
border = (curoff == llength( curline)) &&
(lforw( curline) == curbp->b_linep) ;
else
border = (curoff == 0) && (lback( curline) == curbp->b_linep) ;
return border ;
}
/*
@ -1143,9 +1133,9 @@ int boundry(struct line *curline, int curoff, int dir)
* the current character and move, reverse searches move and
* look at the character.
*/
static int nextch(struct line **pcurline, int *pcuroff, int dir)
static int nextch( line_p *pcurline, int *pcuroff, int dir)
{
struct line *curline;
line_p curline;
int curoff;
int c;
@ -1604,3 +1594,5 @@ static void setbit(int bc, char *cclmap)
*(cclmap + (bc >> 3)) |= BIT(bc & 7);
}
#endif
/* end of search.c */

View File

@ -1,9 +1,9 @@
/* search.h -- */
#ifndef _SEARCH_H_
#define _SEARCH_H_
#define MAGIC 1 /* include regular expression matching? */
#include "line.h"
#include "line.h" /* line_p */
#include "names.h" /* BINDABLE() */
typedef char spat_t[ 128] ; /* search pattern type */
#define NPAT sizeof( spat_t) /* # of bytes, pattern */
@ -26,24 +26,28 @@ extern spat_t rpat ; /* replacement pattern */
int scanner( const char *patrn, int direct, int beg_or_end) ;
int forwsearch( int f, int n) ;
int forwhunt( int f, int n) ;
int backsearch( int f, int n) ;
int backhunt( int f, int n) ;
/* Bindable functions */
BINDABLE( backhunt) ;
BINDABLE( backsearch) ;
BINDABLE( forwhunt) ;
BINDABLE( forwsearch) ;
BINDABLE( qreplace) ;
BINDABLE( sreplace) ;
int eq( unsigned char bc, unsigned char pc) ;
void savematch( void) ;
void rvstrcpy( char *rvstr, char *str) ;
int sreplace( int f, int n) ;
int qreplace( int f, int n) ;
int delins( int dlength, char *instr, int use_meta) ;
int expandp( char *srcstr, char *deststr, int maxlength) ;
int boundry( struct line *curline, int curoff, int dir) ;
int boundary( line_p curline, int curoff, int dir) ;
void setprompt( char *tpat, unsigned tpat_size, char *prompt, char *apat) ;
#define MAGIC 1 /* include regular expression matching? */
#if MAGIC
void mcclear( void) ;
void rmcclear( void) ;
#endif
#endif
/* end of search.h */

47
spawn.c
View File

@ -1,13 +1,12 @@
/* spawn.c -- implements spawn.h */
#include "spawn.h"
/* spawn.c
*
* Various operating system access commands.
/* Various operating system access commands.
*
* Modified by Petri Kutvonen
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -33,13 +32,11 @@
#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
* repaint. Bound to "^X C".
*/
int spawncli(int f, int n)
{
BINDABLE( spawncli) {
#if USG | BSD
char *cp;
#endif
@ -80,9 +77,8 @@ int spawncli(int f, int n)
}
#if BSD | SVR4
int bktoshell(int f, int n)
{ /* suspend MicroEMACS and wait to wake up */
/* suspend MicroEMACS and wait to wake up */
BINDABLE( bktoshell) {
vttidy();
/******************************
int pid;
@ -102,12 +98,12 @@ void rtfrmshell(void)
}
#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
* done. Bound to "C-X !".
*/
int spawn( int f, int n) {
BINDABLE( spawn) {
int s ;
char *line ;
@ -140,13 +136,13 @@ int spawn( int f, int n) {
#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
* done. Bound to "C-X $".
*/
int execprg( int f, int n) {
BINDABLE( execprg) {
int s ;
char *line ;
@ -175,14 +171,14 @@ int execprg( int f, int n) {
#endif
}
/*
* Pipe a one line command into a window
/* Pipe a one line command into a window
* Bound to ^X @
*/
int pipecmd( int f, int n) {
BINDABLE( pipecmd) {
int s ; /* return status from CLI */
struct window *wp ; /* pointer to new window */
struct buffer *bp ; /* pointer to buffer to zot */
buffer_p bp ; /* pointer to buffer to zot */
char *mlarg ;
char *line ; /* command line send to shell */
static char bname[] = "command" ;
@ -270,13 +266,13 @@ int pipecmd( int f, int n) {
return TRUE;
}
/*
* filter a buffer through an external DOS program
/* filter a buffer through an external DOS program
* Bound to ^X #
*/
int filter_buffer( int f, int n) {
BINDABLE( filter_buffer) {
int s ; /* return status from CLI */
struct buffer *bp ; /* pointer to buffer to zot */
buffer_p bp ; /* pointer to buffer to zot */
char *mlarg ;
char *line ; /* command line send to shell */
fname_t tmpnam ; /* place to store real file name */
@ -289,8 +285,7 @@ int filter_buffer( int f, int n) {
if( restflag)
return resterr() ;
if( curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly() ; /* we are in read only mode */
assert( !(curbp->b_mode & MDVIEW)) ;
/* get the filter name and its args */
s = newmlarg( &mlarg, "#", 0) ;

23
spawn.h
View File

@ -1,7 +1,18 @@
int spawncli( int f, int n) ;
int bktoshell( int f, int n) ;
/* spawn.h -- various operating system access commands */
#ifndef _SPAWN_H_
#define _SPAWN_H_
#include "names.h" /* BINDABLE() */
/* Bindable functions */
BINDABLE( spawncli) ;
BINDABLE( bktoshell) ;
BINDABLE( spawn) ;
BINDABLE( execprg) ;
BINDABLE( pipecmd) ;
BINDABLE( filter_buffer) ;
void rtfrmshell( void) ;
int spawn( int f, int n) ;
int execprg( int f, int n) ;
int pipecmd( int f, int n) ;
int filter_buffer( int f, int n) ;
#endif
/* end of spawn.h */

104
tcap.c
View File

@ -1,9 +1,7 @@
/* tcap.c -- implements terminal.h */
#include "terminal.h"
/* tcap.c
*
* Unix V7 SysV and BS4 Termcap video driver
/* Unix V7 SysV and BS4 Termcap video driver
*
* modified by Petri Kutvonen
*/
@ -35,9 +33,9 @@ boolean sgarbf = TRUE ; /* TRUE if screen is garbage */
char sres[ 16] ; /* current screen resolution */
/* NORMAL, CGA, EGA, VGA */
#if UNIX
#include <signal.h>
#endif
# if UNIX
# include <signal.h>
# endif
#define MARGIN 8
#define SCRSIZ 64
@ -57,33 +55,33 @@ static void tcapscrollregion(int top, int bot);
static void putpad(char *str);
static void tcapopen(void);
#if PKCODE
static void tcapclose(void);
#endif
# if PKCODE
static void tcapclose(void);
# endif
#if COLOR
static void tcapfcol(void);
static void tcapbcol(void);
#endif
#if SCROLLCODE
static void tcapscroll_reg(int from, int to, int linestoscroll);
static void tcapscroll_delins(int from, int to, int linestoscroll);
#endif
# if COLOR
static void tcapfcol(void);
static void tcapbcol(void);
# endif
# if SCROLLCODE
static void tcapscroll_reg(int from, int to, int linestoscroll);
static void tcapscroll_delins(int from, int to, int linestoscroll);
# endif
#define TCAPSLEN 315
static char tcapbuf[TCAPSLEN];
static char *_UP, _PC, *CM, *CE, *CL, *SO, *SE;
#if PKCODE
static char *TI, *TE;
#if USE_BROKEN_OPTIMIZATION
static int term_init_ok = 0;
#endif
#endif
# if PKCODE
static char *TI, *TE;
# if USE_BROKEN_OPTIMIZATION
static int term_init_ok = 0;
# endif
# endif
#if SCROLLCODE
static char *CS, *DL, *AL, *SF, *SR;
#endif
# if SCROLLCODE
static char *CS, *DL, *AL, *SF, *SR;
# endif
struct terminal term = {
480, /* actual 479 on 2560x1440 landscape terminal window */
@ -96,11 +94,11 @@ struct terminal term = {
SCRSIZ,
NPAUSE,
tcapopen,
#if PKCODE
# if PKCODE
tcapclose,
#else
# else
ttclose,
#endif
# endif
tcapkopen,
tcapkclose,
ttgetc,
@ -112,14 +110,14 @@ struct terminal term = {
tcapbeep,
tcaprev,
tcapcres
#if COLOR
# if COLOR
, tcapfcol,
tcapbcol
#endif
#if SCROLLCODE
# endif
# if SCROLLCODE
, NULL /* set dynamically at open time */
#endif
};
# endif
} ;
static void tcapopen(void)
{
@ -128,9 +126,9 @@ static void tcapopen(void)
char *tv_stype;
int int_col, int_row;
#if PKCODE && USE_BROKEN_OPTIMIZATION
# if PKCODE && USE_BROKEN_OPTIMIZATION
if (!term_init_ok) {
#endif
# endif
if ((tv_stype = getenv("TERM")) == NULL) {
fputs( "Environment variable TERM not defined!\n", stderr) ;
exit( EXIT_FAILURE) ;
@ -177,7 +175,7 @@ static void tcapopen(void)
SO = tgetstr("so", &p);
if (SO != NULL)
revexist = TRUE;
#if PKCODE
# if PKCODE
if (tgetnum("sg") > 0) { /* can reverse be used? P.K. */
revexist = FALSE;
SE = NULL;
@ -185,7 +183,7 @@ static void tcapopen(void)
}
TI = tgetstr("ti", &p); /* terminal init and exit */
TE = tgetstr("te", &p);
#endif
# endif
if (CL == NULL || CM == NULL || _UP == NULL) {
fputs( "Incomplete termcap entry\n", stderr) ;
@ -194,7 +192,7 @@ static void tcapopen(void)
if (CE == NULL) /* will we be able to use clear to EOL? */
eolexist = FALSE;
#if SCROLLCODE
# if SCROLLCODE
CS = tgetstr("cs", &p);
SF = tgetstr("sf", &p);
SR = tgetstr("sr", &p);
@ -210,20 +208,20 @@ static void tcapopen(void)
} else {
term.t_scroll = NULL;
}
#endif
# endif
if (p >= &tcapbuf[TCAPSLEN]) {
fputs( "Terminal description too big!\n", stderr) ;
exit( EXIT_FAILURE) ;
}
#if PKCODE && USE_BROKEN_OPTIMIZATION
# if PKCODE && USE_BROKEN_OPTIMIZATION
term_init_ok = 1;
}
#endif
# endif
ttopen();
}
#if PKCODE
# if PKCODE
static void tcapclose(void)
{
putpad(tgoto(CM, 0, term.t_nrow));
@ -231,26 +229,26 @@ static void tcapclose(void)
ttflush();
ttclose();
}
#endif
# endif
static void tcapkopen(void)
{
#if PKCODE
# if PKCODE
putpad(TI);
ttflush();
ttrow = 999;
ttcol = 999;
sgarbf = TRUE;
#endif
# endif
strcpy(sres, "NORMAL");
}
static void tcapkclose(void)
{
#if PKCODE
# if PKCODE
putpad(TE);
ttflush();
#endif
# endif
}
static void tcapmove(int row, int col)
@ -288,7 +286,7 @@ static int tcapcres(char *res)
return TRUE;
}
#if SCROLLCODE
# if SCROLLCODE
/* move howmanylines lines starting at from to to */
static void tcapscroll_reg(int from, int to, int howmanylines)
@ -340,9 +338,9 @@ static void tcapscrollregion(int top, int bot)
putpad(tgoto(CS, bot, top));
}
#endif
# endif
#if COLOR
# if COLOR
/* No colors here, ignore this. */
static void tcapfcol(void)
{
@ -351,7 +349,7 @@ static void tcapfcol(void)
static void tcapbcol(void)
{
}
#endif
# endif
static void tcapbeep(void)
{
@ -363,3 +361,5 @@ static void putpad(char *str)
tputs( str, 1, (int (*)( int)) ttputc) ;
}
#endif /* TERMCAP */
/* end of tcap.c */

View File

@ -1,14 +1,12 @@
/* terminal.h -- */
#ifndef __TERMINAL_H__
#define __TERMINAL_H__
#include "defines.h" /* COLOR, SCROLLCODE */
#include "retcode.h"
#include "utf8.h"
/*
* The editor communicates with the display using a high level interface. A
/* The editor communicates with the display using a high level interface. A
* "TERM" structure holds useful variables, and indirect pointers to routines
* that do useful operations. The low level get and put routines are here too.
* This lets a terminal, in addition to having non standard commands, have
@ -48,8 +46,9 @@ struct terminal {
#endif
};
/* TEMPORARY macros for terminal I/O (to be placed in a machine
dependant place later) */
/* TEMPORARY macros for terminal I/O (to be placed in a machine dependant
place later)
*/
#define TTopen (*term.t_open)
#define TTclose (*term.t_close)
@ -83,3 +82,4 @@ extern char sres[] ; /* Current screen resolution. */
/* NORMAL, CGA, EGA, VGA */
#endif
/* end of terminal.h */

View File

@ -1,3 +1,4 @@
/* termio.h -- */
#ifndef _TERMIO_H_
#define _TERMIO_H_
@ -18,3 +19,4 @@ int ttgetc( void) ;
int typahead( void) ;
#endif
/* end of termio.h */

21
utf8.c
View File

@ -7,10 +7,9 @@
#include <assert.h>
#include <wchar.h>
/*
* Display width of UTF-8 character
*/
int utf8_width( unicode_t c) {
/* Display width of UTF-8 character */
int _utf8_width( unicode_t c) {
#if CYGWIN
assert( sizeof( wchar_t) == 2) ; /* wcwidth only supports UTF-16 */
return (c < 0x10000) ? wcwidth( (wchar_t) c) : -1 ;
@ -19,8 +18,14 @@ int utf8_width( unicode_t c) {
#endif
}
/*
* utf8_to_unicode()
int utf8_width( unicode_t c) {
int w = _utf8_width( c) ;
return (w < 0) ? 2 : w ; /* display \u if can't figure out width */
}
/* utf8_to_unicode()
*
* Convert a UTF-8 sequence to its unicode value, and return the length of
* the sequence in bytes.
@ -84,8 +89,8 @@ unsigned utf8_to_unicode( const char *line, unsigned index, unsigned len,
return bytes;
}
/*
* unicode_to_utf8()
/* unicode_to_utf8()
*
* Convert a unicode value to its canonical utf-8 sequence.
*

9
utf8.h
View File

@ -1,12 +1,15 @@
#ifndef UTF8_H
#define UTF8_H
/* utf8.h -- */
#ifndef _UTF8_H_
#define _UTF8_H_
typedef unsigned int unicode_t ;
int utf8_width( unicode_t c) ;
int _utf8_width( unicode_t c) ; /* straight width */
int utf8_width( unicode_t c) ; /* workaround width */
unsigned utf8_to_unicode( const char *line, unsigned index, unsigned len,
unicode_t *res) ;
unsigned utf8_revdelta( unsigned char *buf, unsigned pos) ;
unsigned unicode_to_utf8( unicode_t c, char *utf8) ;
#endif
/* end of utf8.h */

25
util.c
View File

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

11
util.h
View File

@ -1,7 +1,10 @@
#ifndef UTIL_H_
#define UTIL_H_
/* util.h -- utility functions */
#ifndef _UTIL_H_
#define _UTIL_H_
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
void mystrscpy(char *dst, const char *src, int size);
#endif /* UTIL_H_ */
void mystrscpy( char *dst, const char *src, int size) ;
#endif
/* end of util.h */

View File

@ -1,16 +1,18 @@
#ifndef VERSION_H_
#define VERSION_H_
/* version.h -- name and version strings */
#ifndef _VERSION_H_
#define _VERSION_H_
#ifdef PROGRAM
# define _QUOTE( s) #s
# define QUOTE( s) _QUOTE( s)
# define PROGRAM_NAME QUOTE(PROGRAM)
#else
# define PROGRAM_NAME "em"
# define PROGRAM_NAME "ue"
#endif
#define PROGRAM_NAME_UTF8 "µEMACS"
#define VERSION "4.2.4"
#define VERSION "4.2.5"
#endif /* VERSION_H_ */
#endif
/* end of version.h */

317
window.c
View File

@ -1,77 +1,65 @@
/* window.c -- inplements 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 <stdio.h>
#include "basic.h"
#include "buffer.h"
#include "display.h"
#include "display.h" /* upmode() */
#include "estruct.h"
#include "execute.h"
#include "line.h"
#include "mlout.h"
#include "terminal.h"
#include "wrapper.h"
window_p curwp ; /* Current window */
window_p wheadp ; /* Head of list of windows */
struct window *curwp ; /* Current window */
struct window *wheadp ; /* Head of list of windows */
static struct window *swindow = NULL ; /* saved window pointer */
static window_p savwindow = NULL ; /* saved window pointer */
/*
* Reposition dot in the current window to line "n". If the argument is
* positive, it is that line. If it is negative it is that line from the
* 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-!.
/* 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
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-!.
*/
int reposition(int f, int n)
{
if (f == FALSE) /* default to 0 to center screen */
n = 0;
curwp->w_force = n;
curwp->w_flag |= WFFORCE;
return TRUE;
TBINDABLE( reposition) {
curwp->w_force = (f == FALSE) ? 0 : n ; /* default to 0 to center screen */
curwp->w_flag |= WFFORCE ;
return TRUE ;
}
/*
* Refresh the screen. With no argument, it just does the refresh. With an
* argument it recenters "." in the current window. Bound to "C-L".
/* Refresh the screen. With no argument, it just does the refresh. With
an argument it recenters "." in the current window. Bound to "C-L".
*/
int redraw(int f, int n)
{
if (f == FALSE)
sgarbf = TRUE;
TBINDABLE( redraw) {
if( f == FALSE)
sgarbf = TRUE ;
else {
curwp->w_force = 0; /* Center dot. */
curwp->w_flag |= WFFORCE;
curwp->w_force = 0 ; /* Center dot. */
curwp->w_flag |= WFFORCE ;
}
return TRUE;
return TRUE ;
}
/*
* The command make the next window (next => down the screen) the current
* window. There are no real errors, although the command does nothing if
* there is only 1 window on the screen. Bound to "C-X C-N".
*
* with an argument this command finds the <n>th window from the top
*
* int f, n; default flag and numeric argument
*
/* The command make the next window (next => down the screen) the current
window. There are no real errors, although the command does nothing if
there is only 1 window on the screen. Bound to "C-X C-N".
with an argument this command finds the <n>th window from the top
int f, n; default flag and numeric argument
*/
int nextwind(int f, int n)
{
struct window *wp;
BINDABLE( nextwind) {
window_p wp;
int nwindows; /* total number of windows */
if (f) {
@ -94,10 +82,8 @@ int nextwind(int f, int n)
wp = wheadp;
while (--n)
wp = wp->w_wndp;
} else {
mlwrite("Window number out of range");
return FALSE;
}
} else
return mloutfail( "Window number out of range") ;
} else if ((wp = curwp->w_wndp) == NULL)
wp = wheadp;
curwp = wp;
@ -107,15 +93,14 @@ int nextwind(int f, int n)
return TRUE;
}
/*
* 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
* lot if there is 1 window.
/* 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 lot if there is 1 window.
*/
int prevwind(int f, int n)
{
struct window *wp1;
struct window *wp2;
BINDABLE( prevwind) {
window_p wp1;
window_p wp2;
/* if we have an argument, we mean the nth window from the bottom */
if (f)
@ -137,28 +122,26 @@ int prevwind(int f, int n)
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
* 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
* "move up". Magic. Bound to "C-X C-N".
*/
int mvdnwind(int f, int n)
{
return mvupwind(f, -n);
BINDABLE( mvdnwind) {
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.
* 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
* "C-X C-P".
*/
int mvupwind(int f, int n)
{
struct line *lp;
BINDABLE( mvupwind) {
line_p lp;
int i;
lp = curwp->w_linep;
@ -193,17 +176,16 @@ int mvupwind(int f, int n)
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
* 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
* become undisplayed.
*/
int onlywind(int f, int n)
{
struct window *wp;
struct line *lp;
BINDABLE( onlywind) {
window_p wp;
line_p lp;
int i;
while (wheadp != curwp) {
@ -241,23 +223,20 @@ int onlywind(int f, int n)
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.
*
* int f, n; arguments are ignored for this command
*/
int delwind(int f, int n)
{
struct window *wp; /* window to recieve deleted space */
struct window *lwp; /* ptr window before curwp */
BINDABLE( delwind) {
window_p wp; /* window to recieve deleted space */
window_p lwp; /* ptr window before curwp */
int target; /* target line to search for */
/* if there is only one window, don't delete it */
if (wheadp->w_wndp == NULL) {
mlwrite("Can not delete this window");
return FALSE;
}
if( wheadp->w_wndp == NULL)
return mloutfail( "Can not delete this window") ;
/* find window before curwp in linked list */
wp = wheadp;
@ -316,8 +295,8 @@ int delwind(int f, int n)
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
* argument of two forces the cursor to the lower window. The only
* 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 splitwind(int f, int n)
{
struct window *wp;
struct line *lp;
BINDABLE( splitwind) {
window_p wp;
line_p lp;
int ntru;
int ntrl;
int ntrd;
struct window *wp1;
struct window *wp2;
window_p wp1;
window_p wp2;
if (curwp->w_ntrows < 3) {
mlwrite("Cannot split a %d line window", curwp->w_ntrows);
return FALSE;
if( curwp->w_ntrows < 3) {
mloutfmt( "Cannot split a %d line window", curwp->w_ntrows) ;
return FALSE ;
}
wp = xmalloc(sizeof(struct window));
wp = xmalloc( sizeof *wp) ;
++curbp->b_nwnd; /* Displayed twice. */
wp->w_bufp = curbp;
wp->w_dotp = curwp->w_dotp;
@ -398,33 +377,30 @@ int splitwind(int f, int n)
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
* all the hard work. You don't just set "force reframe" because dot would
* move. Bound to "C-X Z".
*/
int enlargewind(int f, int n)
{
struct window *adjwp;
struct line *lp;
BINDABLE( enlargewind) {
window_p adjwp;
line_p lp;
int i;
if (n < 0)
return shrinkwind(f, -n);
if (wheadp->w_wndp == NULL) {
mlwrite("Only one window");
return FALSE;
}
if( wheadp->w_wndp == NULL)
return mloutfail( "Only one window") ;
if ((adjwp = curwp->w_wndp) == NULL) {
adjwp = wheadp;
while (adjwp->w_wndp != curwp)
adjwp = adjwp->w_wndp;
}
if (adjwp->w_ntrows <= n) {
mlwrite("Impossible change");
return FALSE;
}
if( adjwp->w_ntrows <= n)
return mloutfail( "Impossible change") ;
if (curwp->w_wndp == adjwp) { /* Shrink below. */
lp = adjwp->w_linep;
for (i = 0; i < n && lp != adjwp->w_bufp->b_linep; ++i)
@ -450,32 +426,29 @@ int enlargewind(int f, int n)
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
* "C-X C-Z".
*/
int shrinkwind(int f, int n)
{
struct window *adjwp;
struct line *lp;
BINDABLE( shrinkwind) {
window_p adjwp;
line_p lp;
int i;
if (n < 0)
return enlargewind(f, -n);
if (wheadp->w_wndp == NULL) {
mlwrite("Only one window");
return FALSE;
}
if( wheadp->w_wndp == NULL)
return mloutfail( "Only one window") ;
if ((adjwp = curwp->w_wndp) == NULL) {
adjwp = wheadp;
while (adjwp->w_wndp != curwp)
adjwp = adjwp->w_wndp;
}
if (curwp->w_ntrows <= n) {
mlwrite("Impossible change");
return FALSE;
}
if( curwp->w_ntrows <= n)
return mloutfail( "Impossible change") ;
if (curwp->w_wndp == adjwp) { /* Grow below. */
lp = adjwp->w_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;
}
/*
* 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 resize(int f, int n)
{
BINDABLE( resize) {
int clines; /* current # of lines in window */
/* must have a non-default argument, else ignore call */
@ -525,14 +497,14 @@ int resize(int f, int n)
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
* 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 */
&& splitwind(FALSE, 0) == FALSE) /* and it won't split */
@ -543,59 +515,57 @@ struct window *wpopup(void)
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);
backpage(f, n);
prevwind(FALSE, 1);
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);
forwpage(f, n);
prevwind(FALSE, 1);
return TRUE;
}
int savewnd(int f, int n)
{ /* save ptr to current window */
swindow = curwp;
return TRUE;
/* save ptr to current window */
BINDABLE( savewnd) {
savwindow = curwp ;
return TRUE ;
}
int restwnd(int f, int n)
{ /* restore the saved screen */
struct window *wp;
/* find the window */
wp = wheadp;
while (wp != NULL) {
if (wp == swindow) {
curwp = wp;
curbp = wp->w_bufp;
upmode();
return TRUE;
/* restore the saved screen */
BINDABLE( restwnd) {
/* check the saved window still exists */
for( window_p wp = wheadp ; wp != NULL ; wp = wp->w_wndp) {
if( wp == savwindow) {
curwp = wp ;
curbp = wp->w_bufp ;
upmode() ;
return TRUE ;
}
wp = wp->w_wndp;
}
mlwrite("(No such window exists)");
return FALSE;
return mloutfail( "(No such window exists)") ;
}
/*
* resize the screen, re-writing the screen
/* resize the screen, re-writing the screen
*
* int f; default flag
* int n; numeric argument
*/
int newsize(int f, int n)
{
struct window *wp; /* current window being examined */
struct window *nextwp; /* next window to scan */
struct window *lastwp; /* last window scanned */
BINDABLE( newsize) {
window_p wp; /* current window being examined */
window_p nextwp; /* next window to scan */
window_p lastwp; /* last window scanned */
int lastline; /* screen line of last line of current window */
/* if the command defaults, assume the largest */
@ -603,10 +573,8 @@ int newsize(int f, int n)
n = term.t_mrow ;
/* make sure it's in range */
if (n < 3 || n > term.t_mrow) {
mlwrite("%%Screen size out of range");
return FALSE;
}
if( n < 3 || n > term.t_mrow)
return mloutfail( "%%Screen size out of range") ;
if (term.t_nrow == n - 1)
return TRUE;
@ -674,25 +642,22 @@ int newsize(int f, int n)
return TRUE;
}
/*
* resize the screen, re-writing the screen
/* resize the screen, re-writing the screen
*
* int f; default flag
* int n; numeric argument
*/
int newwidth(int f, int n)
{
struct window *wp;
BINDABLE( newwidth) {
window_p wp;
/* if the command defaults, assume the largest */
if (f == FALSE)
n = term.t_mcol;
/* make sure it's in range */
if (n < 10 || n > term.t_mcol) {
mlwrite("%%Screen width out of range");
return FALSE;
}
if (n < 10 || n > term.t_mcol)
return mloutfail( "%%Screen width out of range") ;
/* otherwise, just re-width it (no big deal) */
term.t_ncol = n;
@ -713,7 +678,7 @@ int newwidth(int f, int n)
int getwpos(void)
{ /* get screen offset of current line in current 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 */
lp = curwp->w_linep;
@ -731,3 +696,5 @@ void cknewwindow(void)
{
execute(META | SPEC | 'X', FALSE, 1);
}
/* end of window.c */

View File

@ -1,33 +1,34 @@
/* window.h -- window functionality */
#ifndef _WINDOW_H_
#define _WINDOW_H_
#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. The
* windows are kept in a big list, in top to bottom screen order, with the
* listhead at "wheadp". Each window contains its own values of dot and mark.
* The flag field contains some bits that are set by commands to guide
* redisplay. Although this is a bit of a compromise in terms of decoupling,
* the full blown redisplay is just too expensive to run for every input
* character.
/* There is a window structure allocated for every active display window.
The windows are kept in a big list, in top to bottom screen order, with
the listhead at "wheadp". Each window contains its own values of dot
and mark. The flag field contains some bits that are set by commands to
guide redisplay. Although this is a bit of a compromise in terms of
decoupling, the full blown redisplay is just too expensive to run for
every input character.
*/
typedef struct 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_dotp ; /* Line containing "." */
line_p w_markp ; /* Line containing "mark" */
int w_doto ; /* Byte offset for "." */
int w_marko; /* Byte offset for "mark" */
int w_marko ; /* Byte offset for "mark" */
int w_toprow ; /* Origin 0 top row of window */
int w_ntrows ; /* # of rows of text in window */
char w_force; /* If NZ, forcing row. */
char w_flag; /* Flags. */
char w_force ; /* If NZ, forcing row. */
char w_flag ; /* Flags. */
#if COLOR
char w_fcolor; /* current forground color */
char w_bcolor; /* current background color */
char w_fcolor ; /* current forground color */
char w_bcolor ; /* current background color */
#endif
} *window_p ;
@ -45,30 +46,33 @@ extern window_p wheadp ; /* Head of list of windows */
#define WFCOLR 0x20 /* Needs a color change */
#if SCROLLCODE
#define WFKILLS 0x40 /* something was deleted */
#define WFINS 0x80 /* something was inserted */
# define WFKILLS 0x40 /* something was deleted */
# define WFINS 0x80 /* something was inserted */
#endif
int reposition( int f, int n);
int redraw( int f, int n) ;
int nextwind( int f, int n) ;
int prevwind( int f, int n) ;
int mvdnwind( int f, int n) ;
int mvupwind( int f, int n) ;
int onlywind( int f, int n) ;
int delwind( int f, int n) ;
int splitwind( int f, int n) ;
int enlargewind( int f, int n) ;
int shrinkwind( int f, int n) ;
int resize( int f, int n) ;
int scrnextup( int f, int n) ;
int scrnextdw( int f, int n) ;
int savewnd( int f, int n) ;
int restwnd( int f, int n) ;
int newsize( int f, int n) ;
int newwidth( int f, int n) ;
/* Bindable functions */
BINDABLE( delwind) ;
BINDABLE( enlargewind) ;
BINDABLE( mvdnwind) ;
BINDABLE( mvupwind) ;
BINDABLE( newsize) ;
BINDABLE( newwidth) ;
BINDABLE( nextwind) ;
BINDABLE( onlywind) ;
BINDABLE( prevwind) ;
TBINDABLE( redraw) ;
TBINDABLE( reposition) ;
BINDABLE( resize) ;
BINDABLE( restwnd) ;
BINDABLE( savewnd) ;
BINDABLE( scrnextdw) ;
BINDABLE( scrnextup) ;
BINDABLE( shrinkwind) ;
BINDABLE( splitwind) ;
int getwpos( void) ;
void cknewwindow( void) ;
window_p wpopup( void) ; /* Pop up window creation. */
#endif
/* end of window.h */

199
word.c
View File

@ -1,16 +1,14 @@
/* word.c -- implements 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
* do any sentence mode commands, they are likely to be put in this file.
*
* Modified by Petri Kutvonen
/* 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
do any sentence mode commands, they are likely to be put in this file.
Modified by Petri Kutvonen
*/
#include <stdio.h>
#include <assert.h>
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memcpy */
@ -31,18 +29,18 @@ static int justflag = FALSE ; /* justify, don't fill */
static int inword( void) ;
/* Word wrap on n-spaces. Back-over whatever precedes the point on the current
* line and stop on the first word-break or the beginning of the line. If we
* reach the beginning of the line, jump back to the end of the word and start
* a new line. Otherwise, break the line at the word-break, eat it, and jump
* back to the end of the word.
* Returns TRUE on success, FALSE on errors.
*
* @f: default flag.
* @n: numeric argument.
/* Word wrap on n-spaces. Back-over whatever precedes the point on the
current line and stop on the first word-break or the beginning of the
line. If we reach the beginning of the line, jump back to the end of
the word and start a new line. Otherwise, break the line at the
word-break, eat it, and jump back to the end of the word.
Returns TRUE on success, FALSE on errors.
@f: default flag.
@n: numeric argument.
*/
int wrapword(int f, int n)
{
BINDABLE( wrapword) {
int cnt; /* size of word wrapped to next line */
int c; /* charector temporary */
@ -81,11 +79,12 @@ int wrapword(int f, int n)
return TRUE;
}
/* 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
* move beyond the buffers.
performed by the "backchar" and "forwchar" routines. Error if you try
to move beyond the buffers.
*/
int backword( int f, int n) {
BINDABLE( backword) {
if( n < 0)
return forwword( f, -n) ;
@ -106,10 +105,12 @@ int backword( int f, int n) {
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)
return backword( f, -n) ;
@ -151,8 +152,7 @@ static boolean uniflip( boolean toupper_f) { /* flip unicode case and forward */
}
static boolean capcapword( int n, boolean first_f, boolean rest_f) {
if( curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly() ; /* we are in read only mode */
assert( !(curbp->b_mode & MDVIEW)) ;
if( n < 0)
return FALSE ;
@ -173,48 +173,46 @@ static boolean capcapword( int n, boolean first_f, boolean rest_f) {
return TRUE ;
}
/* 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
* end of the buffer. Bound to "M-U".
convert any characters to upper case. Error if you try and move beyond
the end of the buffer. Bound to "M-U".
*/
int upperword( int f, int n) {
BINDABLE( upperword) {
return capcapword( n, TRUE, TRUE) ;
}
/* 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
* the buffer. Bound to "M-L".
convert characters to lower case. Error if you try and move over the
end of the buffer. Bound to "M-L".
*/
int lowerword( int f, int n) {
BINDABLE( lowerword) {
return capcapword( n, FALSE, FALSE) ;
}
/* 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
* characters to lower case. Error if you try and move past the end of the
* buffer. Bound to "M-C".
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
buffer. Bound to "M-C".
*/
int capword( int f, int n) {
BINDABLE( capword) {
return capcapword( n, TRUE, FALSE) ;
}
/*
* Kill forward by "n" words. Remember the location of dot. Move forward by
* the right number of words. Put dot back where it was and issue the kill
* command for the right number of characters. With a zero argument, just
* kill one word and no whitespace. Bound to "M-D".
/* Kill forward by "n" words. Remember the location of dot. Move forward
by the right number of words. Put dot back where it was and issue the
kill command for the right number of characters. With a zero argument,
just kill one word and no whitespace. Bound to "M-D".
*/
int delfword(int f, int n)
{
struct line *dotp; /* original cursor line */
BINDABLE( delfword) {
line_p dotp; /* original cursor line */
int doto; /* and row */
int c; /* temp char */
long size; /* # of chars to delete */
/* don't allow this command if we are in read only mode */
if (curbp->b_mode & MDVIEW)
return rdonly();
assert( !(curbp->b_mode & MDVIEW)) ;
/* ignore the command if there is a negative argument */
if (n < 0)
@ -230,7 +228,7 @@ int delfword(int f, int n)
doto = curwp->w_doto;
/* figure out how many characters to give the axe */
size = 0;
long size = 0 ;
/* get us into a word.... */
while (inword() == FALSE) {
@ -289,18 +287,14 @@ int delfword(int f, int n)
return ldelete(size, TRUE);
}
/*
* Kill backwards by "n" words. Move backwards by the desired number of words,
* counting the characters. When dot is finally moved to its resting place,
* fire off the kill command. Bound to "M-Rubout" and to "M-Backspace".
*/
int delbword(int f, int n)
{
long size;
/* don't allow this command if we are in read only mode */
if (curbp->b_mode & MDVIEW)
return rdonly();
/* Kill backwards by "n" words. Move backwards by the desired number of
words, counting the characters. When dot is finally moved to its
resting place, fire off the kill command. Bound to "M-Rubout" and to
"M-Backspace".
*/
BINDABLE( delbword) {
assert( !(curbp->b_mode & MDVIEW)) ;
/* ignore the command if there is a nonpositive argument */
if (n <= 0)
@ -313,7 +307,8 @@ int delbword(int f, int n)
if (backchar(FALSE, 1) == FALSE)
return FALSE;
size = 0;
long size = 0 ;
while (n--) {
while (inword() == FALSE) {
if (backchar(FALSE, 1) == FALSE)
@ -345,7 +340,6 @@ static int inword( void) {
return isletter( c) || ( c >= '0' && c <= '9') ;
}
#if WORDPRO
static int parafillnjustify( int f, int n, int justify_f) {
unicode_t c; /* current char during scan */
unicode_t *wbuf ; /* buffer for current word */
@ -354,23 +348,19 @@ static int parafillnjustify( int f, int n, int justify_f) {
int clength; /* position on line during fill */
int eopflag; /* Are we at the End-Of-Paragraph? */
int firstflag = TRUE ; /* first word? (needs no space) */
struct line *eopline; /* pointer to line just past EOP */
line_p eopline; /* pointer to line just past EOP */
int dotflag = 0 ; /* was the last char a period? */
int leftmarg = 0 ; /* left marginal */
if (curbp->b_mode & MDVIEW) /* don't allow this command if */
return rdonly(); /* we are in read only mode */
if (fillcol == 0) { /* no fill column set */
mloutstr( "No fill column set") ;
return FALSE;
}
assert( !(curbp->b_mode & MDVIEW)) ;
if( fillcol == 0) /* no fill column set */
return mloutfail( "No fill column set") ;
if( justify_f) {
leftmarg = getccol( FALSE) ;
if (leftmarg + 10 > fillcol) {
mloutstr( "Column too narrow") ;
return FALSE;
}
if( leftmarg + 10 > fillcol)
return mloutfail( "Column too narrow") ;
justflag = justify_f ;
}
@ -480,35 +470,33 @@ static int parafillnjustify( int f, int n, int justify_f) {
return TRUE;
}
/*
* Fill the current paragraph according to the current
/* Fill the current paragraph according to the current
* fill column
*
* f and n - deFault flag and Numeric argument
*/
int fillpara( int f, int n) {
BINDABLE( fillpara) {
return parafillnjustify( f, n, FALSE) ;
}
/* Fill the current paragraph according to the current
* fill column and cursor position
*
* int f, n; deFault flag and Numeric argument
*/
int justpara( int f, int n) {
BINDABLE( justpara) {
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 n # of paras to delete
*/
int killpara(int f, int n)
{
int status; /* returned status of functions */
BINDABLE( killpara) {
while (n--) { /* for each paragraph to delete */
/* mark out the end and beginning of the para to delete */
@ -523,26 +511,26 @@ int killpara(int f, int n)
curwp->w_doto = 0; /* force us to the beginning of line */
/* and delete it */
if ((status = killregion(FALSE, 1)) != TRUE)
return status;
int status = killregion( FALSE, 1) ;
if( status != TRUE)
return status ;
/* and clean up the 2 extra lines */
ldelete(2L, TRUE);
}
return TRUE;
return TRUE ;
}
/*
* 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,
* and report on them.
*
* int f, n; ignored numeric arguments
*/
int wordcount(int f, int n)
{
struct line *lp; /* current line to scan */
BINDABLE( wordcount) {
line_p lp; /* current line to scan */
int offset; /* current char to scan */
long size; /* size of region left to count */
int ch; /* current character to scan */
@ -553,10 +541,10 @@ int wordcount(int f, int n)
int nlines; /* total number of lines in region */
int avgch; /* average number of chars/word */
int status; /* status return code */
struct region region; /* region to look at */
region_t region ; /* region to look at */
/* make sure we have a region to count */
if ((status = getregion(&region)) != TRUE)
if( (status = getregion( &region)) != TRUE)
return status;
lp = region.r_linep;
offset = region.r_offset;
@ -599,15 +587,14 @@ int wordcount(int f, int n)
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>
* combination to delimit the beginning of a paragraph
*
* int f, n; default Flag & Numeric argument
*/
int gotobop(int f, int n)
{
BINDABLE( gotobop) {
if (n < 0) /* the other way... */
return gotoeop(f, -n);
@ -637,15 +624,14 @@ int gotobop(int f, int n)
return TRUE;
}
/*
* Go forward to the end of the current paragraph
* here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
* combination to delimit the beginning of a paragraph
*
* int f, n; default Flag & Numeric argument
/* Go forward to the end of the current paragraph here we look for a
<NL><NL> or <NL><TAB> or <NL><SPACE> combination to delimit the
beginning of a paragraph
int f, n; default Flag & Numeric argument
*/
int gotoeop(int f, int n)
{
BINDABLE( gotoeop) {
if (n < 0) /* the other way... */
return gotobop(f, -n);
@ -677,6 +663,5 @@ int gotoeop(int f, int n)
curwp->w_flag |= WFMOVE; /* force screen update */
return TRUE;
}
#endif
/* end of word.c */

35
word.h
View File

@ -1,23 +1,24 @@
/* word.h -- word processing functions */
#ifndef _WORD_H_
#define _WORD_H_
#define WORDPRO 1
#include "names.h"
int wrapword( int f, int n) ;
int backword( int f, int n) ;
int forwword( int f, int n) ;
int upperword( int f, int n) ;
int lowerword( int f, int n) ;
int capword( int f, int n) ;
int delfword( int f, int n) ;
int delbword( int f, int n) ;
#if WORDPRO
int gotobop( int f, int n) ;
int gotoeop( int f, int n) ;
int fillpara( int f, int n) ;
int justpara( int f, int n) ;
int killpara( int f, int n) ;
int wordcount( int f, int n) ;
#endif
/* Bindable functions */
BINDABLE( wrapword) ;
BINDABLE( backword) ;
BINDABLE( forwword) ;
BINDABLE( upperword) ;
BINDABLE( lowerword) ;
BINDABLE( capword) ;
BINDABLE( delfword) ;
BINDABLE( delbword) ;
BINDABLE( gotobop) ;
BINDABLE( gotoeop) ;
BINDABLE( fillpara) ;
BINDABLE( justpara) ;
BINDABLE( killpara) ;
BINDABLE( wordcount) ;
#endif
/* end of word.h */

View File

@ -1,10 +1,12 @@
/* wrapper.h -- */
#ifndef WRAPPER_H_
#define WRAPPER_H_
#include <stdlib.h>
#include <stdlib.h> /* size_t */
void xmkstemp( char *fname_template) ;
void *xmalloc( size_t size) ;
#endif /* WRAPPER_H_ */
#endif
/* end of wrapper.h */