home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
disks
/
disk441.lzh
/
Dme
/
src
/
cmd2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-24
|
24KB
|
1,225 lines
/*
* CMD2.C
*
* (C)Copyright 1987 by Matthew Dillon, All Rights Reserved
*/
#include "defs.h"
#include <workbench/startup.h>
#include <workbench/workbench.h>
Prototype struct _ED *uninit_init (struct _ED *);
Prototype void do_remeol (void);
Prototype void do_wleft (void);
Prototype void do_wright (void);
Prototype void do_split (void);
Prototype int do_join (void);
Prototype void do_margin (void);
Prototype void do_wordwrap (void);
Prototype void do_setparcol (void);
Prototype void do_reformat (int);
Prototype void do_tabstop (void);
Prototype void do_insertmode (void);
Prototype void do_insline (void);
Prototype void do_deline (void);
Prototype void do_chfilename (void);
Prototype void do_edit (void);
Prototype void do_bsave (void);
Prototype void do_save (void);
Prototype void do_saveas (void);
Prototype void do_savetabs (void);
Prototype void do_block (void);
Prototype int blockok (void);
Prototype void do_bdelete (void);
Prototype void do_bcopy (void);
Prototype void do_bmove (void);
Prototype void do_if (void);
Prototype int do_toggle (int);
Prototype void do_tlate (void);
Prototype void do_bsource (void);
Prototype void do_scanf (void);
Prototype int extend (struct _ED *, int);
Prototype int makeroom (int);
Prototype void freelist (char **, int);
typedef struct WBStartup WBS;
typedef struct DiskObject DISKOBJ;
extern void *GetDiskObject();
#define nomemory() {memoryfail = 1;}
#if AREXX
#include "rexx.h"
extern int foundcmd; /* control for implicit ARexx macro invocation */
extern int cmderr; /* global command error flag for do_rexx()'s use */
#endif
extern char MForceTitle;
extern void do_bmove();
extern WBS *Wbs;
ED *
uninit_init(ep)
ED *ep;
{
FONT *font;
BPTR lock = DupLock((BPTR)ep->dirlock);
WIN *win;
int bufsiz = offsetof(struct _ED,EndConfig) - offsetof(struct _ED, BeginConfig);
char *buf = malloc(bufsiz);
movmem(&ep->BeginConfig, buf, bufsiz);
win = ep->Win;
font = ep->Font;
ep->Font = NULL;
text_uninit();
text_init(Ep, NULL, NULL);
ep = Ep;
if (ep->Font)
CloseFont(ep->Font);
ep->Win = win;
ep->Font = font;
movmem(buf, &ep->BeginConfig, bufsiz);
ep->Modified = 0;
ep->Line = ep->Topline = 0;
UnLock((BPTR)ep->dirlock);
ep->dirlock = (long)lock;
free(buf);
return(ep);
}
void
do_remeol()
{
Current[Clen = Ep->Column] = 0;
text_sync();
text_redisplaycurrline();
}
void
do_wleft()
{
ED *ep = Ep;
int i;
for (;;) {
i = ep->Column;
if (i == 0)
goto prevline;
--i;
while (i && Current[i] == ' ')
--i;
if (i == 0 && Current[0] == ' ') {
prevline:
if (Comlinemode || ep->Line == 0) {
i = ep->Column;
break;
}
text_sync();
--ep->Line;
text_load();
ep->Column = Clen;
continue;
}
while (i && Current[i] != ' ')
--i;
if (Current[i] == ' ')
++i;
break;
}
ep->Column = i;
text_sync();
}
void
do_wright()
{
ED *ep = Ep;
int i;
for (;;) {
i = ep->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 || ep->Line == ep->Lines - 1) {
i = ep->Column;
break;
}
text_sync();
++ep->Line;
text_load();
ep->Column = i = 0;
if (Current[0] != ' ')
break;
continue;
}
break;
}
ep->Column = i;
text_sync();
}
void
do_split() /* split line in two at cursor pos */
{
ubyte buf[256];
ED *ep = Ep;
RP *rp = ep->Win->RPort;
char onLastLine;
strcpy(buf, Current+ep->Column);
Current[Clen = ep->Column] = '\0';
text_sync();
SetAPen(rp, ep->BGPen);
if (Nsu == 0)
RectFill(rp, COL(0), ROW(ep->Line-ep->Topline), Xbase+Xpixs, ROW(ep->Line-ep->Topline+1)-1);
SetAPen(rp, ep->FGPen);
text_displayseg(ep->Line - ep->Topline, 1);
onLastLine = (ep->Line == ep->Lines-1);
do_downadd();
if (!onLastLine)
do_insline();
strcpy(Current, buf);
Clen = strlen(Current);
text_sync();
text_displayseg(ep->Line - ep->Topline, 1);
do_up();
}
do_join()
{
int i = Clen, j;
ED *ep = Ep;
if (ep->Line + 1 < ep->Lines && strlen(ep->List[ep->Line+1])+i <= 253) {
if (i && Current[i-1] != ' ')
Current[i++] = ' ';
strcpy(Current+i, ep->List[ep->Line+1]);
for (j = i; Current[j] == ' '; ++j);
for (; i >= 0 && Current[i] == ' '; --i);
if (j > i+2)
movmem(Current+j, Current+i+2, strlen(Current+j)+1);
Clen = strlen(Current);
text_sync();
text_displayseg(ep->Line - ep->Topline, 1);
{
int l = text_lineno();
do_down();
do_deline();
if (l != text_lineno())
do_up();
}
return(1);
}
return(0);
}
void
do_margin()
{
Ep->Margin = atoi(av[1]);
}
void
do_wordwrap()
{
ED *ep = Ep;
if (av[1][1] == 'n')
ep->Wordwrap = 1;
if (av[1][1] == 'f')
ep->Wordwrap = 0;
if (av[1][0] == 't')
ep->Wordwrap = 1 - ep->Wordwrap;
if (ep->Wordwrap)
title("Wordwrap ON");
else
title("Wordwrap OFF");
}
void
do_setparcol()
{
Ep->WWCol = atoi(av[1]);
}
/*
* 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.
*/
void
do_reformat(n)
{
char *str;
ED *ep = Ep;
RP *rp = ep->Win->RPort;
int nlok, lnsc, fnst, fnsc;
int column = ep->Column;
int srow = ep->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 (ep->Margin == 0)
ep->Margin = 75;
++Nsu;
for (;;) {
str = (char *)ep->List[ep->Line+1];
fnst = 0;
fnsc = firstns(Current);
nlok = (ep->Line + 1 < ep->Lines && fnsc >= (fnst=firstns(str)));
if (ep->WWCol >= 0)
fnst = fnsc = ep->WWCol;
if (nlok && str[0] == 0)
nlok = 0;
lnsc = lastns(Current);
if (lnsc < ep->Margin) { /* space at end of line for marg-lnsc-2 letter word */
if (nlok == 0) /* but no more data to joinup */
break; /* done */
if (ep->Margin - lnsc - 2 >= wordlen(str+fnst)) {
ep->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 = ep->Line;
continue;
}
/* no space, need to split */
/* find start of prev word */
for (;;) {
int i = lnsc;
while (i && Current[i] != ' ')
--i;
lnsc = i;
if (i >= ep->Margin) {
while (i && Current[i] == ' ')
--i;
if (i < ep->Margin)
break;
lnsc = i;
continue;
}
break;
}
if (lnsc) { /* ok to split at word */
++lnsc;
++dins;
ep->Column = lnsc;
do_split(); /* Split at point LNSC */
do_down(); /* must insert proper amount? */
{
int indent = (nlok == 0) ? fnsc : fnst;
if (ep->WWCol >= 0)
indent = ep->WWCol;
if (!checked) {
checked = 1;
if (lnsc <= column) { /* if split before cursor */
column = column - ep->Column + indent;
++crow;
}
}
if (Clen + indent < 253) {
movmem(Current, Current + indent, strlen(Current)+1);
setmem(Current, indent, ' ');
Clen += indent;
}
}
erow = ep->Line;
continue;
}
if (n == 0)
break;
do_down();
}
if (column < 0 || column > 200)
column = 0;
if (srow >= ep->Lines) {
srow = ep->Lines - 1;
goto ra;
}
if (dins || srow < ep->Topline || srow >= ep->Topline + Rows) {
ra:
text_sync();
--Nsu;
ep->Line = crow;
ep->Column = column;
text_load();
if (!text_sync())
text_redisplay();
} else {
text_sync();
--Nsu;
ep->Line = crow;
ep->Column = column;
text_load();
if (erow != srow) {
if (!text_sync()) {
++erow;
if (erow - ep->Topline > Rows)
erow = ep->Topline + Rows;
SetAPen(rp, ep->BGPen);
RectFill(rp, COL(0), ROW(srow - ep->Topline), Xbase+Xpixs, ROW(erow - ep->Topline)-1);
SetAPen(rp, ep->FGPen);
text_displayseg(srow - ep->Topline, erow - srow);
}
} else {
text_sync();
if (moded)
text_redisplaycurrline();
}
}
if (column > Clen) {
setmem(Current+Clen, column - Clen, ' ');
Current[column] = 0;
}
ep->Column = column;
}
void
do_tabstop()
{
Ep->Tabstop = atoi(av[1]);
}
void
do_insertmode()
{
ED *ep = Ep;
if (av[1][0]) {
switch(av[1][1] & 0x1F) {
case 'n'&0x1F:
ep->Insertmode = 1;
break;
case 'f'&0x1F:
ep->Insertmode = 0;
break;
case 'o'&0x1F:
ep->Insertmode = 1 - ep->Insertmode;
break;
}
if (ep->Insertmode)
title("Insert mode on");
else
title("Insert mode off");
}
}
void
do_insline()
{
ubyte *ptr;
ED *ep = Ep;
RP *rp = ep->Win->RPort;
ep->Modified = 1;
text_sync();
if (makeroom(32) && (ptr = allocb(1))) {
bmovl(ep->List+ep->Line, ep->List+ep->Line+1,ep->Lines-ep->Line);
ep->List[ep->Line] = ptr;
*ptr = 0;
++ep->Lines;
if (BEp == ep) {
if (ep->Line < BSline)
++BSline;
if (ep->Line <= BEline)
++BEline;
}
} else {
nomemory();
}
text_load();
if (Nsu == 0)
ScrollRaster(rp,0,-Ysize, COL(0), ROW(ep->Line-ep->Topline), COL(Columns)-1, ROW(Rows)-1);
text_displayseg(ep->Line - ep->Topline, 1);
}
void
do_deline()
{
int delline;
ED *ep = Ep;
RP *rp = ep->Win->RPort;
strcpy(Deline, Current);
if (ep->Lines > 1) {
ep->Modified = 1;
text_sync();
FreeMem(ep->List[ep->Line], strlen(ep->List[ep->Line])+1);
bmovl(ep->List+ep->Line+1, ep->List+ep->Line,ep->Lines-ep->Line-1);
if (BEp == ep) {
if (ep->Line < BSline)
--BSline;
if (ep->Line <= BEline)
--BEline;
}
delline = ep->Line;
if (ep->Line >= --ep->Lines) {
--ep->Line;
text_load();
if (ep->Line < ep->Topline) {
if (Nsu == 0) {
ep->Topline = ep->Line - (Rows>>1);
if (ep->Topline < 0)
ep->Topline = 0;
text_redisplay();
}
return;
}
}
text_load();
if (Nsu == 0)
ScrollRaster(rp,0,Ysize, COL(0), ROW(delline-ep->Topline), COL(Columns)-1, ROW(Rows)-1);
text_displayseg(Rows-1, 1);
} else {
do_firstcolumn();
do_remeol();
ep->Modified = 0;
}
}
void
do_chfilename()
{
text_sync();
strncpy(Ep->Name, av[1], 63);
MForceTitle = 1;
}
void
do_edit()
{
FILE *fi;
BPTR oldlock;
long lines;
ubyte buf[256];
ubyte *ptr;
char failed = 1;
ED *ep = Ep;
text_sync();
if (*av[0] == 'n') { /* newfile or insfile */
if (ep->Modified && getyn("Delete modified Image?") == 0)
return;
ep = uninit_init(ep);
strncpy(ep->Name, av[1], 63);
} else {
ep->Modified = 1;
}
lines = ep->Lines;
oldlock = CurrentDir((BPTR)ep->dirlock);
if (fi = fopen(av[1], "r")) {
int len;
char oktitle = 1;
title("Loading...");
while ((len = xefgets(fi, buf, 255)) >= 0) {
failed = 0;
if (makeroom(256) && (ptr = allocb(len+1))) {
ep->List[ep->Lines++] = ptr;
movmem(buf, ptr, len+1);
} else {
set_window_params();
nomemory();
oktitle = 0;
break;
}
}
set_window_params();
if (oktitle)
title("OK");
} else {
title("File Not Found");
#if AREXX
cmderr = CMD_FAILED;
#endif
}
fclose(fi);
CurrentDir(oldlock);
if (ep->Lines != 1 && lines == 1 && ep->List[0][0] == 0) {
ep->Modified = 0;
ep->Line = 0;
FreeMem(ep->List[0], strlen(ep->List[0])+1);
bmovl(ep->List+1, ep->List,--ep->Lines);
} else {
if (!failed && lines <= ep->Lines - 1) {
BEp = ep;
BSline = lines;
BEline = ep->Lines - 1;
do_bmove();
}
}
set_window_params();
text_load();
text_redisplay();
}
static char blockmode;
void
do_bsave()
{
blockmode = 1;
do_saveas();
}
void
do_save()
{
av[1] = Ep->Name;
do_saveas();
}
void
do_savetabs()
{
Savetabs = (av[1][0] && av[1][1] == 'n') ? 1 : 0;
}
void
do_saveas()
{
BPTR oldlock;
FILE *fi;
long i;
short j, k;
ubyte *ptr, *bp;
long xs, xe;
ubyte buf[256];
char bm;
ED *ep;
bm = blockmode;
if (blockmode && blockok()) {
xs = BSline;
xe = BEline + 1;
ep = BEp;
} else {
xs = 0;
xe = Ep->Lines;
ep = Ep;
}
blockmode = 0;
text_sync();
oldlock = CurrentDir((BPTR)Ep->dirlock);
if (Wbs && Wdisable == 0) { /* Write out .info file */
DISKOBJ sdo, *d;
clrmem(&sdo, sizeof(sdo));
if ((d = GetDiskObject(av[1])) == NULL) {
if (getpathto(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 (fi = fopen(av[1], "w")) {
title("Saving...");
for (i = xs; i < xe; ++i) {
ptr = ep->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 < 32 || *bp == '\"' || *bp == '\'' || *bp == '\`' || *bp == '(')
break;
}
}
strcpy(bp, ptr);
ptr = buf;
}
fputs(ptr, fi);
fputc('\n', fi);
}
if (fclose(fi)) {
err: Abortcommand = 1;
title("WRITE FAILED!");
} else {
ep->Modified &= bm;
title("OK");
}
} else {
title("Unable to open write file");
Abortcommand = 1;
}
CurrentDir(oldlock);
}
void
do_block() /* block, unblock */
{
text_sync();
switch(av[0][0]) {
case 'b':
if (BSline < 0) {
bstart:
BEp = Ep;
BSline = Ep->Line;
title("Block Begin");
} else {
if (BEline > -1) {
title("Block Already Marked");
break;
}
if (BEp != Ep)
goto bstart;
title("Block End");
BEline = Ep->Line;
if (BSline > BEline) {
BEline = BSline;
BSline = Ep->Line;
}
text_redrawblock(1);
}
break;
case 'u':
text_redrawblock(0);
title ("Block Unmarked");
break;
}
}
blockok()
{
if (BEp && BSline >= 0 && BSline <= BEline && BEline < BEp->Lines)
return(1);
BEp = NULL;
BSline = BEline = -1;
title("Block Not Specified");
return(0);
}
void
do_bdelete()
{
long n;
ED *bep = BEp;
WIN *savewin = Ep->Win;
if (blockok()) {
text_switch(bep->Win);
n = BEline - BSline + 1;
if (bep->Line >= BSline && bep->Line <= BEline)
bep->Line = BSline;
if (bep->Line > BEline)
bep->Line -= n;
freelist(bep->List + BSline, BEline - BSline + 1);
bmovl(bep->List+BEline+1,bep->List+BSline,(bep->Lines-BEline-1));
bep->Lines -= n;
bep->Modified = 1;
if (bep->Line >= bep->Lines)
bep->Line = bep->Lines - 1;
if (bep->Line < 0)
bep->Line = 0;
if (bep->Lines == 0) {
++bep->Lines;
bep->List[0] = allocb(1);
bep->List[0][0] = 0;
}
text_load();
BEp = NULL;
BSline = BEline = -1;
if (!text_sync())
text_redisplay();
text_switch(savewin);
}
}
void
do_bcopy()
{
ubyte **list;
long lines, i;
ED *ep = Ep;
text_sync();
if (!blockok())
return;
if (ep == BEp && ep->Line > BSline && ep->Line <= BEline) {
title("Cannot Move into self");
return;
}
lines = BEline - BSline + 1;
if (extend(ep, lines)) {
if (list = (ubyte **)allocl(lines)) {
bmovl(BEp->List+BSline,list,lines);
bmovl(ep->List+ep->Line, ep->List+ep->Line+lines, ep->Lines-ep->Line);
for (i = 0; i < lines; ++i) {
ubyte *str = allocb(strlen(list[i])+1);
if (!str) {
nomemory();
FreeMem(list, lines * sizeof(char *));
freelist(ep->List + Ep->Line, i);
bmovl(ep->List+ep->Line+lines, ep->List+ep->Line, ep->Lines-ep->Line);
return;
}
strcpy(str, list[i]);
ep->List[ep->Line+i] = str;
}
FreeMem(list, lines * sizeof(char *));
}
}
if (ep == BEp && ep->Line <= BSline) {
BSline += lines;
BEline += lines;
}
ep->Modified = 1;
ep->Lines += lines;
text_load();
if (!text_sync())
text_redisplay();
}
void
do_bmove()
{
long lines;
ubyte **list;
ED *ep = Ep;
text_sync();
if (!blockok())
return;
if (BEp == ep && ep->Line >= BSline && ep->Line <= BEline) {
title("Cannot Move into self");
return;
}
lines = BEline - BSline + 1;
if (!(list = (ubyte **)allocl(lines))) {
nomemory();
return;
}
BEp->Modified = ep->Modified = 1;
bmovl(BEp->List + BSline, list, lines);
if (ep == BEp) {
if (ep->Line > BSline) {
bmovl(ep->List+BEline+1, ep->List+BSline, ep->Line-BEline-1);
bmovl(list, ep->List + ep->Line - lines, lines);
} else {
bmovl(ep->List+ep->Line, ep->List+ep->Line+lines, BSline-ep->Line);
bmovl(list, ep->List + ep->Line, lines);
}
} else {
WIN *savewin = ep->Win;
if (extend(ep, lines)) {
bmovl(BEp->List+BEline+1, BEp->List+BSline, BEp->Lines-BEline-1);
bmovl(ep->List+ep->Line, ep->List+ep->Line+lines, ep->Lines-ep->Line);
bmovl(list, ep->List+ep->Line, lines);
ep->Lines += lines;
BEp->Lines -= lines;
if (BEp->Line >= BSline && BEp->Line <= BEline)
BEp->Line = BSline - 1;
if (BEp->Line > BEline)
BEp->Line -= lines;
if (BEp->Line < 0)
BEp->Line = 0;
BSline = BEline = -1;
if (BEp->Lines == 0) {
ubyte *ptr = allocb(1);
BEp->List[0] = ptr;
*ptr = 0;
++BEp->Lines;
}
text_load();
text_switch(BEp->Win);
BEp = NULL;
ep = Ep;
if (!ep->iconmode) {
if (!text_sync())
text_redisplay();
}
text_switch(savewin);
ep = Ep;
}
}
BSline = BEline = -1;
BEp = NULL;
FreeMem(list, lines * sizeof(char *));
ep->Modified = 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 =) #
*/
void
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;
ubyte *ptr;
ED *ep = Ep;
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;
}
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 = ep->Column + 1;
case 'y':
if (!i)
i = ep->Line + 1;
conditional:
{
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 = ep->Line == 0;
break;
case 'b':
istrue = ep->Line == ep->Lines-1;
break;
case 'l':
istrue = ep->Column == 0;
break;
case 'r':
istrue = ep->Column == Clen;
break;
case 'm':
text_sync();
istrue = ep->Modified != 0;
break;
case 'e':
istrue = Comlinemode != 0;
break;
case 'i':
istrue = ep->Insertmode != 0;
break;
case 'c':
cc = Current[ep->Column];
switch(cx) {
case 'b':
istrue = BEp == ep && ep->Line >= BSline && ep->Line <= 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[ep->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((int)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;
}
}
}
void
do_tlate()
{
ubyte *ptr = av[1];
ED *ep = Ep;
char c = Current[ep->Column];
if (c == 0)
c = ' ';
if (ptr[0] == '+')
c += atoi(ptr+1);
else
if (ptr[0] == '-')
c -= atoi(ptr+1);
else
c = atoi(ptr);
if (c) {
if (Current[ep->Column] == 0) {
Clen = ep->Column + 1;
Current[Clen] = 0;
}
Current[ep->Column] = c;
if (Nsu == 0) {
movetocursor();
setpen(ep->Line);
Text(ep->Win->RPort, Current+ep->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!).
*/
void
do_bsource()
{
ubyte buf[256];
int i, sl, se;
if (blockok()) {
sl = BSline;
se = BEline + 1;
for (i = sl; BEp && i < se && i < BEp->Lines; ++i) {
text_sync(); /* make sure we are using latest text */
strcpy(buf, BEp->List[i]);
if (do_command(buf) == 0)
break;
}
text_redrawblock(0);
}
}
/*
* SCANF controlstring
*
* The C scanf routine. Only one variable, a string, is allowed in the
* control string.
*/
void
do_scanf()
{
char buf[256];
buf[0] = 0;
sscanf(Current+Ep->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);
}
void
movetocursor()
{
ED *ep = Ep;
Move(ep->Win->RPort, XTbase+(ep->Column-ep->Topcolumn)*Xsize, YTbase+(ep->Line-ep->Topline)*Ysize);
}
extend(ep, lines)
ED *ep;
{
long extra = ep->Maxlines - ep->Lines;
ubyte **list;
if (lines > extra) {
lines += ep->Lines;
if (list = (ubyte **)allocl(lines)) {
bmovl(ep->List, list, ep->Lines);
FreeMem(ep->List, sizeof(char *) * ep->Maxlines);
ep->Maxlines = lines;
ep->List = list;
return(1);
}
nomemory();
return(0);
}
return(1);
}
makeroom(n)
{
ED *ep = Ep;
if (ep->Lines >= ep->Maxlines)
return(extend(ep, n));
return(1);
}
void
freelist(list, n)
char **list;
{
while (n) {
FreeMem(list[0], strlen(list[0])+1);
++list;
--n;
}
}