Merge pull request #66 from ibara/master

Update to emg-2.0
This commit is contained in:
Serge Vakulenko
2015-12-17 22:21:49 -08:00
22 changed files with 483 additions and 798 deletions

View File

@@ -1,13 +1,26 @@
ChangeLog
=========
December 17, 2015 : emg 2.0
---------------------------
Remove several unused functions.
Greatly simplify the buffer logic. emg no longer has multi-buffer support.
Remember to reset line number when opening files.
August 21, 2015 : emg 1.9
-------------------------
Smarter terminal setup.
Clarify quit message if you haven't saved the file.
Remove non-standard M-Z quick save.
Simpler arrow key and PgUp/PgDn logic.
August 10, 2015 : emg 1.8
-------------------------
Remove most buffer functions.
Remove all window functions.
Remove window.c, the one remaining function goes to display.c
Rework the modeline to look like Mg.
Add a version function, bound to "M-e".
Add a version function, bound to "M-E".
July 10, 2014 : emg 1.7
-----------------------

View File

@@ -13,11 +13,6 @@ CFLAGS += -ffunction-sections -fdata-sections
# This reduces code size significantly.
CFLAGS += -mips16
# Set the screen size.
# Will default to COLS=80 and ROWS=24
# if not set here.
#CFLAGS += -DCOLS=80 -DROWS=24
# with CFLAGS+= -ffunction-sections -fdata-sections
LDFLAGS += -Wl,--gc-sections

View File

@@ -1,41 +0,0 @@
emg
===
emg, or Ersatz Mg, is a very tiny Emacs-like text editor created by
combining elements of Ersatz Emacs and Mg (both the mg1a release and the
current OpenBSD-maintained version).
The goal of this editor is to have something Emacs like for RetroBSD
(a release of 2.11BSD for PIC32 microcontrollers). After noticing that the
vi clone RetroBSD is using, VIrus, is GPL-licensed, I decided to provide
a better-licensed editor. I also decided that, as a vi user myself, it would
be easier to create an Emacs clone. Like you, I'm also unsure as to how that
conclusion was reached.
I had initially tried to port Mg to RetroBSD but it was simply too large.
Ersatz Emacs does not build on RetroBSD, as RetroBSD is missing some functions
that Ersatz Emacs requires. It made sense to try to take from each and create
an editor that would work.
In a way, emg has a double meaning: not only is it a combination of
the two programs that comprise it, it is also a substitute Mg after my initial
port failed.
I have cleaned up some code where necessary; emg builds without errors on
RetroBSD.
Patches are also very welcome. I ask that you keep in mind the resource
constraints of RetroBSD: everything must fit in 96K RAM. But of course,
smaller is better.
I've left Chris Baird's Ersatz Emacs README here so others can better
appreciate the history of this software.
As both Ersatz Emacs and Mg are Public Domain, emg is also Public Domain.
Versions of emg up to and including 1.2 also supported OpenBSD; OpenBSD
has since dropped the older headers, such as sgtty.h, and it is not worth
reimplementing these for OpenBSD since OpenBSD maintains Mg.
====================================
Brian Callahan <bcallah@openbsd.org>

21
src/cmd/emg/README.md Normal file
View File

@@ -0,0 +1,21 @@
emg
===
emg, or Ersatz Mg, is a very tiny Emacs-like text editor created by
combining elements of Ersatz Emacs and Mg.
emg is distributed as part of the RetroBSD base system. This repo
is for development of emg. New releases are cut from this repo and
integrated into RetroBSD.
You can get a tarball of the latest release at
http://devio.us/~bcallah/emg/
emg is known to work on NetBSD as-is and AIX 5.1L with some small
tweaks, for those looking to get involved with emg development.
emg is Public Domain, because Ersatz Emacs and Mg are both Public
Domain and it would be insulting to all involved to change that.
=================================
Brian Callahan <bcallah@devio.us>

View File

@@ -12,16 +12,16 @@
#include "estruct.h"
#include "edef.h"
extern int getccol(int bflg);
extern int getccol(int);
extern void mlwrite();
extern int mlreplyt();
int forwchar(int f, int n);
int backchar(int f, int n);
int forwline(int f, int n);
int backline(int f, int n);
int pagedown(int f, int n);
int pageup(int f, int n);
int forwchar(int, int);
int backchar(int, int);
int forwline(int, int);
int backline(int, int);
int pagedown(int, int);
int pageup(int, int);
/*
* This routine, given a pointer to a LINE, and the current cursor goal
@@ -254,24 +254,24 @@ int backline(int f, int n)
}
/*
* PgDn. Scroll down (ROWS - 1).
* Just forwline(f, (ROWS -1))
* PgDn. Scroll down (rows / 2).
* Just forwline(f, (rows / 2))
* Bound to C-V
*/
int pagedown(int f, int n)
{
forwline(f, (ROWS - 1));
forwline(f, (rows / 2));
return (TRUE);
}
/*
* PgUp. Scroll up (ROWS - 1).
* Just backline(f, (ROWS -1))
* PgUp. Scroll up (rows / 2).
* Just backline(f, (rows / 2))
* Bound to M-V
*/
int pageup(int f, int n)
{
backline(f, (ROWS - 1));
backline(f, (rows / 2));
return (TRUE);
}

View File

@@ -11,93 +11,17 @@
#include "estruct.h"
#include "edef.h"
extern int mlreply(char *prompt, char *buf, int nbuf);
extern int readin(char fname[]);
extern int mlreply(char *, char *, int);
extern int readin(char []);
extern void mlwrite();
extern void mlerase();
extern int mlyesno(char *prompt);
extern void lfree(LINE *lp);
extern int mlyesno(char *);
extern void lfree(LINE *);
extern LINE *lalloc();
int swbuffer(BUFFER *bp);
int addline(char *text);
int anycb();
BUFFER* bfind(char *bname, int cflag, int bflag);
int bclear(BUFFER *bp);
/*
* make buffer BP current
*/
int swbuffer(BUFFER *bp)
{
WINDOW *wp;
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;
}
curbp = bp; /* Switch. */
if (curbp->b_active != TRUE)
{ /* buffer not active yet */
/* read it in and activate it */
readin(curbp->b_fname);
curbp->b_dotp = lforw(curbp->b_linep);
curbp->b_doto = 0;
curbp->b_active = TRUE;
}
curwp->w_bufp = bp;
curwp->w_linep = bp->b_linep; /* For macros, ignored */
curwp->w_flag |= WFMODE | WFFORCE | WFHARD; /* Quite nasty */
if (bp->b_nwnd++ == 0)
{ /* First use */
curwp->w_dotp = bp->b_dotp;
curwp->w_doto = bp->b_doto;
curwp->w_markp = bp->b_markp;
curwp->w_marko = bp->b_marko;
return (TRUE);
}
wp = wheadp; /* Look for old */
while (wp != 0)
{
if (wp != curwp && wp->w_bufp == bp)
{
curwp->w_dotp = wp->w_dotp;
curwp->w_doto = wp->w_doto;
curwp->w_markp = wp->w_markp;
curwp->w_marko = wp->w_marko;
break;
}
wp = wp->w_wndp;
}
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.
*/
int addline(char *text)
{
LINE *lp;
int ntext, i;
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);
}
int anycb(void);
BUFFER *bfind(char *);
int bclear(BUFFER *);
/*
* Look through the list of buffers. Return TRUE if there are any changed
@@ -105,91 +29,75 @@ int addline(char *text)
* cares if the list of buffer names is hacked. Return FALSE if no buffers
* have been changed.
*/
int anycb()
int anycb(void)
{
BUFFER *bp;
bp = bheadp;
while (bp != NULL)
{
if ((bp->b_flag & BFTEMP) == 0 && (bp->b_flag & BFCHG) != 0)
return (TRUE);
bp = bp->b_bufp;
}
while (bp != NULL) {
if ((bp->b_flag & BFTEMP) == 0 && (bp->b_flag & BFCHG) != 0)
return (TRUE);
bp = bp->b_bufp;
}
return (FALSE);
}
/*
* Find a buffer, by name. Return a pointer to the BUFFER structure associated
* with it. If the named buffer is found, but is a TEMP buffer (like the
* buffer list) conplain. If the buffer is not found and the "cflag" is TRUE,
* create it. The "bflag" is the settings for the flags in in buffer.
* buffer list), complain.
*/
BUFFER* bfind(char *bname, int cflag, int bflag)
BUFFER *
bfind(char *fname)
{
BUFFER *bp, *sb;
LINE *lp;
bp = bheadp;
while (bp != 0)
{
if (strcmp(bname, bp->b_bname) == 0)
{
if ((bp->b_flag & BFTEMP) != 0)
{
mlwrite ("Cannot select builtin buffer");
return (0);
}
return (bp);
}
bp = bp->b_bufp;
while (bp != 0) {
if (strcmp(fname, bp->b_fname) == 0) {
if ((bp->b_flag & BFTEMP) != 0) {
mlwrite("Cannot select builtin buffer");
return (FALSE);
}
return (bp);
}
if (cflag != FALSE)
{
if ((bp = (BUFFER *) malloc(sizeof(BUFFER))) == NULL)
return (0);
if ((lp = lalloc(0)) == NULL)
{
free(bp);
return (BUFFER*)0;
}
/* find the place in the list to insert this buffer */
if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0)
{
/* insert at the begining */
bp->b_bufp = bheadp;
bheadp = bp;
}
else
{
sb = bheadp;
while (sb->b_bufp != 0)
{
if (strcmp(sb->b_bufp->b_bname, bname) > 0)
break;
sb = sb->b_bufp;
}
/* and insert it */
bp->b_bufp = sb->b_bufp;
sb->b_bufp = bp;
}
/* and set up the other buffer fields */
bp->b_active = TRUE;
bp->b_dotp = lp;
bp->b_doto = 0;
bp->b_markp = 0;
bp->b_marko = 0;
bp->b_flag = (char)bflag;
bp->b_nwnd = 0;
bp->b_linep = lp;
bp->b_lines = 1;
strncpy(bp->b_fname, "", 1);
strncpy(bp->b_bname, bname, NBUFN);
lp->l_fp = lp;
lp->l_bp = lp;
bp = bp->b_bufp;
}
if ((bp = (BUFFER *) malloc(sizeof(BUFFER))) == NULL)
return (FALSE);
if ((lp = lalloc(0)) == NULL) {
free(bp);
return (BUFFER *)0;
}
/* find the place in the list to insert this buffer */
if (bheadp == NULL || strcmp(bheadp->b_fname, fname) > 0) {
/* insert at the begining */
bp->b_bufp = bheadp;
bheadp = bp;
} else {
sb = bheadp;
while (sb->b_bufp != 0) {
if (strcmp(sb->b_bufp->b_fname, fname) > 0)
break;
sb = sb->b_bufp;
}
/* and insert it */
bp->b_bufp = sb->b_bufp;
sb->b_bufp = bp;
}
/* and set up the other buffer fields */
bp->b_dotp = lp;
bp->b_doto = 0;
bp->b_markp = 0;
bp->b_marko = 0;
bp->b_flag = 0;
bp->b_linep = lp;
bp->b_lines = 1;
lp->l_fp = lp;
lp->l_bp = lp;
return (bp);
}

View File

@@ -17,28 +17,28 @@ extern int typeahead();
extern int ctrlg();
extern int getccol();
void movecursor(int row, int col);
void movecursor(int, int);
void mlerase();
int refresh();
void vtinit();
void vttidy();
void vtmove(int row, int col);
void vtputc(int c);
void vtpute(int c);
int vtputs(const char *s);
void vtmove(int, int);
void vtputc(int);
void vtpute(int);
int vtputs(const char *);
void vteeol();
void update();
void updext();
void updateline(int row, char vline[], char pline[], short *flags);
void modeline(WINDOW *wp);
void updateline(int, char [], char [], short *);
void modeline(WINDOW *);
void upmode();
int mlyesno(char *prompt);
int mlreplyt(char *prompt, char *buf, int nbuf, char eolchar);
int mlreply(char *prompt, char *buf, int nbuf);
int mlyesno(char *);
int mlreplyt(char *, char *, int, char);
int mlreply(char *, char *, int);
void mlwrite();
void mlputs(char *s);
void mlputi(int i, int r);
void mlputli(long l, int r);
void mlputs(char *);
void mlputi(int, int);
void mlputli(long, int);
typedef struct VIDEO {
short v_flag; /* Flags */
@@ -1001,4 +1001,3 @@ void mlputli(long l, int r)
(*term.t_putchar) ((int) (l % r) + '0');
++ttcol;
}

View File

@@ -50,9 +50,12 @@ KEYTAB keytab[] = {
{META | 'S', forwsearch}, /* non-standard */
{META | 'V', pageup},
{META | 'W', copyregion},
{META | 'Z', quickexit},
{METE | 'A', backline},
{METE | 'B', forwline},
{METE | 'C', forwchar},
{METE | 'D', backchar},
{METE | '5', pageup},
{METE | '6', pagedown},
{0x7F, backdel},
{META | '[', extendedcmd},
{META | 'O', extendedcmd},
{0, 0}
};

View File

@@ -26,11 +26,11 @@ int curcol; /* Cursor column */
int thisflag; /* Flags, this command */
int lastflag; /* Flags, last command */
int curgoal; /* Goal for C-P, C-N */
int rows; /* Screen rows for C-V, M-V */
WINDOW *curwp; /* Current window */
BUFFER *curbp; /* Current buffer */
WINDOW *wheadp; /* Head of list of windows */
BUFFER *bheadp; /* Head of list of buffers */
BUFFER *blistp; /* Buffer for C-X C-B */
short *kbdmip; /* Input pointer for above */
short *kbdmop; /* Output pointer for above */
@@ -61,18 +61,14 @@ extern int curcol; /* Cursor column */
extern int thisflag; /* Flags, this command */
extern int lastflag; /* Flags, last command */
extern int curgoal; /* Goal for C-P, C-N */
extern int rows; /* Screen rows for C-V, M-V */
extern WINDOW *curwp; /* Current window */
extern BUFFER *curbp; /* Current buffer */
extern WINDOW *wheadp; /* Head of list of windows */
extern BUFFER *bheadp; /* Head of list of buffers */
extern BUFFER *blistp; /* Buffer for C-X C-B */
extern short *kbdmip; /* Input pointer for above */
extern short *kbdmop; /* Output pointer for above */
#endif
/* terminal table defined only in TERM.C */
#ifndef termdef
extern TERM term; /* Terminal information */
#endif

View File

@@ -44,11 +44,9 @@ extern int killtext(); /* Kill forward */
extern int yank(); /* Yank back from killbuffer */
extern int killregion(); /* Kill region */
extern int copyregion(); /* Copy region to kill buffer */
extern int quickexit(); /* low keystroke style exit */
extern int setline(); /* go to a numbered line */
extern int deskey(); /* describe a key's binding */
extern int insfile(); /* insert a file */
extern int forwhunt(); /* hunt forward for next match */
extern int backhunt(); /* hunt backwards for next match */
extern int extendedcmd(); /* parse ANSI/VT100 extended keys */
extern int showversion(); /* show emacs version */

View File

@@ -3,7 +3,7 @@
.\" Basic emg man page.
.\" As both Ersatz Emacs and Mg are Public Domain, emg is also Public Domain.
.\"
.Dd August 9, 2014
.Dd August 9, 2015
.Os
.Dt EMG 1
.Sh NAME

View File

@@ -1,4 +1,4 @@
emg keybindings (August 9, 2014)
emg keybindings (August 9, 2015)
Based on Ersatz Emacs (2000/09/14)
M- means to use the <ESC> key prior to using another key

View File

@@ -17,6 +17,7 @@
#define CTRL 0x0100 /* Control flag, or'ed in */
#define META 0x0200 /* Meta flag, or'ed in */
#define CTLX 0x0400 /* ^X flag, or'ed in */
#define METE 0x0800 /* M-[ flag, or'ed in */
#define FALSE 0 /* False, no, bad, etc */
#define TRUE 1 /* True, yes, good, etc */
@@ -31,35 +32,6 @@
#define CFCPCN 0x0001 /* Last command was C-P, C-N */
#define CFKILL 0x0002 /* Last command was a kill */
/*
* screen constants
* override with
* CFLAGS += -DCOLS=XXX -DROWS=XXX
*/
#ifndef COLS
#define COLS 80
#endif
#ifndef ROWS
#define ROWS 24
#endif
/*
* XXX:
* Default/sane(?) maximum column and row sizes.
* Taken from mg1a.
*
* Let the user override these with
* CFLAGS += -DMAXCOL=XXX -DMAXROW=XXX
*/
#ifndef MAXCOL
#define MAXCOL 132
#endif
#ifndef MAXROW
#define MAXROW 66
#endif
/*
* 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
@@ -95,12 +67,9 @@ typedef struct WINDOW
* 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 accosiated with them have not been read in yet. These get read in at
* "use buffer" time
* safe store for the dot and mark in the header. The text for the buffer is
* kept in a circularly linked list of lines, with a pointer to the header
* line in "b_linep".
*/
typedef struct BUFFER
{
@@ -110,11 +79,8 @@ typedef struct BUFFER
struct LINE *b_markp; /* The same as the above two, */
long b_marko; /* but for the "mark" */
struct LINE *b_linep; /* Link to the header LINE */
char b_active; /* window activated flag */
char b_nwnd; /* Count of windows on buffer */
char b_flag; /* Flags */
char b_fname[NFILEN]; /* File name */
char b_bname[NBUFN]; /* Buffer name */
int b_lines; /* Number of lines in file */
} BUFFER;

View File

@@ -9,40 +9,37 @@
#include "estruct.h"
#include "edef.h"
extern int mlreply(char *prompt, char *buf, int nbuf);
extern int swbuffer(BUFFER *bp);
extern int mlreply(char *, char *, int);
extern void mlwrite();
extern int bclear(BUFFER *bp);
extern int ffropen(char *fn);
extern int ffgetline(char buf[], int nbuf);
extern int ffwopen(char *fn);
extern int bclear(BUFFER *);
extern int ffropen(char *);
extern int ffgetline(char [], int);
extern int ffwopen(char *);
extern int ffclose();
extern int ffputline(char buf[], int nbuf);
extern int ffputline(char [], int);
extern BUFFER *bfind();
extern LINE *lalloc();
int fileread(int f, int n);
int insfile(int f, int n);
int getfile(char fname[]);
int readin(char fname[]);
void makename(char bname[], char fname[]);
int filewrite(int f, int n);
int filesave(int f, int n);
int writeout(char *fn);
int filename(int f, int n);
int ifile(char fname[]);
int fileread(int, int);
int insfile(int, int);
int readin(char []);
int filewrite(int, int);
int filesave(int, int);
int writeout(char *);
int filename(int, int);
int ifile(char []);
/*
* Read a file into the current buffer. This is really easy; all you do it
* find the name of the file, and call the standard "read a file into the
* current buffer" code. Bound to "C-X C-R"
* current buffer" code. Bound to "C-X C-F"
*/
int fileread(int f, int n)
{
int s;
char fname[NFILEN];
if ((s = mlreply("Read file: ", fname, NFILEN)) != TRUE)
if ((s = mlreply("Open file: ", fname, NFILEN)) != TRUE)
return (s);
return (readin(fname));
}
@@ -62,65 +59,6 @@ int insfile(int f, int n)
return (ifile(fname));
}
int getfile(char fname[])
{
BUFFER *bp;
LINE *lp;
char bname[NBUFN]; /* buffer name to put file */
int i, s;
for (bp = bheadp; bp != (BUFFER*)0; bp = bp->b_bufp)
{
if ((bp->b_flag & BFTEMP) == 0 && strcmp(bp->b_fname, fname) == 0)
{
if (--curbp->b_nwnd == 0)
{
curbp->b_dotp = curwp->w_dotp;
curbp->b_doto = curwp->w_doto;
curbp->b_markp = curwp->w_markp;
curbp->b_marko = curwp->w_marko;
}
swbuffer(bp);
lp = curwp->w_dotp;
i = curwp->w_ntrows / 2;
while (i-- && lback(lp) != curbp->b_linep)
lp = lback(lp);
curwp->w_linep = lp;
curwp->w_flag |= WFMODE | WFHARD;
mlwrite("[Old buffer]");
return (TRUE);
}
}
makename(bname, fname); /* New buffer name */
while ((bp = bfind(bname, FALSE, 0)) != (BUFFER*)0)
{
s = mlreply("Buffer name: ", bname, NBUFN);
if (s == ABORT) /* ^G to just quit */
return (s);
if (s == FALSE)
{ /* CR to clobber it */
makename(bname, fname);
break;
}
}
if (bp == (BUFFER*)0 && (bp = bfind(bname, TRUE, 0)) == (BUFFER*)0)
{
mlwrite("Cannot create buffer");
return (FALSE);
}
if (--curbp->b_nwnd == 0)
{ /* Undisplay */
curbp->b_dotp = curwp->w_dotp;
curbp->b_doto = curwp->w_doto;
curbp->b_markp = curwp->w_markp;
curbp->b_marko = curwp->w_marko;
}
curbp = bp; /* Switch to it */
curwp->w_bufp = bp;
curbp->b_nwnd++;
return (readin(fname)); /* Read it in */
}
/*
* 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
@@ -196,6 +134,7 @@ int readin(char fname[])
wp->w_doto = 0;
wp->w_markp = NULL;
wp->w_marko = 0;
wp->w_dotline = 0;
wp->w_flag |= WFMODE | WFHARD;
}
}
@@ -204,27 +143,6 @@ int readin(char fname[])
return (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.
*/
void makename(char bname[], char fname[])
{
char *cp1, *cp2;
cp1 = &fname[0];
while (*cp1 != 0)
++cp1;
while (cp1 != &fname[0] && cp1[-1] != '/')
--cp1;
cp2 = &bname[0];
while (cp2 != &bname[NBUFN - 1] && *cp1 != 0 && *cp1 != ';')
*cp2++ = *cp1++;
*cp2 = 0;
}
/*
* 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.
@@ -267,7 +185,7 @@ int filesave(int f, int n)
if ((curbp->b_flag & BFCHG) == 0) /* Return, no changes */
return (TRUE);
if (curbp->b_fname[0] == 0)
if (curbp->b_fname[0] == '\0')
filename(f, n); /* Must have a name */
if ((s = writeout(curbp->b_fname)) == TRUE)
{

View File

@@ -11,11 +11,11 @@
extern void mlwrite();
int ffropen(char *fn);
int ffwopen(char *fn);
int ffropen(char *);
int ffwopen(char *);
int ffclose();
int ffputline(char buf[], int nbuf);
int ffgetline(char buf[], int nbuf);
int ffputline(char [], int);
int ffgetline(char [], int);
FILE *ffp; /* File pointer, all functions */

View File

@@ -6,12 +6,6 @@
* 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
* here for any good reason.
*
* Note that this code only updates the dot and mark values in the window
* list. Since all the code acts on the current window, the buffer that we are
* editing must be being displayed, which means that "b_nwnd" is non zero,
* which means that the dot and mark values in the buffer headers are
* nonsense
*/
#include <stdlib.h> /* malloc(3) */
@@ -19,18 +13,18 @@
#include "edef.h"
extern void mlwrite();
extern int backchar(int f, int n);
extern int backchar(int, int);
LINE* lalloc(int used);
void lfree(LINE *lp);
void lchange(int flag);
int linsert(int n, int c);
LINE* lalloc(int);
void lfree(LINE *);
void lchange(int);
int linsert(int, int);
int lnewline();
int ldelete(int n, int kflag);
int ldelete(int, int);
int ldelnewline();
void kdelete();
int kinsert(int c);
int kremove(int n);
int kinsert(int);
int kremove(int);
#define NBLOCK 16 /* Line block chunk size */
#define KBLOCK 1024 /* Kill buffer block size */
@@ -45,7 +39,8 @@ unsigned long ksize = 0; /* # of bytes allocated in KB */
* a pointer to the new block, or NULL if there isn't any memory left. Print a
* message in the message line if no space.
*/
LINE* lalloc(int used)
LINE *
lalloc(int used)
{
LINE *lp;
int size;
@@ -69,7 +64,8 @@ LINE* lalloc(int used)
* might be in. Release the memory. The buffers are updated too; the magic
* conditions described in the above comments don't hold here
*/
void lfree(LINE *lp)
void
lfree(LINE *lp)
{
BUFFER *bp;
WINDOW *wp;
@@ -92,23 +88,17 @@ void lfree(LINE *lp)
wp = wp->w_wndp;
}
bp = bheadp;
while (bp != NULL)
{
if (bp->b_nwnd == 0)
{
if (bp->b_dotp == lp)
{
bp->b_dotp = lp->l_fp;
bp->b_doto = 0;
}
if (bp->b_markp == lp)
{
bp->b_markp = lp->l_fp;
bp->b_marko = 0;
}
}
bp = bp->b_bufp;
while (bp != NULL) {
if (bp->b_dotp == lp) {
bp->b_dotp = lp->l_fp;
bp->b_doto = 0;
}
if (bp->b_markp == lp) {
bp->b_markp = lp->l_fp;
bp->b_marko = 0;
}
bp = bp->b_bufp;
}
lp->l_bp->l_fp = lp->l_fp;
lp->l_fp->l_bp = lp->l_bp;
free((char *) lp);
@@ -117,28 +107,24 @@ void lfree(LINE *lp)
/*
* This routine gets called when a character is changed in place in the
* current buffer. It updates all of the required flags in the buffer and
* window system. The flag used is passed as an argument; if the buffer is
* being displayed in more than 1 window we change EDIT t HARD. Set MODE if
* the mode line needs to be updated (the "*" has to be set).
* window system. The flag used is passed as an argument. Set MODE if the
* mode line needs to be updated (the "**" has to be set).
*/
void lchange(int flag)
void
lchange(int flag)
{
WINDOW *wp;
if (curbp->b_nwnd != 1) /* Ensure hard */
flag = WFHARD;
if ((curbp->b_flag & BFCHG) == 0)
{ /* First change, so */
flag |= WFMODE; /* update mode lines */
curbp->b_flag |= BFCHG;
}
if ((curbp->b_flag & BFCHG) == 0) { /* First change, so */
flag |= WFMODE; /* update mode lines */
curbp->b_flag |= BFCHG;
}
wp = wheadp;
while (wp != NULL)
{
if (wp->w_bufp == curbp)
wp->w_flag |= flag;
wp = wp->w_wndp;
}
while (wp != NULL) {
if (wp->w_bufp == curbp)
wp->w_flag |= flag;
wp = wp->w_wndp;
}
}
/*
@@ -150,7 +136,8 @@ void lchange(int flag)
* greater than the place where you did the insert. Return TRUE if all is
* well, and FALSE on errors
*/
int linsert(int n, int c)
int
linsert(int n, int c)
{
WINDOW *wp;
LINE *lp1, *lp2, *lp3;
@@ -238,7 +225,8 @@ int linsert(int n, int c)
* update of dot and mark is a bit easier then in the above case, because the
* split forces more updating.
*/
int lnewline()
int
lnewline()
{
WINDOW *wp;
char *cp1, *cp2;
@@ -296,7 +284,8 @@ int lnewline()
* deleted, and FALSE if they were not (because dot ran into the end of the
* buffer. The "kflag" is TRUE if the text should be put in the kill buffer.
*/
int ldelete(int n, int kflag)
int
ldelete(int n, int kflag)
{
LINE *dotp;
WINDOW *wp;
@@ -368,7 +357,8 @@ int ldelete(int n, int kflag)
* require that lines be moved about in memory. Return FALSE on error and TRUE
* if all looks ok. Called by "ldelete" only.
*/
int ldelnewline()
int
ldelnewline()
{
LINE *lp1, *lp2, *lp3;
WINDOW *wp;
@@ -457,10 +447,10 @@ int ldelnewline()
* new kill context is being created. The kill buffer array is released, just
* in case the buffer has grown to immense size. No errors.
*/
void kdelete()
void
kdelete()
{
if (kbufp != NULL)
{
if (kbufp != NULL) {
free((char *) kbufp);
kbufp = NULL;
kused = 0;
@@ -474,7 +464,8 @@ void kdelete()
* put something in the kill buffer you are going to put more stuff there too
* later. Return TRUE if all is well, and FALSE on errors.
*/
int kinsert(int c)
int
kinsert(int c)
{
char *nbufp;
@@ -498,7 +489,8 @@ int kinsert(int c)
* "n" is off the end, it returns "-1". This lets the caller just scan along
* until it gets a "-1" back.
*/
int kremove(int n)
int
kremove(int n)
{
if (n >= kused)
return (-1);

View File

@@ -22,186 +22,154 @@ extern void vttidy();
extern void update();
extern void mlerase();
extern void mlwrite();
extern int mlyesno(char *prompt);
extern void makename(char bname[], char fname[]);
extern int readin(char fname[]);
extern int linsert(int f, int n);
extern int anycb();
extern BUFFER *bfind();
extern int mlyesno(char *);
extern int readin(char []);
extern int linsert(int, int);
extern int anycb(void);
extern BUFFER *bfind(char *);
void edinit(char bname[]);
int execute(int c, int f, int n);
int getkey();
int getctl();
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 extendedcmd(int f, int n);
void edinit(char []);
int execute(int, int, int);
int getkey(void);
int getctl(void);
int quit(int, int);
int ctlxlp(int, int);
int ctlxrp(int, int);
int ctlxe(int, int);
int ctrlg(int, int);
int
main(int argc, char *argv[])
{
BUFFER *bp;
char bname[NBUFN]; /* buffer name of file to read */
char fname[NFILEN];
int c, f, n, mflag;
int ffile; /* first file flag */
int basec; /* c stripped of meta character */
/* initialize the editor and process the startup file */
getwinsize(); /* find out the "real" screen size */
strncpy(bname, "main", 5); /* default buffer name */
edinit(bname); /* Buffers, windows */
vtinit(); /* Displays */
ffile = TRUE; /* no file to edit yet */
update(); /* let the user know we are here */
/* scan through the command line and get the files to edit */
/* In place of getopt() */
if (argc > 2) {
(void) fprintf(stderr, "Can only edit one file at a time\n");
(void) fprintf(stderr, "usage: emg [file]\n");
exit(1);
} else if (argc == 2) {
/* set up a buffer for this file */
makename(bname, argv[1]);
strncpy(fname, argv[1], NFILEN);
} else {
strncpy(fname, "*scratch*", NFILEN);
}
/* if this is the first file, read it in */
if (ffile)
{
bp = curbp;
makename(bname, argv[1]);
strncpy(bp->b_bname, bname, NBUFN);
strncpy(bp->b_fname, argv[1], NFILEN);
if (readin(argv[1]) == ABORT)
{
strncpy(bp->b_bname, "main", 5);
strncpy(bp->b_fname, "", 1);
}
bp->b_dotp = bp->b_linep;
bp->b_doto = 0;
ffile = FALSE;
}
else
{
/* set this to inactive */
bp = bfind(bname, TRUE, 0);
strncpy(bp->b_fname, argv[1], NFILEN);
bp->b_active = FALSE;
}
}
/* initialize the editor and process the startup file */
getwinsize(); /* Find out the "real" screen size */
edinit(fname); /* Buffers, windows */
vtinit(); /* Displays */
update(); /* Let the user know we are here */
/* Read in the file given on the command line */
if (argc == 2) {
bp = curbp;
if (readin(argv[1]) == ABORT)
strncpy(fname, "*scratch*", NFILEN);
bp->b_dotp = bp->b_linep;
bp->b_doto = 0;
}
/* setup to process commands */
lastflag = 0; /* Fake last flags */
curwp->w_flag |= WFMODE; /* and force an update */
loop:
loop:
update(); /* Fix up the screen */
c = getkey();
if (mpresf != FALSE)
{
mlerase();
update();
}
if (mpresf != FALSE) {
mlerase();
update();
}
f = FALSE;
n = 1;
/* do META-# processing if needed */
basec = c & ~META; /* strip meta char off if there */
if ((c & META) && ((basec >= '0' && basec <= '9') || basec == '-'))
{
f = TRUE; /* there is a # arg */
n = 0; /* start with a zero default */
mflag = 1; /* current minus flag */
c = basec; /* strip the META */
while ((c >= '0' && c <= '9') || (c == '-'))
{
if (c == '-')
{
/* already hit a minus or digit? */
if ((mflag == -1) || (n != 0))
break;
mflag = -1;
}
else
n = n * 10 + (c - '0');
if ((n == 0) && (mflag == -1)) /* lonely - */
mlwrite("Arg:");
else
mlwrite("Arg: %d", n * mflag);
if ((c & META) && ((basec >= '0' && basec <= '9') || basec == '-')) {
f = TRUE; /* there is a # arg */
n = 0; /* start with a zero default */
mflag = 1; /* current minus flag */
c = basec; /* strip the META */
while ((c >= '0' && c <= '9') || (c == '-')) {
if (c == '-') {
/* already hit a minus or digit? */
if ((mflag == -1) || (n != 0))
break;
mflag = -1;
} else
n = n * 10 + (c - '0');
if ((n == 0) && (mflag == -1)) /* lonely - */
mlwrite("Arg:");
else
mlwrite("Arg: %d", n * mflag);
c = getkey(); /* get the next key */
}
n = n * mflag; /* figure in the sign */
c = getkey(); /* get the next key */
}
n = n * mflag; /* figure in the sign */
}
/* do ^U repeat argument processing */
if (c == (CTRL | 'U'))
{ /* ^U, start argument */
f = TRUE;
n = 4; /* with argument of 4 */
mflag = 0; /* that can be discarded */
mlwrite("Arg: 4");
while (((c = getkey ()) >= '0')
&& ((c <= '9') || (c == (CTRL | 'U')) || (c == '-')))
{
if (c == (CTRL | 'U'))
n = n * 4;
/*
* If dash, and start of argument string, set arg.
* to -1. Otherwise, insert it.
*/
else if (c == '-')
{
if (mflag)
break;
n = 0;
mflag = -1;
}
/*
* If first digit entered, replace previous argument
* with digit and set sign. Otherwise, append to arg.
*/
else
{
if (!mflag)
{
n = 0;
mflag = 1;
}
n = 10 * n + c - '0';
}
mlwrite("Arg: %d", (mflag >= 0) ? n : (n ? -n : -1));
}
if (c == (CTRL | 'U')) { /* ^U, start argument */
f = TRUE;
n = 4; /* with argument of 4 */
mflag = 0; /* that can be discarded */
mlwrite("Arg: 4");
while (((c = getkey()) >= '0')
&& ((c <= '9') || (c == (CTRL | 'U')) || (c == '-'))) {
if (c == (CTRL | 'U'))
n = n * 4;
/*
* Make arguments preceded by a minus sign negative and change
* the special argument "^U -" to an effective "^U -1".
* If dash, and start of argument string, set arg.
* to -1. Otherwise, insert it.
*/
if (mflag == -1)
{
if (n == 0)
n++;
n = -n;
else if (c == '-') {
if (mflag)
break;
n = 0;
mflag = -1;
/*
* If first digit entered, replace previous argument
* with digit and set sign. Otherwise, append to arg.
*/
} else {
if (!mflag) {
n = 0;
mflag = 1;
}
n = 10 * n + c - '0';
}
mlwrite("Arg: %d", (mflag >= 0) ? n : (n ? -n : -1));
}
/*
* Make arguments preceded by a minus sign negative and change
* the special argument "^U -" to an effective "^U -1".
*/
if (mflag == -1) {
if (n == 0)
n++;
n = -n;
}
}
if (c == (CTRL | 'X')) /* ^X is a prefix */
c = CTLX | getctl ();
if (kbdmip != NULL)
{ /* Save macro strokes */
if (c != (CTLX | ')') && kbdmip > &kbdm[NKBDM - 6])
{
ctrlg(FALSE, 0);
goto loop;
}
if (f != FALSE)
{
*kbdmip++ = (CTRL | 'U');
*kbdmip++ = n;
}
*kbdmip++ = c;
if (c == (META | '[')) /* M-[ is extended ANSI sequence */
c = METE | getctl();
else if (c == (CTRL | 'X')) /* ^X is a prefix */
c = CTLX | getctl();
if (kbdmip != NULL) { /* Save macro strokes */
if (c != (CTLX | ')') && kbdmip > &kbdm[NKBDM - 6]) {
ctrlg(FALSE, 0);
goto loop;
}
if (f != FALSE) {
*kbdmip++ = (CTRL | 'U');
*kbdmip++ = n;
}
*kbdmip++ = c;
}
execute(c, f, n); /* Do it */
goto loop;
}
@@ -211,22 +179,21 @@ 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.
*/
void edinit(char bname[])
void
edinit(char fname[])
{
BUFFER *bp;
WINDOW *wp;
bp = bfind(bname, TRUE, 0); /* First buffer */
blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer */
wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */
if (bp == NULL || wp == NULL || blistp == NULL)
exit (1);
bp = bfind(fname);
wp = (WINDOW *) malloc(sizeof(WINDOW));
if (bp == NULL || wp == NULL)
exit(1);
curbp = bp; /* Make this current */
wheadp = wp;
curwp = wp;
wp->w_wndp = NULL; /* Initialize window */
wp->w_bufp = bp;
bp->b_nwnd = 1; /* Displayed */
wp->w_linep = bp->b_linep;
wp->w_dotp = bp->b_linep;
wp->w_doto = 0;
@@ -244,39 +211,36 @@ void edinit(char bname[])
* 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(int c, int f, int n)
{
KEYTAB *ktp;
int status;
ktp = &keytab[0]; /* Look in key table */
while (ktp->k_fp != NULL)
{
if (ktp->k_code == c)
{
thisflag = 0;
status = (*ktp->k_fp) (f, n);
lastflag = thisflag;
return (status);
}
++ktp;
}
if ((c >= 0x20 && c <= 0x7E) /* Self inserting */
|| (c >= 0xA0 && c <= 0xFE))
{
if (n <= 0)
{ /* Fenceposts */
lastflag = 0;
return (n < 0 ? FALSE : TRUE);
}
thisflag = 0; /* For the future */
status = linsert(n, c);
while (ktp->k_fp != NULL) {
if (ktp->k_code == c) {
thisflag = 0;
status = (*ktp->k_fp) (f, n);
lastflag = thisflag;
return (status);
}
++ktp;
}
if ((c >= 0x20 && c <= 0x7E) /* Self inserting */
|| (c >= 0xA0 && c <= 0xFE)) {
if (n <= 0) { /* Fenceposts */
lastflag = 0;
return (n < 0 ? FALSE : TRUE);
}
thisflag = 0; /* For the future */
status = linsert(n, c);
lastflag = thisflag;
return (status);
}
mlwrite("\007[Key not bound]"); /* complain */
lastflag = 0; /* Fake last flags */
return (FALSE);
@@ -286,17 +250,17 @@ int execute(int c, int f, int n)
* Read in a key. Do the standard keyboard preprocessing. Convert the keys to
* the internal character set.
*/
int getkey()
int
getkey(void)
{
int c;
c = (*term.t_getchar) ();
if (c == METACH)
{ /* Apply M- prefix */
c = getctl ();
return (META | c);
}
if (c == METACH) { /* Apply M- prefix */
c = getctl();
return (META | c);
}
if (c >= 0x00 && c <= 0x1F) /* C0 control -> C- */
c = CTRL | (c + '@');
return (c);
@@ -305,11 +269,12 @@ int getkey()
/*
* Get a key. Apply control modifications to the read key.
*/
int getctl()
int
getctl()
{
int c;
c = (*term.t_getchar) ();
c = (*term.t_getchar)();
if (c >= 'a' && c <= 'z') /* Force to upper */
c -= 0x20;
if (c >= 0x00 && c <= 0x1F) /* C0 control -> C- */
@@ -317,44 +282,21 @@ int getctl()
return (c);
}
/*
* 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)
{
BUFFER *bp; /* scanning pointer to buffers */
bp = bheadp;
while (bp != NULL)
{
if ((bp->b_flag & BFCHG) != 0 /* Changed */
&& (bp->b_flag & BFTEMP) == 0)
{ /* Real */
curbp = bp; /* make that buffer current */
mlwrite("[Saving %s]", (int*)bp->b_fname);
filesave(f, n);
}
bp = bp->b_bufp; /* on to the next buffer */
}
return quit(f, n); /* conditionally quit */
}
/*
* 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
quit(int f, int n)
{
int s;
if (f != FALSE /* Argument forces it */
|| anycb () == FALSE /* All buffers clean */
|| (s = mlyesno("Modified buffers exist. Leave anyway")) == TRUE)
{
vttidy();
exit (0);
}
|| anycb() == FALSE /* All buffers clean */
|| (s = mlyesno("Quit without saving")) == TRUE) {
vttidy();
exit(0);
}
mlwrite("");
return (s);
}
@@ -363,13 +305,13 @@ int quit(int f, int n)
* 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)
int
ctlxlp(int f, int n)
{
if (kbdmip != NULL || kbdmop != NULL)
{
mlwrite("Not now");
return (FALSE);
}
if (kbdmip != NULL || kbdmop != NULL) {
mlwrite("Not now");
return (FALSE);
}
mlwrite("[Start macro]");
kbdmip = &kbdm[0];
return (TRUE);
@@ -379,13 +321,13 @@ int ctlxlp(int f, int n)
* 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)
int
ctlxrp(int f, int n)
{
if (kbdmip == NULL)
{
mlwrite("Not now");
return (FALSE);
}
if (kbdmip == NULL) {
mlwrite("Not now");
return (FALSE);
}
mlwrite("[End macro]");
kbdmip = NULL;
return (TRUE);
@@ -395,36 +337,31 @@ int ctlxrp(int f, int n)
* 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)
int
ctlxe(int f, int n)
{
int c, af, an, s;
if (kbdmip != NULL || kbdmop != NULL)
{
mlwrite("No macro defined");
return (FALSE);
}
if (kbdmip != NULL || kbdmop != NULL) {
mlwrite("No macro defined");
return (FALSE);
}
if (n <= 0)
return (TRUE);
do
{
kbdmop = &kbdm[0];
do
{
af = FALSE;
an = 1;
if ((c = *kbdmop++) == (CTRL | 'U'))
{
af = TRUE;
an = *kbdmop++;
c = *kbdmop++;
}
s = TRUE;
}
while (c != (CTLX | ')') && (s = execute(c, af, an)) == TRUE);
kbdmop = NULL;
}
while (s == TRUE && --n);
do {
kbdmop = &kbdm[0];
do {
af = FALSE;
an = 1;
if ((c = *kbdmop++) == (CTRL | 'U')) {
af = TRUE;
an = *kbdmop++;
c = *kbdmop++;
}
s = TRUE;
} while (c != (CTLX | ')') && (s = execute(c, af, an)) == TRUE);
kbdmop = NULL;
} while (s == TRUE && --n);
return (s);
}
@@ -432,45 +369,18 @@ int ctlxe(int f, int n)
* 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)
int
ctrlg(int f, int n)
{
(*term.t_beep) ();
if (kbdmip != NULL)
{
kbdm[0] = (CTLX | ')');
kbdmip = NULL;
}
if (kbdmip != NULL) {
kbdm[0] = (CTLX | ')');
kbdmip = NULL;
}
mlwrite("[Aborted]");
return (ABORT);
}
/*
* Handle ANSI escape-extended commands (with "ESC [" or "ESC O" prefix)
*/
int extendedcmd(int f, int n)
{
int (*cmd)();
int c;
c = getctl();
switch (c)
{
case 'A': cmd = backline; break;
case 'B': cmd = forwline; break;
case 'C': cmd = forwchar; break;
case 'D': cmd = backchar; break;
case 'H': cmd = gotobob; break;
case 'W': cmd = gotoeob; break;
case '5': cmd = pageup; getctl(); break;
case '6': cmd = pagedown; getctl(); break;
case '7': cmd = gotobob; getctl(); break;
case '8': cmd = gotoeob; getctl(); break;
default: mlwrite("\007[Key not bound]");
return (FALSE);
}
return cmd(f, n);
}
/*
* Display the version. All this does
* is copy the version string into the echo line.
@@ -480,6 +390,6 @@ int extendedcmd(int f, int n)
int
showversion(int f, int n)
{
mlwrite("emg 1.8");
mlwrite("emg 2.0");
return (TRUE);
}

View File

@@ -9,25 +9,25 @@
#include "edef.h"
extern void mlwrite();
extern void lchange(int flag);
extern void lchange(int);
extern int lnewline();
extern int linsert(int n, int c);
extern int backchar(int f, int n);
extern int linsert(int, int);
extern int backchar(int, int);
extern void kdelete();
extern int ldelete(int f, int n);
extern int kremove(int k);
extern int ldelete(int, int);
extern int kremove(int);
int setfillcol(int f, int n);
int getccol(int bflg);
int twiddle(int f, int n);
int quote(int f, int n);
int tab(int f, int n);
int openline(int f, int n);
int newline(int f, int n);
int forwdel(int f, int n);
int backdel(int f, int n);
int killtext(int f, int n);
int yank(int f, int n);
int setfillcol(int, int);
int getccol(int);
int twiddle(int, int);
int quote(int, int);
int tab(int, int);
int openline(int, int);
int newline(int, int);
int forwdel(int, int);
int backdel(int, int);
int killtext(int, int);
int yank(int, int);
/*
* Set fill column to n.

View File

@@ -10,13 +10,13 @@
#include "edef.h"
extern void kdelete();
extern int ldelete(int f, int n);
extern int kinsert(int c);
extern int ldelete(int, int);
extern int kinsert(int);
extern void mlwrite();
int killregion(int f, int n);
int copyregion(int f, int n);
int getregion(REGION *rp);
int killregion(int, int);
int copyregion(int, int);
int getregion(REGION *);
/*
* Kill the region. Ask "getregion" to figure out the bounds of the region.

View File

@@ -11,21 +11,21 @@
#include "edef.h"
extern void mlwrite();
extern int mlreplyt(char *prompt, char *buf, int nbuf, char eolchar);
extern int mlreplyt(char *, char *, int, char);
extern void update();
extern int forwchar(int f, int n);
extern int ldelete(int n, int kflag);
extern int linsert(int n, int c);
extern int forwchar(int, int);
extern int ldelete(int, int);
extern int linsert(int, int);
int forwsearch(int f, int n);
int forwhunt(int f, int n);
int backsearch(int f, int n);
int backhunt(int f, int n);
int bsearch(int f, int n);
int eq(int bc, int pc);
int readpattern(char *prompt);
int forscan(char *patrn, int leavep);
void expandp(char *srcstr, char *deststr, int maxlength);
int forwsearch(int, int);
int forwhunt(int, int);
int backsearch(int, int);
int backhunt(int, int);
int bsearch(int, int);
int eq(int, int);
int readpattern(char *);
int forscan(char *, int);
void expandp(char *, char *, int);
#define PTBEG 1 /* leave the point at the begining on search */
#define PTEND 2 /* leave the point at the end on search */

View File

@@ -2,9 +2,8 @@
/* termios video driver */
#define termdef 1 /* don't define "term" externally */
#include <stdio.h> /* puts(3), snprintf(3) */
#include "estruct.h"
#include "edef.h"
#undef CTRL /* Needs to be done here. */
@@ -22,15 +21,15 @@ extern void ttputc();
extern void ttflush();
extern void ttclose();
extern void panic();
extern void panic(char *);
void getwinsize();
void tcapopen();
void tcapmove(int row, int col);
void tcapeeol();
void tcapeeop();
void tcaprev();
void tcapbeep();
void getwinsize(void);
void tcapopen(void);
void tcapmove(int, int);
void tcapeeol(void);
void tcapeeop(void);
void tcaprev(int);
void tcapbeep(void);
#define MARGIN 8
#define SCRSIZ 64
@@ -45,25 +44,27 @@ TERM term = {
ttflush, tcapmove, tcapeeol, tcapeeop, tcapbeep, tcaprev
};
void getwinsize()
void
getwinsize(void)
{
int cols = COLS;
int rows = ROWS;
struct winsize ws;
/* Too small and we're out */
if ((cols < 10) || (rows < 3))
panic("Too few columns or rows");
if (ioctl(0, TIOCGWINSZ, &ws) == 0) {
term.t_ncol = ws.ws_col;
rows = ws.ws_row;
}
if (COLS > MAXCOL)
cols = MAXCOL;
if (ROWS > MAXROW)
rows = MAXROW;
/* Too small and we hard code */
if ((term.t_ncol < 10) || (rows < 3)) {
term.t_ncol = 80;
rows = 24;
}
term.t_ncol = cols;
term.t_nrow = rows - 1;
}
void tcapopen()
void
tcapopen(void)
{
char tcbuf[1024];
char *p, *tv_stype;
@@ -84,34 +85,39 @@ void tcapopen()
if (SO != NULL && SE != NULL)
revexist = TRUE;
if (CL == NULL || CM == NULL)
panic("Need cl & cm abilities");
panic("Need cl & cm abilities");
if (p >= &tcapbuf[TCAPSLEN]) /* XXX */
panic("Description too big");
ttopen ();
panic("Description too big");
ttopen();
}
void tcaprev(int state)
void
tcaprev(int state)
{
if (revexist)
tputs((state ? SO : SE), 1, ttputc);
}
void tcapmove (int row, int col)
void
tcapmove(int row, int col)
{
tputs(tgoto(CM, col, row), 1, ttputc);
}
void tcapeeol()
void
tcapeeol(void)
{
tputs(CE, 1, ttputc);
}
void tcapeeop()
void
tcapeeop(void)
{
tputs(CL, 1, ttputc);
}
void tcapbeep()
void
tcapbeep(void)
{
ttputc(BEL);
}

View File

@@ -9,11 +9,11 @@
#include "estruct.h"
#include "edef.h"
extern int backchar(int f, int n);
extern int forwchar(int f, int n);
extern int backchar(int, int);
extern int forwchar(int, int);
int backword(int f, int n);
int forwword(int f, int n);
int backword(int, int);
int forwword(int, int);
int inword(void);
/*
@@ -21,14 +21,14 @@ int inword(void);
* performed by the "backchar" and "forwchar" routines. Error if you try to
* move beyond the buffers
*/
int backword(int f, int n)
int
backword(int f, int n)
{
if (n < 0)
return (forwword(f, -n));
if (backchar(FALSE, 1) == FALSE)
return (FALSE);
while (n--)
{
while (n--) {
while (inword() == FALSE)
{
if (backchar(FALSE, 1) == FALSE)
@@ -47,12 +47,12 @@ int backword(int f, int n)
* 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)
int
forwword(int f, int n)
{
if (n < 0)
return (backword(f, -n));
while (n--)
{
while (n--) {
while (inword() != FALSE)
{
if (forwchar(FALSE, 1) == FALSE)
@@ -71,7 +71,8 @@ int forwword(int f, int n)
* Return TRUE if the character at dot is a character that is considered to be
* part of a word. The word character list is hard coded. Should be setable
*/
int inword(void)
int
inword(void)
{
int c;