event.b (2797B)
1 implement Event; 2 3 include "sys.m"; 4 sys: Sys; 5 OREAD, OWRITE: import Sys; 6 print, sprint, read, open: import sys; 7 include "draw.m"; 8 include "string.m"; 9 str: String; 10 include "bufio.m"; 11 bufio: Bufio; 12 Iobuf: import bufio; 13 include "lists.m"; 14 lists: Lists; 15 append, reverse: import lists; 16 include "regex.m"; 17 regex: Regex; 18 Re: import regex; 19 include "sh.m"; 20 sh: Sh; 21 22 Event: module 23 { 24 init: fn(nil: ref Draw->Context, argv: list of string); 25 }; 26 27 line: chan of string; 28 29 suicide() 30 { 31 fd := open(sprint("/proc/%d/pgrp", sys->pctl(0, nil)), OWRITE); 32 sys->fprint(fd, "kill"); 33 } 34 35 buflines(in, out: chan of string) 36 { 37 lines: list of string; 38 for(;;) { 39 if(lines == nil) 40 lines = <-in :: nil; 41 alt { 42 l := <-in => 43 lines = append(lines, l); 44 out <-= hd lines => 45 if(hd lines == nil) 46 suicide(); 47 lines = tl lines; 48 } 49 } 50 } 51 52 readlines(c: chan of string, fd: ref sys->FD) 53 { 54 out := chan of string; 55 56 spawn buflines(out, c); 57 58 b := bufio->fopen(fd, OREAD); 59 while((s := b.gets('\n')) != nil) 60 out <-= s; 61 out <-= nil; 62 } 63 64 readfile(file: string): (string, int) 65 { 66 fd := open(file, OREAD); 67 if(fd == nil) 68 return ("", 0); 69 70 ret := ""; 71 buf := array[512] of byte; 72 while((n := read(fd, buf, len buf)) > 0) 73 ret += string buf[:n]; 74 return (ret, 1); 75 } 76 77 ishex(s: string): int 78 { 79 if(len s < 3 || s[0:2] != "0x") 80 return 0; 81 s = s[2:]; 82 (nil, end) := str->toint(s, 16); 83 return end == nil; 84 } 85 86 init(draw: ref Draw->Context, argv: list of string) 87 { 88 sys = load Sys Sys->PATH; 89 str = load String String->PATH; 90 bufio = load Bufio Bufio->PATH; 91 lists = load Lists "/dis/lib/lists.dis"; 92 regex = load Regex Regex->PATH; 93 sh = load Sh Sh->PATH; 94 95 sys->pctl(sys->NEWPGRP, nil); 96 97 sh->system(draw, "mount -A {os rc -c 'exec dial $WMII_ADDRESS' >[1=0]} /mnt/wmii &"); 98 99 line = chan of string; 100 spawn readlines(line, sys->fildes(0)); 101 102 relist: list of ref (Re, int); 103 104 argv = tl argv; 105 for(; argv != nil; argv = tl argv) { 106 vflag := 0; 107 if(hd argv == "-v") { 108 argv = tl argv; 109 vflag = 1; 110 } 111 (re, err) := regex->compile(hd argv, 0); 112 if(err != nil) 113 raise sprint("bad regex %q: %s", hd argv, err); 114 relist = ref (re, vflag) :: relist; 115 } 116 117 relist = reverse(relist); 118 119 line: for(;;) { 120 lin := <-line; 121 if(lin == nil) 122 break; 123 l := str->unquoted(lin); 124 if(l == nil) 125 continue; 126 127 (evn, end) := str->toint(hd l, 10); 128 if(end == nil) { 129 for(rel := relist; rel != nil; rel = tl relist) { 130 (re, vflag) := *(hd rel); 131 match := regex->execute(re, lin); 132 if((match == nil) != vflag) 133 continue line; 134 } 135 print("%s", lin); 136 for(; l != nil; l = tl l) { 137 (k, v) := str->splitstrr(hd l, "="); 138 if(ishex(v)) { 139 (name, ok) := readfile(sprint("/mnt/wmii/client/%s/props", v)); 140 if(ok) 141 print("%d %s%s\n", evn, k, name); 142 } 143 } 144 }else 145 print("%s", lin); 146 } 147 } 148