diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /appl/cmd/stack.b | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'appl/cmd/stack.b')
| -rw-r--r-- | appl/cmd/stack.b | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/appl/cmd/stack.b b/appl/cmd/stack.b new file mode 100644 index 00000000..7b90a0b5 --- /dev/null +++ b/appl/cmd/stack.b @@ -0,0 +1,184 @@ +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; +} |
