Charles.Forsyth20070608-1402fa5d71119 years agoHistory
1350 lines · 27.2 KB · Brainfuck
RawDownload
implement Exec; include "common.m"; sys : Sys;dat : Dat;acme : Acme;utils : Utils;graph : Graph;gui : Gui;lookx : Look;bufferm : Bufferm;textm : Textm;scrl : Scroll;filem : Filem;windowm : Windowm;rowm : Rowm;columnm : Columnm;fsys : Fsys;editm: Edit; Dir, OREAD, OWRITE : import Sys;EVENTSIZE, QWaddr, QWdata, QWevent, Astring : import dat;Lock, Reffont, Ref, seltext, seq, row : import dat;warning, error, skipbl, findbl, stralloc, strfree, exec : import utils;dirname : import lookx;Body, Text : import textm;File : import filem;sprint : import sys;TRUE, FALSE, XXX, BUFSIZE : import Dat;Buffer : import bufferm;Row : import rowm;Column : import columnm;Window : import windowm;setalphabet: import textm; # snarfbuf : ref Buffer; init(mods : ref Dat->Mods){	sys = mods.sys;	dat = mods.dat;	acme = mods.acme;	utils = mods.utils;	graph = mods.graph;	gui = mods.gui;	lookx = mods.look;	bufferm = mods.bufferm;	textm = mods.textm;	scrl = mods.scroll;	filem = mods.filem;	rowm = mods.rowm;	windowm = mods.windowm;	columnm = mods.columnm;	fsys = mods.fsys;	editm = mods.edit; 	snarfbuf = bufferm->newbuffer();} Exectab : adt {	name : string;	fun : int;	mark : int;	flag1 : int;	flag2 : int;}; F_ALPHABET, F_CUT, F_DEL, F_DELCOL, F_DUMP, F_EDIT, F_EXITX, F_FONTX, F_GET, F_ID, F_INCL, F_KILL, F_LIMBO, F_LINENO, F_LOCAL, F_LOOK, F_NEW, F_NEWCOL, F_PASTE, F_PUT, F_PUTALL, F_UNDO, F_SEND, F_SORT, F_TAB, F_ZEROX : con iota; exectab := array[] of {	Exectab ( "Alphabet",	F_ALPHABET,	FALSE,	XXX,		XXX		),	Exectab ( "Cut",		F_CUT,		TRUE,	TRUE,	TRUE	),	Exectab ( "Del",			F_DEL,		FALSE,	FALSE,	XXX		),	Exectab ( "Delcol",		F_DELCOL,	FALSE,	XXX,		XXX		),	Exectab ( "Delete",		F_DEL,		FALSE,	TRUE,	XXX		),	Exectab ( "Dump",		F_DUMP,		FALSE,	TRUE,	XXX		),	Exectab ( "Edit",		F_EDIT,		FALSE,	XXX,		XXX		),	Exectab ( "Exit",		F_EXITX,		FALSE,	XXX,		XXX		),	Exectab ( "Font",		F_FONTX,		FALSE,	XXX,		XXX		),	Exectab ( "Get",			F_GET,		FALSE,	TRUE,	XXX		),	Exectab ( "ID",			F_ID,		FALSE,	XXX,		XXX		),	Exectab ( "Incl",		F_INCL,		FALSE,	XXX,		XXX		),	Exectab ( "Kill",			F_KILL,		FALSE,	XXX,		XXX		),	Exectab ( "Limbo",		F_LIMBO,		FALSE,	XXX,		XXX   	),	Exectab ( "Lineno",		F_LINENO,	FALSE,	XXX,		XXX		),	Exectab ( "Load",		F_DUMP,		FALSE,	FALSE,	XXX		),	Exectab ( "Local",		F_LOCAL,		FALSE,	XXX,		XXX		),	Exectab ( "Look",		F_LOOK,		FALSE,	XXX,		XXX		),	Exectab ( "New",		F_NEW,		FALSE,	XXX,		XXX		),	Exectab ( "Newcol",		F_NEWCOL,	FALSE,	XXX,		XXX		),	Exectab ( "Paste",		F_PASTE,		TRUE,	TRUE,	XXX		),	Exectab ( "Put",			F_PUT,		FALSE,	XXX,		XXX		),	Exectab ( "Putall",		F_PUTALL,	FALSE,	XXX,		XXX		),	Exectab ( "Redo",		F_UNDO,		FALSE,	FALSE,	XXX		),	Exectab ( "Send",		F_SEND,		TRUE,	XXX,		XXX		),	Exectab ( "Snarf",		F_CUT,		FALSE,	TRUE,	FALSE	),	Exectab ( "Sort",		F_SORT,		FALSE,	XXX,		XXX		),	Exectab ( "Tab",		F_TAB,		FALSE,	XXX,		XXX		),	Exectab ( "Undo",		F_UNDO,		FALSE,	TRUE,	XXX		),	Exectab ( "Zerox",		F_ZEROX,		FALSE,	XXX,		XXX		),	Exectab ( nil, 			0,			0,		0,		0		),}; runfun(fun : int, et, t, argt : ref Text, flag1, flag2 : int, arg : string, narg : int){	case (fun) {		F_ALPHABET	=> alphabet(et, argt, arg, narg);		F_CUT 	 	=> cut(et, t, flag1, flag2);		F_DEL 		=> del(et, flag1);		F_DELCOL	=> delcol(et);		F_DUMP 		=> dump(argt, flag1, arg, narg);		F_EDIT		=> edit(et, argt, arg, narg);		F_EXITX		=> exitx();		F_FONTX		=> fontx(et, t, argt, arg, narg);		F_GET 		=> get(et, t, argt, flag1, arg, narg);		F_ID 		=> id(et);		F_INCL 		=> incl(et, argt, arg, narg);		F_KILL 		=> kill(argt, arg, narg);		F_LIMBO		=> limbo(et);		F_LINENO		=> lineno(et);		F_LOCAL 		=> local(et, argt, arg);		F_LOOK 		=> look(et, t, argt);		F_NEW 		=> lookx->new(et, t, argt, flag1, flag2, arg, narg);		F_NEWCOL	=> newcol(et);		F_PASTE		=> paste(et, t, flag1, flag2);		F_PUT		=> put(et, argt, arg, narg);		F_PUTALL 	=> putall();		F_UNDO 		=> undo(et, flag1);		F_SEND		=> send(et, t);		F_SORT		=> sort(et);		F_TAB		=> tab(et, argt, arg, narg);		F_ZEROX		=> zerox(et, t);		*			=> error("bad case in runfun()");	}}			lookup(r : string, n : int) : int{	nr : int; 	(r, n) = skipbl(r, n);	if(n == 0)		return -1;	(nil, nr) = findbl(r, n);	nr = n-nr;	for(i := 0; exectab[i].name != nil; i++)		if (r[0:nr] == exectab[i].name)			return i;	return -1;} isexecc(c : int) : int{	if(lookx->isfilec(c))		return 1;	return c=='<' || c=='|' || c=='>';} execute(t : ref Text, aq0 : int, aq1 : int, external : int, argt : ref Text){	q0, q1 : int;	r : ref Astring;	s, dir, aa, a : string;	e : int;	c, n, f : int; 	q0 = aq0;	q1 = aq1;	if(q1 == q0){	# expand to find word (actually file name) 		# if in selection, choose selection 		if(t.q1>t.q0 && t.q0<=q0 && q0<=t.q1){			q0 = t.q0;			q1 = t.q1;		}else{			while(q1<t.file.buf.nc && isexecc(c=t.readc(q1)) && c!=':')				q1++;			while(q0>0 && isexecc(c=t.readc(q0-1)) && c!=':')				q0--;			if(q1 == q0)				return;		}	}	r = stralloc(q1-q0);	t.file.buf.read(q0, r, 0, q1-q0);	e = lookup(r.s, q1-q0);	if(!external && t.w!=nil && t.w.nopen[QWevent]>byte 0){		f = 0;		if(e >= 0)			f |= 1;		if(q0!=aq0 || q1!=aq1){			t.file.buf.read(aq0, r, 0, aq1-aq0);			f |= 2;		}		(aa, a) = getbytearg(argt, TRUE, TRUE);		if(a != nil){				if(len a > EVENTSIZE){	# too big; too bad 				aa = a = nil;				warning(nil, "`argument string too long\n");				return;			}			f |= 8;		}		c = 'x';		if(t.what == Body)			c = 'X';		n = aq1-aq0;		if(n <= EVENTSIZE)			t.w.event(sprint("%c%d %d %d %d %s\n", c, aq0, aq1, f, n, r.s[0:n]));		else			t.w.event(sprint("%c%d %d %d 0 \n", c, aq0, aq1, f));		if(q0!=aq0 || q1!=aq1){			n = q1-q0;			t.file.buf.read(q0, r, 0, n);			if(n <= EVENTSIZE)				t.w.event(sprint("%c%d %d 0 %d %s\n", c, q0, q1, n, r.s[0:n]));			else				t.w.event(sprint("%c%d %d 0 0 \n", c, q0, q1));		}		if(a != nil){			t.w.event(sprint("%c0 0 0 %d %s\n", c, len a, a));			if(aa != nil)				t.w.event(sprint("%c0 0 0 %d %s\n", c, len aa, aa));			else				t.w.event(sprint("%c0 0 0 0 \n", c));		}		strfree(r);		r = nil;		a = aa = nil;		return;	}	if(e >= 0){		if(exectab[e].mark && seltext!=nil)		if(seltext.what == Body){			seq++;			seltext.w.body.file.mark();		}		(s, n) = skipbl(r.s, q1-q0);		(s, n) = findbl(s, n);		(s, n) = skipbl(s, n);		runfun(exectab[e].fun, t, seltext, argt, exectab[e].flag1, exectab[e].flag2, s, n);		strfree(r);		r = nil;		return;	} 	(dir, n) = dirname(t, nil, 0);	if(n==1 && dir[0]=='.'){	# sigh 		dir = nil;		n = 0;	}	(aa, a) = getbytearg(argt, TRUE, TRUE);	if(t.w != nil)		t.w.refx.inc();	spawn run(t.w, r.s, dir, n, TRUE, aa, a, FALSE);} printarg(argt : ref Text, q0 : int, q1 : int) : string{	buf : string; 	if(argt.what!=Body || argt.file.name==nil)		return nil;	if(q0 == q1)		buf = sprint("%s:#%d", argt.file.name, q0);	else		buf = sprint("%s:#%d,#%d", argt.file.name, q0, q1);	return buf;} getarg(argt : ref Text, doaddr : int, dofile : int) : (string, string, int){	r : ref Astring;	n : int;	e : Dat->Expand;	a : string;	ok : int; 	if(argt == nil)		return (nil, nil, 0);	a = nil;	argt.commit(TRUE);	(ok, e) = lookx->expand(argt, argt.q0, argt.q1);	if (ok) {		e.bname = nil;		if(len e.name && dofile){			if(doaddr)				a = printarg(argt, e.q0, e.q1);			return (a, e.name, len e.name);		}		e.name = nil;	}else{		e.q0 = argt.q0;		e.q1 = argt.q1;	}	n = e.q1 - e.q0;	r = stralloc(n);	argt.file.buf.read(e.q0, r, 0, n);	if(doaddr)		a = printarg(argt, e.q0, e.q1);	return(a, r.s, n);} getbytearg(argt : ref Text, doaddr : int, dofile : int) : (string, string){	r : string;	n : int;	aa : string; 	(aa, r, n) = getarg(argt, doaddr, dofile);	if(r == nil)		return (nil, nil);	return (aa, r);} newcol(et : ref Text){	c : ref Column; 	c = et.row.add(nil, -1);	if(c != nil)		c.add(nil, nil, -1).settag();} delcol(et : ref Text){	c := et.col;	if(c==nil || !c.clean(FALSE))		return;	for(i:=0; i<c.nw; i++){		w := c.w[i];		if(int w.nopen[QWevent]+int w.nopen[QWaddr]+int w.nopen[QWdata] > 0){			warning(nil, sys->sprint("can't delete column; %s is running an external command\n", w.body.file.name));			return;		}	}	c.row.close(c, TRUE);} del(et : ref Text, flag1 : int){	if(et.col==nil || et.w == nil)		return;	if(flag1 || et.w.body.file.ntext>1 || et.w.clean(FALSE, FALSE))		et.col.close(et.w, TRUE);} sort(et : ref Text){	if(et.col != nil)		et.col.sort();} seqof(w: ref Window, isundo: int): int{	# if it's undo, see who changed with us	if(isundo)		return w.body.file.seq;	# if it's redo, see who we'll be sync'ed up with	return w.body.file.redoseq();} undo(et : ref Text, flag1 : int){	i, j: int;	c: ref Column;	w: ref Window;	seq: int; 	if(et==nil || et.w== nil)		return;	seq = seqof(et.w, flag1);	for(i=0; i<row.ncol; i++){		c = row.col[i];		for(j=0; j<c.nw; j++){			w = c.w[j];			if(seqof(w, flag1) == seq)				w.undo(flag1);		}	}	# et.w.undo(flag1);} getname(t : ref Text, argt : ref Text, arg : string, narg : int, isput : int) : string{	r, dir : string;	i, n, ndir, promote : int; 	(nil, r, n) = getarg(argt, FALSE, TRUE);	promote = FALSE;	if(r == nil)		promote = TRUE;	else if(isput){		# if are doing a Put, want to synthesize name even for non-existent file 		# best guess is that file name doesn't contain a slash 		promote = TRUE;		for(i=0; i<n; i++)			if(r[i] == '/'){				promote = FALSE;				break;			}		if(promote){			t = argt;			arg = r;			narg = n;		}	}	if(promote){		n = narg;		if(n <= 0)			return t.file.name;		# prefix with directory name if necessary 		dir = nil;		ndir = 0;		if(n>0 && arg[0]!='/'){			(dir, ndir) = dirname(t, nil, 0);			if(n==1 && dir[0]=='.'){	# sigh 				dir = nil;				ndir = 0;			}		}		if(dir != nil){			r = dir[0:ndir] + arg[0:n];			dir = nil;			n += ndir;		}else			r = arg[0:n];	}	return r;} zerox(et : ref Text, t : ref Text){	nw : ref Window;	c, locked : int; 	locked = FALSE;	if(t!=nil && t.w!=nil && t.w!=et.w){		locked = TRUE;		c = 'M';		if(et.w != nil)			c = et.w.owner;		t.w.lock(c);	}	if(t == nil)		t = et;	if(t==nil || t.w==nil)		return;	t = t.w.body;	if(t.w.isdir)		warning(nil, sprint("%s is a directory; Zerox illegal\n", t.file.name));	else{		nw = t.w.col.add(nil, t.w, -1);		# ugly: fix locks so w.unlock works 		nw.lock1(t.w.owner);	}	if(locked)		t.w.unlock();} get(et : ref Text, t : ref Text, argt : ref Text, flag1 : int, arg : string, narg : int){	name : string;	r : string;	i, n, dirty : int;	w : ref Window;	u : ref Text;	d : Dir;	ok : int; 	if(flag1)		if(et==nil || et.w==nil)			return;	if(!et.w.isdir && (et.w.body.file.buf.nc>0 && !et.w.clean(TRUE, FALSE)))		return;	w = et.w;	t = w.body;	name = getname(t, argt, arg, narg, FALSE);	if(name == nil){		warning(nil, "no file name\n");		return;	}	if(t.file.ntext>1){		(ok, d) = sys->stat(name);		if (ok == 0 && d.qid.qtype & Sys->QTDIR) {			warning(nil, sprint("%s is a directory; can't read with multiple windows on it\n", name));			return;		}	}	r = name;	n = len name;	for(i=0; i<t.file.ntext; i++){		u = t.file.text[i];		# second and subsequent calls with zero an already empty buffer, but OK 		u.reset();		u.w.dirfree();	}	samename := r[0:n] == t.file.name;	t.loadx(0, name, samename);	if(samename){

Lines 1–500 of 1350.