Charles.Forsyth20060303a828770d19 years agoHistory
184 lines · 3.6 KB · Brainfuck
RawDownload
implement Command; include "sys.m";	sys: Sys;	print, fprint, FD: import sys;	stderr: ref FD; include "draw.m"; include "debug.m";	debug: Debug;	Prog, Module, Exp: import debug; include "arg.m";include "bufio.m";	bufio: Bufio;	Iobuf: import bufio; include "env.m";	env: Env; include "string.m";	str: String; include "dis.m";	dism: Dis; Command: module{	init: fn(ctxt: ref Draw->Context, argv: list of string);}; usage(){	sys->fprint(stderr, "usage: stack [-v] pid\n");	raise "fail:usage";} badmodule(p: string){	sys->fprint(stderr, "stack: cannot load %s: %r\n", p);	raise "fail:bad module";} sbldirs: list of (string, string); init(nil: ref Draw->Context, argv: list of string){ 	sys = load Sys Sys->PATH;	stderr = sys->fildes(2);	arg := load Arg Arg->PATH;	if (arg == nil)		badmodule(Arg->PATH);	bufio = load Bufio Bufio->PATH;	if (bufio == nil)		badmodule(Bufio->PATH);	debug = load Debug Debug->PATH;	if(debug == nil)		badmodule(Debug->PATH);	env = load Env Env->PATH;	if (env != nil) {		str = load String String->PATH;		if (str == nil)			badmodule(String->PATH);	}	bout := bufio->fopen(sys->fildes(1), Sys->OWRITE); 	arg->init(argv);	verbose := 0;	while ((opt := arg->opt()) != 0) {		case opt {		'v' =>			verbose = 1;		'p' =>			dispath := arg->arg();			sblpath := arg->arg();			if (dispath == nil || sblpath == nil)				usage();			sbldirs = (addslash(dispath), addslash(sblpath)) :: sbldirs;		* =>			usage();		}	}	if (env != nil && (pathl := env->getenv("sblpath")) != nil) {		toks := str->unquoted(pathl);		for (; toks != nil && tl toks != nil; toks = tl tl toks)			sbldirs = (addslash(hd toks), addslash(hd tl toks)) :: sbldirs;	}	t: list of (string, string);	for (; sbldirs != nil; sbldirs = tl sbldirs)		t = hd sbldirs :: t;	sbldirs = t; 	argv = arg->argv();	if(argv == nil)		usage(); 	debug->init(); 	(p, err) := debug->prog(int hd argv);	if(err != nil){		fprint(stderr, "stack: %s\n", err);		return;	}	stk: array of ref Exp;	(stk, err) = p.stack(); 	if(err != nil){		fprint(stderr, "stack: %s\n", err);		return;	} 	for(i := 0; i < len stk; i++){		stdsym(stk[i].m);		stk[i].m.stdsym();		stk[i].findsym();		bout.puts(stk[i].name + "(");		vs := stk[i].expand();		if(verbose && vs != nil){			for(j := 0; j < len vs; j++){				if(vs[j].name == "args"){					d := vs[j].expand();					s := "";					for(j = 0; j < len d; j++) {						bout.puts(sys->sprint("%s%s=%s", s, d[j].name, d[j].val().t0));						s = ", ";					}					break;				}			}		}		bout.puts(sys->sprint(") %s\n", stk[i].srcstr()));		if(verbose && vs != nil){			for(j := 0; j < len vs; j++){				if(vs[j].name == "locals"){					d := vs[j].expand();					for(j = 0; j < len d; j++)						bout.puts("\t" + d[j].name + "=" + d[j].val().t0 + "\n");					break;				}			}		}	}	bout.flush();} stdsym(m: ref Module){	dis := m.dis();	if(dism == nil){		dism = load Dis Dis->PATH;		if(dism != nil)			dism->init();	}	if(dism != nil && (sp := dism->src(dis)) != nil){		sp = sp[0: len sp - 1] + "sbl";		(sym, err) := debug->sym(sp);		if (sym != nil) {			m.addsym(sym);			return;		}	}	for (sbl := sbldirs; sbl != nil; sbl = tl sbl) {		(dispath, sblpath) := hd sbl;		if (len dis > len dispath && dis[0:len dispath] == dispath) {			sblpath = sblpath + dis[len dispath:];			if (len sblpath > 4 && sblpath[len sblpath - 4:] == ".dis")				sblpath = sblpath[0:len sblpath - 4] + ".sbl";			(sym, err) := debug->sym(sblpath);			if (sym != nil) {				m.addsym(sym);				return;			}		}	}}			addslash(p: string): string{	if (p != nil && p[len p - 1] != '/')		p[len p] = '/';	return p;}