dillon@CORY.BERKELEY.EDU.UUCP (01/28/87)
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# command.c
# main.c
# text.c
# defs.h
# This archive created: Tue Jan 27 18:59:35 1987
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'command.c'" '(6612 characters)'
if test -f 'command.c'
then
echo shar: "will not over-write existing file 'command.c'"
else
cat << \!Funky!Stuff! > 'command.c'
/*
* COMMAND.C
*
* 'c single character
* `string' string of characters w/ embedded `' allowed!
*
* name arg arg command name. The arguments are interpreted as strings
* for the command.
*
* Any string arguments not part of a command are considered to be typed
* text.
*
*
*/
#include "defs.h"
extern char *breakout();
short ComLineMode;
typedef struct {
char *name; /* command name */
short args; /* # of arguments */
short sl; /* 1 if stays within bounds of the current line */
int (*func)(); /* function */
} COMM;
extern int do_map(), do_unmap(), do_up(), do_down(), do_left(), do_right(),
do_return(), do_bs(), do_del(), do_esc(), do_downadd(),
do_lastcolumn(), do_firstcolumn(), do_edit(), do_tab(),
do_backtab(), do_save(), do_saveas(), do_deline(), do_insline(),
do_top(), do_bottom(), do_source(), do_firstnb(),
do_quit(), do_find(), do_pageup(), do_pagedown(),
do_split(), do_goto(), do_screentop(), do_screenbottom(),
do_join(), do_repeat(), do_tabstop(), do_insertmode(),
do_block(), do_bdelete(), do_bcopy(), do_bmove(), do_bsave();
COMM Comm[] = {
"esc", 0, 1, do_esc,
"escimm", 1, 0, do_esc,
"last", 0, 1, do_lastcolumn,
"first", 0, 1, do_firstcolumn,
"downadd", 0, 0, do_downadd,
"map", 2, 0, do_map,
"unmap", 1, 0, do_unmap,
"up", 0, 0, do_up,
"down", 0, 0, do_down,
"pageup", 0, 0, do_pageup,
"pagedown", 0, 0, do_pagedown,
"left", 0, 1, do_left,
"right", 0, 1, do_right,
"return", 0, 1, do_return, /* special meaning in command line mode */
"bs", 0, 1, do_bs,
"back", 0, 1, do_bs,
"del", 0, 1, do_del,
"insline", 0, 0, do_insline,
"deline", 0, 0, do_deline,
"tab", 0, 1, do_tab,
"backtab", 0, 1, do_backtab,
"newfile", 1, 0, do_edit,
"insfile", 1, 0, do_edit,
"saveold", 0, 0, do_save,
"saveas", 1, 0, do_saveas,
"top", 0, 0, do_top,
"bottom", 0, 0, do_bottom,
"source", 1, 0, do_source,
"firstnb", 0, 1, do_firstnb,
"quit", 0, 0, do_quit,
"find", 1, 0, do_find,
"next", 0, 0, do_find,
"prev", 0, 0, do_find,
"split", 0, 0, do_split,
"join", 0, 0, do_join,
"repeat", 2, 1, do_repeat,
"tabstop", 1, 1, do_tabstop,
"insertmode", 1, 1, do_insertmode,
"screentop", 0, 0, do_screentop,
"screenbottom", 0, 0, do_screenbottom,
"goto", 1, 0, do_goto,
"block", 0, 0, do_block,
"unblock", 0, 0, do_block,
"bcopy", 0, 0, do_bcopy,
"bmove", 0, 0, do_bmove,
"bdelete", 0, 0, do_bdelete,
"bsave", 1, 0, do_bsave,
NULL, 0, 0, NULL
};
do_command(str)
char *str;
{
char *arg;
char quoted;
short i, j;
while (arg = breakout(&str, "ed)) {
if (quoted) {
text_write(arg);
continue;
}
for (i = 0; arg[i]; ++i) {
if (arg[i] >= 'A' && arg[i] <= 'Z')
arg[i] = arg[i] + 'a' - 'A';
}
for (i = 0; Comm[i].name; ++i) {
if (strcmp(arg, Comm[i].name) == 0) {
av[0] = Comm[i].name;
for (j = 1; j <= Comm[i].args; ++j) {
av[j] = breakout(&str, "ed);
if (!av[j]) {
title("Bad argument");
return(0);
}
}
if (Comm[i].sl || !ComLineMode)
(*Comm[i].func)();
goto loop;
}
}
title("Unknown Command");
return(0);
loop:
}
return(1);
}
do_source()
{
char buf[256];
long fi;
if (fi = xopen(av[1], "r", 256)) {
while (xgets(fi, buf, 255))
do_command(buf);
xclose(fi);
} else {
if (av[0])
title("File not found");
}
}
do_quit()
{
extern char Quitflag;
Quitflag = 1;
}
/*
* repeat X command
*
* Since repeat takes up 512+ stack, it should not be nested more than
* twice.
*
* (if X is not a number it can be abbr. with 2 chars)
*
* X = N -number of repeats
* line -current line # (lines begin at 1)
* lbot -#lines to the bottom, inc. current
* cleft -column # (columns begin at 0)
* (thus is also chars to the left)
* cright-#chars to eol, including current char
* tr -#char positions to get to next tab stop
* tl -#char positions to get to next backtab stop
*/
#define SC(a,b) ((a)<<8|(b))
do_repeat()
{
char *ptr = av[1];
char buf1[256];
char buf2[256];
long n;
strcpy(buf1, av[2]);
switch((ptr[0]<<8)+ptr[1]) {
case SC('l','i'):
n = text_lineno();
break;
case SC('l','b'):
n = text_lines() - text_lineno() + 1;
break;
case SC('c','l'):
n = text_colno();
break;
case SC('c','r'):
n = text_cols() - text_colno();
break;
case SC('t','r'):
n = text_tabsize()-(text_colno() % text_tabsize());
break;
case SC('t','l'):
n = text_colno() % text_tabsize();
if (n == 0)
n = text_tabsize();
break;
default:
n = atoi(av[1]);
break;
}
while (n > 0) {
strcpy(buf2, buf1);
do_command(buf2);
--n;
}
}
char *
breakout(ptr, quoted)
char **ptr, *quoted;
{
char *str = *ptr;
char *base = str;
*quoted = 0;
while (*str == ' ')
++str;
if (!*str)
return(NULL);
if (*str == '\'') {
if (str[1]) {
*quoted = 1;
base = str + 1;
if (str[2])
++str;
*str = '\0';
*ptr = str;
return(base);
}
return(NULL);
}
if (*str == '`') {
short count = 1;
base = ++str;
while (*str && count) {
if (*str == '`')
++count;
if (*str == '\'')
--count;
++str;
}
if (count == 0) {
--str;
*quoted = 1;
*str = '\0';
*ptr = str + 1;
return(base);
}
}
base = str;
while (*str && *str != ' ')
++str;
if (*str) {
*str = '\0';
*ptr = str + 1;
return(base);
}
*ptr = str;
return(base);
}
!Funky!Stuff!
fi # end of overwriting check
echo shar: "extracting 'main.c'" '(14917 characters)'
if test -f 'main.c'
then
echo shar: "will not over-write existing file 'main.c'"
else
cat << \!Funky!Stuff! > 'main.c'
/*
* MAIN.C
*/
#include <exec/types.h>
#include <intuition/intuition.h>
#include <typedefs.h>
#include "xmisc.h"
#include "defs.h"
#define KEY_LSHIFT (1 << 0)
#define KEY_RSHIFT (1 << 1)
#define KEY_CAPS (1 << 2)
#define KEY_CTRL (1 << 3)
#define KEY_ALTL (1 << 4)
#define KEY_ALTR (1 << 5)
#define KEY_AMIGAL (1 << 6)
#define KEY_AMIGAR (1 << 7)
#define QUAL_SHIFT 0x01
#define QUAL_CTRL 0x02
#define QUAL_AMIGA 0x04
#define QUAL_ALT 0x08
NW Nw = {
0, 1, 640, 199, -1, -1,
CLOSEWINDOW|NEWSIZE|RAWKEY|MOUSEBUTTONS|ACTIVEWINDOW,
ACTIVATE|WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|RMBTRAP,
NULL, NULL, "MED V1.01 (c)CopyRight 1986 Matthew Dillon, All Rights Reserved ",
NULL, NULL,
32, 32, -1, -1,
WBENCHSCREEN
};
WIN *Win;
RP *Rp;
short Xsize, Ysize; /* font character sizes */
short Rows, Columns; /* character rows/cols available */
short Xbase, Ybase; /* offset pixel base for display */
short XTbase, YTbase; /* used for text display */
short Xpixs, Ypixs; /* actual # X/Y pixels available */
char *av[8];
char Quitflag;
char Overide;
extern ED E;
extern char memoryfail;
main(mac, mav)
char *mav[];
{
IMESS *im;
char notdone;
char iawm;
if (!openlibs(INTUITION_LIB|GRAPHICS_LIB))
exiterr("cannot open intuition or graphics library");
Win = OpenWindow(&Nw);
if (Win == NULL)
exiterr("cannot open window");
Rp = Win->RPort;
set_window_params();
resethash();
text_init();
text_redisplay();
if (mac == 2) {
av[0] = "newfile";
av[1] = mav[1];
do_edit();
}
mountrequest(0);
av[0] = NULL;
av[1] = "c:.edrc";
do_source();
av[0] = NULL;
av[1] = ".edrc";
do_source();
mountrequest(1);
text_titleupdate();
loop:
text_cursor(1);
for (notdone = 1, iawm = 0; !Quitflag && notdone;) {
window_title();
WaitPort(Win->UserPort);
while (im = (IMESS *)GetMsg(Win->UserPort)) {
switch(im->Class) {
case NEWSIZE:
if (ComLineMode)
escapecomlinemode();
set_window_params();
if (!text_sync())
text_redisplay();
text_cursor(1);
break;
case RAWKEY:
text_cursor(0);
keyctl(im->Code);
text_cursor(1);
break;
case CLOSEWINDOW:
if (ComLineMode)
escapecomlinemode();
notdone = 0;
break;
case ACTIVEWINDOW:
iawm = 1;
break;
case MOUSEBUTTONS:
if (iawm) {
iawm = 0;
break;
}
if (ComLineMode)
escapecomlinemode();
text_cursor(0);
switch(im->Code) {
case SELECTDOWN: /* position cursor */
if (im->MouseY >= Ybase)
text_position((im->MouseX-Xbase)/Xsize,(im->MouseY-Ybase)/Ysize);
else
text_position((im->MouseX-Xbase)/Xsize,-1);
break;
case MENUDOWN: /* percentage placement */
{
int line = 1 + (im->MouseY-(Ybase+4))*text_lines()/(Ypixs-8);
char buf[16];
if (line > text_lines())
line = text_lines();
if (line < 1)
line = 1;
sprintf(buf, "%ld", line);
av[1] = buf;
do_goto();
}
break;
}
text_cursor(1);
break;
}
ReplyMsg(im);
}
}
if (E.Modified && !Overide) {
Overide = 1;
SetWindowTitles(Win, "MED: File has been modified", NULL);
Quitflag = 0;
goto loop;
}
text_uninit();
if (Win)
CloseWindow(Win);
closelibs(INTUITION_LIB|GRAPHICS_LIB);
free_memory();
}
getyn(text)
char *text;
{
int result;
ITEXT *body, *pos, *neg;
body = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
pos = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
neg = (ITEXT *)AllocMem(sizeof(ITEXT), 0);
bzero(body, sizeof(ITEXT));
bzero(pos , sizeof(ITEXT));
bzero(neg , sizeof(ITEXT));
body->BackPen = pos->BackPen = neg->BackPen = 1;
body->DrawMode= pos->DrawMode= neg->DrawMode= AUTODRAWMODE;
body->LeftEdge = 10;
body->TopEdge = 12;
body->IText = text;
pos->LeftEdge = AUTOLEFTEDGE;
pos->TopEdge = AUTOTOPEDGE;
pos->IText = "OK";
neg->LeftEdge = AUTOLEFTEDGE;
neg->TopEdge = AUTOTOPEDGE;
neg->IText = "CANCEL";
result = AutoRequest(Win,body,pos,neg,0,0,320,58);
FreeMem(body, sizeof(ITEXT));
FreeMem(pos , sizeof(ITEXT));
FreeMem(neg , sizeof(ITEXT));
return(result);
}
char ShowTitle;
title(buf)
char *buf;
{
SetWindowTitles(Win, buf, -1);
ShowTitle = 1;
}
window_title()
{
static char title[130];
static char cmodified;
int len;
char *mod;
if (memoryfail) {
SetWindowTitles(Win, " -- NO MEMORY -- ", -1);
text_redisplay();
memoryfail = 0;
return(0);
}
if (ShowTitle) {
ShowTitle = 0;
return(0);
}
if (text_titleupdate() || cmodified != E.Modified) {
cmodified = E.Modified;
mod = (E.Modified) ? " (modified)" : "";
sprintf(title, "%3ld/%-3ld %s%s", text_lineno(), text_lines(), text_name(), mod);
len = strlen(title);
if (len < Columns && Columns < 128) {
bset(title+len, Columns - len + 1, ' ');
title[Columns + 1] = 0;
}
SetWindowTitles(Win, title, -1);
}
}
inversemode(n)
{
int v;
v = JAM2;
if (n)
v = JAM2|INVERSVID;
SetDrMd(Rp, v);
}
set_window_params()
{
Xsize = Rp->Font->tf_XSize;
Ysize = Rp->Font->tf_YSize;
Xbase = Win->BorderLeft;
Ybase = Win->BorderTop;
Xpixs = Win->Width - Win->BorderRight - Xbase;
Ypixs = Win->Height- Win->BorderBottom- Ybase;
Columns = Xpixs / Xsize;
Rows = Ypixs / Ysize;
XTbase = Xbase;
YTbase = Ybase + Rp->Font->tf_Baseline;
}
exiterr(str)
char *str;
{
puts(str);
free_memory();
exit(1);
}
#define HASHSIZE 64
typedef struct _HASH {
struct _HASH *next; /* next hash */
char code; /* keycode */
char mask; /* qual. mask */
char qual; /* qual. comp */
char stat; /* string static? */
char *str; /* command string */
} HASH;
HASH *Hash[HASHSIZE];
static char isalpha[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,
0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 };
static char ctoa[] = {
'`','1','2','3','4','5','6','7','8','9','0','-','=','\\',0,'0',
'q','w','e','r','t','y','u','i','o','p','[',']',0,'1','2','3',
'a','s','d','f','g','h','j','k','l',';','\'',0,0,'4','5','6',
0 ,'z','x','c','v','b','n','m',',','.','/',0,'.','7','8','9',
' ',0,0,0,0,0,0,0,0,0,'-',0,0,0,0,0
};
static char cstoa[] = {
'~','!','@','#','$','%','^','&','*','(',')','_','+','|',0,'0',
'Q','W','E','R','T','Y','U','I','O','P','{','}',0,'1','2','3',
'A','S','D','F','G','H','J','K','L',':','\"',0,0,'4','5','6',
0 ,'Z','X','C','V','B','N','M','<','>','?',0,'.','7','8','9',
' ',0,0,0,0,0,0,0,0,0,'-',0,0,0,0,0
};
resethash()
{
short i;
register HASH *hash, *hnext = NULL;
static struct {
char *from, *to;
} defmap[] = {
"esc", "esc",
"return", "return insline up firstnb down",
"enter", "return",
"up", "up",
"down", "down",
"right", "right",
"left", "left",
"bs", "bs",
"del", "del",
"help", "help",
"tab", "tab",
"s-up", "top",
"s-down", "bottom",
"s-right", "last",
"s-left", "first",
"s-tab", "backtab",
"s-del", "deline",
"c-i", "insertmode on",
"c-o", "insertmode off",
"c-j", "join",
"c-s", "split first down",
"c-del", "deline",
"c-n", "next",
"c-p", "prev",
"c-/", "escimm `find '",
"c-up", "pageup",
"c-down", "pagedown",
"f1", "escimm `insfile '",
"f2", "escimm `newfile '",
"f9", "escimm `bsave '",
"f10", "saveold quit",
"c-b", "block",
"c-u", "unblock",
"a-d", "bdelete",
"a-c", "bcopy",
"a-m", "bmove",
NULL, NULL
};
for (i = 0; i < HASHSIZE; ++i) {
for (hash = Hash[i]; hash; hash = hnext) {
hnext = hash->next;
if (!hash->stat)
free(hash->str);
free(hash);
}
Hash[i] = NULL;
}
for (i = 0; defmap[i].from; ++i) {
char code, qual;
if (get_codequal(defmap[i].from, &code, &qual))
addhash(code, 1, -1, qual, defmap[i].to);
}
}
returnoveride(n)
{
HASH *hash;
static char *str;
static int stat;
for (hash = Hash[0x44 % HASHSIZE]; hash; hash = hash->next) {
if (hash->code == 0x44 && hash->qual == 0) {
if (n) {
str = hash->str;
stat= hash->stat;
hash->str = "return";
hash->stat = 1;
} else {
if (str == NULL) {
remhash(0x44, -1, 0);
} else {
hash->str = str;
hash->stat= stat;
}
}
return(0);
}
}
if (n) {
addhash(0x44,1,-1,0,"return");
str = NULL;
}
}
addhash(code, stat, mask, qual, str)
char *str;
{
register HASH **p, *hash;
hash = *(p = &Hash[code % HASHSIZE]);
while (hash) {
if (hash->code == code && hash->qual == qual && hash->mask == mask) {
if (!hash->stat)
free(hash->str);
goto newstr;
}
hash = *(p = &hash->next);
}
*p = hash = (HASH *)malloc(sizeof(HASH));
hash->next = NULL;
newstr:
hash->code = code;
hash->stat = stat;
hash->mask = mask;
hash->qual = qual;
hash->str = str;
if (!stat) /* if not static */
hash->str = (char *)strcpy(malloc(strlen(str)+1), str);
}
remhash(code, mask, qual)
{
HASH *hash, **p;
hash = *(p = &Hash[code % HASHSIZE]);
while (hash) {
if (hash->code == code && hash->qual == qual && hash->mask == mask) {
if (!hash->stat)
free(hash->str);
*p = hash->next;
free(hash);
return(1);
}
hash = *(p = &hash->next);
}
return(0);
}
keyctl(code)
char code;
{
static char state;
register char c, c2;
register HASH *hash;
if ((code & 0x78) == 0x60) {
c2 = 1 << (code & 7);
if (code & 0x80)
state &= ~c2;
else
state |= c2;
return(0);
}
if (code & 0x80)
return(0);
c2 = 0;
if (state & (KEY_LSHIFT|KEY_RSHIFT)) c2 |= QUAL_SHIFT;
if (state & (KEY_CTRL )) c2 |= QUAL_CTRL;
if (state & (KEY_AMIGAL|KEY_AMIGAR)) c2 |= QUAL_AMIGA;
if (state & (KEY_ALTL |KEY_ALTR )) c2 |= QUAL_ALT;
if ((state & KEY_CAPS) && (code <= 0x37) && (isalpha[code]))
c2 |= QUAL_SHIFT;
for (hash = Hash[code % HASHSIZE]; hash; hash = hash->next) {
if (hash->code == code) {
if ((c2 & hash->mask) == hash->qual)
break;
}
}
if (hash) {
char buf[256];
strcpy(buf, hash->str);
do_command(buf);
} else {
/* disallow CTL, ALT, and non-ascii keys. form: 'c or "ccc.." */
if (code < 0x50) {
c = (c2 & QUAL_SHIFT) ? cstoa[code] : ctoa[code];
if (c) {
char buf[3];
buf[0] = '\'';
buf[1] = c;
buf[2] = 0;
do_command(buf);
}
}
}
}
#define LN(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|d)
long lname[] = {
LN('e','s','c',0x45), LN('f','1', 0 ,0x50), LN('f','2', 0 ,0x51),
LN('f','3', 0 ,0x52), LN('f','4', 0 ,0x53), LN('f','5', 0 ,0x54),
LN('f','6', 0 ,0x55), LN('f','7', 0 ,0x56), LN('f','8', 0 ,0x57),
LN('f','9', 0 ,0x58), LN('f','1','0',0x59), LN('d','e','l',0x46),
LN('b','a','c',0x41), LN('b','s', 0 ,0x41), LN('t','a','b',0x42),
LN('h','e','l',0x5F), LN('r','e','t',0x44), LN('u','p', 0 ,0x4C),
LN('d','o','w',0x4D), LN('r','i','g',0x4E), LN('l','e','f',0x4F),
LN('e','n','t',0x43), LN('n','k','-',0x4A), LN('n','k','.',0x3C),
LN('n','k','0',0x0F),
LN('n','k','1',0x1D), LN('n','k','2',0x1E), LN('n','k','3',0x1F),
LN('n','k','4',0x2D), LN('n','k','5',0x2E), LN('n','k','6',0x2F),
LN('n','k','7',0x3D), LN('n','k','8',0x3E), LN('n','k','9',0x3F),
0
};
get_codequal(str, pcode, pqual)
char *pcode, *pqual;
char *str;
{
char qual;
register short i;
qual = 0;
if (strlen(str) > 1) {
for (; *str && *str != '-'; ++str) {
if (*str == 's')
qual |= QUAL_SHIFT;
if (*str == 'c')
qual |= QUAL_CTRL;
if (*str == 'a')
qual |= QUAL_ALT;
if (!qual)
goto notqual;
}
if (*str)
++str;
}
notqual:
*pqual = qual;
if (strlen(str) != 1) { /* long name */
register short shift = 24;
register long mult = 0;
while (*str && shift >= 8) {
if (*str >= 'A' && *str <= 'Z')
*str = *str - 'A' + 'a';
mult |= *str << shift;
shift -= 8;
++str;
}
for (i = 0; lname[i]; ++i) {
if (mult == (lname[i] & 0xFFFFFF00)) {
*pcode = lname[i] & 0x7F;
return(1);
}
}
} else { /* short name */
for (i = 0; i < sizeof(ctoa); ++i) {
if (*str == ctoa[i]) {
*pcode = i;
return(1);
}
}
for (i = 0; i < sizeof(cstoa); ++i) {
if (*str == cstoa[i]) {
*pcode = i;
*pqual |= QUAL_SHIFT;
return(1);
}
}
}
return(0);
}
do_map()
{
char code, qual;
if (get_codequal(av[1], &code, &qual)) {
addhash(code, 0, -1, qual, av[2]);
} else {
title("Unknown Command");
}
}
do_unmap() /* key */
{
char code, qual;
if (get_codequal(av[1], &code, &qual)) {
remhash(code, -1, qual);
} else {
title("Unknown Command");
}
}
do_clearmap()
{
resethash();
}
!Funky!Stuff!
fi # end of overwriting check
echo shar: "extracting 'text.c'" '(20909 characters)'
if test -f 'text.c'
then
echo shar: "will not over-write existing file 'text.c'"
else
cat << \!Funky!Stuff! > 'text.c'
/*
* TEXT.C
*
*/
#include "defs.h"
#define TU titleupdate = 1
#define nomemory() {memoryfail = 1; TU;}
ED E; /* Current File */
ED *Base; /* doubly linked list of Files */
char titleupdate;
char memoryfail;
char Current[256];
short Clen;
extern long Rp;
extern char *AllocMem(), *Allocate();
text_init()
{
E.Insertmode = 1;
E.Tabstop = 4;
E.Lines = 1;
E.Maxlines = 32;
E.List = (char **)Allocate(sizeof(char *) * E.Maxlines);
E.List[0] = Allocate(1);
E.List[0][0] = Current[0] = Clen = 0;
E.BSline = E.BEline = -1;
text_cursor(1);
}
text_sync()
{
char redraw = 0;
short len;
char *ptr;
if (strlen(Current) != Clen)
puts ("LENGTH FAIL");
for (len = strlen(Current) - 1; len >= 0 && Current[len] == ' '; --len)
Current[len] = '\0';
Clen = len + 1;
if (!ComLineMode) {
if (strlen(E.List[E.Line]) != Clen) {
if (ptr = Allocate(Clen+1)) {
E.Modified = 1;
FreeMem(E.List[E.Line], strlen(E.List[E.Line])+1);
E.List[E.Line] = ptr;
} else {
nomemory();
strcpy(Current, E.List[E.Line]);
Clen = strlen(Current);
}
} else {
if (strcmp(E.List[E.Line], Current))
E.Modified = 1;
}
strcpy(E.List[E.Line], Current);
}
if (E.Column - E.Topcolumn >= Columns || E.Column < E.Topcolumn) {
redraw = 1;
E.Topcolumn = E.Column - (Columns>>1);
if (E.Topcolumn < 0)
E.Topcolumn = 0;
}
if (E.Line - E.Topline >= Rows || E.Line < E.Topline) {
redraw = 1;
E.Topline = E.Line - (Rows>>1);
if (E.Topline < 0)
E.Topline = 0;
}
while (E.Column > Clen)
Current[Clen++] = ' ';
Current[Clen] = '\0';
if (redraw)
text_redisplay();
return((int)redraw);
}
text_load()
{
if (ComLineMode)
return(0);
strcpy(Current, E.List[E.Line]);
Clen = strlen(Current);
while (E.Column > Clen)
Current[Clen++] = ' ';
Current[Clen] = '\0';
}
text_titleupdate()
{
int r = titleupdate;
titleupdate = 0;
return(r);
}
text_lineno()
{
return(E.Line + 1);
}
text_lines()
{
return(E.Lines);
}
text_colno()
{
return(E.Column);
}
text_cols()
{
return((int)Clen);
}
text_tabsize()
{
return((int)E.Tabstop);
}
char *
text_name()
{
return(E.Name);
}
text_uninit()
{
register int i;
for (i = 0; i < E.Lines; ++i)
FreeMem(E.List[i], strlen(E.List[i])+1);
FreeMem(E.List, E.Maxlines * sizeof(char *));
}
text_cursor(n)
{
Move(Rp, XTbase+(E.Column-E.Topcolumn)*Xsize, YTbase+(E.Line-E.Topline)*Ysize);
inversemode(n);
if (Current[E.Column])
Text(Rp, Current+E.Column, 1);
else
Text(Rp, " ", 1);
inversemode(0);
}
text_position(col, row)
{
TU;
text_sync();
if (col == 0)
col = -1;
E.Column = E.Topcolumn + col;
if (E.Column > 254)
E.Column = 254;
if (E.Column < 0)
E.Column = 0;
E.Line = E.Topline + row;
if (E.Line >= E.Lines)
E.Line = E.Lines - 1;
if (E.Line < 0)
E.Line = 0;
text_load();
text_sync();
}
text_displayseg(start, n)
{
register short i, c;
register char *ptr;
for (i = start; i < start+n && E.Topline + i < E.Lines; ++i) {
if (ComLineMode) {
if (E.Topline + i != E.Line)
continue;
ptr = Current;
} else {
ptr = E.List[E.Topline + i];
}
for (c = E.Topcolumn; c && *ptr; ++ptr, --c);
if (*ptr) {
c = strlen(ptr);
Move(Rp, XTbase, YTbase + i * Ysize);
Text(Rp, ptr, (c > Columns) ? Columns : c);
}
}
}
text_redisplay()
{
SetAPen(Rp, 0);
if (ComLineMode) {
RectFill(Rp, Xbase, Ybase+(Ysize*(Rows-1)), Xbase+Xpixs, Ybase+(Ysize*Rows));
} else {
RectFill(Rp, Xbase, Ybase, Xbase + Xpixs, Ybase + Ypixs);
}
SetAPen(Rp, 1);
text_displayseg(0,Rows);
}
text_write(str)
char *str;
{
short len = strlen(str);
short i;
if (Clen + len >= 255) {
text_sync();
text_load();
}
if (E.Insertmode == 0) {
i = len;
if (E.Column + len < 255) {
bmov(str, Current + E.Column, len);
if (E.Column + len >= Clen)
Clen = E.Column + len;
Current[Clen] = 0;
goto bin;
}
return(0);
}
if (Clen + len < 255) {
bmov(Current + E.Column, Current + E.Column + len, Clen+1-E.Column);
bmov(str, Current + E.Column, len);
Clen += len;
ScrollRaster(Rp, -len * Xsize, 0 ,
Xbase + (E.Column - E.Topcolumn) * Xsize,
Ybase + (E.Line - E.Topline) * Ysize,
Xbase + Columns * Xsize - 1,
Ybase + Ysize - 1 + (E.Line - E.Topline) * Ysize);
i = (E.Column - E.Topcolumn + len > Columns) ? Columns - E.Column + E.Topcolumn : len;
bin:
Move(Rp, XTbase + (E.Column - E.Topcolumn) * Xsize,
YTbase + (E.Line - E.Topline) * Ysize);
Text(Rp, str, i);
E.Column += len;
if (E.Column - E.Topcolumn >= Columns)
text_sync();
}
}
do_up()
{
if (E.Line) {
TU;
text_sync();
--E.Line;
text_load();
if (E.Line < E.Topline) {
ScrollRaster(Rp,0,-Ysize,Xbase,Ybase,Xbase+Xpixs,Ybase+Ypixs);
--E.Topline;
text_displayseg(0, 1);
}
}
}
do_down()
{
if (E.Line + 1 < E.Lines) {
TU;
text_sync();
++E.Line;
text_load();
if (E.Line - E.Topline >= Rows) {
ScrollRaster(Rp,0,Ysize,Xbase,Ybase,Xbase+Xpixs,Ybase+Ypixs);
++E.Topline;
text_displayseg(Rows-1, 1);
}
}
}
do_pagedown()
{
text_sync();
TU;
E.Line += Rows;
E.Topline += Rows;
if (E.Line >= E.Lines)
E.Line = E.Lines - 1;
if (E.Topline >= E.Lines)
E.Topline = E.Lines - Rows - 1;
if (E.Topline < 0)
E.Topline = 0;
text_load();
if (!text_sync())
text_redisplay();
}
do_pageup()
{
text_sync();
TU;
E.Line -= Rows;
E.Topline -= Rows;
if (E.Line < 0)
E.Line = 0;
if (E.Topline < 0)
E.Topline = 0;
text_load();
if (!text_sync())
text_redisplay();
}
do_downadd()
{
char *ptr;
if (E.Line + 1 == E.Lines) {
E.Modified = 1;
if (makeroom(32) && (ptr = Allocate(1))) {
E.List[E.Lines] = ptr;
*ptr = 0;
++E.Lines;
} else {
nomemory();
}
}
do_down();
}
do_left()
{
if (E.Column) {
--E.Column;
if (E.Column < E.Topcolumn)
text_sync();
}
}
do_right()
{
if (E.Column != 254) {
if (Current[E.Column] == 0) {
Current[E.Column] = ' ';
Current[E.Column+1]= '\0';
++Clen;
}
++E.Column;
if (E.Column - E.Topcolumn >= Columns)
text_sync();
}
}
do_tab()
{
register short n;
for (n = E.Tabstop-(E.Column % E.Tabstop); n > 0; --n)
do_right();
}
do_backtab()
{
register short n;
n = E.Column % E.Tabstop;
if (!n)
n = E.Tabstop;
for (; n > 0; --n)
do_left();
}
do_return()
{
char buf[256];
if (ComLineMode) {
strcpy(buf, Current);
escapecomlinemode();
do_command(buf);
} else {
E.Column = 0;
text_sync();
do_downadd();
}
}
do_bs()
{
if (E.Column) {
bmov(Current + E.Column, Current + E.Column - 1, Clen - E.Column + 1);
--E.Column;
--Clen;
if (E.Column < E.Topcolumn) {
text_sync();
} else {
ScrollRaster(Rp, Xsize, 0,
Xbase + (E.Column - E.Topcolumn) * Xsize,
Ybase + (E.Line - E.Topline) * Ysize,
Xbase + Columns * Xsize - 1,
Ybase + (E.Line - E.Topline) * Ysize + Ysize - 1);
if (Clen >= E.Topcolumn + Columns) {
Move(Rp, XTbase+(Columns-1)*Xsize, YTbase+(E.Line-E.Topline)*Ysize);
Text(Rp, Current+E.Topcolumn+Columns-1, 1);
}
}
}
}
/*
* esc, escimm
*/
int Savetopline, Savecolumn, Savetopcolumn;
do_esc()
{
if (ComLineMode)
return(escapecomlinemode());
text_sync();
if (av[0][3] == 'i')
strcpy(Current, av[1]);
else
Current[0] = 0;
Clen = strlen(Current);
ComLineMode = 1;
returnoveride(1);
Savetopline = E.Topline;
Savecolumn = E.Column;
Savetopcolumn = E.Topcolumn;
E.Column = Clen;
E.Topcolumn = 0;
E.Topline = E.Line - Rows + 1;
SetAPen(Rp, 0);
RectFill(Rp, Xbase, Ybase+(Ysize*(Rows-1)), Xbase+Xpixs, Ybase+Ypixs);
SetAPen(Rp, 1);
Move(Rp, Xbase, Ybase+(Ysize*(Rows-1))-1);
Draw(Rp, Xbase+Xpixs, Ybase+(Ysize*(Rows-1))-1);
text_displayseg(Rows-1,1);
}
escapecomlinemode()
{
if (ComLineMode) {
ComLineMode = 0;
returnoveride(0);
E.Topline = Savetopline;
E.Column = Savecolumn;
E.Topcolumn = Savetopcolumn;
text_load();
SetAPen(Rp, 0);
RectFill(Rp, Xbase, Ybase+(Ysize*(Rows-1))-1, Xbase+ Xpixs,Ybase+(Ysize*Rows));
SetAPen(Rp, 1);
text_displayseg(Rows-2,2);
}
}
do_del()
{
if (Current[E.Column]) {
bmov(Current + E.Column + 1, Current + E.Column, Clen - E.Column);
--Clen;
ScrollRaster(Rp, Xsize, 0,
Xbase + (E.Column - E.Topcolumn) * Xsize,
Ybase + (E.Line - E.Topline) * Ysize,
Xbase + Columns * Xsize - 1,
Ybase + (E.Line - E.Topline) * Ysize + Ysize - 1);
if (Clen >= E.Topcolumn + Columns) {
Move(Rp, XTbase+(Columns-1)*Xsize, YTbase+(E.Line-E.Topline)*Ysize);
Text(Rp, Current+E.Topcolumn+Columns-1, 1);
}
}
}
do_top()
{
text_sync();
E.Line = 0;
TU;
text_load();
text_sync();
}
do_bottom()
{
text_sync();
E.Line = E.Lines - 1;
TU;
text_load();
text_sync();
}
do_firstcolumn()
{
if (E.Column) {
E.Column = 0;
text_sync();
}
}
do_firstnb()
{
for (E.Column = 0; Current[E.Column] == ' '; ++E.Column);
if (Current[E.Column] == 0)
E.Column = 0;
text_sync();
}
do_lastcolumn()
{
short i;
text_sync();
i = (ComLineMode) ? Clen : strlen(E.List[E.Line]);
if (i != E.Column) {
E.Column = i;
text_sync();
}
}
do_goto()
{
int n = atoi(av[1]) - 1;
if (n >= 0 && n < E.Lines) {
text_sync();
E.Line = n;
TU;
text_load();
text_sync();
}
}
do_screentop()
{
text_sync();
TU;
E.Line = E.Topline;
text_load();
text_sync();
}
do_screenbottom()
{
text_sync();
TU;
if (E.Topline + Rows - 1 >= E.Lines)
E.Line = E.Lines;
else
E.Line = E.Topline + Rows - 1;
text_load();
text_sync();
}
/*
* find, next, prev
*/
do_find()
{
static char fstr[256];
int n;
int col;
int i = E.Line;
int sign = 1;
int len;
TU;
text_sync();
switch(av[0][0]) {
case 'f':
strcpy(fstr, av[1]);
break;
case 'p':
sign = -1;
break;
}
len = strlen(fstr);
if (!len)
return(0);
for (n = E.Lines, i = E.Line, col = E.Column; n; --n) {
for (; col >= 0 && E.List[i][col]; col += sign) {
if (strncmp(fstr, E.List[i]+col, len) == 0) {
if (n == E.Lines)
continue;
E.Line = i;
E.Column = col;
text_load();
text_sync();
return(1);
}
}
i += sign;
if (i < 0 ) i = E.Lines - 1;
if (i >= E.Lines) i = 0;
col = 0;
if (sign < 0) {
col = strlen(E.List[i]) - 1;
if (col < 0)
col = 0;
}
}
title("Pattern Not Found");
return(0);
}
do_split() /* split line in two at cursor pos */
{
char buf[256];
strcpy(buf, Current+E.Column);
Current[Clen = E.Column] = '\0';
text_sync();
SetAPen(Rp, 0);
RectFill(Rp, Xbase, Ybase+(E.Line-E.Topline)*Ysize, Xbase+Xpixs, Ybase+(E.Line-E.Topline+1)*Ysize);
SetAPen(Rp, 1);
text_displayseg(E.Line - E.Topline, 1);
do_downadd();
do_insline();
strcpy(Current, buf);
Clen = strlen(Current);
text_sync();
text_displayseg(E.Line - E.Topline, 1);
do_up();
}
do_join()
{
if (E.Line + 1 < E.Lines && strlen(E.List[E.Line+1])+Clen <= 255) {
strcat(Current, E.List[E.Line+1]);
Clen = strlen(Current);
text_sync();
text_displayseg(E.Line - E.Topline, 1);
do_down();
do_deline();
do_up();
}
}
do_tabstop()
{
E.Tabstop = atoi(av[1]);
}
do_insertmode()
{
if (av[1][0]) {
switch(av[1][1] & 0x1F) {
case 'n'&0x1F:
E.Insertmode = 1;
break;
case 'f'&0x1F:
E.Insertmode = 0;
break;
case 'o'&0x1F:
E.Insertmode = 1 - E.Insertmode;
break;
}
if (E.Insertmode)
title("Insert mode on");
else
title("Insert mode off");
}
}
do_insline()
{
char *ptr;
TU;
E.Modified = 1;
text_sync();
if (makeroom(32) && (ptr = Allocate(1))) {
bmov(E.List+E.Line, E.List+E.Line+1, sizeof(char *) * (E.Lines-E.Line));
E.List[E.Line] = ptr;
*ptr = 0;
++E.Lines;
if (E.Line < E.BSline)
++E.BSline;
if (E.Line <= E.BEline)
++E.BEline;
} else {
nomemory();
}
text_load();
ScrollRaster(Rp,0,-Ysize,
Xbase,Ybase+(E.Line - E.Topline)*Ysize,
Xbase+Xpixs,Ybase+Ypixs);
text_displayseg(E.Line - E.Topline, 1);
}
do_deline()
{
if (E.Lines > 1) {
TU;
E.Modified = 1;
text_sync();
FreeMem(E.List[E.Line], strlen(E.List[E.Line])+1);
bmov(E.List+E.Line+1, E.List+E.Line, sizeof(char *) * (E.Lines-E.Line-1));
if (E.Line < E.BSline)
--E.BSline;
if (E.Line <= E.BEline)
--E.BEline;
if (E.Line >= --E.Lines) {
if (--E.Line < E.Topline) {
text_load();
E.Topline = E.Line - (Rows>>1);
if (E.Topline < 0)
E.Topline = 0;
text_redisplay();
return(0);
}
}
text_load();
ScrollRaster(Rp,0,Ysize,
Xbase,Ybase+(E.Line - E.Topline)*Ysize,
Xbase+Xpixs,Ybase+Ypixs);
text_displayseg(Rows-1, 1);
}
}
do_edit()
{
long fi;
long lines;
char buf[256];
char ebuf[256];
char *ptr;
char failed = 1;
TU;
text_sync();
if (*av[0] == 'n') { /* newfile or insfile */
if (E.Modified && getyn("Delete modified Image?") == 0)
return(0);
text_uninit();
text_init();
E.Modified = 0;
E.Line = 0;
strncpy(E.Name, av[1], 63);
} else {
E.Modified = 1;
}
lines = E.Lines;
if (fi = xopen(av[1], "r", 4096)) {
register int i, j;
while (xgets(fi, buf, 255)) {
failed = 0;
for(i = j = 0; buf[i] && j < 254; ++i) {
if (buf[i] == 9) { /* expand tabs (always 8) */
do {
ebuf[j++] = ' ';
} while ((j % 8) && j < 254);
} else {
ebuf[j++] = buf[i];
}
}
while (j && ebuf[j-1] == ' ')
--j;
ebuf[j] = 0;
if (makeroom(256) && (ptr = Allocate(j+1))) {
E.List[E.Lines++] = ptr;
bmov(ebuf, ptr, j+1);
} else {
nomemory();
break;
}
}
} else {
title("File Not Found");
}
xclose(fi);
if (E.Lines != 1 && lines == 1 && E.List[0][0] == 0) {
E.Modified = 0;
E.Line = 0;
FreeMem(E.List[0], strlen(E.List[0])+1);
bmov(E.List+1, E.List, sizeof(char *) * (--E.Lines));
} else {
if (!failed && lines <= E.Lines - 1) {
E.BSline = lines;
E.BEline = E.Lines-1;
do_bmove();
}
}
text_load();
text_redisplay();
}
static char blockmode;
do_bsave()
{
blockmode = 1;
do_saveas();
}
do_save()
{
av[1] = E.Name;
do_saveas();
}
do_saveas()
{
long fi;
long i;
long xs, xe;
if (blockmode && blockok()) {
xs = E.BSline;
xe = E.BEline + 1;
} else {
xs = 0;
xe = E.Lines;
}
blockmode = 0;
text_sync();
if (fi = xopen(av[1], "w", 4096)) {
for (i = xs; i < xe; ++i) {
xwrite(fi, E.List[i], strlen(E.List[i]));
xwrite(fi, "\n", 1);
}
xclose(fi);
E.Modified = 0;
} else {
title("Unable to open write file");
}
}
do_block() /* block, unblock */
{
switch(av[0][0]) {
case 'b':
if (E.BSline < 0) {
E.BSline = E.Line;
title("Block Begin");
} else {
if (E.BEline >= 0) {
title("Block Already Marked");
break;
}
title("Block End");
E.BEline = E.Line;
if (E.BSline > E.BEline) {
E.BEline = E.BSline;
E.BSline = E.Line;
}
}
break;
case 'u':
E.BSline = E.BEline = -1;
title ("Block Unmarked");
break;
}
}
blockok()
{
if (E.BSline >= 0 && E.BEline >= 0 && E.BSline <= E.BEline && E.BEline < E.Lines)
return(1);
E.BSline = E.BEline = -1;
title("Block Not Specified");
return(0);
}
do_bdelete()
{
int i;
int n;
if (blockok()) {
text_sync();
n = E.BEline - E.BSline + 1;
if (E.Line >= E.BSline && E.Line <= E.BEline)
E.Line = E.BSline;
if (E.Line > E.BEline)
E.Line -= n;
for (i = E.BSline; i < E.BEline; ++i)
FreeMem(E.List[i], strlen(E.List[i])+1);
bmov(E.List+E.BEline+1,E.List+E.BSline,(E.Lines-E.BEline-1)*sizeof(E.List[0]));
E.Lines -= n;
if (E.Line < 0 || E.Line >= E.Lines)
E.Line = 0;
if (E.Lines == 0) {
text_uninit();
text_init();
}
TU;
text_load();
E.BSline = E.BEline = -1;
if (!text_sync())
text_redisplay();
}
}
do_bcopy()
{
char **list;
int lines, i;
if (blockok()) {
text_sync();
lines = E.BEline - E.BSline + 1;
list = (char **)Allocate(sizeof(char *) * (E.Lines+lines));
if (list) {
for (i = 0; i < lines; ++i) {
list[E.Line + i] = Allocate(strlen(E.List[E.BSline+i])+1);
strcpy(list[E.Line + i], E.List[E.BSline+i]);
}
bmov(E.List+0, list, E.Line * sizeof(char *));
bmov(E.List+E.Line, list + E.Line + lines, (E.Lines-E.Line)*sizeof(char *));
}
FreeMem(E.List, E.Maxlines * 4);
E.List = list;
E.Lines += lines;
E.Maxlines = E.Lines;
text_load();
E.BSline = E.BEline = -1;
if (!text_sync())
text_redisplay();
}
}
do_bmove()
{
int lines;
char **temp;
if (blockok()) {
if (E.Line >= E.BSline && E.Line <= E.BEline) {
title("Cannot Move into self");
return(0);
}
text_sync();
lines = E.BEline - E.BSline + 1;
temp = (char **)Allocate(lines * sizeof(char *));
bmov(E.List + E.BSline, temp, lines * sizeof(char *));
if (E.Line > E.BSline) {
bmov(E.List+E.BEline+1, E.List+E.BSline, (E.Line-E.BEline-1)*4);
bmov(temp, E.List + E.Line - lines, lines * 4);
} else {
bmov(E.List+E.Line, E.List+E.Line+lines, (E.BSline-E.Line)*4);
bmov(temp, E.List + E.Line, lines * 4);
}
FreeMem(temp, lines * sizeof(char *));
E.BSline = E.BEline = -1;
text_load();
if (!text_sync())
text_redisplay();
}
}
char *
Allocate(bytes)
{
return(AllocMem(bytes, 0));
}
makeroom(n)
{
char **Newlist;
if (E.Lines >= E.Maxlines) {
Newlist = (char **)Allocate(sizeof(char *) * (E.Maxlines + n));
if (Newlist) {
bmov(E.List, Newlist, sizeof(char *) * E.Maxlines);
FreeMem(E.List, sizeof(char *) * E.Maxlines);
E.List = Newlist;
E.Maxlines += n;
return(1);
} else {
nomemory();
}
return(0);
}
return(1);
}
!Funky!Stuff!
fi # end of overwriting check
echo shar: "extracting 'defs.h'" '(537 characters)'
if test -f 'defs.h'
then
echo shar: "will not over-write existing file 'defs.h'"
else
cat << \!Funky!Stuff! > 'defs.h'
/*
* DEFS.H
*
*/
extern short Xsize, Ysize;
extern short XTbase, YTbase;
extern short Rows, Columns;
extern short Xbase, Ybase;
extern short Xpixs, Ypixs;
extern char *av[];
extern short ComLineMode;
typedef struct _ED {
struct _ED *next, **prev;
long Topline, Topcolumn;
long Line, Column;
long Lines, Maxlines;
char **List;
char Name[64];
char Modified;
char Tabstop;
char Insertmode;
long BSline, BEline; /* block start and end lines */
} ED;
#ifndef NULL
#define NULL 0
#endif
!Funky!Stuff!
fi # end of overwriting check
exit 0
# End of shell archive