Category : C Source Code
Archive   : MRU-TC.ZIP
Filename : EDITOR.C

 
Output of file : EDITOR.C contained in archive : MRU-TC.ZIP
/* ----------------------- editor.c ---------------------- */

#include
#include
#include
#include
#include
#include "twindow.h"
#include "keys.h"

#define TRUE 1
#define FALSE 0
#define TAB 4
#define NEXTTAB (TAB-(x%TAB))
#define LASTTAB (((wwd-1)/TAB)*TAB)
#define PREVTAB (((x-1)%TAB)+1)
#define curr(x,y) (bfptr+(y)*wwd+(x))
#define lineno(y) ((int)(bfptr-topptr)/wwd+(y))

extern int VSG;
int last_x, last_y;
static int wht;
static int wwd;
static int wsz;
static char *topptr;
static char *bfptr;
static char *lstptr;
static int lines;
static char *endptr;
static int blkbeg;
static int blkend;
static int inserting;
static WINDOW *wnd;
static int do_display_text = 1;
/*page*/
/* ---------- local function prototypes ----------- */
void erase_buffer(int *x, int *y);
int lastword(int x, int y);
void last_char(int *x, int *y);
void test_para(int x, int y);
int trailing_spaces(int y);
int first_wordlen(int y);
void paraform(int x, int y);
int blankline(int line);
void delete_word(int x, int y);
void delete_line(int y);
void delete_block(void);
void copy_block(int y);
void move_block(int y);
void mvblock(int y, int moving);
void findlast(void);
void find_end(int *x, int *y);
void carrtn(int *x, int *y, int insert);
void backspace(int *x, int *y);
void fore_word(int *x, int *y, char *bf);
int spaceup(int *x, int *y, char **bf);
void back_word(int *x, int *y, char *bf);
int spacedn(int *x, int *y, char **bf);
void forward(int *x, int *y);
int downward(int *y);
void upward(int *y);
void display_text(void);
void disp_line(int y);
void insert_line(void);
/*page*/
/* ----- Process text entry for a window. ---- */
void text_editor(WINDOW *wnd1, char *bf, unsigned bsize)
{
char *b, *buff;
int depart = FALSE, i, c;
int x, y, svx, svlw, tx, tabctr = 0;

wnd = wnd1;
wht = HEIGHT-2;
wwd = WIDTH-2;
wsz = wwd * wht;
topptr = bfptr = bf;
lines = bsize / wwd;
endptr = bf + wwd * lines;
blkbeg = 0;
blkend = 0;
inserting = FALSE;
x = 0;
y = 0;
display_text();
/* --------- read in text from the keyboard ---------- */
findlast();
while (TRUE) {
last_x = COL + 1 + x;
last_y = ROW + 1 + y;
cursor(last_x, last_y);
buff = curr(x, y);
if (tabctr) {
--tabctr;
c = ' ';
}
else {
c = get_char();
clear_message();
}
switch (c) {
case '\r': carrtn(&x, &y, inserting);
break;
case DN: downward(&y);
break;
case PGUP: y = 0;
for (i = 0; i < wht; i++)
upward(&y);
break;
case PGDN: y = HEIGHT - 2;
for (i = 0; i < wht; i++)
downward(&y);
y = 0;
break;
case '\t': if (x + NEXTTAB < wwd) {
if (inserting)
tabctr = NEXTTAB;
else
x += NEXTTAB;
}
else
carrtn(&x, &y, inserting);
break;
case SHIFT_HT:
if (x < TAB) {
upward(&y);
x = LASTTAB;
}
else
x -= PREVTAB;
break;
case CTRL_FWD:
fore_word(&x, &y, buff);
break;
case CTRL_BS:
back_word(&x, &y, buff);
break;
case CTRL_B:
y = wht - 1;
break;
case CTRL_T:
y = 0;
break;
case CTRL_HOME:
x = y = 0;
bfptr = topptr;
display_text();
break;
case HOME: x = 0;
break;
case CTRL_END:
find_end(&x, &y);
display_text();
break;
case END: last_char(&x, &y);
break;
case UP: upward(&y);
break;
case F2:
case ESC: depart = TRUE;
break;
case '\b':
case BS: if (curr(x, y) == topptr)
break;
backspace(&x, &y);
if (x == wwd - 1)
last_char(&x, &y);
if (c == BS)
break;
buff = curr(x, y);
case DEL: movmem(buff+1, buff, wwd-1-x);
*(buff+wwd-1-x) = ' ';
disp_line(y);
test_para(x+1, y);
break;
case ALT_D: delete_line(y);
break;
case CTRL_D:delete_word(x, y);
test_para(x, y);
break;
case INS: inserting ^= TRUE;
insert_line();
break;
case F3: erase_buffer(&x, &y);
break;
case F4: paraform(0, y);
break;
case F5: blkbeg = lineno(y) + 1;
if (blkbeg > blkend)
blkend = lines;
display_text();
break;
case F6: blkend = lineno(y) + 1;
if (blkend < blkbeg)
blkbeg = 1;
display_text();
break;
case F7: move_block(y);
break;
case F8: copy_block(y);
break;
case F9: delete_block();
break;
case F10: blkbeg = blkend = 0;
display_text();
break;
case FWD: forward(&x, &y);
break;
default: if (!isprint(c))
break;
if (curr(x, y) == endptr-1 ||
(lineno(y)+1 >= lines && inserting
&& *curr(wwd-2, y) != ' ')) {
error_message(" End of Buffer ");
break;
}
if (inserting) {
buff = curr(x, y);
movmem(buff, buff + 1, wwd-1-x);
}
buff = curr(x, y);

if (buff < endptr) {
if (buff >= lstptr)
lstptr = buff + 1;
*buff = c;
disp_line(y);
}
buff = curr(wwd-1, y);
if (endptr && *buff != ' ') {
for (b = buff+1; b < endptr; b++)
if (*b==' ' && *(b + 1)==' ')
break;
movmem(buff+1, buff+2, b-buff-1);
*(buff+1) = ' ';
svx = x;
svlw = lastword(x, y);
x = wwd-1;
if (*(buff-1) != ' ')
back_word(&x, &y, buff);
tx = x;
carrtn(&x, &y, TRUE);
if (svlw)
x = svx-tx;
else {
x = svx;
--y;
}
}
forward(&x, &y);
break;
}
if (depart)
break;
}
inserting = FALSE;
insert_line();
}
/*page*/
/* -------- erase the buffer --------------- */
static void erase_buffer(int *x, int *y)
{
int c = 0;
WINDOW *sur;

sur = establish_window(28, 11, 4, 24);
set_colors(sur, ALL, RED, YELLOW, BRIGHT);
display_window(sur);
wprintf(sur, " Erase text window\n Are you sure? (y/n)");
while (c != 'y' && c != 'n') {
c = get_char();
c = tolower(c);
if (c == 'y') {
lstptr = bfptr = topptr;
*x = *y = 0;
setmem(bfptr, lines * wwd, ' ');
blkbeg = blkend = 0;
display_text();
}
}
delete_window(sur);
}

/* ----- see if a word is the last word on the line ------ */
static int lastword(int x, int y)
{
char *bf = curr(x, y);

while (x++ < wwd-1)
if (*bf++ == ' ')
return 0;
return 1;
}
/*page*/
/* --- go to last displayable character on the line --- */
static void last_char(int *x, int *y)
{
char *bf;

*x = wwd-1;
bf = curr(0, *y);
while (*x && *(bf + *x) == ' ')
--(*x);
if (*x && *x < wwd - 1)
(*x)++;
}

/* ----- test to see if paragraph should be reformed ----- */
static void test_para(int x, int y)
{
int ts, fw;

if (!scroll_lock() && y < lines) {
ts = trailing_spaces(y);
fw = first_wordlen(y+1);
if (fw && ts > fw)
paraform(x, y);
}
}

/* ---- count the trailing spaces on a line ----- */
static int trailing_spaces(int y)
{
int x = wwd-1, ct = 0;
char *bf = curr(0, y);

while (x >= 0) {
if (*(bf + x) != ' ')
break;
--x;
ct++;
}
return ct;
}
/* ----- count the length of the first word on a line --- */
static int first_wordlen(int y)
{
int ct = 0, x = 0;
char *bf = curr(0, y);

while (x < wwd-1 && *(bf+x) == ' ')
x++;
while (x+ct < wwd-1 && *(bf+x+ct) != ' ')
ct++;
return ct;
}


/* ------------ form a paragraph -------------- */
static void paraform(int x, int y)
{
char *cp1, *cp2, *cpend, *svcp;
int x1;

if (blankline(lineno(y)+1))
return;
if (!blkbeg) {
blkbeg = blkend = lineno(y)+1;
blkend++;
while (blkend < lines) {
if (blankline(blkend))
break;
blkend++;
}
--blkend;
}
if (lineno(y) != blkbeg-1)
x = 0;
x1 = x;
cp1 = cp2 = topptr + (blkbeg - 1) * wwd + x;
cpend = topptr + blkend * wwd;
while (cp2 < cpend) {
while (*cp2 == ' ' && cp2 < cpend)
cp2++;
if (cp2 == cpend)
break;
/* at a word */
while (*cp2 != ' ' && cp2 < cpend) {
if (x1 >= wwd - 1) {
/* wrap the word */
svcp = cp1 + (wwd - x1);
while (*--cp1 != ' ') {
*cp1 = ' ';
--cp2;
}
x1 = 0;
blkbeg++;
cp1 = svcp;
}
*cp1++ = *cp2++;
x1++;
}
if (cp2 < cpend) {
*cp1++ = ' ';
x1++;
}
}
while (cp1 < cpend)
*cp1++ = ' ';
blkbeg++;
if (blkbeg <= blkend)
delete_block();
blkbeg = blkend = 0;
display_text();
findlast();
}
/*page*/
/* ------- test for a blank line ---------- */
static int blankline(int line)
{
char *cp;
int x;

cp = topptr + (line-1) * wwd;
for (x = 0; x < wwd; x++)
if (*(cp + x) != ' ')
break;
return (x == wwd);
}

/* ------------- delete a word -------------- */
static void delete_word(int x, int y)
{
int wct = 0;
char *cp1, *cp2;

cp1 = cp2 = curr(x, y);
if (*cp2 == ' ')
while (*cp2 == ' ' && x + wct < wwd) {
wct++;
cp2++;
}
else {
while (*cp2 != ' ' && x + wct < wwd) {
wct++;
cp2++;
}
while (*cp2 == ' ' && x + wct < wwd) {
wct++;
cp2++;
}
}
movmem(cp2, cp1, wwd - x - wct);
setmem(cp1 + wwd - x - wct, wct, ' ');
display_text();
findlast();
}
/* ----------- delete a line --------------- */
static void delete_line(int y)
{
char *cp1, *cp2;
int len;

cp1 = bfptr + y * wwd;
cp2 = cp1 + wwd;
if (cp1 < lstptr) {
len = endptr - cp2;
movmem(cp2, cp1, len);
lstptr -= wwd;
setmem(endptr - wwd, wwd, ' ');
display_text();
}
}

/* ----------- delete a block ------------- */
static void delete_block()
{
char *cp1, *cp2;
int len;

if (!blkbeg || !blkend) {
putchar(BELL);
return;
}
cp1 = topptr + blkend * wwd;
cp2 = topptr + (blkbeg - 1) * wwd;
len = endptr - cp1;
movmem(cp1, cp2, len);
setmem(cp2 + len, endptr - (cp2 + len), ' ');
blkbeg = blkend = 0;
lstptr -= (cp1 - cp2);
display_text();
}
/*page*/
/* ------- move and copy text blocks -------- */
static void mvblock(int y, int moving)
{
char *cp1, *cp2, *hd;
int len;
if (!blkbeg || !blkend) {
putchar(BELL);
return;
}
if (lineno(y) >= blkbeg-1 && lineno(y) <= blkend-1) {
error_message("Can't move/copy a block into itself");
return;
}
len = (blkend - blkbeg + 1) * wwd;
if ((hd = malloc(len)) == 0)
return;
cp1 = topptr + (blkbeg-1) * wwd;
movmem(cp1, hd, len);
cp2 = topptr + lineno(y) * wwd;
if (moving) {
if (lineno(y) > blkbeg-1)
cp2 -= len;
do_display_text = 0;
delete_block();
do_display_text = 1;
}
if (cp2+len <= endptr) {
movmem(cp2, cp2 + len, endptr - cp2 - len);
movmem(hd, cp2, len);
}
free(hd);
blkbeg = blkend = 0;
display_text();
}
/* ------------- copy a block ---------------- */
static void copy_block(int y)
{
mvblock(y, FALSE);
findlast();
}

/* --------- move a block ------------ */
static void move_block(int y)
{
mvblock(y, TRUE);
}

/* ------- find the last character in the buffer -------- */
static void findlast()
{
register char *lp = endptr - 1;
register char *tp = topptr;

while (lp > tp && (*lp == ' ' || *lp == '\0')) {
if (*lp == '\0')
*lp = ' ';
--lp;
}
if (*lp != ' ')
lp++;
lstptr = lp;
}

/* ------- go to the end of the data in the buffer ------- */
static void find_end(int *x, int *y)
{
int ct;

bfptr = lstptr;
ct = (lstptr - topptr) % wsz;
bfptr -= ct;
if (bfptr + wsz > endptr)
bfptr = endptr - wsz;
*y = (ct / wwd);
*x = 0;
downward(y);
}
/*page*/
/* -------- carriage return -------- */
static void carrtn(int *x, int *y, int insert)
{
int insct;
char *cp, *nl;
int ctl = 2;

cp = curr(*x, *y);
nl = cp + ((cp - topptr) % wwd);
if (lineno(*y) + 2 < lines)
if (insert && nl < endptr) {
insct = wwd - *x;
while (ctl--) {
if (endptr > cp + insct) {
movmem(cp, cp+insct, endptr-insct-cp);
setmem(cp, insct, ' ');
}
else if (ctl == 1)
setmem(cp, endptr - cp, ' ');
cp += insct * 2;
insct = *x;
}
}
*x = 0;
downward(y);
if (insert) {
test_para(*x, *y);
display_text();
}
if (lineno(*y) + 2 < lines)
if (insert)
if ((lstptr + wwd) <= endptr)
if (lstptr > curr(*x, *y))
lstptr += wwd;
}
/*page*/
/* ------- move the buffer offset back one position ------ */
static void backspace(int *x, int *y)
{
if (*x == 0) {
*x = wwd - 1;
upward(y);
}
else
--(*x);
}

/* -------- move the buffer offset forward one word ------ */
static void fore_word(int *x, int *y, char *bf)
{
while (*bf != ' ') {
if (spaceup(x, y, &bf) == 0)
return;
if (*x == 0)
break;
}
while (*bf == ' ')
if (spaceup(x, y, &bf) == 0)
return;
}

static int spaceup(int *x, int *y, char **bf)
{
if (*bf == lstptr)
return 0;
(*bf)++;
forward(x, y);
return 1;
}
/*page*/
/* ------- move the buffer offset backward one word ------ */
static void back_word(int *x, int *y, char *bf)
{
spacedn(x, y, &bf);
while (*bf == ' ')
if (spacedn(x, y, &bf) == 0)
return;
while (*bf != ' ') {
if (*x == 0)
return;
if (spacedn(x, y, &bf) == 0)
return;
}
spaceup(x, y, &bf);
}

static int spacedn(int *x, int *y, char **bf)
{
if (*bf == topptr)
return 0;
--(*bf);
backspace(x, y);
return 1;
}


/* ----- move the buffer offset forward one position ----- */
static void forward(int *x, int *y)
{
int ww = wwd;

(*x)++;
if (*x == ww) {
downward(y);
*x = 0;
}
}
/*page*/
/* ------- move the buffer offset down one position ------ */
static int downward(int *y)
{
if (*y < wht - 1) {
(*y)++;
return 1;
}
else if ((bfptr + wsz) < endptr) {
bfptr += wwd;
scroll(wnd, UP);
disp_line(wht-1);
return 1;
}
return 0;
}

/* -------- move the buffer offset up one position ------ */
static void upward(int *y)
{
if (*y)
--(*y);
else if ((topptr + wwd) <= bfptr) {
bfptr -= wwd;
scroll(wnd, DN);
disp_line(0);
}
}

/* ---- display all the lines in a window ------ */
static void display_text()
{
int y = 0;

if (do_display_text)
while (y < wht)
disp_line(y++);
}
/*page*/
/* ---------- Display a line -------- */
static void disp_line(int y)
{
int x = 0, atr = WNORMAL;

if (blkbeg || blkend)
if (lineno(y) >= blkbeg-1)
if (lineno(y) <= blkend-1)
atr = WACCENT;
while (x < wwd) {
displ(wnd, x+1, y+1, *(bfptr+y * wwd+x), atr);
x++;
}
}

/* ---------- set insert/exchange cursor shape ----------- */
static void insert_line()
{
set_cursor_type(inserting ? 0x0106 : 0x0607);
}



  3 Responses to “Category : C Source Code
Archive   : MRU-TC.ZIP
Filename : EDITOR.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/