forsyth20121205-174063a80cc13 years agoHistory
323 lines · 6.9 KB · Brainfuck
RawDownload
implement Wmprof; include "sys.m";	sys: Sys;include "bufio.m";	bufio: Bufio;	Iobuf: import bufio;include "draw.m";	draw: Draw;include "tk.m";	tk: Tk;include "tkclient.m";	tkclient: Tkclient;include "arg.m";	arg: Arg;include "profile.m"; Prof: module{	init0: fn(ctxt: ref Draw->Context, argv: list of string): Profile->Prof;}; prof: Prof; Wmprof: module{	init: fn(ctxt: ref Draw->Context, argl: list of string);}; usage(s: string){	sys->fprint(sys->fildes(2), "wm/prof: %s\n", s);	sys->fprint(sys->fildes(2), "usage: wm/prof [-e] [-m modname]... cmd [arg ... ]");	exit;} TXTBEGIN: con 3; init(ctxt: ref Draw->Context, argl: list of string){	sys = load Sys Sys->PATH;	bufio = load Bufio Bufio->PATH;	draw = load Draw Draw->PATH;	tk = load Tk Tk->PATH;	tkclient = load Tkclient Tkclient->PATH;	arg = load Arg Arg->PATH;		if(ctxt == nil)		fatal("wm not running");	sys->pctl(Sys->NEWPGRP, nil); 	arg->init(argl);	while((o := arg->opt()) != 0){		case(o){			'e' => ;			'm' =>				if(arg->arg() == nil)					usage("missing module/file");			's' =>				if(arg->arg() == nil)					usage("missing sample rate");			* => 				usage(sys->sprint("unknown option -%c", o));		}	} 	stats := execprof(ctxt, argl);	if(stats.mods == nil)		exit; 	tkclient->init();	(win, wmc) := tkclient->toplevel(ctxt, nil, hd argl, Tkclient->Resize|Tkclient->Hide);	tkc := chan of string;	tk->namechan(win, tkc, "tkc");	for(i := 0; i < len wincfg; i++)		cmd(win, wincfg[i]);	tkclient->onscreen(win, nil);	tkclient->startinput(win, "kbd"::"ptr"::nil);	createmenu(win, stats);	curc := 0;	cura := newprint(win, stats, curc);		for(;;){		alt{			c := <-win.ctxt.kbd =>				tk->keyboard(win, c);			c := <-win.ctxt.ptr =>				tk->pointer(win, *c);			c := <-win.ctxt.ctl or			c = <-win.wreq or			c = <-wmc =>				tkclient->wmctl(win, c);			c := <- tkc =>				(nil, toks) := sys->tokenize(c, " ");				case(hd toks){					"b" =>						if(curc > 0)							cura = newprint(win, stats, --curc);					"f" =>						if(curc < len stats.mods - 1)							cura = newprint(win, stats, ++curc);					"s" =>						if(cura  != nil)							scroll(win, cura);					"m" =>						x := cmd(win, ".f cget actx");						y := cmd(win, ".f cget acty");						cmd(win, ".f.menu post " + x + " " + y);					* =>						curc = int hd toks;						cura = newprint(win, stats, curc);				}		}	}} execprof(ctxt: ref Draw->Context, argl: list of string): Profile->Prof{	{		prof = load Prof "/dis/prof.dis";		if(prof == nil)			fatal("cannot load profiler");		return prof->init0(ctxt, hd argl :: "-g" :: tl argl);	}	exception{		"fail:*" =>			return (nil, 0, nil);	}	return (nil, 0, nil);} newprint(win: ref Tk->Toplevel, p: Profile->Prof, i: int): array of int{	cmd(win, ".f.t delete 1.0 end");	cmd(win, "update");	m0, m1: list of Profile->Modprof;	for(m := p.mods; m != nil && --i >= 0; m = tl m)		m0 = m;	if(m == nil)		return nil;	m1 = tl m;		(name, nil, spath, nil, line, nil, nil, tot, nil, nil) := hd m;	name0 := name1 := "nil";	if(m0 != nil)		name0 = (hd m0).name;	if(m1 != nil)		name1 = (hd m1).name;	a := len name;	name += sys->sprint(" (%d%%) ", percent(tot, p.total));	cmd(win, ".f.t insert end {" + name + "        <- " + name0 + "        -> " + name1 + "}");	tag := gettag(win, tot, p.total);	cmd(win, ".f.t tag add " + tag + " " + "1.0" + " " + "1." + string a);	cmd(win, ".f.t insert end \n\n");	cmd(win, "update");	lineno := TXTBEGIN;	bio := bufio->open(spath, Bufio->OREAD);	if(bio == nil)		return nil;	i = 1;	ll := len line;	while((s := bio.gets('\n')) != nil){		f := 0;		if(i < ll)			f = line[i];		a = len s;		if(f > 0)			s = sys->sprint("%d%%\t%s", percent(f, tot), s);		else			s = sys->sprint("- \t%s", s);		b := len s;		cmd(win, ".f.t insert end " + tk->quote(s));		tag = gettag(win, f, tot);		cmd(win, ".f.t tag add " + tag + " " + string lineno + "." + string (b-a) + " " + string lineno + "." + string (b-1));		cmd(win, "update");		lineno++;		i++;	}	return line;} index(win: ref Tk->Toplevel, x: int, y: int): int{	t := cmd(win, ".f.t index @" + string x + "," + string y);	(nil, l) := sys->tokenize(t, ".");# sys->print("%d,%d -> %s\n", x, y, t);	return int hd l;} winextent(win: ref Tk->Toplevel): (int, int){	w := int cmd(win, ".f.t cget -actwidth");	h := int cmd(win, ".f.t cget -actheight");	lw := index(win, 0, 0);	uw := index(win, w-1, h-1);	return (lw, uw);} see(win: ref Tk->Toplevel, line: int){	cmd(win, ".f.t see " + string line + ".0");	cmd(win, "update");	} scroll(win: ref Tk->Toplevel, line: array of int){	(nil, uw) := winextent(win);	lno := TXTBEGIN;	ll := len line;	for(i := 1; i < ll; i++){		n := line[i];		if(n > 0 && lno > uw){			see(win, lno);			return;		}		lno++;	}	lno = TXTBEGIN;	ll = len line;	for(i = 1; i < ll; i++){		n := line[i];		if(n > 0){			see(win, lno);			return;		}		lno++;	}} cmd(top: ref Tk->Toplevel, s: string): string{	# sys->print("%s\n", s);	e := tk->cmd(top, s);	if (e != nil && e[0] == '!')		sys->fprint(sys->fildes(2), "tk error on '%s': %s\n", s, e);	return e;} fatal(s: string){	sys->fprint(sys->fildes(2), "%s\n", s);	exit;} MENUMAX: con 20; createmenu(top: ref Tk->Toplevel, p: Profile->Prof ){	mn := ".f.menu";	cmd(top, "menu " + mn);	i := j := 0;	for(m := p.mods; m != nil; m = tl m){		name := (hd m).name;		cmd(top, mn + " add command -label " + name + " -command {send tkc " + string i + "}");		i++;		j++;		if(j == MENUMAX && tl m != nil){			cmd(top, mn + " add cascade -label MORE -menu " + mn + ".menu");			mn += ".menu";			cmd(top, "menu " + mn);			j = 0;		}	}} tags := array[256]  of { * => byte 0 }; gettag(win: ref Tk->Toplevel, n: int, d: int): string{	i := int ((real n/real d) * real 15);	if(i < 0 || i > 15)		i = 0;	s := "tag" + string i;	if(tags[i] == byte 0){		rgb := "#" + hex2(255-64*0)+hex2(255-64*(i/4))+hex2(255-64*(i%4));		cmd(win, ".f.t tag configure " + s + " -fg black -bg " + rgb);		tags[i] = byte 1;	}	return s;} percent(n: int, d: int): int{	return int ((real n/real d) * real 100);} hex(i: int): int{	if(i < 10)		return i+'0';	else		return i-10+'A';} hex2(i: int): string{	s := "00";	s[0] = hex(i/16);	s[1] = hex(i%16);	return s;} wincfg := array[] of {	"frame .f",	"text .f.t -width 809 -height 500 -state disabled -wrap char -bg white -yscrollcommand {.f.s set}",	"scrollbar .f.s -orient vertical -command {.f.t yview}",	"frame .i",	"button .i.b -bitmap small_color_left.bit -command {send tkc b}",	"button .i.f -bitmap small_color_right.bit -command {send tkc f}",	"button .i.s -bitmap small_find.bit -command {send tkc s}",	"button .i.m -bitmap small_reload.bit -command {send tkc m}", 	"pack .i.b -side left",	"pack .i.f -side left",	"pack .i.s -side left",	"pack .i.m -side left", 	"pack .f.s -fill y -side left",	"pack .f.t -fill both -expand 1", 	"pack .i -fill x",	"pack .f -fill both -expand 1",	"pack propagate . 0", 	"update",};