ain@j.cc.purdue.edu (Patrick White) (01/13/88)
Program Name: DME Submitted By: dillon%cory.Berkeley.EDU@ucbvax.berkeley.edu (Matt Dillon) Summary: DME is Matt Dillon's editor. Features multiple windows and key mapping among other things... read the docs (part 2 of the binary posting) as they explain it much better than I can in a line or two. Poster Boy: Pat White (ain@j.cc.purdue.edu) Untested. NOTES: Binary version posted on comp.binaries.amiga. Docs posted with binary version (part 2). Didn't test it. -- Pat White (co-moderator comp.sources/binaries.amiga) UUCP: j.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421 U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906 ======================================== #! /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: # Makefile # defs.h # command.c # filereq.c # globals.c # keyboard.c # main.c # This archive created: Tue Jan 12 02:23:20 1988 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'Makefile'" '(1080 characters)' if test -f 'Makefile' then echo shar: "will not over-write existing file 'Makefile'" else cat << \!Funky!Stuff! > 'Makefile' # Note: In terms of compiling, if you do not have my latest # support library you may have to do some hacking to get the # code to link. # # The precompiled symbol table, SYMBOLS.M, is *only* the AMIGA includes # .. */*.h (exec/*.h, etc....). When generating a precompiled symbol # table remember to use the +L compiler option. CFLAGS= +L +Ivd0:include/symbols.m OBJS= globals.o command.o keyboard.o main.o text1.o text2.o subs.o refs.o filereq.o menu.o ASMS= globals.asm command.asm keyboard.asm main.asm text1.asm text2.asm subs.asm refs.asm filereq.asm menu.asm SRCS= globals.c command.c keyboard.c main.c text1.c text2.c subs.c refs.c filereq.c menu.c HDR= defs.h .c.o: cc $(CFLAGS) -o $@ $*.c .c.asm: cc $(CFLAGS) -A -o ram:$@ $*.c all: $(OBJS) ln +Q $(OBJS) -lsup32 -lc32 -O ram:dme asm: $(ASMS) arc: -delete ram:dme.arc arc a ram:dme DME.DOC ram:dme dme.info README sample.edrc macros.edrc dme.refs.1 dme.refs.2 srcarc: -delete ram:dmesrc.arc arc a ram:dmesrc Makefile $(SRCS) $(HDR) clean: -delete $(OBJS) ram:dme !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'defs.h'" '(2078 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 * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved * */ #include <exec/types.h> #include <exec/io.h> #include <devices/keymap.h> #include <devices/console.h> #include <exec/memory.h> #include <intuition/intuition.h> #include <typedefs.h> #include "xmisc.h" #define MAXTOGGLE 256 #define QMOVE (0x6B|0x80) #define COLT(n) (XTbase + (n) * Xsize) #define ROWT(n) (YTbase + (n) * Ysize) #define COL(n) (Xbase + (n) * Xsize) #define ROW(n) (Ybase + (n) * Ysize) typedef unsigned char ubyte; typedef struct WBStartup WBS; typedef struct DiskObject DISKOBJ; extern WBS *Wbs; extern DISKOBJ *Do; extern short Xsize, Ysize; extern short XTbase, YTbase; extern short Rows, Columns; extern short Xbase, Ybase; extern short Xpixs, Ypixs; extern ubyte *av[]; extern char Wdisable; typedef struct _ED { struct _ED *next, **prev; WIN *Win; long Topline, Topcolumn; long Line, Column; long Lines, Maxlines; ubyte **List; ubyte Name[64]; ubyte Wtitle[130]; char Modified; ubyte Tabstop; ubyte Margin; char Insertmode; char Wordwrap; char iconmode; /* window in icon mode */ short Winx; /* save state of non-icon window */ short Winy; short Winwidth; short Winheight; short IWinx, IWiny; /* save state of icon window */ long dirlock; /* directory lock */ } ED; extern long BSline, BEline; extern short BSchar, BEchar; extern ED *BEp; #ifndef NULL #define NULL 0 #endif #ifdef E #undef E #endif extern ED *Ep, *Base; extern char Overide; extern char Savetabs; extern char memoryfail, Nsu, Msgchk; extern ubyte CtlC; extern ubyte Current[256]; extern ubyte Space[32]; extern short Clen; extern char Abortcommand, MShowTitle; extern char Comlinemode; extern RP *Rp; extern WIN *Win; extern char *Partial; extern char *String; extern ubyte *allocl(), *allocb(); extern char *keyspectomacro(); extern char *menutomacro(); extern void search_operation(); extern void *malloc(), *AllocMem(), *strcpy(); extern long Dirlock; !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'command.c'" '(11555 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)Copyright 1987 by Matthew Dillon, All Rights Reserved * * )c single character (typing) * 'c single character (typing) * `string' string of characters w/ embedded `' allowed! * (string) same thing w/ embedded () allowed! * * name arg arg command name. The arguments are interpreted as strings * for the command. * * $scanf macro insert scanf'd variable * $filename macro insert current file name * * Any string arguments not part of a command are considered to be typed * text. */ #include "defs.h" #include <stdio.h> #define CF_COK 1 /* Can be executed while in command line mode */ #define CF_PAR 2 /* ESCIMM special flag.. save rest of command line */ /* so it can be executed after user entry */ extern char *breakout(); typedef struct { char *name; /* command name */ ubyte args; ubyte flags; 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_page(), do_savetabs(), 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(), do_wleft(), do_wright(), do_remeol(), do_savemap(), do_toggle(), do_if(), do_tlate(), do_bsource(), do_findr(), do_findstr(), do_newwindow(), do_windowparm(),do_resize(), do_margin(), do_wordwrap(), do_reformat(), do_execute(), do_chfilename(),do_scrollup(), do_scrolldown(),do_recall(), do_scanf(), do_iconify(), do_tomouse(), do_refs(), do_arpload(), do_arpsave(); extern int do_menu(), do_menuclear(), do_menuadd(), do_menudel(), do_menudelhdr(), do_menuon(), do_menuoff(); /* * WLEFT/WRIGHT will check command line mode themselves, and thus can * be marked flags=1 even though they can change the line number. * * No more than 255 commands may exist unless you change the type of hindex[] * * Command names MUST be sorted by their first character */ unsigned char hindex[26]; /* alpha hash into table */ /* args flags */ COMM Comm[] = { "arpload", 0, 0, do_arpload, "arpsave", 0, 0, do_arpsave, "back", 0, CF_COK, do_bs, "backtab", 0, CF_COK, do_backtab, "bcopy", 0, 0, do_bcopy, "bdelete", 0, 0, do_bdelete, "block", 0, 0, do_block, /* checks com name for mode */ "bmove", 0, 0, do_bmove, "bottom", 0, 0, do_bottom, "bs", 0, CF_COK, do_bs, "bsave", 1, CF_COK, do_bsave, "bsource", 0, 0, do_bsource, "chfilename", 1, 0, do_chfilename, "del", 0, CF_COK, do_del, "deline", 0, 0, do_deline, "down", 0, 0, do_down, "downadd", 0, 0, do_downadd, "esc", 0, CF_COK, do_esc, "escimm", 1, CF_PAR, do_esc, "execute", 1, 0, do_execute, "find", 1, 0, do_find, /* checks com name for mode */ "findr", 2, 0, do_findr, /* checks com name for mode */ "findstr", 1, CF_COK, do_findstr, /* checks com name for mode */ "first", 0, CF_COK, do_firstcolumn, "firstnb", 0, CF_COK, do_firstnb, "goto", 1, 0, do_goto, "height", 1, CF_COK, do_windowparm, "iconify", 0, 0, do_iconify, "if", 2, CF_COK, do_if, "ifelse", 3, CF_COK, do_if, "insertmode", 1, CF_COK, do_insertmode, "insfile", 1, 0, do_edit, "insline", 0, 0, do_insline, "join", 0, 0, do_join, "last", 0, CF_COK, do_lastcolumn, "left", 0, CF_COK, do_left, "leftedge", 1, CF_COK, do_windowparm, "map", 2, CF_COK, do_map, "margin", 1, CF_COK, do_margin, "menuon", 0, 0, do_menuon, "menuoff", 0, 0, do_menuoff, "menuadd", 3, 0, do_menuadd, "menudel", 2, 0, do_menudel, "menudelhdr", 1, 0, do_menudelhdr, "menuclear", 0, 0, do_menuclear, "newfile", 1, 0, do_edit, /* checks com name for mode */ "newwindow", 0, 0, do_newwindow, "next", 0, 0, do_find, "nextr", 0, 0, do_findr, "pagedown", 0, 0, do_page, "pageset", 1, 0, do_page, "pageup", 0, 0, do_page, "prev", 0, 0, do_find, "prevr", 0, 0, do_findr, "quit", 0, 0, do_quit, "recall", 0, CF_COK, do_recall, "ref", 0, 0, do_refs, "reformat", 0, 0, do_reformat, "remeol", 0, CF_COK, do_remeol, "repeat", 2, CF_COK, do_repeat, "repstr", 1, CF_COK, do_findstr, "resettoggle", 1, CF_COK, do_toggle, "resize", 2, 0, do_resize, "return", 0, CF_COK, do_return, /* special meaning in command line mode */ "right", 0, CF_COK, do_right, "saveas", 1, CF_COK, do_saveas, "savemap", 1, CF_COK, do_savemap, /* checks com name for mode */ "saveold", 0, CF_COK, do_save, "savesmap", 1, CF_COK, do_savemap, "savetabs", 1, CF_COK, do_savetabs, "scanf", 1, CF_COK, do_scanf, "screenbottom", 0, 0, do_screenbottom, "screentop", 0, 0, do_screentop, "scrollup", 0, 0, do_scrollup, "scrolldown", 0, 0, do_scrolldown, "settoggle", 1, CF_COK, do_toggle, "source", 1, CF_COK, do_source, "split", 0, 0, do_split, "tab", 0, CF_COK, do_tab, "tabstop", 1, CF_COK, do_tabstop, "tlate", 1, CF_COK, do_tlate, "tmpheight", 1, CF_COK, do_windowparm, "tmpwidth", 1, CF_COK, do_windowparm, "toggle", 1, CF_COK, do_toggle, "tomouse", 0, 0, do_tomouse, "top", 0, 0, do_top, "topedge", 1, CF_COK, do_windowparm, "unblock", 0, 0, do_block, "unmap", 1, CF_COK, do_unmap, "up", 0, 0, do_up, "while", 2, CF_COK, do_if, "width", 1, CF_COK, do_windowparm, "wleft", 0, CF_COK, do_wleft, "wordwrap", 1, CF_COK, do_wordwrap, "wright", 0, CF_COK, do_wright, NULL, 0, 0, NULL }; init_command() { register short hi; register COMM *comm; hi = sizeof(Comm)/sizeof(Comm[0]) - 2; comm = Comm + hi; while (hi >= 0) { hindex[comm->name[0] - 'a'] = hi; --hi; --comm; } } do_command(str) char *str; { register char *arg; char quoted; register short i, j; static int level; if (++level > 20) { title("Recursion Too Deep!"); --level; return(0); } 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] += 'a' - 'A'; } if (arg[0] >= 'a' && arg[0] <= 'z') { register COMM *comm = &Comm[hindex[arg[0]-'a']]; for (; comm->name && comm->name[0] == arg[0]; ++comm) { if (strcmp(arg, comm->name) == 0) { av[0] = (ubyte *)comm->name; for (j = 1; j <= comm->args; ++j) { av[j] = (ubyte *)breakout(&str, "ed); if (!av[j]) { title("Bad argument"); --level; return(0); } if (av[j][0] == '$') av[j] = (ubyte *)String; } if ((comm->flags & CF_COK) || !Comlinemode) { if (comm->flags & CF_PAR) { if (Partial) free(Partial); Partial = (char *)malloc(strlen(str)+1); strcpy(Partial, str); str += strlen(str); /* skip string */ } (*comm->func)(-1); } if (Abortcommand) goto fail; goto loop; } } } /* Command not found, check for macro */ { char *str; int ret; if ((str = keyspectomacro(arg)) || (str = menutomacro(arg))) { str = (char *)strcpy(malloc(strlen(str)+1), str); ret = do_command(str); free(str); if (ret) goto loop; goto fail; } } title("Unknown Command"); fail: --level; return(0); loop: ; } --level; return(1); } do_source() { char buf[256]; long xfi; register char *str; if (xfi = xfopen(av[1], "r", 512)) { while (xfgets(xfi, buf, 256) >= 0) { if (buf[0] == '#') continue; for (str = buf; *str; ++str) { if (*str == 9) *str = ' '; } do_command(buf); } xfclose(xfi); } else { if (av[0]) title("File not found"); } } do_quit() { extern char Quitflag; Quitflag = 1; } do_execute() { Execute(av[1], 0, 0); } /* * 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() { register ubyte *ptr = av[1]; register unsigned long n; char buf1[256]; char buf2[256]; breakreset(); 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); if (do_command(buf2) == 0 || breakcheck()) { Abortcommand = 1; break; } --n; } } char * breakout(ptr, quoted) register char **ptr; char *quoted; { register char *str = *ptr; register char *base = str; *quoted = 0; while (*str == ' ') ++str; if (!*str) return(NULL); if (*str == '\'' || *str == ')') { if (str[1]) { *quoted = 1; base = str + 1; if (str[2]) ++str; *str = '\0'; *ptr = str; return(base); } return(NULL); } if (*str == '`' || *str == '(') { short count = 1; char opc = *str; char clc = (opc == '(') ? ')' : '\''; base = ++str; while (*str && count) { if (*str == opc) ++count; if (*str == clc) --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 'filereq.c'" '(1746 characters)' if test -f 'filereq.c' then echo shar: "will not over-write existing file 'filereq.c'" else cat << \!Funky!Stuff! > 'filereq.c' /* * ARP interface (ARPLOAD, ARPSAVE) */ #include "defs.h" void do_arpload() { char file[64]; char dir[64]; strcpy(file, Ep->Name); dir[0] = 0; if (arpreq("NEWFILE", file, dir, NULL)) { fixfile(file,dir); av[0] = (ubyte *)"n"; av[1] = (ubyte *)file; do_edit(); } } void do_arpsave() { char file[64]; char dir[64]; strcpy(file, Ep->Name); dir[0] = 0; if (arpreq("SAVEAS", file, dir, NULL)) { fixfile(file,dir); av[1] = (ubyte *)file; do_saveas(); } } fixfile(file,dir) char *file,*dir; { register char *ptr; register short hasdev = 0; register short len = strlen(dir); for (ptr = file; *ptr; ++ptr) { if (ptr[0] == ':') hasdev = 1; } if (!hasdev) { movmem(file,file+len,strlen(file)+1); movmem(dir,file,len); } } #asm ; arpreq(hail,file,dir,window) FAR DATA FAR CODE public _arpreq public _LVOOldOpenLibrary public _LVOCloseLibrary public _SysBase _LVOFileRequest equ -294 arp_name_text dc.b 'arp.library',0 fs ds.l 1 ;hailing text ds.l 1 ;file name ds.l 1 ;directory ds.l 1 ;window requesting ds.w 1 ;LONG Align, idiots! set to 0 ds.l 1 ;func for wildcards ds.l 1 ;func to call w/intuimessages _arpreq: lea.l fs,A0 movem.l 4(sp),D0-D3 ;setup fields movem.l D0-D3,(A0) clr.w fs+16 move.l _SysBase,A6 lea.l arp_name_text,a1 ;open library jsr _LVOOldOpenLibrary(a6) tst.l d0 beq.s done move.l d0,a6 lea.l fs,a0 jsr _LVOFileRequest(A6) ;call requestor move.l D0,-(sp) ;return value move.l A6,A1 ;CloseLibrary(arpbase) move.l _SysBase,A6 jsr _LVOCloseLibrary(A6) move.l (sp)+,D0 ;return value done rts #endasm !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'globals.c'" '(912 characters)' if test -f 'globals.c' then echo shar: "will not over-write existing file 'globals.c'" else cat << \!Funky!Stuff! > 'globals.c' /* * GLOBALS.C * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved */ #include "defs.h" ED *Ep; /* Current Window */ ED *Base; /* Doubly linked list of Files */ char Nsu; /* Used in formatter to disable screen updates */ char Msgchk; /* Force message queue check for break */ ubyte CtlC; /* Keycode for 'c' */ char Savetabs; /* SaveTabs mode? */ char memoryfail; /* out of memory flag */ ubyte Current[256]; /* Current Line buffer and length */ ubyte Space[32] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32 }; short Clen; char *Partial; /* Partial command line when executing ESCIMM */ char *String; /* String Capture variable */ char Comlinemode; char Abortcommand; long BSline = -1; long BEline = -1; short BSchar; short BEchar; ED *BEp; long Dirlock; /* base directory lock */ !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'keyboard.c'" '(14427 characters)' if test -f 'keyboard.c' then echo shar: "will not over-write existing file 'keyboard.c'" else cat << \!Funky!Stuff! > 'keyboard.c' /* * KEYBOARD.C * * (C)Copyright 1987 by Matthew Dillon * * Handle keyboard related stuff such as keyboard mappings. Every time * a key is pressed, KEYCTL() is called with the code. KEYCTL() remembers * which qualifier keys are currently held down, and when a non-qualifier * key is pressed finds the hash entry for the key. If no hash entry * exists (e.g. you type a normal 'a') the default keymap is used. */ #include "defs.h" #include <stdio.h> extern ubyte *cqtoa(); typedef struct IOStdReq CIO; #define QUAL_SHIFT 0x01 #define QUAL_CTRL 0x02 #define QUAL_AMIGA 0x04 #define QUAL_ALT 0x08 #define QUAL_LMB 0x10 #define QUAL_MMB 0x20 #define QUAL_RMB 0x40 #define HASHSIZE 64 /* power of 2 */ #define HASHMASK (HASHSIZE-1) typedef struct _HASH { struct _HASH *next; /* next hash */ ubyte code; /* keycode */ ubyte mask; /* qual. mask */ ubyte qual; /* qual. comp */ ubyte stat; /* string static? */ char *str; /* command string */ } HASH; HASH *Hash[HASHSIZE]; struct Device *ConsoleDevice; ubyte ctoa[128]; ubyte cstoa[128]; void keyctl(im, code, qual) IMESS *im; register USHORT qual; { ubyte buf[256]; ubyte c2; short blen = 0; code &= 0xFF; if (im) { im->Qualifier &= ~IEQUALIFIER_REPEAT; blen = DeadKeyConvert(im, buf+1, 254, NULL); if (blen < 0) return; } c2 = 0; if (qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) c2 |= QUAL_SHIFT; if (qual & (IEQUALIFIER_CONTROL)) c2 |= QUAL_CTRL; if (qual & (IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND)) c2 |= QUAL_AMIGA; if (qual & (IEQUALIFIER_LALT|IEQUALIFIER_RALT)) c2 |= QUAL_ALT; if ((qual & IEQUALIFIER_CAPSLOCK) && blen == 1 && buf[1] >= 'a' && buf[1] <= 'z') c2 |= QUAL_SHIFT; if (qual & IEQUALIFIER_LEFTBUTTON) c2 |= QUAL_LMB; if (qual & IEQUALIFIER_MIDBUTTON) c2 |= QUAL_MMB; if (qual & (IEQUALIFIER_RBUTTON)) c2 |= QUAL_RMB; { register HASH *hash; for (hash = Hash[code&HASHMASK]; hash; hash = hash->next) { if (hash->code == code && (c2 & hash->mask) == hash->qual) break; } /* * Use hash entry only if not in command line mode, or if the * entry does not correspond to an alpha key. */ if (hash) { if (c2 || !Comlinemode || blen > 1 || !ctoa[code]) { strcpy(buf, hash->str); do_command(buf); return; } } } /* * No hash entry */ if (blen == 1) { buf[0] = '\''; buf[2] = 0; } else { buf[0] = '\`'; buf[blen+1] = '\''; } if (blen) do_command(buf); } dealloc_hash() { register HASH *hash, *hnext = NULL; register short i; for (i = 0; i < HASHSIZE; ++i) { for (hash = Hash[i]; hash; hash = hnext) { hnext = hash->next; if (!hash->stat) FreeMem(hash->str, strlen(hash->str)+1); FreeMem(hash, sizeof(HASH)); } Hash[i] = NULL; } } resethash() { register short i; CIO cio; static struct { char *from, *to; } defmap[] = { "esc", "esc", "c-esc", "recall", "return", "return insline up firstnb down", "enter", "return", "up", "up", "down", "down", "right", "right", "left", "left", "bs", "bs", "del", "del", "tab", "tab", "a-up", "scrollup", "a-down", "scrolldown", "a-r", "nextr", "a-u", "while cl (tlate -32 right)", "a-l", "while cu (tlate +32 right)", "s-up", "top", "s-down", "bottom", "s-right", "last", "s-left", "first", "s-tab", "backtab", "s-del", "deline", "s- ", "( )", /* shift space to space */ "c-1", "goto block", "c-c", "", /* break.. map to a nop */ "c-l", "wleft", "c-r", "wright", "c-i", "insertmode on", "c-o", "insertmode off", "c-j", "join", "c-s", "split first down", "c-del", "remeol", "c-n", "next", "c-p", "prev", "c-/", "escimm (find )", "c-]", "ref", "c-g", "escimm (goto )", "c-up", "pageup", "c-down", "pagedown", "c-q", "quit", "c-f", "reformat", "c-w", "wordwrap toggle", "f1", "escimm (insfile )", "f2", "escimm (newfile )", "f3", "escimm (newwindow newfile )", "f6", "saveold iconify", "f7", "escimm (bsave )", "f8", "saveold escimm (newfile )", "f9", "saveold", "f10", "saveold quit", "c-b", "block", "c-u", "unblock", "a-d", "bdelete", "a-c", "bcopy", "a-m", "bmove", "a-s", "bsource", "a-S", "unblock block block bsource", "L-lmb", "tomouse", /* left button */ "L-mmo", "tomouse", /* mouse move w/left held down */ "R-rmb", "iconify", /* right button */ NULL, NULL }; dealloc_hash(); OpenDevice("console.device", -1, &cio, 0); ConsoleDevice = cio.io_Device; keyboard_init(); for (i = 0; defmap[i].from; ++i) { ubyte code, qual; if (get_codequal(defmap[i].from, &code, &qual)) addhash(code, 1, 0xFF, qual, defmap[i].to); } } returnoveride(n) { HASH *hash; static ubyte *str; static int stat; for (hash = Hash[0x44&HASHMASK]; hash; hash = hash->next) { if (hash->code == 0x44 && hash->qual == 0) { if (n) { str = (ubyte *)hash->str; stat= hash->stat; hash->str = "return"; hash->stat = 1; } else { if (str == NULL) { remhash(0x44, -1, 0); } else { hash->str = (char *)str; hash->stat= stat; } } return(0); } } if (n) { addhash(0x44, 1, 0xFF, 0, "return"); str = NULL; } } addhash(code, stat, mask, qual, str) ubyte code, stat, mask, qual; ubyte *str; { register HASH **p, *hash; hash = *(p = &Hash[code&HASHMASK]); while (hash) { if (hash->code == code && hash->qual == qual && hash->mask == mask) { if (!hash->stat) FreeMem(hash->str, strlen(hash->str)+1); goto newstr; } hash = *(p = &hash->next); } *p = hash = (HASH *)AllocMem(sizeof(HASH), 0); hash->next = NULL; newstr: hash->code = code; hash->stat = stat; hash->mask = mask; hash->qual = qual; hash->str = (char *)str; if (!stat) /* if not static */ hash->str = (char *)strcpy(AllocMem(strlen(str)+1, 0), str); } remhash(code, mask, qual) ubyte code, mask, qual; { register HASH *hash, **p; hash = *(p = &Hash[code&HASHMASK]); while (hash) { if (hash->code == code && hash->qual == qual && hash->mask == mask) { if (!hash->stat) FreeMem(hash->str, strlen(hash->str)+1); *p = hash->next; FreeMem(hash, sizeof(HASH)); return(1); } hash = *(p = &hash->next); } return(0); } char * keyspectomacro(str) char *str; { HASH *hash; ubyte code, qual; if (get_codequal(str, &code, &qual)) { for (hash = Hash[code&HASHMASK]; hash; hash = hash->next) { if (hash->code == code) { if (hash->qual == (qual & hash->mask)) { return(hash->str); } } } } return(NULL); } do_map() { ubyte code, qual; if (get_codequal(av[1], &code, &qual)) { addhash(code, 0, 0xFF, qual, av[2]); } else { title("Unknown Key"); } } do_unmap() /* key */ { ubyte code, qual; if (get_codequal(av[1], &code, &qual)) { remhash(code, -1, qual); } else { title("Unknown Command"); } } do_clearmap() { resethash(); } /* * SAVEMAP file * SAVESMAP file */ do_savemap() { char sysalso; char err = 0; char buf[256]; long xfi; register int i; register HASH *hash; register ubyte *ptr; xfi = xfopen(av[1], "w", 512); if (xfi) { sysalso = av[0][4] == 's'; for (i = 0; i < HASHSIZE; ++i) { for (hash = Hash[i]; hash; hash = hash->next) { if (hash->stat == 0 || sysalso) { char soc = '('; char eoc = ')'; char ksoc = '('; char keoc = ')'; short len; for (ptr = (ubyte *)hash->str; *ptr; ++ptr) { if (*ptr == '(') break; if (*ptr == '\`') { soc = '\`'; eoc = '\''; break; } } len = strlen(ptr = cqtoa(hash->code, hash->qual)) - 1; if (ptr[len] == '(' || ptr[len] == ')') { ksoc = '\`'; keoc = '\''; } sprintf(buf, "map %c%s%c %c%s%c\n", ksoc, cqtoa(hash->code, hash->qual), keoc, soc, hash->str, eoc); xfwrite(xfi, buf, strlen(buf)); } } } xfclose(xfi); if (err) title ("Unable to Write"); else title ("OK"); } else { title("Unable to open file"); } } DeadKeyConvert(msg,buf,bufsize,keymap) struct IntuiMessage *msg; UBYTE *buf; int bufsize; struct KeyMap *keymap; { static struct InputEvent ievent = { NULL, IECLASS_RAWKEY }; if (msg->Class != RAWKEY) return(-2); ievent.ie_Code = msg->Code; ievent.ie_Qualifier = msg->Qualifier; ievent.ie_position.ie_addr = *((APTR *)msg->IAddress); return(RawKeyConvert(&ievent,buf,bufsize,keymap)); } /* * Nitty Gritty. * * keyboard_init: initialize for get_codequal() and cqtoa() * get_codequal: convert a qualifier-string combo to a keycode and qual. * cqtoa: convert a keycode and qual to a qual & string */ #define LN(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|d) long lname[] = { LN('e','s','c', 0 ), LN('f','1', 0 , 0 ), LN('f','2', 0 , 0 ), LN('f','3', 0 , 0 ), LN('f','4', 0 , 0 ), LN('f','5', 0 , 0 ), LN('f','6', 0 , 0 ), LN('f','7', 0 , 0 ), LN('f','8', 0 , 0 ), LN('f','9', 0 , 0 ), LN('f','1','0', 0 ), LN('d','e','l', 0 ), LN('b','a','c', 0 ), LN('b','s', 0 , 0 ), LN('t','a','b', 0 ), LN('h','e','l', 0 ), LN('r','e','t', 0 ), LN('u','p', 0 , 0 ), LN('d','o','w', 0 ), LN('r','i','g', 0 ), LN('l','e','f', 0 ), LN('e','n','t', 0 ), LN('n','k','-', 0 ), LN('n','k','.', 0 ), LN('n','k','0', 0 ), /* 24 */ LN('n','k','1', 0 ), LN('n','k','2', 0 ), LN('n','k','3', 0 ), LN('n','k','4', 0 ), LN('n','k','5', 0 ), LN('n','k','6', 0 ), LN('n','k','7', 0 ), LN('n','k','8', 0 ), LN('n','k','9', 0 ), LN('n','k','(', 0 ), LN('n','k',')', 0 ), LN('n','k','/', 0 ), /*34-36*/ LN('n','k','*', 0 ), LN('n','k','+', 0 ), LN('l','m','b',0xE8), LN('m','m','b',0xEA), LN('r','m','b',0xE9), LN('m','m','o',QMOVE), 0 }; /* * ESC: x1B * FUNCKEYS: x9B 30 7E to x9B 39 7E * DEL: x7E * BS: x08 * TAB: x09 * RETURN: x0D * HELP x9B 3F 7E * UP/D/L/R x9B 41/42/44/43 * NK0-9,-,.,ENTER * * Mouse buttons */ keyboard_init() { static struct InputEvent ievent = { NULL, IECLASS_RAWKEY }; ubyte buf[32]; register short i, q, len; lname[16] |= 0x44; lname[21] |= 0x43; for (i = 0; i < 128; ++i) { ievent.ie_Code = i; ievent.ie_Qualifier = 0; ievent.ie_position.ie_addr = NULL; len = RawKeyConvert(&ievent,buf,32,NULL); switch(len) { case 1: /* ESC/DEL/BS/TAB/NKx */ if (buf[0] > 32) ctoa[i] = buf[0]; switch(buf[0]) { case 0x1B: lname[ 0] |= i; break; case 0x7F: lname[11] |= i; break; case 0x09: lname[14] |= i; break; case 0x08: lname[12] |= i; lname[13] |= i; break; case '(': if (i > 0x3A) lname[34] |= i; break; case ')': if (i > 0x3A) lname[35] |= i; break; case '/': if (i > 0x3A) lname[36] |= i; break; case '*': if (i > 0x3A) lname[37] |= i; break; case '-': if (i > 0x3A) lname[22] |= i; break; case '+': if (i > 0x3A) lname[38] |= i; break; case '.': if (i > 0x3A) lname[23] |= i; break; default: if (i >= 0x0F && buf[0] >= '0' && buf[0] <= '9') lname[24+buf[0]-'0'] |= i; } break; case 2: /* cursor */ if (buf[0] == 0x9B) { switch(buf[1]) { case 0x41: lname[17] |= i; break; case 0x42: lname[18] |= i; break; case 0x43: lname[19] |= i; break; case 0x44: lname[20] |= i; break; } } break; case 3: /* function/help */ if (buf[0] == 0x9B && buf[2] == 0x7E) { if (buf[1] == 0x3F) lname[15] |= i; if (buf[1] >= 0x30 && buf[1] <= 0x39) lname[buf[1]-0x30+1] |= i; } break; } } for (i = 0; i < 128; ++i) { ievent.ie_Code = i; ievent.ie_Qualifier = IEQUALIFIER_LSHIFT; ievent.ie_position.ie_addr = NULL; len = RawKeyConvert(&ievent,buf,32,NULL); if (len == 1) cstoa[i] = buf[0]; } { ubyte code, qual; get_codequal("c", &code, &qual); CtlC = code; } } ubyte * cqtoa(code, qual) register int qual; { static ubyte buf[32]; register ubyte *ptr = buf; register int i; if (qual & QUAL_SHIFT) *ptr++ = 's'; if (qual & QUAL_CTRL) *ptr++ = 'c'; if (qual & QUAL_ALT) *ptr++ = 'a'; if (qual & QUAL_AMIGA) *ptr++ = 'A'; if (qual & QUAL_LMB) *ptr++ = 'L'; if (qual & QUAL_MMB) *ptr++ = 'M'; if (qual & QUAL_RMB) *ptr++ = 'R'; if (qual) *ptr++ = '-'; for (i = 0; i < sizeof(lname)/sizeof(lname[0]); ++i) { if ((lname[i]&0xFF) == code) { *ptr++ = (lname[i]>>24); *ptr++ = (lname[i]>>16); *ptr++ = (lname[i]>>8); break; } } if (i == sizeof(lname)/sizeof(lname[0])) *ptr++ = ctoa[code]; *ptr++ = 0; return(buf); } get_codequal(str, pcode, pqual) ubyte *pcode, *pqual; register ubyte *str; { register ubyte 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 (*str == 'A') qual |= QUAL_AMIGA; if (*str == 'L') qual |= QUAL_LMB; if (*str == 'M') qual |= QUAL_MMB; if (*str == 'R') qual |= QUAL_RMB; if (!qual) goto notqual; } if (*str) ++str; } notqual: if (strlen(str) != 1) { /* long name */ register short shift = 24; register long mult = 0; *pqual = qual; 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] & 0xFF; return(1); } } } else { /* single character keycap */ for (i = 0; i < sizeof(ctoa); ++i) { if (*str == ctoa[i]) { *pcode = i; *pqual = qual; return(1); } } for (i = 0; i < sizeof(cstoa); ++i) { if (*str == cstoa[i]) { *pcode = i; *pqual = qual|QUAL_SHIFT; return(1); } } } return(0); } !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'main.c'" '(15834 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 * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved. * */ #include "defs.h" #define IDCMPFLAGS CLOSEWINDOW|NEWSIZE|RAWKEY|MOUSEBUTTONS|ACTIVEWINDOW|MOUSEMOVE|MENUPICK extern WIN *OpenWindow(); extern char *menu_cmd(); NW Nw = { 0, 1, 0 , 0 , -1, -1, /* width, height filled in by program */ IDCMPFLAGS, ACTIVATE|WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH|RMBTRAP, NULL, NULL, (ubyte *)" WAIT ", NULL, NULL, 32, 32, -1, -1, WBENCHSCREEN }; short Sharedrefs; short Oldtlen = 999; /* Old Title Length */ struct MsgPort *Sharedport; DISKOBJ *Do; WBS *Wbs; 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 */ short Mx, My; ubyte *av[8]; char Quitflag; char Overide; char SizeOveride; char Wdisable = 1; /* Disable icon save */ char MShowTitle, MForceTitle; short Nwwidth, Nwheight, Nwtopedge, Nwleftedge, Nwtmpwidth, Nwtmpheight; int Enable_Abort; extern WIN *opensharedwindow(); extern IMESS *GetMsg(); static char *Ffile; main(mac, mav) char *mav[]; { register IMESS *im; /* intuition message */ char nf, ni; /* # files on command line */ char notdone; /* for endless loop */ char iawm = 0; /* overide mouse buttons */ char dontwait = 0; /* don't wait for a message */ short i; short Code; if (!openlibs(INTUITION_LIB|GRAPHICS_LIB)) exiterr("cannot open intuition or graphics library"); { SCR scr; GetScreenData(&scr, sizeof(scr), WBENCHSCREEN, NULL); Nw.Width = (scr.Width > 640) ? 640 : scr.Width; Nw.Height= scr.Height - ((scr.Height > 200) ? 40 : 1); } init_command(); Nwwidth = Nw.Width; /* Parameters for new windows */ Nwheight = Nw.Height; Nwtopedge = Nw.TopEdge; Nwleftedge = Nw.LeftEdge; Enable_Abort= 0; /* disable break */ String = (char *)malloc(1); /* initialize scanf variable */ *String = 0; if (mac == 0) { /* WORKBENCH STARTUP */ long oldlock; Wdisable = 0; /* allow icon save */ Wbs = (WBS *)mav; if (!openlibs(ICON_LIB)) exiterr("unable to open icon library"); oldlock = CurrentDir(Wbs->sm_ArgList[0].wa_Lock); /* Tool */ Do = GetDiskObject(Wbs->sm_ArgList[0].wa_Name); CurrentDir(oldlock); if (Do == NULL) exiterr("unable to get disk object"); mac = 99; } resethash(); if (Do) { ops(Do->do_ToolTypes, 1); nf = Wbs->sm_NumArgs - 1; Dirlock = Wbs->sm_ArgList[0].wa_Lock; } else { nf = ops(mav+1, 0); } for (ni = 0, i = 1; i < mac; ++i) { register char *str; register DISKOBJ *dso; long oldlock; if (Wbs) { if (i > nf) break; str = Wbs->sm_ArgList[i].wa_Name; oldlock = CurrentDir(Wbs->sm_ArgList[i].wa_Lock); if (dso = GetDiskObject(Wbs->sm_ArgList[i].wa_Name)) { ops(dso->do_ToolTypes, 1); FreeDiskObject(dso); } Dirlock = CurrentDir(oldlock); } else { str = mav[i]; if (*str == '-') continue; } do_newwindow(nf > 1, ni * 10); ++ni; av[0] = (ubyte *)"newfile"; av[1] = (ubyte *)str; do_edit(); MForceTitle = 1; window_title(); } if (nf == 0) /* no files to edit */ do_newwindow(nf > 1, ni * 10); mountrequest(0); av[0] = NULL; av[1] = (ubyte *)"s:.edrc"; do_source(); av[0] = NULL; av[1] = (ubyte *)((Ffile) ? Ffile : ".edrc"); do_source(); mountrequest(1); title("DME V1.29 \251Copyright 1988 Matthew Dillon, All Rights Reserved "); loop: if (!Ep->iconmode) text_cursor(1); for (notdone = 1; !Quitflag && notdone;) { char mmove = 0; short mqual; if (!Ep->iconmode) window_title(); if (dontwait) --dontwait; else WaitPort(Win->UserPort); /* * NOTE: due to operation of breakcheck(), the userport signal * may not be set even if there are messages pending. */ while (im = (IMESS *)GetMsg(Win->UserPort)) { Msgchk = 1; Abortcommand = 0; Code = im->Code; if (im->IDCMPWindow != Win) { Overide = 0; if (Comlinemode) escapecomlinemode(); text_sync(); MShowTitle = 0; if (!Ep->iconmode) window_title(); if (text_switch(im->IDCMPWindow) == 0) { ReplyMsg(im); continue; } } Mx = im->MouseX; My = im->MouseY; switch(im->Class) { case NEWSIZE: if (!Ep->iconmode) { if (Comlinemode) escapecomlinemode(); set_window_params(); if (!text_sync()) text_redisplay(); text_cursor(1); } break; case MOUSEBUTTONS: switch(Code) { case SELECTDOWN: case MENUDOWN: if (Ep->iconmode || iawm) { uniconify(); break; } ReportMouse(-1, Win); uniconify(); text_cursor(0); keyctl(NULL, im->Code|0x80, im->Qualifier); text_cursor(1); break; case SELECTUP: case MENUUP: ReportMouse(0, Win); break; } break; case RAWKEY: if ((im->Code & 0x80) == 0) { if (Ep->iconmode) { uniconify(); break; } text_cursor(0); keyctl(im, im->Code, im->Qualifier); text_cursor(1); } break; case MENUPICK: { register char *str = menu_cmd(im); if (str) { str = strcpy(malloc(strlen(str)+1), str); text_cursor(0); do_command(str); free(str); text_cursor(1); } } break; case CLOSEWINDOW: if (Comlinemode) escapecomlinemode(); text_sync(); notdone = 0; break; case ACTIVEWINDOW: if (!Ep->iconmode) iawm = 1; break; case MOUSEMOVE: mmove = 1; mqual = im->Qualifier; break; } if (im) ReplyMsg(im); if (notdone == 0 || Quitflag) { dontwait = 2; goto boom; } } iawm = 0; if (mmove) { uniconify(); mmove = 0; text_cursor(0); keyctl(NULL, QMOVE, mqual); text_cursor(1); } closesharedwindow(NULL); } boom: if (Ep->Modified && !Overide) { uniconify(); Overide = 1; title("*** File has been modified ***"); Quitflag = 0; goto loop; } SetWindowTitles(Win, "", -1); text_uninit(); /* uninitialize text portion */ closesharedwindow(Win); if (Base) { Quitflag = 0; Win = Ep->Win; /* make arbitrary other window act. */ Rp = Win->RPort; if (!Ep->iconmode) set_window_params(); text_load(); MShowTitle = 0; goto loop; } closesharedwindow(NULL); if (Do) FreeDiskObject(Do); closelibs(-1); dealloc_hash(); } do_iconify() { if (!Comlinemode) iconify(); } do_tomouse() { text_position((Mx-Xbase)/Xsize, (My-Ybase)/Ysize); } iconify() { if (!Ep->iconmode) { Ep->Winx = Win->LeftEdge; Ep->Winy = Win->TopEdge; Ep->Winwidth = Win->Width; Ep->Winheight = Win->Height; Nw.Height = 10; Nw.Width = 20 + 5*8 + strlen(Ep->Name)*8; Nw.LeftEdge= Ep->IWinx; Nw.TopEdge = Ep->IWiny; if (Nw.LeftEdge + Nw.Width > Win->WScreen->Width) Nw.LeftEdge = Win->WScreen->Width - Nw.Width; if (Nw.TopEdge + Nw.Height > Win->WScreen->Height) Nw.TopEdge = Win->WScreen->Height - Nw.Height; Nw.Title = Ep->Wtitle; Nw.Flags &= ~(WINDOWSIZING|WINDOWDEPTH); Nw.Flags |= BORDERLESS; sprintf(Ep->Wtitle, "%s %s ", Ep->Name, ((Ep->Modified) ? "(mod)":"")); closesharedwindow(Win); Win = Ep->Win = opensharedwindow(&Nw); Nw.Flags |= WINDOWSIZING|WINDOWDEPTH; Nw.Flags &= ~BORDERLESS; Rp = Win->RPort; } Ep->iconmode = 1; } uniconify() { if (Ep->iconmode) { Ep->IWinx = Win->LeftEdge; Ep->IWiny = Win->TopEdge; closesharedwindow(Win); Nw.LeftEdge = Ep->Winx; Nw.TopEdge = Ep->Winy; Nw.Width = Ep->Winwidth; Nw.Height = Ep->Winheight; Nw.Title = Ep->Wtitle; Win = Ep->Win = opensharedwindow(&Nw); menu_strip(Win); Rp = Win->RPort; set_window_params(); if (!text_sync()) text_redisplay(); text_cursor(1); MShowTitle = 0; window_title(); } Ep->iconmode = 0; } do_newwindow(makesmall, deltaheight) { WIN *win; int msadj = makesmall; if (SizeOveride) msadj = 0; if (Ep) text_sync(); Nw.Title = (ubyte *)" OK "; Nw.Width = (Nwtmpwidth) ? Nwtmpwidth : Nwwidth; Nw.Height= (Nwtmpheight)? Nwtmpheight: Nwheight; Nwtmpwidth = Nwtmpheight = 0; Nw.LeftEdge = Nwleftedge; Nw.TopEdge = Nwtopedge; if (msadj > 0) { /* deltaheight must be valid */ Nw.TopEdge = deltaheight + 16; Nw.LeftEdge= 10*8; Nw.Flags &= ~ACTIVATE; Nw.Width = 40*8; Nw.Height= 10*8; if (Nw.TopEdge + Nw.Height > 200) Nw.TopEdge = deltaheight = 200 - Nw.Height; } win = opensharedwindow(&Nw); menu_strip(win); Nw.Flags |= ACTIVATE; if (win) { Win = win; /* set new window */ Rp = Win->RPort; set_window_params(); text_init(); /* initialize */ text_load(); if (makesmall != -1) /* if deltaheight valid */ Ep->IWiny = deltaheight + 16; } } WIN * TOpenWindow(nw) NW *nw; { WIN *win; while ((win = OpenWindow(nw)) == NULL) { if (nw->Width < 50 || nw->Height < 50) break; nw->Width -= 10; nw->Height-= 10; } return(win); } WIN * opensharedwindow(nw) NW *nw; { WIN *win; if (Sharedport) nw->IDCMPFlags = NULL; else nw->IDCMPFlags = IDCMPFLAGS; win = TOpenWindow(nw); if (win) { if (Sharedport) { win->UserPort = Sharedport; ModifyIDCMP(win, IDCMPFLAGS); } else { Sharedport = win->UserPort; } ++Sharedrefs; } return(win); } closesharedwindow(win) WIN *win; { static WIN *wunlink; register IMESS *im; char notoktoclosenow = 0; if (win) { SetWindowTitles(win, "", -1); ClearMenuStrip(win); Forbid(); win->UserPort = NULL; ModifyIDCMP(win, GADGETUP); /* NEVER occurs */ notoktoclosenow = 1; Permit(); if (notoktoclosenow) { win->UserData = (char *)wunlink; wunlink = win; } else { CloseWindow(win); } --Sharedrefs; } else { if (Sharedrefs == 0 && Sharedport) { DeletePort(Sharedport); Sharedport = NULL; } for (win = wunlink; win; win = wunlink) { wunlink = (WIN *)win->UserData; CloseWindow(win); } wunlink = NULL; } } 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 = (ubyte *)text; pos->LeftEdge = AUTOLEFTEDGE; pos->TopEdge = AUTOTOPEDGE; pos->IText = (ubyte *)"OK"; neg->LeftEdge = AUTOLEFTEDGE; neg->TopEdge = AUTOTOPEDGE; neg->IText = (ubyte *)"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); } title(buf) char *buf; { SetWindowTitles(Win, buf, -1); Oldtlen = 999; MShowTitle = 3; } window_title() { register int len, maxlen; if (memoryfail) { title(" -- NO MEMORY -- "); memoryfail = 0; text_redisplay(); } if (MForceTitle) { MShowTitle = 0; MForceTitle = 0; } if (MShowTitle) { --MShowTitle; return(0); } { register char *mod; mod = (Ep->Modified) ? " (modified)" : " "; sprintf(Ep->Wtitle, "%3ld/%-3ld %3ld %s%s ", text_lineno(), text_lines(), text_colno()+1, text_name(), mod); if (!text_imode()) strcat(Ep->Wtitle, "Ovr "); len = strlen(Ep->Wtitle); if (len < Columns && Columns < 128) { bset(Ep->Wtitle+len, Columns - len + 1, ' '); Ep->Wtitle[Columns + 1] = 0; } Win->Title = Ep->Wtitle; SetAPen(Rp, 0); SetBPen(Rp, 1); Move(Rp, 30, Win->RPort->Font->tf_Baseline+1); maxlen = (Win->Width-96)/Win->RPort->Font->tf_XSize; if (maxlen < 0) maxlen = 0; if (len > maxlen) len = Oldtlen = maxlen; if (Oldtlen > maxlen) Oldtlen = maxlen; Text(Rp, Ep->Wtitle, len); /* No flash */ while (Oldtlen - len >= (int)sizeof(Space)) { Text(Rp, Space, sizeof(Space)); Oldtlen -= sizeof(Space); } if (Oldtlen - len > 0) Text(Rp, Space, Oldtlen - len); Oldtlen = len; /* Oldtlen might have been < */ SetAPen(Rp, 1); SetBPen(Rp, 0); } } 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; { if (Output()) { Write(Output(),str,strlen(str)); Write(Output(),"\n",1); } exit(1); } /* * Check break by scanning pending messages in the I stream for a ^C. * Msgchk forces a check, else the check is only made if the signal is * set in the I stream (the signal is reset). */ breakcheck() { IMESS *im; register struct List *list = &Win->UserPort->mp_MsgList; if (Msgchk || (SetSignal(0,0) & (1<<Win->UserPort->mp_SigBit))) { Msgchk = 0; SetSignal(0,1<<Win->UserPort->mp_SigBit); im = (IMESS *)list->lh_Head; Forbid(); for (; im != &list->lh_Tail; im = (IMESS *)im->ExecMessage.mn_Node.ln_Succ) { if (im->Class == RAWKEY && (im->Qualifier & 0xFB) == 0x08 && im->Code == CtlC) { Permit(); SetSignal(SIGBREAKF_CTRL_C,SIGBREAKF_CTRL_C); return(1); } } Permit(); } return(0); } breakreset() { SetSignal(0, SIGBREAKF_CTRL_C); } /* * leftedge n * topedge n * width n * height n * tmpwidth n * tmpheight n */ void do_windowparm() { int val = atoi(av[1]); if (av[0][0] == 't' && av[0][1] == 'm') { /* tmpwidth/tmpheight */ if (av[0][3] == 'w') Nwtmpwidth = val; if (av[0][3] == 'h') Nwtmpheight= val; return; } switch(av[0][0]) { case 'l': Nwleftedge = val; break; case 't': Nwtopedge = val; break; case 'w': Nwwidth = val; break; case 'h': Nwheight = val; break; } } /* * resize cols rows */ do_resize() { int cols = atoi(av[1]); int rows = atoi(av[2]); short width = (cols*Win->RPort->Font->tf_XSize) + Win->BorderLeft + Win->BorderRight; short height= (rows*Win->RPort->Font->tf_YSize) + Win->BorderTop + Win->BorderBottom; if (width < 16 || height < 16 || width > Win->WScreen->Width - Win->LeftEdge || height > Win->WScreen->Height - Win->TopEdge) { title ("window too big (try moving to upper left corner and retrying)"); return(0); } SizeWindow(Win, width - Win->Width, height - Win->Height); Delay(50*2); /* wait 2 seconds */ } ops(av, iswb) register char *av[]; { register short nonops; register short i; register long val; register char *str; for (i = nonops = 0; str = av[i]; ++i) { if (iswb) { if (strncmp(str, "ARG", 3) == 0) { while (*str && *str != '-') ++str; } } if (*str == '-') { val = atoi(str+2); switch(str[1]) { case 'f': Ffile = str+2; break; case 'b': SizeOveride = 1; break; case 't': Nwtopedge = val; break; case 'l': Nwleftedge= val; break; case 'w': SizeOveride = 1; Nwwidth = val; break; case 'h': SizeOveride = 1; Nwheight = val; break; } } else { ++nonops; } } return(nonops); } !Funky!Stuff! fi # end of overwriting check exit 0 # End of shell archive
ain@j.cc.purdue.edu (Patrick White) (01/13/88)
Program Name: DME Submitted By: dillon%cory.Berkeley.EDU@ucbvax.berkeley.edu (Matt Dillon) Summary: DME is Matt Dillon's editor. Features multiple windows and key mapping among other things... read the docs (part 2 of the binary posting) as they explain it much better than I can in a line or two. Poster Boy: Pat White (ain@j.cc.purdue.edu) Untested. NOTES: Binary version posted on comp.binaries.amiga. Docs posted with binary version (part 2). Didn't test it. -- Pat White (co-moderator comp.sources/binaries.amiga) UUCP: j.cc.purdue.edu!ain BITNET: PATWHITE@PURCCVM PHONE: (317) 743-8421 U.S. Mail: 320 Brown St. apt. 406, West Lafayette, IN 47906 ======================================== #! /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: # menu.c # refs.c # subs.c # text1.c # text2.c # This archive created: Tue Jan 12 02:23:36 1988 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'menu.c'" '(5316 characters)' if test -f 'menu.c' then echo shar: "will not over-write existing file 'menu.c'" else cat << \!Funky!Stuff! > 'menu.c' /* * MENU.C * * Menu routines... made to take up as little space as possible, and * thus uses many tricks which you should watch out for. */ #include "defs.h" typedef struct { ITEM item; char *com; } XITEM; short Menuoff; short DoMenuoff; MENU *Menu; extern XITEM *ItemAddress(); menu_strip(win) WIN *win; { if (!Menuoff && Menu) { SetMenuStrip(win,Menu); Forbid(); win->Flags &= ~RMBTRAP; Permit(); } } menu_off() { register ED *ed; if (Menuoff == 0) { for (ed = Base; ed; ed = ed->next) { ClearMenuStrip(ed->Win); Forbid(); ed->Win->Flags |= RMBTRAP; Permit(); } } ++Menuoff; } menu_on() { register ED *ed; if (Menu && Menuoff == 1) { fixmenu(); for (ed = Base; ed; ed = ed->next) { SetMenuStrip(ed->Win,Menu); Forbid(); ed->Win->Flags &= ~RMBTRAP; Permit(); } } --Menuoff; } do_menuoff() { menu_off(); ++DoMenuoff; } do_menuon() { if (DoMenuoff) { --DoMenuoff; menu_on(); } } char * menutomacro(str) char *str; { char header[64]; char itembuf[64]; register short i; register char *ptr; register MENU *menu; register ITEM *item; for (i = 0; str[i] && str[i] != '-'; ++i); if (str[i] == '-') { strncpy(header, str, i); header[i] = 0; strcpy(itembuf, str + i + 1); for (menu = Menu; menu; menu = menu->NextMenu) { if (ncstrcmp(header, menu->MenuName) == 0) { for (item = menu->FirstItem; item; item = item->NextItem) { ptr = (char *)((ITEXT *)item->ItemFill)->IText; if (ncstrcmp(itembuf, ptr) == 0) { ptr = ((XITEM *)item)->com; goto done; } } } } } ptr = NULL; done: return(ptr); } char * menu_cmd(im) IMESS *im; { XITEM *item; char *ptr; if (item = ItemAddress(Menu, im->Code)) return(item->com); return(NULL); } fixmenu() { register MENU *menu; register ITEM *item; register ITEXT *it; register int row, col, maxc, scr; col = 0; for (menu = Menu; menu; menu = menu->NextMenu) { maxc = strlen(menu->MenuName); row = 0; for (item = menu->FirstItem; item; item = item->NextItem) { it = (ITEXT *)item->ItemFill; item->TopEdge = row; scr = strlen(((ITEXT *)item->ItemFill)->IText); if (scr > maxc) maxc = scr; item->Height = 10; row += item->Height; } maxc = (maxc * 8) + 16; for (item = menu->FirstItem; item; item = item->NextItem) item->Width = maxc; menu->Width = maxc; menu->LeftEdge = col; menu->Height = row; col += maxc; } } /* * menuclear * menuadd header item command * menudel header item * menudelhdr header */ do_menuclear() { menu_off(); while (Menu) { av[1] = (ubyte *)Menu->MenuName; do_menudelhdr(); } menu_on(); } do_menuadd() { register MENU *menu, **mpr; register ITEM *item, **ipr; register ITEXT *it; menu_off(); mpr = &Menu; for (menu = *mpr; menu; menu = *mpr) { if (strcmp(av[1], menu->MenuName) == 0) { ipr = &menu->FirstItem; for (item = *ipr; item; item = *ipr) { if (strcmp(av[2], ((ITEXT *)item->ItemFill)->IText) == 0) goto newname; ipr = &item->NextItem; } goto newitem; } mpr = &menu->NextMenu; } newmenu: /* create new menu */ menu = malloc(sizeof(MENU)); bzero(menu, sizeof(MENU)); menu->NextMenu = *mpr; *mpr = menu; menu->Flags = MENUENABLED; menu->MenuName = malloc(strlen(av[1])+1); strcpy(menu->MenuName, av[1]); ipr = &menu->FirstItem; *ipr = NULL; newitem: /* create new item */ it = malloc(sizeof(ITEXT)); bzero(it, sizeof(ITEXT)); it->BackPen = 1; it->DrawMode = JAM2; it->IText = malloc(strlen(av[2])+1); strcpy(it->IText, av[2]); item = malloc(sizeof(XITEM)); bzero(item, sizeof(XITEM)); item->NextItem = *ipr; *ipr = item; item->ItemFill = (APTR)it; item->Flags = ITEMTEXT|ITEMENABLED|HIGHCOMP; newname: /* create new name */ if (((XITEM *)item)->com) free(((XITEM *)item)->com); ((XITEM *)item)->com = malloc(strlen(av[3])+1); strcpy(((XITEM *)item)->com, av[3]); menu_on(); } do_menudelhdr() { register MENU *menu; register MENU **mpr; menu_off(); mpr = &Menu; for (menu = *mpr; menu; menu = *mpr) { if (strcmp(av[1], menu->MenuName) == 0) { if (menu->FirstItem) { while (menu->FirstItem) { av[2] = ((ITEXT *)menu->FirstItem->ItemFill)->IText; if (do_menudel()) break; } break; } *mpr = menu->NextMenu; free(menu->MenuName); free(menu); break; } mpr = &menu->NextMenu; } menu_on(); } do_menudel() { register MENU *menu; register ITEM *item, **ipr; register ITEXT *it; short ret = 0; menu_off(); for (menu = Menu; menu; menu = menu->NextMenu) { if (strcmp(av[1], menu->MenuName) == 0) { ipr = &menu->FirstItem; for (item = *ipr; item; item = *ipr) { it = (ITEXT *)item->ItemFill; if (strcmp(av[2], it->IText) == 0) { *ipr = item->NextItem; free(it->IText); free(it); free(((XITEM *)item)->com); free(item); if (!menu->FirstItem) { do_menudelhdr(); ret = 1; } menu_on(); return(ret); } ipr = &item->NextItem; } } } menu_on(); return(ret); } !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'refs.c'" '(3782 characters)' if test -f 'refs.c' then echo shar: "will not over-write existing file 'refs.c'" else cat << \!Funky!Stuff! > 'refs.c' /* * REFS.C * * Bringup a cross reference editor window. The file S:dme.refs and * dme.refs in the current directory are searched for the reference. * If found, the file specified is searched and the segment specified * loaded as a new file in a new window. */ #include "defs.h" #include <stdio.h> extern char *breakout(); void do_refs() { char str[256]; char *srch; char *file; char *estr; long len; int bcnt = 10; register short i, j; short slen, elen; long xfi, xfj; short tmph, tmpw; for (i = Ep->Column; Current[i] == ' '; ++i); /* skip spaces */ for (j = i ; ; ++j) { if (Current[j] && Current[j] != ' ') continue; break; } j -= i; if (j > 63) j = 63; bmov(Current+i, str, j); str[j] = 0; title("search .refs"); if (!searchref("s:dme.refs", str,&srch,&file,&len,&estr) && !searchref("dme.refs", str,&srch,&file,&len,&estr) && !searchref("df0:s/dme.refs",str,&srch,&file,&len,&estr) && !searchref("df1:s/dme.refs",str,&srch,&file,&len,&estr) && !searchref("df2:s/dme.refs",str,&srch,&file,&len,&estr) && !searchref("df3:s/dme.refs",str,&srch,&file,&len,&estr) ) { title("Reference not found"); return; } title("search file"); slen = strlen(srch); if (estr) elen = strlen(estr); if (xfi = xfopen(file, "r", 4096)) { short lenstr; while ((lenstr = xefgets(xfi, str, 256)) >= 0) { if (strncmp(str, srch, slen) == 0) { title("load.."); if (xfj = xfopen("t:dme_ref", "w", 1024)) { tmph = 0; tmpw = 0; do { if (lenstr > tmpw) tmpw = strlen(str); ++tmph; xfwrite(xfj, str, strlen(str)); xfwrite(xfj, "\n", 1); if (estr && strncmp(str,estr,elen) == 0) break; --len; } while ((lenstr=xefgets(xfi, str, 256)) >= 0 && len); xfclose(xfj); if (tmph > 23) tmph = 23; if (tmpw > 80) tmpw = 80; sprintf(str, "tmpheight %ld tmpwidth %ld newwindow newfile t:dme_ref", (tmph<<3)+16, (tmpw<<3)+16); do_command(str); unlink("t:dme_ref"); } else { title("Unable to open t:dme_ref for write"); } xfclose(xfi); free(srch); free(file); if (estr) free(estr); return; } if (--bcnt == 0) { /* check break every so so */ bcnt = 50; if (breakcheck()) break; } } xfclose(xfi); title("Search failed"); } else { title("Unable to open sub document"); } free(srch); free(file); if (estr) free(estr); } /* * Reference file format: * * `key' `lines' `file' `searchstring' * * where `lines' can be a string instead ... like a read-until, otherwise * the number of lines to read from the reference. */ searchref(file, find, psstr, pfile, plines, pestr) char *file, *find; char **psstr, **pfile, **pestr; long *plines; { long xfi; char buf[256]; char *ptr, *base; char quoted; mountrequest(0); if (xfi = xfopen(file, "r", 4096)) { while (xefgets(xfi,(base=buf), 256) >= 0) { if (buf[0]=='#') continue; ptr = breakout(&base, "ed); if (ptr && *ptr && strncmp(ptr, find, strlen(ptr)) == 0) { if (ptr = breakout(&base, "ed)) { *pestr = NULL; *plines = atoi(ptr); if (*plines == 0) { *pestr = (char *)malloc(strlen(ptr)+1); strcpy(*pestr, ptr); } if (ptr = breakout(&base, "ed)) { *pfile = (char *)malloc(strlen(ptr)+1); strcpy(*pfile, ptr); if (ptr = breakout(&base, "ed)) { *psstr = (char *)malloc(strlen(ptr)+1); strcpy(*psstr, ptr); xfclose(xfi); mountrequest(1); return(1); } free(*pfile); } if (pestr) free (*pestr); } } } xfclose(xfi); } mountrequest(1); return(0); } !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'subs.c'" '(4150 characters)' if test -f 'subs.c' then echo shar: "will not over-write existing file 'subs.c'" else cat << \!Funky!Stuff! > 'subs.c' /* * SUBS.C * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved * * Subroutines. */ #include "defs.h" /* * Create DME's text icon. */ makemygadget(gad) register struct Gadget *gad; { static unsigned long ga[] = { 0xFFFFFFFF, /* 32 pixels across */ 0x80FDCBFD, 0xFFFDDFFD, 0x80000001, 0x80DFDDDF, 0x80000001, 0xBC0EF00B, 0x80000001, 0xBFC00CDD, 0x80000001, 0xA00DF00F, 0x80000001, 0x80000001, 0x80000001, 0x80FDCBFD, 0xFFFDDFFD, 0x80000001, 0x80DFDDDF, 0x80000001, 0xBC0EF00B, 0x80000001, 0xBFC00CDD, 0x80000001, 0xA00DF00F, 0x80000001, 0xFFFFFFFF }; static struct Image image = { 0, 0, 20, sizeof(ga)/4/2, 2, (unsigned short *)ga, 3, 0, NULL }; bzero(gad, sizeof(struct Gadget)); gad->Width = 20; gad->Height = sizeof(ga)/4/2 + 1; gad->Flags = GADGIMAGE|GADGHCOMP; gad->GadgetType = BOOLGADGET; gad->Activation = RELVERIFY|GADGIMMEDIATE; gad->GadgetRender = (APTR)ℑ } /* * return index of first non space. Returns 0 if no spaces found. */ firstns(str) register char *str; { register short i; for (i = 0; str[i] && str[i] == ' '; ++i); if (str[i] == 0) i = 0; return(i); } /* * Return index of last non-space, 0 if no spaces. */ lastns(str) register char *str; { register short i; for (i = strlen(str) - 1; i > 0 && str[i] == ' '; --i); if (i < 0) i = 0; return(i); } /* * Return length of word under cursor */ wordlen(str) register char *str; { register short i; for (i = 0; *str && *str != ' '; ++i, ++str); return(i); } /* * Find the path from some root device to a specific filename (src), and * stick the result in (dest). If unable to backtrace along directories, * simply copy (src) into (dest) * * Returns (1) if able to backtrace, (0) if not. */ getpath(src, dest) char *src, *dest; { register long flock, pflock; register short len, total; register FIB *fib = (FIB *)malloc(sizeof(FIB)); char c; dest[0] = 0; total = 1; flock = Lock(src, ACCESS_READ); if (flock == NULL) { /* missing file? */ for (len = strlen(src); len >= 0; --len) { if (src[len] == '/') { --len; break; } if (src[len] == ':') break; } if (c = src[len + 1]) { strcpy(dest, src+len+2); total = strlen(dest)+1; } src[len + 1] = 0; flock = Lock(src, ACCESS_READ); src[len + 1] = c; } if (flock) { do { pflock = ParentDir(flock); if (Examine(flock, fib) == 0) fib->fib_FileName[0] = 0; if (fib->fib_FileName[0] == 0) strcpy(fib->fib_FileName, "ram"); len = strlen(fib->fib_FileName); bmov(dest, dest + len + 1, total); dest[len] = (pflock) ? '/' : ':'; bmov(fib->fib_FileName, dest, len); total += len + 1; UnLock(flock); flock = pflock; } while(pflock); len = strlen(dest) - 1; if (dest[len] == '/') dest[len] = 0; return(1); } strcpy(dest, src); return(0); } /* * Allocation routines and other shortcuts */ ubyte * allocb(bytes) { return(AllocMem(bytes, MEMF_CLEAR|MEMF_PUBLIC)); } ubyte * allocl(lwords) { return(AllocMem(lwords<<2, MEMF_CLEAR|MEMF_PUBLIC)); } bmovl(s,d,n) char *s,*d; { bmov(s,d,n<<2); } /* * Remove tabs in a buffer */ detab(ibuf, obuf, maxlen) register char *ibuf, *obuf; { register short i, j; maxlen -= 2; for (i = j = 0; ibuf[i] && j < maxlen; ++i) { if (ibuf[i] == 9) { do { obuf[j++] = ' '; } while ((j & 7) && j < maxlen); } else { obuf[j++] = ibuf[i]; } } while (j && obuf[j-1] == ' ') --j; obuf[j] = 0; return(j); } xefgets(xfi, buf, max) char *buf; long xfi; { char ebuf[256]; if (xfgets(xfi, ebuf, max) >= 0) return(detab(ebuf, buf, max)); return(-1); } ncstrcmp(s1, s2) register ubyte *s1, *s2; { register ubyte c1, c2; for (;;) { c1 = *s1; c2 = *s2; if (c1 >= 'A' && c1 <= 'Z') c1 |= 0x20; if (c2 >= 'A' && c2 <= 'Z') c2 |= 0x20; if (c1 != c2) break; if ((c1|c2) == 0) return(0); ++s1; ++s2; } if (c1 < c2) return(-1); if (c1 > c2) return(1); } !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'text1.c'" '(16337 characters)' if test -f 'text1.c' then echo shar: "will not over-write existing file 'text1.c'" else cat << \!Funky!Stuff! > 'text1.c' /* * TEXT1.C * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved */ #include "defs.h" #define nomemory() { memoryfail = 1; } char RecallBuf[256]; setpen(line) { register short pen = (Ep == BEp && line >= BSline && line <= BEline) ? 2 : 1; if (Comlinemode) pen = 1; if (pen != Rp->FgPen) SetAPen(Rp, pen); } text_init() { register ED *e; register ED *ep = Ep; text_switch(NULL); e = (ED *)allocb(sizeof(ED)); if (e == NULL) return(0); bzero(e, sizeof(ED)); e->Win = Win; if (ep) { e->Insertmode = ep->Insertmode; e->Tabstop = ep->Tabstop; e->Wordwrap = ep->Wordwrap; } else { e->Insertmode = 1; e->Tabstop = 4; } e->Lines = 1; e->Maxlines = 32; e->List = (ubyte **)allocl(e->Maxlines); e->List[0] = allocb(1); e->List[0][0] = Current[0] = Clen = 0; e->IWiny = 16; e->dirlock = (ep) ? ep->dirlock : Dirlock; llink(&Base, e); strcpy(e->Name, "unnamed"); Ep = e; text_cursor(1); return(1); } text_switch(win) WIN *win; { register ED *e; if (win) text_sync(); if (win) { for (e = Base; e; e = e->next) { if (e->Win == win) { Ep = e; Win = win; Rp = Win->RPort; text_load(); if (!Ep->iconmode) { set_window_params(); window_title(); } return(1); } } return(0); } } text_sync() { register ED *ep = Ep; char redraw = 0; short len; ubyte *ptr; for (len = strlen(Current) - 1; len >= 0 && Current[len] == ' '; --len) Current[len] = '\0'; Clen = len + 1; if (!Comlinemode) { if (strlen(ep->List[ep->Line]) != Clen) { if (ptr = allocb(Clen+1)) { ep->Modified = 1; Overide = 0; FreeMem(ep->List[ep->Line], strlen(ep->List[ep->Line])+1); ep->List[ep->Line] = ptr; } else { nomemory(); strcpy(Current, ep->List[ep->Line]); Clen = strlen(Current); } } else { if (strcmp(ep->List[ep->Line], Current)) { ep->Modified = 1; Overide = 0; } } strcpy(ep->List[ep->Line], Current); } if (Nsu == 0) { if (ep->Column - ep->Topcolumn >= Columns || ep->Column < ep->Topcolumn) { redraw = 1; ep->Topcolumn = ep->Column - (Columns>>1); if (ep->Topcolumn < 0) ep->Topcolumn = 0; } if (ep->Line - ep->Topline >= Rows || ep->Line < ep->Topline) { redraw = 1; ep->Topline = ep->Line - (Rows>>1); if (ep->Topline < 0) ep->Topline = 0; } } while (ep->Column > Clen) Current[Clen++] = ' '; Current[Clen] = '\0'; if (redraw) text_redisplay(); return((int)redraw); } text_load() { if (Comlinemode) return(0); strcpy(Current, Ep->List[Ep->Line]); Clen = strlen(Current); while (Ep->Column > Clen) Current[Clen++] = ' '; Current[Clen] = '\0'; } text_colno() { return(Ep->Column); } text_lineno() { return(Ep->Line+1); } text_lines() { return(Ep->Lines); } text_cols() { return((int)Clen); } text_imode() { return(Ep->Insertmode); } text_tabsize() { return((int)Ep->Tabstop); } ubyte * text_name() { return(Ep->Name); } text_uninit() { register int i; register ED *ep = Ep; freelist(ep->List, ep->Lines); FreeMem(ep->List, ep->Maxlines * sizeof(char *)); if (BEp == ep) { BEp = NULL; BSline = BEline = -1; } lunlink(ep); FreeMem(ep, sizeof(ED)); if (Base) { Ep = Base; text_load(); } else { Ep = NULL; } } inversemode(n) { if (n) { SetAPen(Rp, 3); SetDrMd(Rp, JAM2|INVERSVID); } else { setpen(Ep->Line); SetDrMd(Rp, JAM2); } } text_cursor(n) { movetocursor(); inversemode(n); if (Current[Ep->Column]) Text(Rp, Current+Ep->Column, 1); else Text(Rp, " ", 1); inversemode(0); } text_position(col, row) { register ED *ep = Ep; text_sync(); if (col == 0) col = -1; ep->Column = ep->Topcolumn + col; if (ep->Column > 254) ep->Column = 254; if (ep->Column < 0) ep->Column = 0; ep->Line = ep->Topline + row; if (ep->Line >= ep->Lines) ep->Line = ep->Lines - 1; if (ep->Line < 0) ep->Line = 0; text_load(); text_sync(); } displayblock(on) { register long start = Ep->Topline; register long lines = BEline - BSline + 1; if (start < BSline) start = BSline; if (!on) { BSline = BEline = -1; BEp = NULL; } if (Ep == BEp) text_displayseg(start - Ep->Topline, lines); } text_redrawblock(ok) { WIN *savewin = NULL; if (BEp) { if (BEp != Ep) { savewin = Ep->Win; text_switch(BEp->Win); } if (BSline <= BEline && BSline >= 0 && BEline < Ep->Lines) { if (!ok) { BEp = NULL; BSline = BEline = -1; } text_displayseg(0, Rows); } if (savewin) text_switch(savewin); } if (!ok) { BEp = NULL; BSline = BEline = -1; } } text_displayseg(start, n) { register short i, c; register ubyte *ptr; register ED *ep = Ep; char ib; if (Nsu) return(0); for (i = start; i < start + n && i < Rows && ep->Topline + i < ep->Lines; ++i) { if (Comlinemode) { if (ep->Topline + i != ep->Line) continue; ptr = Current; SetAPen(Rp, 1); } else { ptr = ep->List[ep->Topline + i]; setpen(i+ep->Topline); } for (c = ep->Topcolumn; c && *ptr; ++ptr, --c); c = strlen(ptr); if (c) { Move(Rp, COLT(0), ROWT(i)); Text(Rp, ptr, (c > Columns) ? Columns : c); } } } text_redisplay() { if (Nsu) return(0); SetAPen(Rp, 0); if (Comlinemode) RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs); else RectFill(Rp, Xbase, Ybase, Xbase + Xpixs, Ybase + Ypixs); text_displayseg(0,Rows); } text_redisplaycurrline() { int row = Ep->Line - Ep->Topline; if (Nsu) return(0); SetAPen(Rp, 0); RectFill(Rp, COL(0), ROW(row), Xbase+Xpixs, ROW(row+1)-1); text_displayseg(row, 1); } text_write(str) ubyte *str; { register short len = strlen(str); register short i; register ED *ep = Ep; if (Clen + len >= 255) { text_sync(); text_load(); } if (ep->Insertmode == 0) { i = len; if (ep->Column + len < 255) { bmov(str, Current + ep->Column, len); if (ep->Column + len >= Clen) Clen = ep->Column + len; Current[Clen] = 0; goto bin; } goto ok; } if (Clen + len < 255) { bmov(Current + ep->Column, Current + ep->Column + len, Clen+1-ep->Column); bmov(str, Current + ep->Column, len); Clen += len; ScrollRaster(Rp, -len * Xsize, 0 , COL(ep->Column - ep->Topcolumn), ROW(ep->Line - ep->Topline), COL(Columns) - 1, ROW(ep->Line - ep->Topline + 1) - 1 ); i = (ep->Column - ep->Topcolumn + len > Columns) ? Columns - ep->Column + ep->Topcolumn : len; bin: setpen(ep->Line); Move(Rp, COLT(ep->Column - ep->Topcolumn), ROWT(ep->Line - ep->Topline)); Text(Rp, str, i); ep->Column += len; if (ep->Column - ep->Topcolumn >= Columns) text_sync(); } ok: if (Comlinemode == 0 && ep->Wordwrap) do_reformat(0); } do_up() { if (Ep->Line) { text_sync(); --Ep->Line; text_load(); if (Ep->Line < Ep->Topline) { if (Nsu == 0) { ScrollRaster(Rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1); --Ep->Topline; text_displayseg(0, 1); } } } else { Abortcommand = 1; } } do_scrolldown() { if (Ep->Topline + Rows < Ep->Lines) { if (Nsu == 0) { text_sync(); ScrollRaster(Rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1); ++Ep->Topline; ++Ep->Line; text_load(); text_displayseg(Rows-1, 1); } } else { Abortcommand = 1; } } do_scrollup() { if (Ep->Topline) { if (Nsu == 0) { text_sync(); ScrollRaster(Rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1); --Ep->Topline; --Ep->Line; text_load(); text_displayseg(0, 1); } } else { Abortcommand = 1; } } do_down() { if (Ep->Line + 1 < Ep->Lines) { text_sync(); ++Ep->Line; text_load(); if (Ep->Line - Ep->Topline >= Rows) { if (Nsu == 0) { ScrollRaster(Rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1); ++Ep->Topline; text_displayseg(Rows-1, 1); } } } else { Abortcommand = 1; } } /* * PAGEUP * PAGEDOWN * PAGESET n (n = 0 to 100 for percentage of #rows to scroll, minimum 1) * can be > 100. */ do_page() { register int n, multiplier = 1; register ED *ep = Ep; static short pctg = 80; switch(av[0][4]) { case 'u': multiplier = -1; case 'd': n = multiplier * Rows * pctg / 100; if (!n) n = multiplier; if (n > 0 && ep->Topline >= ep->Lines - Rows) return(0); text_sync(); ep->Line += n; ep->Topline += n; if (ep->Line >= ep->Lines) ep->Line = ep->Lines - 1; if (ep->Line < 0) ep->Line = 0; if (ep->Topline >= ep->Lines) ep->Topline = ep->Lines - Rows - 1; if (ep->Topline < 0) ep->Topline = 0; text_load(); if (!text_sync()) text_redisplay(); break; case 's': pctg = atoi(av[1]); break; } } do_downadd() { ubyte *ptr; if (Ep->Line + 1 == Ep->Lines) { Ep->Modified = 1; if (makeroom(32) && (ptr = allocb(1))) { Ep->List[Ep->Lines] = ptr; *ptr = 0; ++Ep->Lines; } else { nomemory(); } } do_down(); } do_left() { if (Ep->Column) { --Ep->Column; if (Ep->Column < Ep->Topcolumn) text_sync(); } else { Abortcommand = 1; } } do_right() { if (Ep->Column != 254) { if (Current[Ep->Column] == 0) { Current[Ep->Column] = ' '; Current[Ep->Column+1]= '\0'; ++Clen; } ++Ep->Column; if (Ep->Column - Ep->Topcolumn >= Columns) text_sync(); } else { Abortcommand = 1; } } do_tab() { register short n; for (n = Ep->Tabstop-(Ep->Column % Ep->Tabstop); n > 0; --n) do_right(); } do_backtab() { register short n; n = Ep->Column % Ep->Tabstop; if (!n) n = Ep->Tabstop; for (; n > 0; --n) do_left(); } do_return() { ubyte buf[256]; char *partial; if (Comlinemode) { strcpy(buf, Current); strcpy(RecallBuf, Current); partial = Partial; Partial = NULL; escapecomlinemode(); if (partial) { if (do_command(buf)) do_command(partial); free(partial); } else { do_command(buf); } } else { Ep->Column = 0; text_sync(); do_downadd(); } } do_bs() { register ED *ep = Ep; if (ep->Column) { bmov(Current + ep->Column, Current + ep->Column - 1, Clen - ep->Column + 1); --ep->Column; --Clen; if (ep->Column < ep->Topcolumn) { text_sync(); } else { ScrollRaster(Rp, Xsize, 0, COL(ep->Column - ep->Topcolumn), ROW(ep->Line - ep->Topline), COL(Columns)-1, ROW(ep->Line - ep->Topline + 1)-1 ); if (Clen >= ep->Topcolumn + Columns) { setpen(ep->Line); Move(Rp, COLT(Columns-1), ROWT(ep->Line - ep->Topline)); Text(Rp, Current + ep->Topcolumn + Columns - 1, 1); } } if (Comlinemode == 0 && ep->Wordwrap) do_reformat(0); } else { Abortcommand = 1; } } /* * esc, escimm */ int Savetopline, Savecolumn, Savetopcolumn; do_recall() { av[0] = (ubyte *)"escimm"; av[1] = (ubyte *)RecallBuf; do_esc(); } do_esc() { register ED *ep = Ep; 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 = ep->Topline; Savecolumn = ep->Column; Savetopcolumn = ep->Topcolumn; ep->Column = Clen; ep->Topcolumn = 0; ep->Topline = ep->Line - Rows + 1; SetAPen(Rp, 0); RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs); SetAPen(Rp, 1); Move(Rp, COL(0), ROW(Rows-1) - 1); Draw(Rp, Xbase + Xpixs, ROW(Rows-1) - 1); text_displayseg(Rows-1,1); } escapecomlinemode() { register ED *ep = Ep; if (Partial) { free(Partial); Partial = NULL; } if (Comlinemode) { strcpy(RecallBuf, Current); Comlinemode = 0; returnoveride(0); ep->Topline = Savetopline; ep->Column = Savecolumn; ep->Topcolumn = Savetopcolumn; text_load(); SetAPen(Rp, 0); RectFill(Rp, COL(0), ROW(Rows-1)-1, Xbase+Xpixs, Ybase+Ypixs); SetAPen(Rp, 1); text_displayseg(Rows-2,2); } } do_del() { register ED *ep = Ep; if (Current[ep->Column]) { bmov(Current + ep->Column + 1, Current + ep->Column, Clen - ep->Column); --Clen; ScrollRaster(Rp, Xsize, 0, COL(ep->Column - ep->Topcolumn), ROW(ep->Line - ep->Topline), COL(Columns)-1, ROW(ep->Line - ep->Topline + 1) - 1 ); if (Clen >= ep->Topcolumn + Columns) { setpen(ep->Line); Move(Rp, COLT(Columns-1), ROWT(ep->Line-ep->Topline)); Text(Rp, Current+ep->Topcolumn+Columns-1, 1); } if (Comlinemode == 0 && ep->Wordwrap) do_reformat(0); } } do_top() { text_sync(); Ep->Line = 0; text_load(); text_sync(); } do_bottom() { text_sync(); Ep->Line = Ep->Lines - 1; text_load(); text_sync(); } do_firstcolumn() { if (Ep->Column) { Ep->Column = 0; text_sync(); } } do_firstnb() { for (Ep->Column = 0; Current[Ep->Column] == ' '; ++Ep->Column); if (Current[Ep->Column] == 0) Ep->Column = 0; text_sync(); } do_lastcolumn() { short i; text_sync(); i = (Comlinemode) ? Clen : strlen(Ep->List[Ep->Line]); if (i != Ep->Column) { Ep->Column = i; text_sync(); } } /* * GOTO [+/-]N * GOTO BLOCK start of block * GOTO START start of block * GOTO END end of block */ do_goto() { register short n, i; register ubyte *ptr = av[1]; i = 0; n = -1; switch(*ptr) { case 'b': case 's': case 'B': case 'S': n = -1; if (Ep == BEp) n = BSline; break; case 'e': case 'E': n = -1; if (Ep == BEp) n = BEline; break; case '+': i = 1; case '-': n = Ep->Line; default: n += atoi(ptr+i); } if (n >= Ep->Lines) n = Ep->Lines - 1; if (n < 0) n = 0; text_sync(); Ep->Line = n; text_load(); text_sync(); } do_screentop() { text_sync(); Ep->Line = Ep->Topline; text_load(); text_sync(); } do_screenbottom() { text_sync(); Ep->Line = Ep->Topline + Rows - 1; if (Ep->Line < 0 || Ep->Line >= Ep->Lines) Ep->Line = Ep->Lines - 1; text_load(); text_sync(); } static ubyte Fstr[256]; static ubyte Rstr[256]; static short Srch_sign; static char Doreplace; /* * findstr, repstr */ do_findstr() { if (av[0][0] == 'f') strcpy(Fstr, av[1]); else strcpy(Rstr, av[1]); } /* * findr, nextr, prevr */ do_findr() { Doreplace = 1; Srch_sign = 1; switch(av[0][0]) { case 'f': strcpy(Fstr, av[1]); strcpy(Rstr, av[2]); break; case 'p': Srch_sign = -1; break; } search_operation(); } /* * find, next, prev */ do_find() { Doreplace = 0; Srch_sign = 1; switch(av[0][0]) { case 'f': strcpy(Fstr, av[1]); break; case 'p': Srch_sign = -1; break; } search_operation(); } void search_operation() { int flen = strlen(Fstr); int rlen = strlen(Rstr); char senabled = 0; register ubyte *ptr; register int i, col; register ED *ep = Ep; text_sync(); if (!flen) { title("No find pattern"); Abortcommand = 1; return; } col = ep->Column; if (col >= strlen(ep->List[ep->Line])) col = strlen(ep->List[ep->Line]); for (i = ep->Line;;) { ptr = ep->List[i]; if (Srch_sign > 0) { while (ptr[col]) { if (Fstr[0] == ptr[col] && strncmp(Fstr,ptr+col,flen) == 0 && senabled) { goto found; } senabled = 1; ++col; } senabled = 1; if (++i >= ep->Lines) break; col = 0; } else { while (col >= 0) { if (Fstr[0] == ptr[col] && strncmp(Fstr,ptr+col,flen) == 0 && senabled) { goto found; } senabled = 1; --col; } senabled = 1; if (--i < 0) break; col = strlen(ep->List[i]); } } title("Pattern Not Found"); Abortcommand = 1; return; found: ep->Line = i; ep->Column = col; text_load(); if (Doreplace) { if (rlen > flen && rlen-flen+strlen(ptr) > 254) { title("Replace: Line Too Long"); Abortcommand = 1; return; } if (Clen-col-flen >= 0) { bmov(Current+col+flen, Current+col+rlen, Clen-col-flen+1); bmov(Rstr, Current+col, rlen); Clen += rlen-flen; } text_sync(); text_redisplaycurrline(); } else { text_sync(); } } !Funky!Stuff! fi # end of overwriting check echo shar: "extracting 'text2.c'" '(22408 characters)' if test -f 'text2.c' then echo shar: "will not over-write existing file 'text2.c'" else cat << \!Funky!Stuff! > 'text2.c' /* * TEXT2.C * * (C)Copyright 1987 by Matthew Dillon, All Rights Reserved */ #include "defs.h" #include <stdio.h> #define nomemory() {memoryfail = 1;} extern char MForceTitle; extern void do_bmove(); do_remeol() { Current[Clen = Ep->Column] = 0; text_sync(); text_redisplaycurrline(); } do_wleft() { register ED *ep = Ep; register ubyte *ptr; register 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(); } do_wright() { register ubyte *ptr; register ED *ep = Ep; register 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(); } do_split() /* split line in two at cursor pos */ { ubyte buf[256]; register ED *ep = Ep; strcpy(buf, Current+ep->Column); Current[Clen = ep->Column] = '\0'; text_sync(); SetAPen(Rp, 0); if (Nsu == 0) RectFill(Rp, COL(0), ROW(ep->Line-ep->Topline), Xbase+Xpixs, ROW(ep->Line-ep->Topline+1)-1); SetAPen(Rp, 1); text_displayseg(ep->Line - ep->Topline, 1); do_downadd(); do_insline(); strcpy(Current, buf); Clen = strlen(Current); text_sync(); text_displayseg(ep->Line - ep->Topline, 1); do_up(); } do_join() { register int i = Clen, j; register 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) bmov(Current+j, Current+i+2, strlen(Current+j)+1); Clen = strlen(Current); text_sync(); text_displayseg(ep->Line - ep->Topline, 1); do_down(); do_deline(); do_up(); return(1); } return(0); } do_margin() { Ep->Margin = atoi(av[1]); } do_wordwrap() { register 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"); } /* * 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; register ED *ep = Ep; 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 (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 (;;) { register 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 (!checked) { checked = 1; if (lnsc <= column) { /* if split before cursor */ column = column - ep->Column + indent; ++crow; } } if (Clen + indent < 253) { bmov(Current, Current + indent, strlen(Current)+1); bset(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, 0); RectFill(Rp, COL(0), ROW(srow - ep->Topline), Xbase+Xpixs, ROW(erow - ep->Topline)-1); SetAPen(Rp, 1); text_displayseg(srow - ep->Topline, erow - srow); } } else { text_sync(); if (moded) text_redisplaycurrline(); } } if (column > Clen) { bset(Current+Clen, column - Clen, ' '); Current[column] = 0; } ep->Column = column; } do_tabstop() { Ep->Tabstop = atoi(av[1]); } do_insertmode() { register 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"); } } do_insline() { register ubyte *ptr; register ED *ep = Ep; 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); } do_deline() { register int delline; register ED *ep = Ep; 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(0); } } 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; } } do_chfilename() { text_sync(); strncpy(Ep->Name, av[1], 63); MForceTitle = 1; } do_edit() { long xfi; long oldlock; long lines; ubyte buf[256]; ubyte *ptr; char failed = 1; short iwinx, iwiny; char tabstop, margin, insertmode, wordwrap; register ED *ep = Ep; text_sync(); if (*av[0] == 'n') { /* newfile or insfile */ if (ep->Modified && getyn("Delete modified Image?") == 0) return(0); iwinx = ep->IWinx; iwiny = ep->IWiny; tabstop= ep->Tabstop; margin = ep->Margin; insertmode = ep->Insertmode; wordwrap = ep->Wordwrap; text_uninit(); text_init(); ep = Ep; ep->IWiny = iwiny; ep->IWinx = iwinx; ep->Tabstop = tabstop; ep->Margin = margin; ep->Insertmode = insertmode; ep->Wordwrap = wordwrap; ep->Modified = 0; ep->Line = ep->Topline = 0; strncpy(ep->Name, av[1], 63); } else { ep->Modified = 1; } lines = ep->Lines; if (Wbs && Wdisable == 0) oldlock = CurrentDir(ep->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))) { ep->List[ep->Lines++] = ptr; bmov(buf, ptr, len+1); } else { set_window_params(); nomemory(); oktitle = 0; break; } } set_window_params(); if (oktitle) title("OK"); } else { title("File Not Found"); } xfclose(xfi); if (Wbs && Wdisable == 0) 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; do_bsave() { blockmode = 1; do_saveas(); } do_save() { av[1] = Ep->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; 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(); if (Wbs && Wdisable == 0) { /* Write out .info file */ DISKOBJ sdo, *d; bzero(&sdo, sizeof(sdo)); oldlock = CurrentDir(Ep->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 = 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 == '\"' || *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 { ep->Modified &= bm; title("OK"); } if (Wbs && Wdisable == 0) CurrentDir(oldlock); } else { title("Unable to open write file"); Abortcommand = 1; } } do_block() /* block, unblock */ { text_sync(); switch(av[0][0]) { case 'b': if (BSline < 0) { BSline = Ep->Line; title("Block Begin"); } else { if (BEp) { title("Block Already Marked"); break; } title("Block End"); BEline = Ep->Line; if (BSline > BEline) { BEline = BSline; BSline = Ep->Line; } BEp = Ep; text_redrawblock(1); } break; case 'u': text_redrawblock(0); title ("Block Unmarked"); break; } } static blockok() { if (BEp && BSline >= 0 && BSline <= BEline && BEline < BEp->Lines) return(1); BEp = NULL; BSline = BEline = -1; title("Block Not Specified"); return(0); } do_bdelete() { register long i, n; register ED *bep = BEp; register 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) { text_uninit(); text_init(); } text_load(); BEp = NULL; BSline = BEline = -1; if (!text_sync()) text_redisplay(); text_switch(savewin); } } void do_bcopy() { register ubyte **list; register long lines, i; register 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() { register long lines; register ubyte **list; register 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; } 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; 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 *)); BEp->Modified = 1; 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 =) # */ 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; register 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(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 = ep->Column + 1; case 'y': if (!i) i = ep->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 = 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 '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]; register 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 ED *ep = Ep; register 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(Rp, 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!). */ do_bsource() { ubyte buf[256]; register 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); } movetocursor() { register ED *ep = Ep; Move(Rp, XTbase+(ep->Column-ep->Topcolumn)*Xsize, YTbase+(ep->Line-ep->Topline)*Ysize); } extend(ep, lines) register ED *ep; { register long extra = ep->Maxlines - ep->Lines; register 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) { register ED *ep = Ep; if (ep->Lines >= ep->Maxlines) return(extend(ep, n)); return(1); } freelist(list, n) register char **list; { while (n) { FreeMem(list[0], strlen(list[0])+1); ++list; --n; } } !Funky!Stuff! fi # end of overwriting check exit 0 # End of shell archive