10d13e2d8SCharles.Forsythimplement Mc; 237da2899SCharles.Forsyth 337da2899SCharles.Forsythinclude "sys.m"; 437da2899SCharles.Forsyth sys: Sys; 50d13e2d8SCharles.Forsyth open, read, fprint, fildes, tokenize, 60d13e2d8SCharles.Forsyth ORDWR, OREAD, OWRITE: import sys; 737da2899SCharles.Forsythinclude "draw.m"; 80d13e2d8SCharles.Forsyth draw: Draw; 90d13e2d8SCharles.Forsyth Font: import draw; 1037da2899SCharles.Forsythinclude "bufio.m"; 1137da2899SCharles.Forsyth bufio: Bufio; 1237da2899SCharles.Forsyth Iobuf: import bufio; 130d13e2d8SCharles.Forsythinclude "arg.m"; 1437da2899SCharles.Forsyth 150d13e2d8SCharles.Forsythfont: ref Font; 160d13e2d8SCharles.Forsythcolumns := 65; 170d13e2d8SCharles.Forsythtabwid := 0; 180d13e2d8SCharles.Forsythmintab := 1; 190d13e2d8SCharles.Forsyth 200d13e2d8SCharles.ForsythMc: module{ 2137da2899SCharles.Forsyth init: fn(nil: ref Draw->Context, argv: list of string); 2237da2899SCharles.Forsyth}; 2337da2899SCharles.Forsyth 240d13e2d8SCharles.Forsythinit(ctxt: ref Draw->Context, argv: list of string) 2537da2899SCharles.Forsyth{ 2637da2899SCharles.Forsyth sys = load Sys Sys->PATH; 270d13e2d8SCharles.Forsyth if((bufio = load Bufio Bufio->PATH) == nil) 280d13e2d8SCharles.Forsyth fatal("can't load " + Bufio->PATH); 29*9f620229SCharles.Forsyth draw = load Draw Draw->PATH; 300d13e2d8SCharles.Forsyth if((arg := load Arg Arg->PATH) == nil) 310d13e2d8SCharles.Forsyth fatal("can't load " + Arg->PATH); 3237da2899SCharles.Forsyth 330d13e2d8SCharles.Forsyth getwidth(ctxt); 340d13e2d8SCharles.Forsyth arg->init(argv); 350d13e2d8SCharles.Forsyth arg->setusage("mc [-c columns] [file ...]"); 360d13e2d8SCharles.Forsyth while((c:=arg->opt()) != 0) 370d13e2d8SCharles.Forsyth case c { 380d13e2d8SCharles.Forsyth 'c' => columns = int arg->earg() * mintab; 390d13e2d8SCharles.Forsyth * => arg->usage(); 400d13e2d8SCharles.Forsyth } 410d13e2d8SCharles.Forsyth argv = arg->argv(); 420d13e2d8SCharles.Forsyth if(len argv == 0) 430d13e2d8SCharles.Forsyth argv = "/fd/0" :: nil; 4437da2899SCharles.Forsyth 450d13e2d8SCharles.Forsyth a := array[1024] of (string, int); 460d13e2d8SCharles.Forsyth n := 0; 470d13e2d8SCharles.Forsyth maxwidth := 0; 480d13e2d8SCharles.Forsyth for(; argv!=nil; argv=tl argv){ 490d13e2d8SCharles.Forsyth if((bin:=bufio->open(hd argv, OREAD)) == nil){ 500d13e2d8SCharles.Forsyth fprint(fildes(2), "mc: can't open %s: %r\n", hd argv); 510d13e2d8SCharles.Forsyth continue; 5237da2899SCharles.Forsyth } 530d13e2d8SCharles.Forsyth while((s:=bin.gets('\n')) != nil){ 540d13e2d8SCharles.Forsyth if(s[len s-1] == '\n') 550d13e2d8SCharles.Forsyth s = s[0:len s-1]; 560d13e2d8SCharles.Forsyth if(n == len a) 570d13e2d8SCharles.Forsyth a = (array[n+1024] of (string, int))[0:] = a; 580d13e2d8SCharles.Forsyth a[n].t0 = s; 590d13e2d8SCharles.Forsyth a[n].t1 = wordsize(s); 600d13e2d8SCharles.Forsyth if(a[n].t1 > maxwidth) 610d13e2d8SCharles.Forsyth maxwidth = a[n].t1; 620d13e2d8SCharles.Forsyth n++; 6337da2899SCharles.Forsyth } 640d13e2d8SCharles.Forsyth bin.close(); 6537da2899SCharles.Forsyth } 660d13e2d8SCharles.Forsyth outcols(a[:n], maxwidth); 6737da2899SCharles.Forsyth} 6837da2899SCharles.Forsyth 690d13e2d8SCharles.Forsythoutcols(words: array of (string, int), maxwidth: int) 7037da2899SCharles.Forsyth{ 710d13e2d8SCharles.Forsyth maxwidth = nexttab(maxwidth+mintab-1); 720d13e2d8SCharles.Forsyth numcols := columns / maxwidth; 730d13e2d8SCharles.Forsyth if(numcols <= 0) 740d13e2d8SCharles.Forsyth numcols = 1; 750d13e2d8SCharles.Forsyth nwords := len words; 760d13e2d8SCharles.Forsyth nlines := (nwords+numcols-1) / numcols; 770d13e2d8SCharles.Forsyth bout := bufio->fopen(fildes(1), OWRITE); 780d13e2d8SCharles.Forsyth for(i := 0; i < nlines; i++){ 790d13e2d8SCharles.Forsyth col := endcol := 0; 800d13e2d8SCharles.Forsyth for(j:=i; j<nwords; j+=nlines){ 810d13e2d8SCharles.Forsyth endcol += maxwidth; 820d13e2d8SCharles.Forsyth bout.puts(words[j].t0); 830d13e2d8SCharles.Forsyth col += words[j].t1; 840d13e2d8SCharles.Forsyth if(j+nlines < nwords){ 850d13e2d8SCharles.Forsyth while(col < endcol){ 860d13e2d8SCharles.Forsyth if(tabwid) 870d13e2d8SCharles.Forsyth bout.putc('\t'); 8837da2899SCharles.Forsyth else 890d13e2d8SCharles.Forsyth bout.putc(' '); 900d13e2d8SCharles.Forsyth col = nexttab(col); 910d13e2d8SCharles.Forsyth } 920d13e2d8SCharles.Forsyth } 930d13e2d8SCharles.Forsyth } 940d13e2d8SCharles.Forsyth bout.putc('\n'); 950d13e2d8SCharles.Forsyth } 960d13e2d8SCharles.Forsyth bout.close(); 970d13e2d8SCharles.Forsyth} 980d13e2d8SCharles.Forsyth 990d13e2d8SCharles.Forsythwordsize(s: string): int 1000d13e2d8SCharles.Forsyth{ 1010d13e2d8SCharles.Forsyth if(font != nil) 1020d13e2d8SCharles.Forsyth return font.width(s); 1030d13e2d8SCharles.Forsyth return len s; 1040d13e2d8SCharles.Forsyth} 1050d13e2d8SCharles.Forsyth 1060d13e2d8SCharles.Forsythnexttab(col: int): int 1070d13e2d8SCharles.Forsyth{ 1080d13e2d8SCharles.Forsyth if(tabwid){ 1090d13e2d8SCharles.Forsyth col += tabwid; 1100d13e2d8SCharles.Forsyth col -= col%tabwid; 1110d13e2d8SCharles.Forsyth return col; 1120d13e2d8SCharles.Forsyth } 1130d13e2d8SCharles.Forsyth return col+1; 1140d13e2d8SCharles.Forsyth} 1150d13e2d8SCharles.Forsyth 1160d13e2d8SCharles.Forsythgetwidth(ctxt: ref Draw->Context) 1170d13e2d8SCharles.Forsyth{ 118*9f620229SCharles.Forsyth if(ctxt == nil || draw == nil) 119*9f620229SCharles.Forsyth return; 120*9f620229SCharles.Forsyth if((wid := rf("/env/acmewin")) == nil) 1210d13e2d8SCharles.Forsyth return; 1220d13e2d8SCharles.Forsyth if((fd := open("/chan/" + wid + "/ctl", ORDWR)) == nil) 1230d13e2d8SCharles.Forsyth return; 1240d13e2d8SCharles.Forsyth buf := array[256] of byte; 1250d13e2d8SCharles.Forsyth if((n := read(fd, buf, len buf)) <= 0) 1260d13e2d8SCharles.Forsyth return; 1270d13e2d8SCharles.Forsyth (nf, f) := tokenize(string buf[:n], " "); 1280d13e2d8SCharles.Forsyth if(nf != 8) 1290d13e2d8SCharles.Forsyth return; 1300d13e2d8SCharles.Forsyth f0 := tl tl tl tl tl f; 1310d13e2d8SCharles.Forsyth if((font = Font.open(ctxt.display, hd tl f0)) == nil) 1320d13e2d8SCharles.Forsyth return; 1330d13e2d8SCharles.Forsyth tabwid = int hd tl tl f0; 1340d13e2d8SCharles.Forsyth mintab = font.width("0"); 1350d13e2d8SCharles.Forsyth columns = int hd f0; 13637da2899SCharles.Forsyth} 13737da2899SCharles.Forsyth 13837da2899SCharles.Forsythfatal(s: string) 13937da2899SCharles.Forsyth{ 1400d13e2d8SCharles.Forsyth fprint(fildes(2), "mc: %s: %r\n", s); 1410d13e2d8SCharles.Forsyth raise "fail:"+s; 14237da2899SCharles.Forsyth} 143*9f620229SCharles.Forsyth 144*9f620229SCharles.Forsythrf(f: string): string 145*9f620229SCharles.Forsyth{ 146*9f620229SCharles.Forsyth fd := sys->open(f, Sys->OREAD); 147*9f620229SCharles.Forsyth if(fd == nil) 148*9f620229SCharles.Forsyth return nil; 149*9f620229SCharles.Forsyth b := array[Sys->NAMEMAX] of byte; 150*9f620229SCharles.Forsyth n := sys->read(fd, b, len b); 151*9f620229SCharles.Forsyth if(n < 0) 152*9f620229SCharles.Forsyth return nil; 153*9f620229SCharles.Forsyth return string b[0:n]; 154*9f620229SCharles.Forsyth} 155