xref: /inferno-os/appl/cmd/stack.b (revision 3f1f06c5d12b24c4061e5123acabf72348ff45a2)
137da2899SCharles.Forsythimplement Command;
237da2899SCharles.Forsyth
337da2899SCharles.Forsythinclude "sys.m";
437da2899SCharles.Forsyth	sys: Sys;
537da2899SCharles.Forsyth	print, fprint, FD: import sys;
637da2899SCharles.Forsyth	stderr: ref FD;
737da2899SCharles.Forsyth
837da2899SCharles.Forsythinclude "draw.m";
937da2899SCharles.Forsyth
1037da2899SCharles.Forsythinclude "debug.m";
1137da2899SCharles.Forsyth	debug: Debug;
1237da2899SCharles.Forsyth	Prog, Module, Exp: import debug;
1337da2899SCharles.Forsyth
1437da2899SCharles.Forsythinclude "arg.m";
1537da2899SCharles.Forsythinclude "bufio.m";
1637da2899SCharles.Forsyth	bufio: Bufio;
1737da2899SCharles.Forsyth	Iobuf: import bufio;
1837da2899SCharles.Forsyth
1937da2899SCharles.Forsythinclude "env.m";
2037da2899SCharles.Forsyth	env: Env;
2137da2899SCharles.Forsyth
2237da2899SCharles.Forsythinclude "string.m";
2337da2899SCharles.Forsyth	str: String;
2437da2899SCharles.Forsyth
2537da2899SCharles.Forsythinclude "dis.m";
2637da2899SCharles.Forsyth	dism: Dis;
2737da2899SCharles.Forsyth
2837da2899SCharles.ForsythCommand: module
2937da2899SCharles.Forsyth{
3037da2899SCharles.Forsyth	init: fn(ctxt: ref Draw->Context, argv: list of string);
3137da2899SCharles.Forsyth};
3237da2899SCharles.Forsyth
3337da2899SCharles.Forsythusage()
3437da2899SCharles.Forsyth{
3537da2899SCharles.Forsyth	sys->fprint(stderr, "usage: stack [-v] pid\n");
3637da2899SCharles.Forsyth	raise "fail:usage";
3737da2899SCharles.Forsyth}
3837da2899SCharles.Forsyth
3937da2899SCharles.Forsythbadmodule(p: string)
4037da2899SCharles.Forsyth{
4137da2899SCharles.Forsyth	sys->fprint(stderr, "stack: cannot load %s: %r\n", p);
4237da2899SCharles.Forsyth	raise "fail:bad module";
4337da2899SCharles.Forsyth}
4437da2899SCharles.Forsyth
4537da2899SCharles.Forsythsbldirs: list of (string, string);
4637da2899SCharles.Forsyth
4737da2899SCharles.Forsythinit(nil: ref Draw->Context, argv: list of string)
4837da2899SCharles.Forsyth{
4937da2899SCharles.Forsyth
5037da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
5137da2899SCharles.Forsyth	stderr = sys->fildes(2);
5237da2899SCharles.Forsyth	arg := load Arg Arg->PATH;
5337da2899SCharles.Forsyth	if (arg == nil)
5437da2899SCharles.Forsyth		badmodule(Arg->PATH);
5537da2899SCharles.Forsyth	bufio = load Bufio Bufio->PATH;
5637da2899SCharles.Forsyth	if (bufio == nil)
5737da2899SCharles.Forsyth		badmodule(Bufio->PATH);
5837da2899SCharles.Forsyth	debug = load Debug Debug->PATH;
5937da2899SCharles.Forsyth	if(debug == nil)
6037da2899SCharles.Forsyth		badmodule(Debug->PATH);
6137da2899SCharles.Forsyth	env = load Env Env->PATH;
6237da2899SCharles.Forsyth	if (env != nil) {
6337da2899SCharles.Forsyth		str = load String String->PATH;
6437da2899SCharles.Forsyth		if (str == nil)
6537da2899SCharles.Forsyth			badmodule(String->PATH);
6637da2899SCharles.Forsyth	}
6737da2899SCharles.Forsyth	bout := bufio->fopen(sys->fildes(1), Sys->OWRITE);
6837da2899SCharles.Forsyth
6937da2899SCharles.Forsyth	arg->init(argv);
7037da2899SCharles.Forsyth	verbose := 0;
7137da2899SCharles.Forsyth	while ((opt := arg->opt()) != 0) {
7237da2899SCharles.Forsyth		case opt {
7337da2899SCharles.Forsyth		'v' =>
7437da2899SCharles.Forsyth			verbose = 1;
7537da2899SCharles.Forsyth		'p' =>
7637da2899SCharles.Forsyth			dispath := arg->arg();
7737da2899SCharles.Forsyth			sblpath := arg->arg();
7837da2899SCharles.Forsyth			if (dispath == nil || sblpath == nil)
7937da2899SCharles.Forsyth				usage();
8037da2899SCharles.Forsyth			sbldirs = (addslash(dispath), addslash(sblpath)) :: sbldirs;
8137da2899SCharles.Forsyth		* =>
8237da2899SCharles.Forsyth			usage();
8337da2899SCharles.Forsyth		}
8437da2899SCharles.Forsyth	}
8537da2899SCharles.Forsyth	if (env != nil && (pathl := env->getenv("sblpath")) != nil) {
8637da2899SCharles.Forsyth		toks := str->unquoted(pathl);
8737da2899SCharles.Forsyth		for (; toks != nil && tl toks != nil; toks = tl tl toks)
8837da2899SCharles.Forsyth			sbldirs = (addslash(hd toks), addslash(hd tl toks)) :: sbldirs;
8937da2899SCharles.Forsyth	}
9037da2899SCharles.Forsyth	t: list of (string, string);
9137da2899SCharles.Forsyth	for (; sbldirs != nil; sbldirs = tl sbldirs)
9237da2899SCharles.Forsyth		t = hd sbldirs :: t;
9337da2899SCharles.Forsyth	sbldirs = t;
9437da2899SCharles.Forsyth
9537da2899SCharles.Forsyth	argv = arg->argv();
9637da2899SCharles.Forsyth	if(argv == nil)
9737da2899SCharles.Forsyth		usage();
9837da2899SCharles.Forsyth
9937da2899SCharles.Forsyth	debug->init();
10037da2899SCharles.Forsyth
10137da2899SCharles.Forsyth	(p, err) := debug->prog(int hd argv);
10237da2899SCharles.Forsyth	if(err != nil){
10337da2899SCharles.Forsyth		fprint(stderr, "stack: %s\n", err);
10437da2899SCharles.Forsyth		return;
10537da2899SCharles.Forsyth	}
10637da2899SCharles.Forsyth	stk: array of ref Exp;
10737da2899SCharles.Forsyth	(stk, err) = p.stack();
10837da2899SCharles.Forsyth
10937da2899SCharles.Forsyth	if(err != nil){
11037da2899SCharles.Forsyth		fprint(stderr, "stack: %s\n", err);
11137da2899SCharles.Forsyth		return;
11237da2899SCharles.Forsyth	}
11337da2899SCharles.Forsyth
11437da2899SCharles.Forsyth	for(i := 0; i < len stk; i++){
11537da2899SCharles.Forsyth		stdsym(stk[i].m);
11637da2899SCharles.Forsyth		stk[i].m.stdsym();
11737da2899SCharles.Forsyth		stk[i].findsym();
11837da2899SCharles.Forsyth		bout.puts(stk[i].name + "(");
11937da2899SCharles.Forsyth		vs := stk[i].expand();
12037da2899SCharles.Forsyth		if(verbose && vs != nil){
12137da2899SCharles.Forsyth			for(j := 0; j < len vs; j++){
12237da2899SCharles.Forsyth				if(vs[j].name == "args"){
12337da2899SCharles.Forsyth					d := vs[j].expand();
12437da2899SCharles.Forsyth					s := "";
12537da2899SCharles.Forsyth					for(j = 0; j < len d; j++) {
12637da2899SCharles.Forsyth						bout.puts(sys->sprint("%s%s=%s", s, d[j].name, d[j].val().t0));
12737da2899SCharles.Forsyth						s = ", ";
12837da2899SCharles.Forsyth					}
12937da2899SCharles.Forsyth					break;
13037da2899SCharles.Forsyth				}
13137da2899SCharles.Forsyth			}
13237da2899SCharles.Forsyth		}
13337da2899SCharles.Forsyth		bout.puts(sys->sprint(") %s\n", stk[i].srcstr()));
13437da2899SCharles.Forsyth		if(verbose && vs != nil){
13537da2899SCharles.Forsyth			for(j := 0; j < len vs; j++){
13637da2899SCharles.Forsyth				if(vs[j].name == "locals"){
13737da2899SCharles.Forsyth					d := vs[j].expand();
13837da2899SCharles.Forsyth					for(j = 0; j < len d; j++)
13937da2899SCharles.Forsyth						bout.puts("\t" + d[j].name + "=" + d[j].val().t0 + "\n");
14037da2899SCharles.Forsyth					break;
14137da2899SCharles.Forsyth				}
14237da2899SCharles.Forsyth			}
14337da2899SCharles.Forsyth		}
14437da2899SCharles.Forsyth	}
14537da2899SCharles.Forsyth	bout.flush();
14637da2899SCharles.Forsyth}
14737da2899SCharles.Forsyth
14837da2899SCharles.Forsythstdsym(m: ref Module)
14937da2899SCharles.Forsyth{
15037da2899SCharles.Forsyth	dis := m.dis();
15137da2899SCharles.Forsyth	if(dism == nil){
15237da2899SCharles.Forsyth		dism = load Dis Dis->PATH;
15337da2899SCharles.Forsyth		if(dism != nil)
15437da2899SCharles.Forsyth			dism->init();
15537da2899SCharles.Forsyth	}
15637da2899SCharles.Forsyth	if(dism != nil && (sp := dism->src(dis)) != nil){
15737da2899SCharles.Forsyth		sp = sp[0: len sp - 1] + "sbl";
158*3f1f06c5SCharles.Forsyth		(sym, nil) := debug->sym(sp);
15937da2899SCharles.Forsyth		if (sym != nil) {
16037da2899SCharles.Forsyth			m.addsym(sym);
16137da2899SCharles.Forsyth			return;
16237da2899SCharles.Forsyth		}
16337da2899SCharles.Forsyth	}
16437da2899SCharles.Forsyth	for (sbl := sbldirs; sbl != nil; sbl = tl sbl) {
16537da2899SCharles.Forsyth		(dispath, sblpath) := hd sbl;
16637da2899SCharles.Forsyth		if (len dis > len dispath && dis[0:len dispath] == dispath) {
16737da2899SCharles.Forsyth			sblpath = sblpath + dis[len dispath:];
16837da2899SCharles.Forsyth			if (len sblpath > 4 && sblpath[len sblpath - 4:] == ".dis")
16937da2899SCharles.Forsyth				sblpath = sblpath[0:len sblpath - 4] + ".sbl";
170*3f1f06c5SCharles.Forsyth			(sym, nil) := debug->sym(sblpath);
17137da2899SCharles.Forsyth			if (sym != nil) {
17237da2899SCharles.Forsyth				m.addsym(sym);
17337da2899SCharles.Forsyth				return;
17437da2899SCharles.Forsyth			}
17537da2899SCharles.Forsyth		}
17637da2899SCharles.Forsyth	}
17737da2899SCharles.Forsyth}
17837da2899SCharles.Forsyth
17937da2899SCharles.Forsythaddslash(p: string): string
18037da2899SCharles.Forsyth{
18137da2899SCharles.Forsyth	if (p != nil && p[len p - 1] != '/')
18237da2899SCharles.Forsyth		p[len p] = '/';
18337da2899SCharles.Forsyth	return p;
18437da2899SCharles.Forsyth}
185