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