summaryrefslogtreecommitdiff
path: root/web/l19.txt
diff options
context:
space:
mode:
Diffstat (limited to 'web/l19.txt')
-rw-r--r--web/l19.txt1412
1 files changed, 0 insertions, 1412 deletions
diff --git a/web/l19.txt b/web/l19.txt
deleted file mode 100644
index af9d0bb..0000000
--- a/web/l19.txt
+++ /dev/null
@@ -1,1412 +0,0 @@
--- front
-6.828 Shells Lecture
-
-Hello.
-
--- intro
-Bourne shell
-
-Simplest shell: run cmd arg arg ...
- fork
- exec in child
- wait in parent
-
-More functionality:
- file redirection: cmd >file
- open file as fd 1 in child before exec
-
-Still more functionality:
- pipes: cmd | cmd | cmd ...
- create pipe,
- run first cmd with pipe on fd 1,
- run second cmd with other end of pipe on fd 0
-
-More Bourne arcana:
- $* - command args
- "$@" - unexpanded command args
- environment variables
- macro substitution
- if, while, for
- ||
- &&
- "foo $x"
- 'foo $x'
- `cat foo`
-
--- rc
-Rc Shell
-
-
-No reparsing of input (except explicit eval).
-
-Variables as explicit lists.
-
-Explicit concatenation.
-
-Multiple input pipes <{cmd} - pass /dev/fd/4 as file name.
-
-Syntax more like C, less like Algol.
-
-diff <{echo hi} <{echo bye}
-
--- es
-Es shell
-
-
-rc++
-
-Goal is to override functionality cleanly.
-
-Rewrite input like cmd | cmd2 as %pipe {cmd} {cmd2}.
-
-Users can redefine %pipe, etc.
-
-Need lexical scoping and let to allow new %pipe refer to old %pipe.
-
-Need garbage collection to collect unreachable code.
-
-Design principle:
- minimal functionality + good defaults
- allow users to customize implementations
-
- emacs, exokernel
-
--- apps
-Applications
-
-Shell scripts are only as good as the programs they use.
- (What good are pipes without cat, grep, sort, wc, etc.?)
-
-The more the scripts can access, the more powerful they become.
-
--- acme
-Acme, Plan 9 text editor
-
-Make window system control files available to
-everything, including shell.
-
-Can write shell scripts to script interactions.
-
-/home/rsc/bin/Slide
-/home/rsc/bin/Slide-
-/home/rsc/bin/Slide+
-
-/usr/local/plan9/bin/adict
-
-win
-
--- javascript
-JavaScript
-
-Very powerful
- - not because it's a great language
- - because it has a great data set
- - Google Maps
- - Gmail
- - Ymail
- - etc.
-
--- greasemonkey
-GreaseMonkey
-
-// ==UserScript==
-// @name Google Ring
-// @namespace http://swtch.com/greasemonkey/
-// @description Changes Google Logo
-// @include http://*.google.*/*
-// ==/UserScript==
-
-(function() {
- for(var i=0; i<document.images.length; i++){
- if(document.images[i].src == "http://www.google.com/intl/en/images/logo.gif")
- document.images[i].src = "http://swtch.com/googlering.png";
- }
-})();
-
--- webscript0
-Webscript
-
-Why can't I script my web interactions?
-
-/home/rsc/plan9/bin/rc/fedex
-
-webscript /home/rsc/src/webscript/a3
- /home/rsc/src/webscript/a2
-
--- acid
-Acid, a programmable (scriptable) debugger
-
-defn stopped(pid)
-{
- pfixstop(pid);
- pstop(pid);
-}
-
-defn pfixstop(pid)
-{
- if *fmt(*PC-1, 'b') == 0xCC then {
- // Linux stops us after the breakpoint, not at it
- *PC = *PC-1;
- }
-}
-
-/usr/local/plan9/acid/port:/^defn.bpset
-/usr/local/plan9/acid/port:/^defn.step
-
-defn checkpdb(pdb)
-{
- loop 1,768 do {
- if *pdb != 0 then { print(pdb\X, " ", *pdb\X, "\n"); }
- pdb = pdb +4;
- }
-}
-
--- guis
-GUIs
-
-Can we script guis? Not as clear.
-
-Acme examples show one way:
- turn events into file (pipe) to read.
-
-Tcl/tk is close too.
-
-Eventually everyone turns to C.
-
--- others
-Honorable Mentions
-
-Scheme
-
-Lisp
-
-AutoCAD
-
-Viaweb RTML
-
--- c
-"Real" programming languages vs. Scripts
-
-Why does everyone eventually rewrite scripts in C?
- (aka C++, C#, any compiled language)
-
-What do you need C for now?
-
-How could you make it accessible to a script language?
-
--- /home/rsc/bin/Slide
-#!/usr/local/plan9/bin/rc
-
-echo name `{pwd}^/$1 | 9p write acme/$winid/ctl
-echo clean | 9p write acme/$winid/ctl
-echo get | 9p write acme/$winid/ctl
-
--- /home/rsc/bin/Slide-
-#!/usr/local/plan9/bin/rc
-
-name=$%
-current=`{basename $name}
-currentx=`{9 grep -n '^'$current'([ ]|$)' index | sed 's/:.*//'}
-
-pagex=`{echo $currentx - 1 | hoc}
-if(~ $pagex 0){
- echo no such page
- exit 0
-}
-page=`{sed -n $pagex^p index | awk '{print $1}'}
-if(~ $#page 0){
- echo no such page
- exit 0
-}
-
-Slide $page
--- /home/rsc/bin/Slide+
-#!/usr/local/plan9/bin/rc
-
-name=$%
-current=`{basename $name}
-currentx=`{9 grep -n '^'$current'([ ]|$)' index | sed 's/:.*//'}
-
-pagex=`{echo $currentx + 1 | hoc}
-page=`{sed -n $pagex^p index | awk '{print $1}'}
-if(~ $#page 0){
- echo no such page
- exit 0
-}
-
-Slide $page
--- /usr/local/plan9/bin/adict
-#!/usr/local/plan9/bin/rc
-
-. 9.rc
-. $PLAN9/lib/acme.rc
-
-fn event {
- # $1 - c1 origin of event
- # $2 - c2 type of action
- # $3 - q0 beginning of selection
- # $4 - q1 end of selection
- # $5 - eq0 beginning of expanded selection
- # $6 - eq1 end of expanded selection
- # $7 - flag
- # $8 - nr number of runes in $7
- # $9 - text
- # $10 - chorded argument
- # $11 - origin of chorded argument
-
- switch($1$2){
- case E* # write to body or tag
- case F* # generated by ourselves; ignore
- case K* # type away we do not care
- case Mi # mouse: text inserted in tag
- case MI # mouse: text inserted in body
- case Md # mouse: text deleted from tag
- case MD # mouse: text deleted from body
-
- case Mx MX # button 2 in tag or body
- winwriteevent $*
-
- case Ml ML # button 3 in tag or body
- {
- if(~ $dict NONE)
- dictwin /adict/$9/ $9
- if not
- dictwin /adict/$dict/$9 $dict $9
- } &
- }
-}
-
-fn dictwin {
- newwindow
- winname $1
- switch($#*){
- case 1
- dict -d '?' >[2=1] | sed 1d | winwrite body
- case 2
- dict=$2
- case 3
- dict=$2
- dict -d $dict $3 >[2=1] | winwrite body
- }
- winctl clean
- wineventloop
-}
-
-dict=NONE
-if(~ $1 -d){
- shift
- dict=$2
- shift
-}
-if(~ $1 -d*){
- dict=`{echo $1 | sed 's/-d//'}
- shift
-}
-if(~ $1 -*){
- echo 'usage: adict [-d dict] [word...]' >[1=2]
- exit usage
-}
-
-switch($#*){
-case 0
- if(~ $dict NONE)
- dictwin /adict/
- if not
- dictwin /adict/$dict/ $dict
-case *
- if(~ $dict NONE){
- dict=`{dict -d'?' | 9 sed -n 's/^ ([^\[ ]+).*/\1/p' | sed 1q}
- if(~ $#dict 0){
- echo 'no dictionaries present on this system' >[1=2]
- exit nodict
- }
- }
- for(i)
- dictwin /adict/$dict/$i $dict $i
-}
-
--- /usr/local/plan9/lib/acme.rc
-fn newwindow {
- winctl=`{9p read acme/new/ctl}
- winid=$winctl(1)
- winctl noscroll
-}
-
-fn winctl {
- echo $* | 9p write acme/acme/$winid/ctl
-}
-
-fn winread {
- 9p read acme/acme/$winid/$1
-}
-
-fn winwrite {
- 9p write acme/acme/$winid/$1
-}
-
-fn windump {
- if(! ~ $1 - '')
- winctl dumpdir $1
- if(! ~ $2 - '')
- winctl dump $2
-}
-
-fn winname {
- winctl name $1
-}
-
-fn winwriteevent {
- echo $1$2$3 $4 | winwrite event
-}
-
-fn windel {
- if(~ $1 sure)
- winctl delete
- if not
- winctl del
-}
-
-fn wineventloop {
- . <{winread event >[2]/dev/null | acmeevent}
-}
--- /home/rsc/plan9/rc/bin/fedex
-#!/bin/rc
-
-if(! ~ $#* 1) {
- echo usage: fedex 123456789012 >[1=2]
- exit usage
-}
-
-rfork e
-
-fn bgrep{
-pattern=`{echo $1 | sed 's;/;\\&;'}
-shift
-
-@{ echo 'X {
-$
-a
-
-.
-}
-X ,x/(.+\n)+\n/ g/'$pattern'/p' |
-sam -d $* >[2]/dev/null
-}
-}
-
-fn awk2 {
- awk 'NR%2==1 { a=$0; }
- NR%2==0 { b=$0; printf("%-30s %s\n", a, b); }
- ' $*
-}
-
-fn awk3 {
- awk '{line[NR] = $0}
- END{
- i = 4;
- while(i < NR){
- what=line[i++];
- when=line[i];
- comment="";
- if(!(when ~ /..\/..\/.... ..:../)){
- # out of sync
- printf("%s\n", what);
- continue;
- }
- i++;
- if(!(line[i+1] ~ /..\/..\/.... ..:../) &&
- (i+2 > NR || line[i+2] ~ /..\/..\/.... ..:../)){
- what = what ", " line[i++];
- }
- printf("%s %s\n", when, what);
- }
- }' $*
-}
-
-# hget 'http://www.fedex.com/cgi-bin/track_it?airbill_list='$1'&kurrent_airbill='$1'&language=english&cntry_code=us&state=0' |
-hget 'http://www.fedex.com/cgi-bin/tracking?action=track&language=english&cntry_code=us&initial=x&mps=y&tracknumbers='$1 |
- htmlfmt >/tmp/fedex.$pid
-sed -n '/Tracking number/,/^$/p' /tmp/fedex.$pid | awk2
-echo
-sed -n '/Reference number/,/^$/p' /tmp/fedex.$pid | awk2
-echo
-sed -n '/Date.time/,/^$/p' /tmp/fedex.$pid | sed 1,4d | fmt -l 4000 | sed 's/ [A-Z][A-Z] /&\n/g'
-rm /tmp/fedex.$pid
--- /home/rsc/src/webscript/a3
-#!./o.webscript
-
-load "http://www.ups.com/WebTracking/track?loc=en_US"
-find textbox "InquiryNumber1"
-input "1z30557w0340175623"
-find next checkbox
-input "yes"
-find prev form
-submit
-if(find "Delivery Information"){
- find outer table
- print
-}else if(find "One or more"){
- print
-}else{
- print "Unexpected results."
- find page
- print
-}
--- /home/rsc/src/webscript/a2
-#load "http://apc-reset/outlets.htm"
-load "apc.html"
-print
-print "\n=============\n"
-find "yoshimi"
-find outer row
-find next select
-input "Immediate Reboot"
-submit
-print
--- /usr/local/plan9/acid/port
-// portable acid for all architectures
-
-defn pfl(addr)
-{
- print(pcfile(addr), ":", pcline(addr), "\n");
-}
-
-defn
-notestk(addr)
-{
- local pc, sp;
- complex Ureg addr;
-
- pc = addr.pc\X;
- sp = addr.sp\X;
-
- print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " ");
- pfl(pc);
- _stk({"PC", pc, "SP", sp, linkreg(addr)}, 1);
-}
-
-defn
-notelstk(addr)
-{
- local pc, sp;
- complex Ureg addr;
-
- pc = addr.pc\X;
- sp = addr.sp\X;
-
- print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " ");
- pfl(pc);
- _stk({"PC", pc, "SP", sp, linkreg(addr)}, 1);
-}
-
-defn params(param)
-{
- while param do {
- sym = head param;
- print(sym[0], "=", itoa(sym[1], "%#ux"));
- param = tail param;
- if param then
- print (",");
- }
-}
-
-stkprefix = "";
-stkignore = {};
-stkend = 0;
-
-defn locals(l)
-{
- local sym;
-
- while l do {
- sym = head l;
- print(stkprefix, "\t", sym[0], "=", itoa(sym[1], "%#ux"), "\n");
- l = tail l;
- }
-}
-
-defn _stkign(frame)
-{
- local file;
-
- file = pcfile(frame[0]);
- s = stkignore;
- while s do {
- if regexp(head s, file) then
- return 1;
- s = tail s;
- }
- return 0;
-}
-
-// print a stack trace
-//
-// in a run of leading frames in files matched by regexps in stkignore,
-// only print the last one.
-defn _stk(regs, dolocals)
-{
- local stk, frame, pc, fn, done, callerpc, paramlist, locallist;
-
- stk = strace(regs);
- if stkignore then {
- while stk && tail stk && _stkign(head tail stk) do
- stk = tail stk;
- }
-
- callerpc = 0;
- done = 0;
- while stk && !done do {
- frame = head stk;
- stk = tail stk;
- fn = frame[0];
- pc = frame[1];
- callerpc = frame[2];
- paramlist = frame[3];
- locallist = frame[4];
-
- print(stkprefix, fmt(fn, 'a'), "(");
- params(paramlist);
- print(")");
- if pc != fn then
- print("+", itoa(pc-fn, "%#ux"));
- print(" ");
- pfl(pc);
- if dolocals then
- locals(locallist);
- if fn == var("threadmain") || fn == var("p9main") then
- done=1;
- if fn == var("threadstart") || fn == var("scheduler") then
- done=1;
- if callerpc == 0 then
- done=1;
- }
- if callerpc && !done then {
- print(stkprefix, fmt(callerpc, 'a'), " ");
- pfl(callerpc);
- }
-}
-
-defn findsrc(file)
-{
- local lst, src;
-
- if file[0] == '/' then {
- src = file(file);
- if src != {} then {
- srcfiles = append srcfiles, file;
- srctext = append srctext, src;
- return src;
- }
- return {};
- }
-
- lst = srcpath;
- while head lst do {
- src = file(head lst+file);
- if src != {} then {
- srcfiles = append srcfiles, file;
- srctext = append srctext, src;
- return src;
- }
- lst = tail lst;
- }
-}
-
-defn line(addr)
-{
- local src, file;
-
- file = pcfile(addr);
- src = match(file, srcfiles);
-
- if src >= 0 then
- src = srctext[src];
- else
- src = findsrc(file);
-
- if src == {} then {
- print("no source for ", file, "\n");
- return {};
- }
- line = pcline(addr)-1;
- print(file, ":", src[line], "\n");
-}
-
-defn addsrcdir(dir)
-{
- dir = dir+"/";
-
- if match(dir, srcpath) >= 0 then {
- print("already in srcpath\n");
- return {};
- }
-
- srcpath = {dir}+srcpath;
-}
-
-defn source()
-{
- local l;
-
- l = srcpath;
- while l do {
- print(head l, "\n");
- l = tail l;
- }
- l = srcfiles;
-
- while l do {
- print("\t", head l, "\n");
- l = tail l;
- }
-}
-
-defn Bsrc(addr)
-{
- local lst;
-
- lst = srcpath;
- file = pcfile(addr);
- if file[0] == '/' && access(file) then {
- rc("B "+file+":"+itoa(pcline(addr)));
- return {};
- }
- while head lst do {
- name = head lst+file;
- if access(name) then {
- rc("B "+name+":"+itoa(pcline(addr)));
- return {};
- }
- lst = tail lst;
- }
- print("no source for ", file, "\n");
-}
-
-defn srcline(addr)
-{
- local text, cline, line, file, src;
- file = pcfile(addr);
- src = match(file,srcfiles);
- if (src>=0) then
- src = srctext[src];
- else
- src = findsrc(file);
- if (src=={}) then
- {
- return "(no source)";
- }
- return src[pcline(addr)-1];
-}
-
-defn src(addr)
-{
- local src, file, line, cline, text;
-
- file = pcfile(addr);
- src = match(file, srcfiles);
-
- if src >= 0 then
- src = srctext[src];
- else
- src = findsrc(file);
-
- if src == {} then {
- print("no source for ", file, "\n");
- return {};
- }
-
- cline = pcline(addr)-1;
- print(file, ":", cline+1, "\n");
- line = cline-5;
- loop 0,10 do {
- if line >= 0 then {
- if line == cline then
- print(">");
- else
- print(" ");
- text = src[line];
- if text == {} then
- return {};
- print(line+1, "\t", text, "\n");
- }
- line = line+1;
- }
-}
-
-defn step() // single step the process
-{
- local lst, lpl, addr, bput;
-
- bput = 0;
- if match(*PC, bplist) >= 0 then { // Sitting on a breakpoint
- bput = fmt(*PC, bpfmt);
- *bput = @bput;
- }
-
- lst = follow(*PC);
-
- lpl = lst;
- while lpl do { // place break points
- *(head lpl) = bpinst;
- lpl = tail lpl;
- }
-
- startstop(pid); // do the step
-
- while lst do { // remove the breakpoints
- addr = fmt(head lst, bpfmt);
- *addr = @addr;
- lst = tail lst;
- }
- if bput != 0 then
- *bput = bpinst;
-}
-
-defn bpset(addr) // set a breakpoint
-{
- if status(pid) != "Stopped" then {
- print("Waiting...\n");
- stop(pid);
- }
- if match(addr, bplist) >= 0 then
- print("breakpoint already set at ", fmt(addr, 'a'), "\n");
- else {
- *fmt(addr, bpfmt) = bpinst;
- bplist = append bplist, addr;
- }
-}
-
-defn bptab() // print a table of breakpoints
-{
- local lst, addr;
-
- lst = bplist;
- while lst do {
- addr = head lst;
- print("\t", fmt(addr, 'X'), " ", fmt(addr, 'a'), " ", fmt(addr, 'i'), "\n");
- lst = tail lst;
- }
-}
-
-defn bpdel(addr) // delete a breakpoint
-{
- local n, pc, nbplist;
-
- if addr == 0 then {
- while bplist do {
- pc = head bplist;
- pc = fmt(pc, bpfmt);
- *pc = @pc;
- bplist = tail bplist;
- }
- return {};
- }
-
- n = match(addr, bplist);
- if n < 0 then {
- print("no breakpoint at ", fmt(addr, 'a'), "\n");
- return {};
- }
-
- addr = fmt(addr, bpfmt);
- *addr = @addr;
-
- nbplist = {}; // delete from list
- while bplist do {
- pc = head bplist;
- if pc != addr then
- nbplist = append nbplist, pc;
- bplist = tail bplist;
- }
- bplist = nbplist; // delete from memory
-}
-
-defn cont() // continue execution
-{
- local addr;
-
- addr = fmt(*PC, bpfmt);
- if match(addr, bplist) >= 0 then { // Sitting on a breakpoint
- *addr = @addr;
- step(); // Step over
- *addr = bpinst;
- }
- startstop(pid); // Run
-}
-
-defn stopped(pid) // called from acid when a process changes state
-{
- pfixstop(pid);
- pstop(pid); // stub so this is easy to replace
-}
-
-defn procs() // print status of processes
-{
- local c, lst, cpid;
-
- cpid = pid;
- lst = proclist;
- while lst do {
- np = head lst;
- setproc(np);
- if np == cpid then
- c = '>';
- else
- c = ' ';
- print(fmt(c, 'c'), np, ": ", status(np), " at ", fmt(*PC, 'a'), " setproc(", np, ")\n");
- lst = tail lst;
- }
- pid = cpid;
- if pid != 0 then
- setproc(pid);
-}
-
-_asmlines = 30;
-
-defn asm(addr)
-{
- local bound;
-
- bound = fnbound(addr);
-
- addr = fmt(addr, 'i');
- loop 1,_asmlines do {
- print(fmt(addr, 'a'), " ", fmt(addr, 'X'));
- print("\t", @addr++, "\n");
- if bound != {} && addr > bound[1] then {
- lasmaddr = addr;
- return {};
- }
- }
- lasmaddr = addr;
-}
-
-defn casm()
-{
- asm(lasmaddr);
-}
-
-defn xasm(addr)
-{
- local bound;
-
- bound = fnbound(addr);
-
- addr = fmt(addr, 'i');
- loop 1,_asmlines do {
- print(fmt(addr, 'a'), " ", fmt(addr, 'X'));
- print("\t", *addr++, "\n");
- if bound != {} && addr > bound[1] then {
- lasmaddr = addr;
- return {};
- }
- }
- lasmaddr = addr;
-}
-
-defn xcasm()
-{
- xasm(lasmaddr);
-}
-
-defn win()
-{
- local npid, estr;
-
- bplist = {};
- notes = {};
-
- estr = "/sys/lib/acid/window '0 0 600 400' "+textfile;
- if progargs != "" then
- estr = estr+" "+progargs;
-
- npid = rc(estr);
- npid = atoi(npid);
- if npid == 0 then
- error("win failed to create process");
-
- setproc(npid);
- stopped(npid);
-}
-
-defn win2()
-{
- local npid, estr;
-
- bplist = {};
- notes = {};
-
- estr = "/sys/lib/acid/transcript '0 0 600 400' '100 100 700 500' "+textfile;
- if progargs != "" then
- estr = estr+" "+progargs;
-
- npid = rc(estr);
- npid = atoi(npid);
- if npid == 0 then
- error("win failed to create process");
-
- setproc(npid);
- stopped(npid);
-}
-
-printstopped = 1;
-defn new()
-{
- local a;
-
- bplist = {};
- newproc(progargs);
- a = var("p9main");
- if a == {} then
- a = var("main");
- if a == {} then
- return {};
- bpset(a);
- while *PC != a do
- cont();
- bpdel(a);
-}
-
-defn stmnt() // step one statement
-{
- local line;
-
- line = pcline(*PC);
- while 1 do {
- step();
- if line != pcline(*PC) then {
- src(*PC);
- return {};
- }
- }
-}
-
-defn func() // step until we leave the current function
-{
- local bound, end, start, pc;
-
- bound = fnbound(*PC);
- if bound == {} then {
- print("cannot locate text symbol\n");
- return {};
- }
-
- pc = *PC;
- start = bound[0];
- end = bound[1];
- while pc >= start && pc < end do {
- step();
- pc = *PC;
- }
-}
-
-defn next()
-{
- local sp, bound, pc;
-
- sp = *SP;
- bound = fnbound(*PC);
- if bound == {} then {
- print("cannot locate text symbol\n");
- return {};
- }
- stmnt();
- pc = *PC;
- if pc >= bound[0] && pc < bound[1] then
- return {};
-
- while (pc < bound[0] || pc > bound[1]) && sp >= *SP do {
- step();
- pc = *PC;
- }
- src(*PC);
-}
-
-defn maps()
-{
- local m, mm;
-
- m = map();
- while m != {} do {
- mm = head m;
- m = tail m;
- print(mm[2]\X, " ", mm[3]\X, " ", mm[4]\X, " ", mm[0], " ", mm[1], "\n");
- }
-}
-
-defn dump(addr, n, fmt)
-{
- loop 0, n do {
- print(fmt(addr, 'X'), ": ");
- addr = mem(addr, fmt);
- }
-}
-
-defn mem(addr, fmt)
-{
-
- local i, c, n;
-
- i = 0;
- while fmt[i] != 0 do {
- c = fmt[i];
- n = 0;
- while '0' <= fmt[i] && fmt[i] <= '9' do {
- n = 10*n + fmt[i]-'0';
- i = i+1;
- }
- if n <= 0 then n = 1;
- addr = fmt(addr, fmt[i]);
- while n > 0 do {
- print(*addr++, " ");
- n = n-1;
- }
- i = i+1;
- }
- print("\n");
- return addr;
-}
-
-defn symbols(pattern)
-{
- local l, s;
-
- l = symbols;
- while l do {
- s = head l;
- if regexp(pattern, s[0]) then
- print(s[0], "\t", s[1], "\t", s[2], "\t", s[3], "\n");
- l = tail l;
- }
-}
-
-defn havesymbol(name)
-{
- local l, s;
-
- l = symbols;
- while l do {
- s = head l;
- l = tail l;
- if s[0] == name then
- return 1;
- }
- return 0;
-}
-
-defn spsrch(len)
-{
- local addr, a, s, e;
-
- addr = *SP;
- s = origin & 0x7fffffff;
- e = etext & 0x7fffffff;
- loop 1, len do {
- a = *addr++;
- c = a & 0x7fffffff;
- if c > s && c < e then {
- print("src(", a, ")\n");
- pfl(a);
- }
- }
-}
-
-defn acidtypes()
-{
- local syms;
- local l;
-
- l = textfile();
- if l != {} then {
- syms = "acidtypes";
- while l != {} do {
- syms = syms + " " + ((head l)[0]);
- l = tail l;
- }
- includepipe(syms);
- }
-}
-
-defn getregs()
-{
- local regs, l;
-
- regs = {};
- l = registers;
- while l != {} do {
- regs = append regs, var(l[0]);
- l = tail l;
- }
- return regs;
-}
-
-defn setregs(regs)
-{
- local l;
-
- l = registers;
- while l != {} do {
- var(l[0]) = regs[0];
- l = tail l;
- regs = tail regs;
- }
- return regs;
-}
-
-defn resetregs()
-{
- local l;
-
- l = registers;
- while l != {} do {
- var(l[0]) = register(l[0]);
- l = tail l;
- }
-}
-
-defn clearregs()
-{
- local l;
-
- l = registers;
- while l != {} do {
- var(l[0]) = refconst(~0);
- l = tail l;
- }
-}
-
-progargs="";
-print(acidfile);
-
--- /usr/local/plan9/acid/386
-// 386 support
-
-defn acidinit() // Called after all the init modules are loaded
-{
- bplist = {};
- bpfmt = 'b';
-
- srcpath = {
- "./",
- "/sys/src/libc/port/",
- "/sys/src/libc/9sys/",
- "/sys/src/libc/386/"
- };
-
- srcfiles = {}; // list of loaded files
- srctext = {}; // the text of the files
-}
-
-defn linkreg(addr)
-{
- return {};
-}
-
-defn stk() // trace
-{
- _stk({"PC", *PC, "SP", *SP}, 0);
-}
-
-defn lstk() // trace with locals
-{
- _stk({"PC", *PC, "SP", *SP}, 1);
-}
-
-defn gpr() // print general(hah hah!) purpose registers
-{
- print("AX\t", *AX, " BX\t", *BX, " CX\t", *CX, " DX\t", *DX, "\n");
- print("DI\t", *DI, " SI\t", *SI, " BP\t", *BP, "\n");
-}
-
-defn spr() // print special processor registers
-{
- local pc;
- local cause;
-
- pc = *PC;
- print("PC\t", pc, " ", fmt(pc, 'a'), " ");
- pfl(pc);
- print("SP\t", *SP, " ECODE ", *ECODE, " EFLAG ", *EFLAGS, "\n");
- print("CS\t", *CS, " DS\t ", *DS, " SS\t", *SS, "\n");
- print("GS\t", *GS, " FS\t ", *FS, " ES\t", *ES, "\n");
-
- cause = *TRAP;
- print("TRAP\t", cause, " ", reason(cause), "\n");
-}
-
-defn regs() // print all registers
-{
- spr();
- gpr();
-}
-
-defn mmregs()
-{
- print("MM0\t", *MM0, " MM1\t", *MM1, "\n");
- print("MM2\t", *MM2, " MM3\t", *MM3, "\n");
- print("MM4\t", *MM4, " MM5\t", *MM5, "\n");
- print("MM6\t", *MM6, " MM7\t", *MM7, "\n");
-}
-
-defn pfixstop(pid)
-{
- if *fmt(*PC-1, 'b') == 0xCC then {
- // Linux stops us after the breakpoint, not at it
- *PC = *PC-1;
- }
-}
-
-
-defn pstop(pid)
-{
- local l;
- local pc;
- local why;
-
- pc = *PC;
-
- // FIgure out why we stopped.
- if *fmt(pc, 'b') == 0xCC then {
- why = "breakpoint";
-
- // fix up instruction for print; will put back later
- *pc = @pc;
- } else if *(pc-2\x) == 0x80CD then {
- pc = pc-2;
- why = "system call";
- } else
- why = "stopped";
-
- if printstopped then {
- print(pid,": ", why, "\t");
- print(fmt(pc, 'a'), "\t", *fmt(pc, 'i'), "\n");
- }
-
- if why == "breakpoint" then
- *fmt(pc, bpfmt) = bpinst;
-
- if printstopped && notes then {
- if notes[0] != "sys: breakpoint" then {
- print("Notes pending:\n");
- l = notes;
- while l do {
- print("\t", head l, "\n");
- l = tail l;
- }
- }
- }
-}
-
-aggr Ureg
-{
- 'U' 0 di;
- 'U' 4 si;
- 'U' 8 bp;
- 'U' 12 nsp;
- 'U' 16 bx;
- 'U' 20 dx;
- 'U' 24 cx;
- 'U' 28 ax;
- 'U' 32 gs;
- 'U' 36 fs;
- 'U' 40 es;
- 'U' 44 ds;
- 'U' 48 trap;
- 'U' 52 ecode;
- 'U' 56 pc;
- 'U' 60 cs;
- 'U' 64 flags;
- {
- 'U' 68 usp;
- 'U' 68 sp;
- };
- 'U' 72 ss;
-};
-
-defn
-Ureg(addr) {
- complex Ureg addr;
- print(" di ", addr.di, "\n");
- print(" si ", addr.si, "\n");
- print(" bp ", addr.bp, "\n");
- print(" nsp ", addr.nsp, "\n");
- print(" bx ", addr.bx, "\n");
- print(" dx ", addr.dx, "\n");
- print(" cx ", addr.cx, "\n");
- print(" ax ", addr.ax, "\n");
- print(" gs ", addr.gs, "\n");
- print(" fs ", addr.fs, "\n");
- print(" es ", addr.es, "\n");
- print(" ds ", addr.ds, "\n");
- print(" trap ", addr.trap, "\n");
- print(" ecode ", addr.ecode, "\n");
- print(" pc ", addr.pc, "\n");
- print(" cs ", addr.cs, "\n");
- print(" flags ", addr.flags, "\n");
- print(" sp ", addr.sp, "\n");
- print(" ss ", addr.ss, "\n");
-};
-sizeofUreg = 76;
-
-aggr Linkdebug
-{
- 'X' 0 version;
- 'X' 4 map;
-};
-
-aggr Linkmap
-{
- 'X' 0 addr;
- 'X' 4 name;
- 'X' 8 dynsect;
- 'X' 12 next;
- 'X' 16 prev;
-};
-
-defn
-linkdebug()
-{
- local a;
-
- if !havesymbol("_DYNAMIC") then
- return 0;
-
- a = _DYNAMIC;
- while *a != 0 do {
- if *a == 21 then // 21 == DT_DEBUG
- return *(a+4);
- a = a+8;
- }
- return 0;
-}
-
-defn
-dynamicmap()
-{
- if systype == "linux" || systype == "freebsd" then {
- local r, m, n;
-
- r = linkdebug();
- if r then {
- complex Linkdebug r;
- m = r.map;
- n = 0;
- while m != 0 && n < 100 do {
- complex Linkmap m;
- if m.name && *(m.name\b) && access(*(m.name\s)) then
- print("textfile({\"", *(m.name\s), "\", ", m.addr\X, "});\n");
- m = m.next;
- n = n+1;
- }
- }
- }
-}
-
-defn
-acidmap()
-{
-// dynamicmap();
- acidtypes();
-}
-
-print(acidfile);