home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 2: PC
/
frozenfish_august_1995.bin
/
bbs
/
d01xx
/
d0113.lha
/
Dme
/
src
/
text2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-11-21
|
20KB
|
1,006 lines
/*
* TEXT2.C
*
* (C)Copyright 1987 by Matthew Dillon, All Rights Reserved
*/
#include "defs.h"
#include <stdio.h>
#define nomemory() {memoryfail = 1;}
extern char MForceTitle;
do_remeol()
{
Current[Clen = E.Column] = 0;
text_sync();
text_redisplaycurrline();
}
do_wleft()
{
register ubyte *ptr;
register int i;
for (;;) {
i = E.Column;
if (i == 0)
goto prevline;
--i;
while (i && Current[i] == ' ')
--i;
if (i == 0 && Current[0] == ' ') {
prevline:
if (Comlinemode || E.Line == 0) {
i = E.Column;
break;
}
text_sync();
--E.Line;
text_load();
E.Column = Clen;
continue;
}
while (i && Current[i] != ' ')
--i;
if (Current[i] == ' ')
++i;
break;
}
E.Column = i;
text_sync();
}
do_wright()
{
register ubyte *ptr;
register int i;
for (;;) {
i = E.Column;
if (i == Clen)
goto nextline;
while (i != Clen && Current[i] != ' ') /* skip past current word */
++i;
while (i != Clen && Current[i] == ' ') /* to beg. of next word */
++i;
if (i == Clen) {
nextline:
if (Comlinemode || E.Line == E.Lines - 1) {
i = E.Column;
break;
}
text_sync();
++E.Line;
text_load();
E.Column = i = 0;
if (Current[0] != ' ')
break;
continue;
}
break;
}
E.Column = i;
text_sync();
}
do_split() /* split line in two at cursor pos */
{
ubyte buf[256];
strcpy(buf, Current+E.Column);
Current[Clen = E.Column] = '\0';
text_sync();
SetAPen(Rp, 0);
if (Nsu == 0)
RectFill(Rp, COL(0), ROW(E.Line-E.Topline), Xbase+Xpixs, ROW(E.Line-E.Topline+1)-1);
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()
{
register int i = Clen, j;
if (E.Line + 1 < E.Lines && strlen(E.List[E.Line+1])+i <= 253) {
if (i && Current[i-1] != ' ')
Current[i++] = ' ';
strcpy(Current+i, E.List[E.Line+1]);
for (j = i; Current[j] == ' '; ++j);
for (; i >= 0 && Current[i] == ' '; --i);
if (j > i+2)
bmov(Current+j, Current+i+2, strlen(Current+j)+1);
Clen = strlen(Current);
text_sync();
text_displayseg(E.Line - E.Topline, 1);
do_down();
do_deline();
do_up();
return(1);
}
return(0);
}
do_margin()
{
E.Margin = atoi(av[1]);
}
do_wordwrap()
{
if (av[1][1] == 'n')
E.Wordwrap = 1;
if (av[1][1] == 'f')
E.Wordwrap = 0;
if (av[1][0] == 't')
E.Wordwrap = 1 - E.Wordwrap;
if (E.Wordwrap)
title("Wordwrap ON");
else
title("Wordwrap OFF");
}
/*
* n == -1 : force reformat entire paragraph
* n == 0 : only until line equalizes (from text_write())
*
* What is a paragraph? A paragraph ends whenever the left justification
* gets larger, or on a blank line.
*/
do_reformat(n)
{
register char *str;
int nlok, lnsc, fnst, fnsc;
int column = E.Column;
int srow = E.Line;
int crow = srow;
int erow = srow;
short dins = 0; /* relative insert lines/delete lines */
char moded = 0; /* any modifications done at all? */
char checked = 0; /* for cursor positioning. */
if (E.Margin == 0)
E.Margin = 75;
++Nsu;
for (;;) {
str = (char *)E.List[E.Line+1];
fnst = 0;
fnsc = firstns(Current);
nlok = (E.Line + 1 < E.Lines && fnsc >= (fnst=firstns(str)));
if (nlok && str[0] == 0)
nlok = 0;
lnsc = lastns(Current);
if (lnsc < E.Margin) { /* space at end of line for marg-lnsc-2 letter word */
if (nlok == 0) /* but no more data to joinup */
break; /* done */
if (E.Margin - lnsc - 2 >= wordlen(str+fnst)) {
E.Column = 0;
Clen = lastns(Current);
if (Current[Clen])
++Clen;
moded = 1;
--dins;
if (do_join())
continue;
++dins;
title("Error, Margin > 124");
break;
}
if (n == 0) /* if couldn't mod line, and text_write, don't update any more */
break;
do_down();
erow = E.Line;
continue;
}
/* no space, need to split */
/* find start of prev word */
for (;;) {
register int i = lnsc;
while (i && Current[i] != ' ')
--i;
lnsc = i;
if (i >= E.Margin) {
while (i && Current[i] == ' ')
--i;
if (i < E.Margin)
break;
lnsc = i;
continue;
}
break;
}
if (lnsc) { /* ok to split at word */
++lnsc;
++dins;
E.Column = lnsc;
do_split(); /* Split at point LNSC */
do_down(); /* must insert proper amount? */
{
int indent = (nlok == 0) ? fnsc : fnst;
if (!checked) {
checked = 1;
if (lnsc <= column) { /* if split before cursor */
column = column - E.Column + indent;
++crow;
}
}
if (Clen + indent < 253) {
bmov(Current, Current + indent, strlen(Current)+1);
bset(Current, indent, ' ');
Clen += indent;
}
}
erow = E.Line;
continue;
}
if (n == 0)
break;
do_down();
}
if (column < 0 || column > 200)
column = 0;
if (srow >= E.Lines) {
srow = E.Lines - 1;
goto ra;
}
if (dins || srow < E.Topline || srow >= E.Topline + Rows) {
ra:
text_sync();
--Nsu;
E.Line = crow;
E.Column = column;
text_load();
if (!text_sync())
text_redisplay();
} else {
text_sync();
--Nsu;
E.Line = crow;
E.Column = column;
text_load();
if (erow != srow) {
if (!text_sync()) {
++erow;
if (erow - E.Topline > Rows)
erow = E.Topline + Rows;
SetAPen(Rp, 0);
RectFill(Rp, COL(0), ROW(srow - E.Topline), Xbase+Xpixs, ROW(erow - E.Topline)-1);
SetAPen(Rp, 1);
text_displayseg(srow - E.Topline, erow - srow);
}
} else {
text_sync();
if (moded)
text_redisplaycurrline();
}
}
if (column > Clen) {
bset(Current+Clen, column - Clen, ' ');
Current[column] = 0;
}
E.Column = column;
}
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()
{
register ubyte *ptr;
E.Modified = 1;
text_sync();
if (makeroom(32) && (ptr = allocb(1))) {
bmovl(E.List+E.Line, E.List+E.Line+1,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();
if (Nsu == 0)
ScrollRaster(Rp,0,-Ysize, COL(0), ROW(E.Line-E.Topline), COL(Columns)-1, ROW(Rows)-1);
text_displayseg(E.Line - E.Topline, 1);
}
do_deline()
{
int delline;
if (E.Lines > 1) {
E.Modified = 1;
text_sync();
FreeMem(E.List[E.Line], strlen(E.List[E.Line])+1);
bmovl(E.List+E.Line+1, E.List+E.Line,E.Lines-E.Line-1);
if (E.Line < E.BSline)
--E.BSline;
if (E.Line <= E.BEline)
--E.BEline;
delline = E.Line;
if (E.Line >= --E.Lines) {
--E.Line;
text_load();
if (E.Line < E.Topline) {
if (Nsu == 0) {
E.Topline = E.Line - (Rows>>1);
if (E.Topline < 0)
E.Topline = 0;
text_redisplay();
}
return(0);
}
}
text_load();
if (Nsu == 0)
ScrollRaster(Rp,0,Ysize, COL(0), ROW(delline-E.Topline), COL(Columns)-1, ROW(Rows)-1);
text_displayseg(Rows-1, 1);
} else {
do_firstcolumn();
do_remeol();
E.Modified = 0;
}
}
do_chfilename()
{
text_sync();
strncpy(E.Name, av[1], 63);
MForceTitle = 1;
}
do_edit()
{
long xfi;
long oldlock;
long lines;
ubyte buf[256];
ubyte *ptr;
char failed = 1;
short iwiny;
text_sync();
if (*av[0] == 'n') { /* newfile or insfile */
if (E.Modified && getyn("Delete modified Image?") == 0)
return(0);
iwiny = E.IWiny;
text_uninit();
text_init();
E.IWiny = iwiny;
E.Modified = 0;
E.Line = E.Topline = 0;
strncpy(E.Name, av[1], 63);
} else {
E.Modified = 1;
}
lines = E.Lines;
if (Wbs && Wdisable == 0)
oldlock = CurrentDir(E.dirlock);
if (xfi = xfopen(av[1], "r", 4096)) {
register int len;
char oktitle = 1;
title("Loading...");
while ((len = xefgets(xfi, buf, 255)) >= 0) {
failed = 0;
if (makeroom(256) && (ptr = allocb(len+1))) {
E.List[E.Lines++] = ptr;
bmov(buf, ptr, len+1);
} else {
nomemory();
oktitle = 0;
break;
}
}
if (oktitle)
title("OK");
} else {
title("File Not Found");
}
xfclose(xfi);
if (Wbs && Wdisable == 0)
CurrentDir(oldlock);
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);
bmovl(E.List+1, E.List,--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_savetabs()
{
Savetabs = (av[1][0] && av[1][1] == 'n') ? 1 : 0;
}
do_saveas()
{
long oldlock;
long xfi;
register long i;
register short j, k;
register ubyte *ptr, *bp;
long xs, xe;
ubyte buf[256];
char bm;
bm = blockmode;
if (blockmode && blockok()) {
xs = E.BSline;
xe = E.BEline + 1;
} else {
xs = 0;
xe = E.Lines;
}
blockmode = 0;
text_sync();
if (Wbs && Wdisable == 0) { /* Write out .info file */
DISKOBJ sdo, *d;
bzero(&sdo, sizeof(sdo));
oldlock = CurrentDir(E.dirlock);
if ((d = GetDiskObject(av[1])) == NULL) {
if (getpath(Wbs->sm_ArgList[0].wa_Name, buf)) {
sdo.do_Magic = WB_DISKMAGIC;
sdo.do_Version = WB_DISKVERSION;
makemygadget(&sdo.do_Gadget);
sdo.do_Type = WBPROJECT;
sdo.do_DefaultTool = (char *)buf;
sdo.do_ToolTypes = NULL;
sdo.do_CurrentX = NO_ICON_POSITION;
sdo.do_CurrentY = NO_ICON_POSITION;
sdo.do_DrawerData = NULL;
sdo.do_ToolWindow = NULL;
sdo.do_StackSize = 8192;
PutDiskObject(av[1], &sdo);
}
} else {
FreeDiskObject(d);
}
}
if (xfi = xfopen(av[1], "w", 4096)) {
title("Saving...");
for (i = xs; i < xe; ++i) {
ptr = E.List[i];
if (Savetabs) {
for (bp = buf, j = 0; *ptr; ++ptr, ++bp, j = (j+1)&7) {
*bp = *ptr;
if (j == 7 && *bp == ' ' && *(bp-1) == ' ') {
k = j;
while (k-- >= 0 && *bp == ' ')
--bp;
*++bp = 9;
} else {
if (*bp == '\"' || *bp == '\'' || *bp == '\`' || *bp == '(')
break;
}
}
strcpy(bp, ptr);
ptr = buf;
}
xfwrite(xfi, ptr, strlen(ptr));
if (xfwrite(xfi, "\n", 1)) {
xfclose(xfi);
goto err;
}
}
if (xfclose(xfi)) {
err: Abortcommand = 1;
title("WRITE FAILED!");
} else {
E.Modified &= bm;
title("OK");
}
if (Wbs && Wdisable == 0)
CurrentDir(oldlock);
} else {
title("Unable to open write file");
Abortcommand = 1;
}
}
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;
}
}
static
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()
{
register long i, 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);
bmovl(E.List+E.BEline+1,E.List+E.BSline,(E.Lines-E.BEline-1));
E.Lines -= n;
E.Modified = 1;
if (E.Line >= E.Lines)
E.Line = E.Lines - 1;
if (E.Line < 0)
E.Line = 0;
if (E.Lines == 0) {
text_uninit();
text_init();
}
text_load();
E.BSline = E.BEline = -1;
if (!text_sync())
text_redisplay();
}
}
void
do_bcopy()
{
register ubyte **list;
register long lines, i, scr;
register ED *e;
if (!blockok())
return;
text_sync();
lines = E.BEline - E.BSline + 1;
list = (ubyte **)allocl(E.Lines+lines);
if (!list) {
nomemory();
return;
}
for (i = 0; i < lines; ++i) {
register ubyte *ptr = E.List[E.BSline+i];
if (!(list[E.Line+i] = allocb(strlen(ptr)+1))) {
nomemory();
while (--i >= 0)
FreeMem(list[E.Line+i], strlen(E.List[E.BSline+i])+1);
FreeMem(list, sizeof(char *)*(E.Lines+lines));
return;
}
strcpy(list[E.Line+i], ptr);
}
bmovl(E.List, list, E.Line);
bmovl(E.List+E.Line, list + E.Line + lines, E.Lines-E.Line);
if (E.Line < E.BSline) {
E.BSline += lines;
E.BEline += lines;
}
E.Modified = 1;
FreeMem(E.List, E.Maxlines * sizeof(char *));
E.List = list;
E.Lines += lines;
E.Maxlines = E.Lines;
text_load();
if (!text_sync())
text_redisplay();
}
do_bmove()
{
register long lines;
register ubyte **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 = (ubyte **)allocl(lines);
bmovl(E.List + E.BSline, temp, lines);
if (E.Line > E.BSline) {
bmovl(E.List+E.BEline+1, E.List+E.BSline, E.Line-E.BEline-1);
bmovl(temp, E.List + E.Line - lines, lines);
} else {
bmovl(E.List+E.Line, E.List+E.Line+lines, E.BSline-E.Line);
bmovl(temp, E.List + E.Line, lines);
}
E.Modified = 1;
FreeMem(temp, lines * sizeof(char *));
E.BSline = E.BEline = -1;
text_load();
if (!text_sync())
text_redisplay();
}
}
/*
* IF condition trueaction, IFELSE condition trueaction falseaction
*
* condition: !condition NOT the specified condition.
* # toggle number is SET
* top top of file (on first line)
* bot end of file (on last line)
* left start of line (leftmost column)
* right end of line (nothing but spaces under and to the right)
* modified text has been modified
* insert currently in insert mode
* y[<=>]# cursor is (any OR combo of <,>,=) row # (line numbers start at 1)
* x[<=>]# cursor is (<,>,<=,>=,<>) column # (columns start at 1)
* <> means 'not equal'
*
* cl char under cursor is lower case
* cu char under cursor is upper case
* ca char under cursor is alpha
* cn char under cursor is numeric
* cb char within selected block
* c[<=>]# char under cursor is (combo of <,>,and =) #
*/
do_if()
{
char haselse = (av[0][2] == 'e');
char iswhile = (av[0][0] == 'w');
char istrue, notop = 0;
char c, cx, cc;
ubyte *buf1, *buf2;
register ubyte *ptr;
int i, cxn, cn;
buf1 = (ubyte *)malloc(256);
buf2 = (ubyte *)malloc(256);
if (buf1 == NULL || buf2 == NULL) {
if (buf1) free(buf1);
if (buf2) free(buf2);
title("No Memory!");
return(0);
}
breakreset();
ptr = av[1];
if (*ptr == '!') {
notop = 1;
++ptr;
}
c = ptr[0];
cn= atoi(ptr);
cx= ptr[1];
cxn=atoi(ptr+1);
strcpy(buf1, av[2]);
loop:
istrue = 0;
i = 0;
switch(c) {
case 'x':
i = E.Column + 1;
case 'y':
if (!i)
i = E.Line + 1;
conditional:
{
register int j, n;
char any = 0;
for (j = 1; ptr[j] && (ptr[j]<'0'||ptr[j]>'9'); ++j);
n = atoi(ptr+j);
for (j = 1; ptr[j]; ++j) {
switch(ptr[j]) {
case '<':
any = 1;
if (i < n)
istrue = 1;
break;
case '=':
any = 1;
if (i == n)
istrue = 1;
break;
case '>':
any = 1;
if (i > n)
istrue = 1;
break;
}
}
if (!any && i == n) /* default is equivalence */
istrue = 1;
}
break;
case 't':
istrue = E.Line == 0;
break;
case 'b':
istrue = E.Line == E.Lines-1;
break;
case 'l':
istrue = E.Column == 0;
break;
case 'r':
istrue = E.Column == Clen;
break;
case 'm':
text_sync();
istrue = E.Modified != 0;
break;
case 'i':
istrue = E.Insertmode != 0;
break;
case 'c':
cc = Current[E.Column];
switch(cx) {
case 'b':
istrue = E.Line >= E.BSline && E.Line <= E.BEline;
break;
case 'l':
istrue = cc >= 'a' && cc <= 'z';
break;
case 'u':
istrue = cc >= 'A' && cc <= 'Z';
break;
case 'a':
istrue = (cc>='a'&&cc<='z')||(cc>='A'&&cc<='Z')||(cc>='0'&&cc<='9');
break;
case 'n':
istrue = (cc >= '0' && cc <= '9');
break;
default: /* c[<=>]# */
i = Current[E.Column];
goto conditional;
break;
}
break;
default:
if (c >= '0' && c <= '9')
istrue = do_toggle(cn) != 0;
else
title("bad conditional");
break;
}
istrue ^= notop;
if (istrue) {
strcpy(buf2, buf1); /* could be executed multiple times */
if (do_command(buf2) == 0)
goto done;
if (iswhile) {
if (breakcheck())
Abortcommand = 1;
else
goto loop;
}
} else {
if (haselse) { /* only executed once */
strcpy(buf2, av[3]);
do_command(buf2);
}
}
done:
free(buf1);
free(buf2);
}
/*
* TOGGLE #, SETTOGGLE #, RESETTOGGLE #
*/
do_toggle(n)
{
static char tg[MAXTOGGLE];
int i;
if (n >= 0) {
if (n >= MAXTOGGLE)
return(0);
return(tg[n]);
}
i = atoi(av[1]);
if (i >= 0 && i < MAXTOGGLE) {
switch(av[0][0]) {
case 't':
tg[i] = !tg[i];
break;
case 's':
tg[i] = 1;
break;
case 'r':
tg[i] = 0;
break;
}
}
}
do_tlate()
{
register ubyte *ptr = av[1];
register int n;
char c = Current[E.Column];
if (ptr[0] == '+')
c += atoi(ptr+1);
else
if (ptr[0] == '-')
c -= atoi(ptr+1);
else
c = atoi(ptr);
if (c) {
if (Current[E.Column] == 0)
Current[E.Column+1] = 0;
Current[E.Column] = c;
if (Nsu == 0) {
movetocursor();
Text(Rp, Current+E.Column, 1);
}
}
}
/*
* BSOURCE
*
* note that since the start and end lines are loaded immediately and the
* block unblock'd before execution starts, you can theoretically have
* another BSOURCE as part of this BSOURCE (but be carefull!).
*/
do_bsource()
{
ubyte buf[256];
register int i, sl, se;
if (blockok()) {
sl = E.BSline;
se = E.BEline + 1;
E.BSline = E.BEline = -1;
for (i = sl; i < se && i < E.Lines; ++i) {
text_sync(); /* make sure we are using latest text */
strcpy(buf, E.List[i]);
if (do_command(buf) == 0)
break;
}
}
}
/*
* SCANF controlstring
*
* The C scanf routine. Only one variable, a string, is allowed in the
* control string.
*/
void
do_scanf()
{
char buf[256];
short i;
short ovr;
register char *ptr;
buf[0] = 0;
sscanf(Current+E.Column,av[1],buf,buf,buf,buf,buf,buf,buf);
if (String)
free(String);
String = (char *)malloc(strlen(buf)+1);
strcpy(String,buf);
title(String);
}
movetocursor()
{
Move(Rp, XTbase+(E.Column-E.Topcolumn)*Xsize, YTbase+(E.Line-E.Topline)*Ysize);
}
makeroom(n)
{
register ubyte **Newlist;
if (E.Lines >= E.Maxlines) {
Newlist = (ubyte **)allocl(E.Maxlines + n);
if (Newlist) {
bmovl(E.List, Newlist, E.Maxlines);
FreeMem(E.List, sizeof(char *) * E.Maxlines);
E.List = Newlist;
E.Maxlines += n;
return(1);
} else {
nomemory();
}
return(0);
}
return(1);
}