Browse Source

Plan 9 from Bell Labs 2006-09-02

David du Colombier 14 years ago
parent
commit
77859bf171

+ 18 - 14
dist/replica/_plan9.db

@@ -228,7 +228,7 @@
 386/bin/faces - 775 sys sys 1155491750 194710
 386/bin/factor - 775 sys sys 1148500632 61793
 386/bin/fcp - 775 sys sys 1148500632 82527
-386/bin/file - 775 sys sys 1155229029 123983
+386/bin/file - 775 sys sys 1157143567 124531
 386/bin/fmt - 775 sys sys 1148500633 65661
 386/bin/fortune - 775 sys sys 1148500633 67450
 386/bin/fossil - 20000000775 sys sys 1042005470 0
@@ -264,7 +264,7 @@
 386/bin/gif - 775 sys sys 1150062736 158649
 386/bin/grap - 775 sys sys 1136656337 280496
 386/bin/graph - 775 sys sys 1148500640 129344
-386/bin/grep - 775 sys sys 1148500640 79405
+386/bin/grep - 775 sys sys 1157138535 79446
 386/bin/gs - 775 sys sys 1137468663 13275174
 386/bin/gunzip - 775 sys sys 1148500640 80617
 386/bin/gview - 775 sys sys 1155491751 239077
@@ -275,7 +275,7 @@
 386/bin/hoc - 775 sys sys 1155491751 100190
 386/bin/html2ms - 775 sys sys 1148500645 66415
 386/bin/htmlfmt - 775 sys sys 1155491752 163435
-386/bin/htmlroff - 775 sys sys 1148500646 148482
+386/bin/htmlroff - 775 sys sys 1157138536 148544
 386/bin/ico - 775 sys sys 1155491752 162226
 386/bin/iconv - 775 sys sys 1150062738 113723
 386/bin/idiff - 775 sys sys 1148500648 76436
@@ -333,6 +333,7 @@
 386/bin/mount - 775 sys sys 1148500672 73436
 386/bin/ms2html - 775 sys sys 1148500672 104279
 386/bin/mtime - 775 sys sys 1148500673 59470
+386/bin/mug - 775 sys sys 1157143842 176351
 386/bin/mv - 775 sys sys 1148500673 65825
 386/bin/ndb - 20000000775 sys sys 985743147 0
 386/bin/ndb/cs - 775 sys sys 1148500674 150956
@@ -509,7 +510,7 @@
 386/bin/webcookies - 775 sys sys 1148500701 167738
 386/bin/webfs - 775 sys sys 1134389883 360008
 386/bin/webfsget - 775 sys sys 1148500702 39177
-386/bin/wikifs - 775 sys sys 1134505646 203414
+386/bin/wikifs - 775 sys sys 1157146170 203727
 386/bin/winwatch - 775 sys sys 1155491758 155371
 386/bin/x.echo - 775 sys sys 1148500702 57686
 386/bin/xd - 775 sys sys 1148500703 64373
@@ -1288,6 +1289,7 @@ lib/face/48x48x4/a/andrey.1 - 664 sys sys 1056984105 1212
 lib/face/48x48x4/b - 20000000775 sys sys 944945360 0
 lib/face/48x48x4/b/bobf.1 - 664 sys sys 944941890 1429
 lib/face/48x48x4/b/bsb.1 - 664 sys sys 944941890 1374
+lib/face/48x48x4/b/bwc.1 - 664 sys sys 1157087065 1210
 lib/face/48x48x4/b/bwk.1 - 664 sys sys 944941890 968
 lib/face/48x48x4/c - 20000000775 sys sys 945319564 0
 lib/face/48x48x4/c/ches.1 - 664 sys sys 944941891 965
@@ -1408,7 +1410,7 @@ lib/face/48x48x8/e - 20000000775 sys sys 944941833 0
 lib/face/48x48x8/e/ericvh.2 - 664 sys sys 1155331573 1049
 lib/face/48x48x8/f - 20000000775 sys sys 944941833 0
 lib/face/48x48x8/f/forsyth.1 - 664 sys sys 1056982111 1864
-lib/face/48x48x8/f/fst.1 - 664 sys sys 1155331586 6750
+lib/face/48x48x8/f/fst.1 - 664 sys sys 1157149515 1099
 lib/face/48x48x8/g - 20000000775 sys sys 944941833 0
 lib/face/48x48x8/g/gmail.1 - 664 sys sys 1097900774 1779
 lib/face/48x48x8/g/google.1 - 664 sys sys 1038967265 712
@@ -1431,6 +1433,7 @@ lib/face/48x48x8/n/nigel.1 - 664 sys sys 1056981488 1611
 lib/face/48x48x8/n/noah.1 - 664 sys sys 1081200582 7065
 lib/face/48x48x8/o - 20000000775 sys sys 944941833 0
 lib/face/48x48x8/p - 20000000775 sys sys 944941833 0
+lib/face/48x48x8/p/plus.1 - 664 sys sys 1157142255 1049
 lib/face/48x48x8/q - 20000000775 sys sys 944941833 0
 lib/face/48x48x8/q/quanstro.1 - 664 sys sys 1136131296 2250
 lib/face/48x48x8/r - 20000000775 sys sys 944941833 0
@@ -5626,7 +5629,7 @@ sys/doc/auth.ms - 664 sys sys 1138396404 66854
 sys/doc/auth.ps - 664 sys sys 1021579976 451672
 sys/doc/cleanps - 775 sys sys 961259933 184
 sys/doc/colophon.ps - 664 sys sys 960837922 214122
-sys/doc/comp.ms - 664 sys sys 1138396405 37832
+sys/doc/comp.ms - 664 sys sys 1157083635 37859
 sys/doc/comp.ps - 664 sys sys 960837915 345786
 sys/doc/compiler.ms - 664 sys sys 1138396405 30305
 sys/doc/compiler.ps - 664 sys sys 1091459054 309735
@@ -5671,7 +5674,7 @@ sys/doc/lp.ps - 664 sys sys 960837917 294399
 sys/doc/mk.ms - 664 sys sys 1138396445 34456
 sys/doc/mk.ps - 664 sys sys 960837917 329779
 sys/doc/mkdirlist - 775 sys sys 1138498508 48
-sys/doc/mkfile - 664 sys sys 1138396461 2393
+sys/doc/mkfile - 664 sys sys 1157083603 2493
 sys/doc/mkfilelist - 775 sys sys 1138498508 50
 sys/doc/mkfiles.ms - 664 sys sys 1138396445 17910
 sys/doc/mkfiles.ps - 664 sys sys 960837918 269496
@@ -7297,7 +7300,7 @@ sys/man/1/eqn - 664 sys sys 1134592617 5655
 sys/man/1/expect - 664 sys sys 1141913757 3018
 sys/man/1/faces - 664 sys sys 1113743326 2395
 sys/man/1/factor - 664 sys sys 1135084026 1015
-sys/man/1/file - 664 sys sys 1015024739 1578
+sys/man/1/file - 664 sys sys 1157143697 1481
 sys/man/1/filter - 664 sys sys 1135083932 6142
 sys/man/1/fmt - 664 sys sys 1070032221 1557
 sys/man/1/fortune - 664 sys sys 944959673 449
@@ -10143,7 +10146,7 @@ sys/src/cmd/fax/receiverc - 775 sys sys 944960990 581
 sys/src/cmd/fax/send.c - 664 sys sys 944960990 923
 sys/src/cmd/fax/subr.c - 664 sys sys 1015090401 1245
 sys/src/cmd/fcp.c - 664 sys sys 1136651872 3799
-sys/src/cmd/file.c - 664 sys sys 1156733921 26901
+sys/src/cmd/file.c - 664 sys sys 1157143564 27438
 sys/src/cmd/fmt.c - 664 sys sys 1137603598 4078
 sys/src/cmd/fortune.c - 664 sys sys 1072729222 1779
 sys/src/cmd/fossil - 20000000775 sys sys 1042005512 0
@@ -10234,7 +10237,7 @@ sys/src/cmd/grep/grep.h - 664 sys sys 1068478083 2176
 sys/src/cmd/grep/grep.y - 664 sys sys 944961351 2804
 sys/src/cmd/grep/main.c - 664 sys sys 1136378273 4686
 sys/src/cmd/grep/mkfile - 664 sys sys 944961351 153
-sys/src/cmd/grep/sub.c - 664 sys sys 984789207 3896
+sys/src/cmd/grep/sub.c - 664 sys sys 1157090728 3941
 sys/src/cmd/gs - 20000000775 sys sys 1017695101 0
 sys/src/cmd/gs/386.h - 664 sys sys 1137462348 1464
 sys/src/cmd/gs/alpha.h - 664 sys sys 1137462348 1373
@@ -12259,7 +12262,7 @@ sys/src/cmd/htmlfmt/mkfile - 664 sys sys 1034015650 297
 sys/src/cmd/htmlfmt/util.c - 664 sys sys 1015364025 1765
 sys/src/cmd/htmlroff - 20000000775 sys sys 1138396082 0
 sys/src/cmd/htmlroff/a.h - 664 sys sys 1138396079 3200
-sys/src/cmd/htmlroff/char.c - 664 sys sys 1157078288 2295
+sys/src/cmd/htmlroff/char.c - 664 sys sys 1157082850 2301
 sys/src/cmd/htmlroff/html.c - 664 sys sys 1147180952 3992
 sys/src/cmd/htmlroff/input.c - 664 sys sys 1138396079 3147
 sys/src/cmd/htmlroff/main.c - 664 sys sys 1138396080 1065
@@ -12635,6 +12638,7 @@ sys/src/cmd/mntgen.c - 664 sys sys 1106410349 3630
 sys/src/cmd/mount.c - 664 sys sys 1138061862 1633
 sys/src/cmd/ms2html.c - 664 sys sys 1143695278 41022
 sys/src/cmd/mtime.c - 664 sys sys 1036172302 450
+sys/src/cmd/mug.c - 664 sys sys 1157143847 24888
 sys/src/cmd/mv.c - 664 sys sys 1126278115 4241
 sys/src/cmd/ndb - 20000000775 sys sys 988249988 0
 sys/src/cmd/ndb/convDNS2M.c - 664 sys sys 1119276409 6866
@@ -14303,14 +14307,14 @@ sys/src/cmd/webfs/webget.c - 664 sys sys 1124711795 1589
 sys/src/cmd/webfsget.c - 664 sys sys 1141913846 1597
 sys/src/cmd/wikifs - 20000000775 sys sys 1018211094 0
 sys/src/cmd/wikifs/fs.c - 664 sys sys 1143759339 14446
-sys/src/cmd/wikifs/io.c - 664 sys sys 1134498935 11573
+sys/src/cmd/wikifs/io.c - 664 sys sys 1157090225 11589
 sys/src/cmd/wikifs/lookup.c - 664 sys sys 1018211093 182
 sys/src/cmd/wikifs/map.c - 664 sys sys 1018211093 109
 sys/src/cmd/wikifs/mkfile - 664 sys sys 1045503591 468
-sys/src/cmd/wikifs/parse.c - 664 sys sys 1124975709 5394
+sys/src/cmd/wikifs/parse.c - 664 sys sys 1157146110 5388
 sys/src/cmd/wikifs/parsehist.c - 664 sys sys 1124975708 1988
 sys/src/cmd/wikifs/testwrite.c - 664 sys sys 1018211093 818
-sys/src/cmd/wikifs/tohtml.c - 664 sys sys 1128979520 14527
+sys/src/cmd/wikifs/tohtml.c - 664 sys sys 1157090250 14546
 sys/src/cmd/wikifs/util.c - 664 sys sys 1018211093 1807
 sys/src/cmd/wikifs/wdir.c - 664 sys sys 1018211094 876
 sys/src/cmd/wikifs/wiki.h - 664 sys sys 1113275619 1897

+ 18 - 14
dist/replica/plan9.db

@@ -228,7 +228,7 @@
 386/bin/faces - 775 sys sys 1155491750 194710
 386/bin/factor - 775 sys sys 1148500632 61793
 386/bin/fcp - 775 sys sys 1148500632 82527
-386/bin/file - 775 sys sys 1155229029 123983
+386/bin/file - 775 sys sys 1157143567 124531
 386/bin/fmt - 775 sys sys 1148500633 65661
 386/bin/fortune - 775 sys sys 1148500633 67450
 386/bin/fossil - 20000000775 sys sys 1042005470 0
@@ -264,7 +264,7 @@
 386/bin/gif - 775 sys sys 1150062736 158649
 386/bin/grap - 775 sys sys 1136656337 280496
 386/bin/graph - 775 sys sys 1148500640 129344
-386/bin/grep - 775 sys sys 1148500640 79405
+386/bin/grep - 775 sys sys 1157138535 79446
 386/bin/gs - 775 sys sys 1137468663 13275174
 386/bin/gunzip - 775 sys sys 1148500640 80617
 386/bin/gview - 775 sys sys 1155491751 239077
@@ -275,7 +275,7 @@
 386/bin/hoc - 775 sys sys 1155491751 100190
 386/bin/html2ms - 775 sys sys 1148500645 66415
 386/bin/htmlfmt - 775 sys sys 1155491752 163435
-386/bin/htmlroff - 775 sys sys 1148500646 148482
+386/bin/htmlroff - 775 sys sys 1157138536 148544
 386/bin/ico - 775 sys sys 1155491752 162226
 386/bin/iconv - 775 sys sys 1150062738 113723
 386/bin/idiff - 775 sys sys 1148500648 76436
@@ -333,6 +333,7 @@
 386/bin/mount - 775 sys sys 1148500672 73436
 386/bin/ms2html - 775 sys sys 1148500672 104279
 386/bin/mtime - 775 sys sys 1148500673 59470
+386/bin/mug - 775 sys sys 1157143842 176351
 386/bin/mv - 775 sys sys 1148500673 65825
 386/bin/ndb - 20000000775 sys sys 985743147 0
 386/bin/ndb/cs - 775 sys sys 1148500674 150956
@@ -509,7 +510,7 @@
 386/bin/webcookies - 775 sys sys 1148500701 167738
 386/bin/webfs - 775 sys sys 1134389883 360008
 386/bin/webfsget - 775 sys sys 1148500702 39177
-386/bin/wikifs - 775 sys sys 1134505646 203414
+386/bin/wikifs - 775 sys sys 1157146170 203727
 386/bin/winwatch - 775 sys sys 1155491758 155371
 386/bin/x.echo - 775 sys sys 1148500702 57686
 386/bin/xd - 775 sys sys 1148500703 64373
@@ -1288,6 +1289,7 @@ lib/face/48x48x4/a/andrey.1 - 664 sys sys 1056984105 1212
 lib/face/48x48x4/b - 20000000775 sys sys 944945360 0
 lib/face/48x48x4/b/bobf.1 - 664 sys sys 944941890 1429
 lib/face/48x48x4/b/bsb.1 - 664 sys sys 944941890 1374
+lib/face/48x48x4/b/bwc.1 - 664 sys sys 1157087065 1210
 lib/face/48x48x4/b/bwk.1 - 664 sys sys 944941890 968
 lib/face/48x48x4/c - 20000000775 sys sys 945319564 0
 lib/face/48x48x4/c/ches.1 - 664 sys sys 944941891 965
@@ -1408,7 +1410,7 @@ lib/face/48x48x8/e - 20000000775 sys sys 944941833 0
 lib/face/48x48x8/e/ericvh.2 - 664 sys sys 1155331573 1049
 lib/face/48x48x8/f - 20000000775 sys sys 944941833 0
 lib/face/48x48x8/f/forsyth.1 - 664 sys sys 1056982111 1864
-lib/face/48x48x8/f/fst.1 - 664 sys sys 1155331586 6750
+lib/face/48x48x8/f/fst.1 - 664 sys sys 1157149515 1099
 lib/face/48x48x8/g - 20000000775 sys sys 944941833 0
 lib/face/48x48x8/g/gmail.1 - 664 sys sys 1097900774 1779
 lib/face/48x48x8/g/google.1 - 664 sys sys 1038967265 712
@@ -1431,6 +1433,7 @@ lib/face/48x48x8/n/nigel.1 - 664 sys sys 1056981488 1611
 lib/face/48x48x8/n/noah.1 - 664 sys sys 1081200582 7065
 lib/face/48x48x8/o - 20000000775 sys sys 944941833 0
 lib/face/48x48x8/p - 20000000775 sys sys 944941833 0
+lib/face/48x48x8/p/plus.1 - 664 sys sys 1157142255 1049
 lib/face/48x48x8/q - 20000000775 sys sys 944941833 0
 lib/face/48x48x8/q/quanstro.1 - 664 sys sys 1136131296 2250
 lib/face/48x48x8/r - 20000000775 sys sys 944941833 0
@@ -5626,7 +5629,7 @@ sys/doc/auth.ms - 664 sys sys 1138396404 66854
 sys/doc/auth.ps - 664 sys sys 1021579976 451672
 sys/doc/cleanps - 775 sys sys 961259933 184
 sys/doc/colophon.ps - 664 sys sys 960837922 214122
-sys/doc/comp.ms - 664 sys sys 1138396405 37832
+sys/doc/comp.ms - 664 sys sys 1157083635 37859
 sys/doc/comp.ps - 664 sys sys 960837915 345786
 sys/doc/compiler.ms - 664 sys sys 1138396405 30305
 sys/doc/compiler.ps - 664 sys sys 1091459054 309735
@@ -5671,7 +5674,7 @@ sys/doc/lp.ps - 664 sys sys 960837917 294399
 sys/doc/mk.ms - 664 sys sys 1138396445 34456
 sys/doc/mk.ps - 664 sys sys 960837917 329779
 sys/doc/mkdirlist - 775 sys sys 1138498508 48
-sys/doc/mkfile - 664 sys sys 1138396461 2393
+sys/doc/mkfile - 664 sys sys 1157083603 2493
 sys/doc/mkfilelist - 775 sys sys 1138498508 50
 sys/doc/mkfiles.ms - 664 sys sys 1138396445 17910
 sys/doc/mkfiles.ps - 664 sys sys 960837918 269496
@@ -7297,7 +7300,7 @@ sys/man/1/eqn - 664 sys sys 1134592617 5655
 sys/man/1/expect - 664 sys sys 1141913757 3018
 sys/man/1/faces - 664 sys sys 1113743326 2395
 sys/man/1/factor - 664 sys sys 1135084026 1015
-sys/man/1/file - 664 sys sys 1015024739 1578
+sys/man/1/file - 664 sys sys 1157143697 1481
 sys/man/1/filter - 664 sys sys 1135083932 6142
 sys/man/1/fmt - 664 sys sys 1070032221 1557
 sys/man/1/fortune - 664 sys sys 944959673 449
@@ -10143,7 +10146,7 @@ sys/src/cmd/fax/receiverc - 775 sys sys 944960990 581
 sys/src/cmd/fax/send.c - 664 sys sys 944960990 923
 sys/src/cmd/fax/subr.c - 664 sys sys 1015090401 1245
 sys/src/cmd/fcp.c - 664 sys sys 1136651872 3799
-sys/src/cmd/file.c - 664 sys sys 1156733921 26901
+sys/src/cmd/file.c - 664 sys sys 1157143564 27438
 sys/src/cmd/fmt.c - 664 sys sys 1137603598 4078
 sys/src/cmd/fortune.c - 664 sys sys 1072729222 1779
 sys/src/cmd/fossil - 20000000775 sys sys 1042005512 0
@@ -10234,7 +10237,7 @@ sys/src/cmd/grep/grep.h - 664 sys sys 1068478083 2176
 sys/src/cmd/grep/grep.y - 664 sys sys 944961351 2804
 sys/src/cmd/grep/main.c - 664 sys sys 1136378273 4686
 sys/src/cmd/grep/mkfile - 664 sys sys 944961351 153
-sys/src/cmd/grep/sub.c - 664 sys sys 984789207 3896
+sys/src/cmd/grep/sub.c - 664 sys sys 1157090728 3941
 sys/src/cmd/gs - 20000000775 sys sys 1017695101 0
 sys/src/cmd/gs/386.h - 664 sys sys 1137462348 1464
 sys/src/cmd/gs/alpha.h - 664 sys sys 1137462348 1373
@@ -12259,7 +12262,7 @@ sys/src/cmd/htmlfmt/mkfile - 664 sys sys 1034015650 297
 sys/src/cmd/htmlfmt/util.c - 664 sys sys 1015364025 1765
 sys/src/cmd/htmlroff - 20000000775 sys sys 1138396082 0
 sys/src/cmd/htmlroff/a.h - 664 sys sys 1138396079 3200
-sys/src/cmd/htmlroff/char.c - 664 sys sys 1157078288 2295
+sys/src/cmd/htmlroff/char.c - 664 sys sys 1157082850 2301
 sys/src/cmd/htmlroff/html.c - 664 sys sys 1147180952 3992
 sys/src/cmd/htmlroff/input.c - 664 sys sys 1138396079 3147
 sys/src/cmd/htmlroff/main.c - 664 sys sys 1138396080 1065
@@ -12635,6 +12638,7 @@ sys/src/cmd/mntgen.c - 664 sys sys 1106410349 3630
 sys/src/cmd/mount.c - 664 sys sys 1138061862 1633
 sys/src/cmd/ms2html.c - 664 sys sys 1143695278 41022
 sys/src/cmd/mtime.c - 664 sys sys 1036172302 450
+sys/src/cmd/mug.c - 664 sys sys 1157143847 24888
 sys/src/cmd/mv.c - 664 sys sys 1126278115 4241
 sys/src/cmd/ndb - 20000000775 sys sys 988249988 0
 sys/src/cmd/ndb/convDNS2M.c - 664 sys sys 1119276409 6866
@@ -14303,14 +14307,14 @@ sys/src/cmd/webfs/webget.c - 664 sys sys 1124711795 1589
 sys/src/cmd/webfsget.c - 664 sys sys 1141913846 1597
 sys/src/cmd/wikifs - 20000000775 sys sys 1018211094 0
 sys/src/cmd/wikifs/fs.c - 664 sys sys 1143759339 14446
-sys/src/cmd/wikifs/io.c - 664 sys sys 1134498935 11573
+sys/src/cmd/wikifs/io.c - 664 sys sys 1157090225 11589
 sys/src/cmd/wikifs/lookup.c - 664 sys sys 1018211093 182
 sys/src/cmd/wikifs/map.c - 664 sys sys 1018211093 109
 sys/src/cmd/wikifs/mkfile - 664 sys sys 1045503591 468
-sys/src/cmd/wikifs/parse.c - 664 sys sys 1124975709 5394
+sys/src/cmd/wikifs/parse.c - 664 sys sys 1157146110 5388
 sys/src/cmd/wikifs/parsehist.c - 664 sys sys 1124975708 1988
 sys/src/cmd/wikifs/testwrite.c - 664 sys sys 1018211093 818
-sys/src/cmd/wikifs/tohtml.c - 664 sys sys 1128979520 14527
+sys/src/cmd/wikifs/tohtml.c - 664 sys sys 1157090250 14546
 sys/src/cmd/wikifs/util.c - 664 sys sys 1018211093 1807
 sys/src/cmd/wikifs/wdir.c - 664 sys sys 1018211094 876
 sys/src/cmd/wikifs/wiki.h - 664 sys sys 1113275619 1897

+ 25 - 0
dist/replica/plan9.log

@@ -30336,3 +30336,28 @@
 1156995007 0 c lib/face/48x48x4/.dict - 664 sys sys 1156993280 3337
 1156995007 1 c lib/face/48x48x8/.dict - 664 sys sys 1156993289 2648
 1157079606 0 c sys/src/cmd/htmlroff/char.c - 664 sys sys 1157078288 2295
+1157083207 0 c sys/src/cmd/htmlroff/char.c - 664 sys sys 1157082850 2301
+1157085007 0 c sys/doc/comp.ms - 664 sys sys 1157083635 37859
+1157085007 1 c sys/doc/mkfile - 664 sys sys 1157083603 2493
+1157088606 0 a lib/face/48x48x4/b/bwc.1 - 664 sys sys 1157087065 1210
+1157088606 1 a lib/face/48x48x8/p/plus.1 - 664 sys sys 1157087127 1161
+1157090407 0 c sys/src/cmd/grep/sub.c - 664 sys sys 1157090466 3903
+1157090407 1 c sys/src/cmd/wikifs/io.c - 664 sys sys 1157090225 11589
+1157090407 2 c sys/src/cmd/wikifs/tohtml.c - 664 sys sys 1157090250 14546
+1157092206 0 c 386/bin/wikifs - 775 sys sys 1157091160 203741
+1157092206 1 c 386/bin/file - 775 sys sys 1157091209 123983
+1157092206 2 c 386/bin/grep - 775 sys sys 1157091146 79446
+1157092206 3 c 386/bin/htmlroff - 775 sys sys 1157091161 148530
+1157092206 4 c sys/src/cmd/grep/sub.c - 664 sys sys 1157090728 3941
+1157139005 0 c 386/bin/wikifs - 775 sys sys 1157138536 203741
+1157139005 1 c 386/bin/grep - 775 sys sys 1157138535 79446
+1157139005 2 c 386/bin/htmlroff - 775 sys sys 1157138536 148544
+1157142606 0 c lib/face/48x48x8/p/plus.1 - 664 sys sys 1157142255 1049
+1157144406 0 c 386/bin/file - 775 sys sys 1157143567 124531
+1157144406 1 a 386/bin/mug - 775 sys sys 1157143842 176351
+1157144406 2 c sys/man/1/file - 664 sys sys 1157143697 1481
+1157144406 3 a sys/src/cmd/mug.c - 664 sys sys 1157143847 24888
+1157144406 4 c sys/src/cmd/file.c - 664 sys sys 1157143564 27438
+1157146206 0 c 386/bin/wikifs - 775 sys sys 1157146170 203727
+1157146206 1 c sys/src/cmd/wikifs/parse.c - 664 sys sys 1157146110 5388
+1157149806 0 c lib/face/48x48x8/f/fst.1 - 664 sys sys 1157149515 1099

BIN
lib/face/48x48x4/b/bwc.1


BIN
lib/face/48x48x8/f/fst.1


BIN
lib/face/48x48x8/p/plus.1


+ 3 - 1
sys/doc/comp.ms

@@ -284,6 +284,8 @@ for SPARC,
 for Motorola Power PC 630 and 640,
 .CW v
 for MIPS,
+.CW 0
+for little-endian MIPS,
 .CW 1
 for Motorola 68000,
 .CW 2
@@ -291,7 +293,7 @@ for Motorola 68020 and 68040,
 .CW 5
 for Acorn ARM 7500,
 .CW 6
-for Intel 960,
+for AMD 64,
 .CW 7
 for DEC Alpha,
 .CW 8

+ 7 - 4
sys/doc/mkfile

@@ -43,6 +43,7 @@ ALL=\
 
 ALLPS=${ALL:%=%.ps}
 HTML=${ALL:%=%.html} release3.html release4.html
+PDF=${ALL:%=%.pdf} release3.pdf release4.pdf
 FILES=`{mkfilelist $ALL}
 DIRS=`{mkdirlist $ALL}
 NAMES=$FILES $DIRS
@@ -56,7 +57,7 @@ dirs:V:
 	}
 
 print:V: $ALLPS
-	lp -dfn -H -i0 $prereq
+	lp -H -i0 $prereq
 
 title.ps:D:	title
 	troff $prereq | lp -dstdout > $target
@@ -96,6 +97,8 @@ index.html: contents.html
 &.html:D:	&.ms
 	pic $stem.ms | tbl | eqn | htmlroff -ms -mhtml >$target
 
+pdf:V: $PDF
+
 ^(8½|acme|fs|il|net|sam|venti)/([^/]*\.(pdf|ps|html))'$':R:
 	cd $stem1
 	mk $stem2
@@ -104,9 +107,9 @@ index.html: contents.html
 	cp $stem1/$stem1.html .
 
 %.pdf: %.ps
-	{ cat docfonts $stem.ps } >_$stem.ps
-	distill _$stem.ps
-	mv _$stem.pdf $stem.pdf
+	cat docfonts $stem.ps >_$stem.ps
+	# distill _$stem.ps && mv _$stem.pdf $stem.pdf
+	ps2pdf _$stem.ps $stem.pdf && rm -f _$stem.ps
 
 %.all:V:
 	mk $stem.ps $stem.pdf $stem.html

+ 1 - 6
sys/man/1/file

@@ -109,9 +109,4 @@ binary.
 .SH SOURCE
 .B /sys/src/cmd/file.c
 .SH BUGS
-It can make mistakes, for example classifying a file of decimal data,
-.LR .01 ,
-.LR .02 ,
-etc. as
-.IR troff (1)
-input.
+It can make mistakes.

+ 12 - 0
sys/src/cmd/file.c

@@ -746,6 +746,18 @@ struct	FILE_STRING
 	"P3\n",			"ppm",				3,	"image/ppm",
 	"P6\n",			"ppm",				3,	"image/ppm",
 	"/* XPM */\n",	"xbm",				10,	"image/xbm",
+	".HTML ",		"troff -ms input",	6,	"text/plain",
+	".LP",			"troff -ms input",	3,	"text/plain",
+	".ND",			"troff -ms input",	3,	"text/plain",
+	".PP",			"troff -ms input",	3,	"text/plain",
+	".TL",			"troff -ms input",	3,	"text/plain",
+	".TR",			"troff -ms input",	3,	"text/plain",
+	".TH",			"manual page",		3,	"text/plain",
+	".\\\"",		"troff input",		3,	"text/plain",
+	".de",			"troff input",		3,	"text/plain",
+	".if",			"troff input",		3,	"text/plain",
+	".nr",			"troff input",		3,	"text/plain",
+	".tr",			"troff input",		3,	"text/plain",
 	0,0,0,0
 };
 

+ 2 - 0
sys/src/cmd/grep/sub.c

@@ -156,6 +156,8 @@ str2top(char *p)
 
 	oldtop = topre;
 	input = p;
+	if (*p == '\0')
+		yyerror("empty pattern");
 	topre.beg = 0;
 	topre.end = 0;
 	yyparse();

+ 1239 - 0
sys/src/cmd/mug.c

@@ -0,0 +1,1239 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <event.h>
+#include <cursor.h>
+
+#define initstate muginitstate
+
+typedef struct State State;
+struct State {
+	double black;
+	double white;
+	double stretch;
+	double gamma;
+	int depth;
+	int gtab[1001];
+	Rectangle selr;
+};
+
+typedef struct Face Face;
+struct Face {
+	Rectangle r;
+	State state;
+	Image *small;
+};
+
+double GAMMA = 1.0;		/* theory tells me this should be 2.2, but 1.0 sure looks better */
+enum {
+	Left=0,
+	Right,
+	Top,
+	Bottom,
+
+	RTopLeft=0,
+	RTop,
+	RTopRight,
+	RLeft,
+	RMiddle,
+	RRight,
+	RBotLeft,
+	RBot,
+	RBotRight,
+};
+
+void*
+emalloc(ulong sz)
+{
+	void *v;
+
+	v = malloc(sz);
+	if(v == nil)
+		sysfatal("malloc %lud fails\n", sz);
+	memset(v, 0, sz);
+	return v;
+}
+
+Face *face[8];
+int nface;
+uchar grey2cmap[256];
+Image *bkgd;
+Image *orig;
+Image *ramp, *small, *osmall, *tmp8, *red, *green, *blue;
+State state, ostate;
+uchar val2cmap[256];
+uchar clamp[3*256];
+Rectangle rbig, rramp, rface[nelem(face)], rsmall;
+double *rdata;
+int sdy, sdx;
+
+void
+geometry(Rectangle r)
+{
+	int i;
+	Rectangle fr[9];
+
+	rramp.min = addpt(r.min, Pt(4,4));
+	rramp.max = addpt(rramp.min, Pt(256,256));
+
+	rbig.min = Pt(rramp.max.x+6, rramp.min.y);
+	rbig.max = addpt(rbig.min, Pt(Dx(orig->r), Dy(orig->r)));
+
+	for(i=0; i<9; i++)
+		fr[i] = rectaddpt(Rect(0,0,48,48), Pt(rramp.min.x+48+56*(i%3), rramp.max.y+6+56*(i/3)));
+
+	rsmall = fr[4];
+	for(i=0; i<4; i++)
+		rface[i] = fr[i];
+	for(i=4; i<8; i++)
+		rface[i] = fr[i+1];
+}
+
+double
+y2gamma(int y)
+{
+	double g;
+
+	g = (double)y / 128.0;
+	return 0.5+g*g;		/* gamma from 0.5 to 4.5, with 1.0 near the middle */
+}
+
+int
+gamma2y(double g)
+{
+	g -= 0.5;
+	return (int)(128.0*sqrt(g)+0.5);
+}
+
+void
+drawface(int i)
+{
+	if(i==-1){
+		border(screen, rsmall, -3, blue, ZP);
+		draw(screen, rsmall, small, nil, ZP);
+		return;
+	}
+	border(screen, rface[i], -1, display->black, ZP);
+	if(face[i])
+		draw(screen, rface[i], face[i]->small, nil, ZP);
+	else
+		draw(screen, rface[i], display->white, nil, ZP);
+}
+
+void
+drawrampbar(Image *color, State *s)
+{
+	Rectangle liner, r;
+	static Rectangle br;
+
+	if(Dx(br))
+		draw(screen, br, ramp, nil, subpt(br.min, rramp.min));
+
+	r = rramp;
+	r.max.x = r.min.x + (int)(s->white*255.0);
+	r.min.x += (int)(s->black*255.0);
+	r.min.y += gamma2y(s->gamma);
+	r.max.y = r.min.y+1; 
+	rectclip(&r, rramp);
+	draw(screen, r, color, nil, ZP);
+	br = r;
+
+	r.min.y -= 2;
+	r.max.y += 2;
+	
+	liner = r;
+	r.min.x += Dx(liner)/3;
+	r.max.x -= Dx(liner)/3;
+	rectclip(&r, rramp);
+	draw(screen, r, color, nil, ZP);
+	combinerect(&br, r);
+
+	r = liner;
+	r.max.x = r.min.x+3;
+	rectclip(&r, rramp);
+	draw(screen, r, color, nil, ZP);
+	combinerect(&br, r);
+
+	r = liner;
+	r.min.x = r.max.x-3;
+	rectclip(&r, rramp);
+	draw(screen, r, color, nil, ZP);
+	combinerect(&br, r);
+}
+
+void
+drawscreen(int clear)
+{
+	int i;
+
+	if(clear){
+		geometry(screen->r);
+		draw(screen, screen->r, bkgd, nil, ZP);
+	}
+
+	border(screen, rbig, -1, display->black, ZP);
+	draw(screen, rbig, orig, nil, orig->r.min);
+
+	border(screen, rramp, -1, display->black, ZP);
+	draw(screen, rramp, ramp, nil, ramp->r.min);
+	drawrampbar(red, &state);
+
+	border(screen, rectaddpt(state.selr, subpt(rbig.min, orig->r.min)), -2, red, ZP);
+	if(clear){
+		drawface(-1);
+		for(i=0; i<nelem(face); i++)
+			drawface(i);
+	}
+}
+
+void
+moveframe(Rectangle old, Rectangle new)
+{
+	border(screen, rectaddpt(old, subpt(rbig.min, orig->r.min)), -2, orig, old.min);
+	border(screen, rectaddpt(new, subpt(rbig.min, orig->r.min)), -2, red, ZP);
+}
+
+
+/*
+ * Initialize gamma ramp; should dither for
+ * benefit of non-true-color displays.
+ */
+void
+initramp(void)
+{
+	int k, x, y;
+	uchar dat[256*256];
+	double g;
+
+	k = 0;
+	for(y=0; y<256; y++) {
+		g = y2gamma(y);
+		for(x=0; x<256; x++)
+			dat[k++] = 255.0 * pow(x/255.0, g);
+	}
+	assert(k == sizeof dat);
+
+	ramp = allocimage(display, Rect(0,0,256,256), GREY8, 0, DNofill);
+	if(ramp == nil)
+		sysfatal("allocimage: %r");
+
+	if(loadimage(ramp, ramp->r, dat, sizeof dat) != sizeof dat)
+		sysfatal("loadimage: %r");
+}
+
+void
+initclamp(void)
+{
+	int i;
+
+	for(i=0; i<256; i++) {
+		clamp[i] = 0;
+		clamp[256+i] = i;
+		clamp[512+i] = 255;
+	}
+}
+
+void
+changestretch(double stretch)
+{
+	state.stretch = stretch;
+}
+
+/*
+ * There is greyscale data for the rectangle datar in data;
+ * extract square r and write it into the 48x48 pixel image small.
+ */
+void
+process(double *data, Rectangle datar, Rectangle r, Image *small)
+{
+	double black, center, delta, *k, shrink, sum, *tmp[48], *tt, w, white, x;
+	int datadx, dp, dx, dy, error, i, ii, j, jj;
+	int ksize, ksizeby2, sdata[48*48], sd, sh, sm, sv, u, uu, uuu, v, vv;
+	uchar bdata[48*48];
+
+	datadx = Dx(datar);
+	dx = Dx(r);
+	dy = Dy(r);
+	shrink = dx/48.0;
+
+	ksize = 1+2*(int)(shrink/2.0);
+	if(ksize <= 2)
+		return;
+
+	k = emalloc(ksize*sizeof(k[0]));
+
+	/* center of box */
+	for(i=1; i<ksize-1; i++)
+		k[i] = 1.0;
+
+	/* edges */
+	x = shrink - floor(shrink);
+	k[0] = x;
+	k[ksize-1] = x;
+
+	sum = 0.0;
+	for(i=0; i<ksize; i++)
+		sum += k[i];
+
+	for(i=0; i<ksize; i++)
+		k[i] /= sum;
+
+	ksizeby2 = ksize/2;
+
+	for(i=0; i<48; i++)
+		tmp[i] = emalloc(datadx*sizeof(tmp[i][0]));
+
+	/* squeeze vertically */
+	for(i=0; i<48; i++) {
+		ii = r.min.y+i*dy/48;
+		tt = tmp[i];
+		uu = ii - ksizeby2;
+		for(j=r.min.x-ksize; j<r.max.x+ksize; j++) {
+			if(j<datar.min.x || j>=datar.max.x)
+				continue;
+			w = 0.0;
+
+			uuu = uu*datadx+j;
+			if(uu>=datar.min.y && uu+ksize<datar.max.y)
+				for(u=0; u<ksize; u++){
+					w += k[u]*data[uuu];
+					uuu += datadx;
+				}
+			else
+				for(u=0; u<ksize; u++){
+					if(uu+u>=datar.min.y && uu+u<datar.max.y)
+						w += k[u]*data[uuu];
+					uuu+=datadx;
+				}
+			tt[j-datar.min.x] = w;
+		}
+	}
+
+	/* stretch value scale */
+	center = (state.black+state.white)/2;
+	delta = state.stretch*(state.white-state.black)/2;
+	black = center - delta;
+	white = center + delta;
+
+	/* squeeze horizontally */
+	for(i=0; i<48; i++) {
+		tt = tmp[i];
+		for(j=0; j<48; j++) {
+			jj = r.min.x+j*dx/48;
+			w = 0.0;
+			for(v=0; v<ksize; v++) {
+				vv = jj - ksizeby2 + v;
+				if(vv<datar.min.x || vv>=datar.max.x) {
+					w += k[v];		/* assume white surround */
+					continue;
+				}
+				w += k[v]*tt[vv-datar.min.x];
+			}
+			if(w < black || black==white)
+				w = 0.0;
+			else if(w > white)
+				w = 1.0;
+			else
+				w = (w-black)/(white-black);
+			sdata[i*48+j] = state.gtab[(int)(1000.0*w)];
+		}
+	}
+
+	/* dither to lower depth before copying into GREY8 version */
+	if(small->chan != GREY8) {
+		u = 0;
+		dp = small->depth;
+		for(i=0; i<48; i++) {
+			sm = 0xFF ^ (0xFF>>dp);
+			sh = 0;
+			v = 0;
+			for(j=0; j<48; j++) {
+				ii = 48*i+j;
+				sd = clamp[sdata[ii]+256];
+				sv = sd&sm;
+				v |= sv>>sh;
+				sh += dp;
+				if(sh == 8) {
+					bdata[u++] = v;
+					v = 0;
+					sh = 0;
+				}
+
+				/* propagate error, with decay (sum errors < 1) */
+				error = sd - sv;
+				if(ii+49 < 48*48) {	/* one test is enough, really */
+					sdata[ii+1] = sdata[ii+1]+((3*error)>>4);
+					sdata[ii+48] = sdata[ii+48]+((3*error)>>4);
+					sdata[ii+49] = sdata[ii+49]+((3*error)>>3);
+				}
+
+				/* produce correct color map value by copying bits */
+				switch(dp){
+				case 1:
+					sv |= sv>>1;
+				case 2:
+					sv |= sv>>2;
+				case 4:
+					sv |= sv>>4;
+				}
+				sdata[ii] = sv;
+			}
+		}
+		for(i=0; i<nelem(bdata); i++)
+			bdata[i] = sdata[i];
+		if(loadimage(tmp8, tmp8->r, bdata, sizeof bdata) != sizeof bdata)
+			sysfatal("loadimage: %r");
+		draw(small, small->r, tmp8, nil, tmp8->r.min);
+	} else {
+		for(i=0; i<nelem(bdata); i++)
+			bdata[i] = sdata[i];
+		if(loadimage(small, small->r, bdata, sizeof bdata) != sizeof bdata)
+			sysfatal("loadimage: %r");
+	}
+
+	free(k);
+	for(i=0; i<48; i++)
+		free(tmp[i]);
+}
+
+void
+initval2cmap(void)
+{
+	int i;
+
+	for(i=0; i<256; i++)
+		val2cmap[i] = rgb2cmap(i, i, i);
+}
+
+void
+setgtab(State *s)
+{
+	int i;
+
+	for(i=0; i<=1000; i++)
+		s->gtab[i] = val2cmap[(int)(255.0*pow((i/1000.0), 1.0/s->gamma))];
+}
+
+int
+section(int x)
+{
+	int ib, iw;
+
+	ib = state.black * 255.0;
+	iw = state.white * 255.0;
+
+	if(x<ib-5 || iw+5<x)
+		return -1;
+
+	iw -= ib;
+	x -= ib;
+	if(x < iw/3)
+		return 0;
+	if(x < 2*iw/3)
+		return 1;
+	return 2;
+}
+
+Image*
+copyimage(Image *i)
+{
+	Image *n;
+
+	if(i == nil)
+		return nil;
+
+	n = allocimage(display, i->r, i->chan, 0, DNofill);
+	if(n == nil)
+		sysfatal("allocimage: %r");
+
+	draw(n, n->r, i, nil, i->r.min);
+	return n;
+}
+
+Image*
+grey8image(Image *i)
+{
+	Image *n;
+
+	if(i->chan == GREY8)
+		return i;
+
+	n = allocimage(display, i->r, GREY8, 0, DNofill);
+	if(n == nil)
+		sysfatal("allocimage: %r");
+
+	draw(n, n->r, i, nil, i->r.min);
+	freeimage(i);
+	return n;
+}
+
+
+void
+mark(void)
+{
+	if(osmall != small){
+		freeimage(osmall);
+		osmall = small;
+	}
+	ostate = state;
+}
+
+void
+undo(void)
+{
+	if(small != osmall){
+		freeimage(small);
+		small = osmall;
+	}
+	state = ostate;
+	process(rdata, orig->r, state.selr, small);
+	drawface(-1);
+	drawscreen(0);
+}
+
+void
+saveface(Face *f, int slot)
+{
+	if(slot == -1){
+		mark();
+		state = f->state;
+		small = copyimage(f->small);
+		drawface(-1);
+		drawscreen(0);
+		return;
+	}
+
+	if(face[slot]==nil)
+		face[slot] = emalloc(sizeof(*face[slot]));
+	else{
+		freeimage(face[slot]->small);
+		face[slot]->small = nil;
+	}
+
+	if(f == nil){
+		face[slot]->small = copyimage(small);
+		face[slot]->state = state;
+	}else{
+		face[slot]->small = copyimage(f->small);
+		face[slot]->state = f->state;
+	}
+	drawface(slot);
+}
+
+int
+writeface(char *outfile, Image *image)
+{
+	int i, fd, rv, y;
+	uchar data[48*48/2];
+
+	if(outfile == nil)
+		fd = 1;
+	else{
+		if((fd = create(outfile, OWRITE, 0666)) < 0) 
+			return -1;
+	}
+
+	switch(image->chan) {
+	default:
+		rv = -1;
+		break;
+
+	case GREY1:
+		if(unloadimage(image, image->r, data, 48*48/8) != 48*48/8)
+			sysfatal("unloadimage: %r");
+		for(y=0; y<48; y++) {
+			for(i=0; i<3; i++)
+				fprint(fd, "0x%.2x%.2x,", data[y*6+i*2+0], data[y*6+i*2+1]);
+			fprint(fd, "\n");
+		}
+		rv = 0;
+		break;
+		
+	case GREY2:
+		if(unloadimage(image, image->r, data, 48*48/4) != 48*48/4)
+			sysfatal("unloadimage: %r");
+		for(y=0; y<48; y++) {
+			for(i=0; i<3; i++)
+				fprint(fd, "0x%.2x%.2x,%.2x%.2x,",
+					data[y*12+i*4+0], data[y*12+i*4+1],
+					data[y*12+i*4+2], data[y*12+i*4+3]);
+			fprint(fd, "\n");
+		}
+		rv = 0;
+		break;
+
+	case GREY4:
+	case GREY8:
+		rv = writeimage(fd, image, 0);	/* dolock? */
+		break;
+	}
+
+	if(outfile)
+		close(fd);
+	return rv;
+}
+
+void
+room(Rectangle out, Rectangle in, int *a)
+{
+	a[Left] = out.min.x - in.min.x;
+	a[Right] = out.max.x - in.max.x;
+	a[Top] = out.min.y - in.min.y;
+	a[Bottom] = out.max.y - in.max.y;
+}
+
+int
+min(int a, int b)
+{
+	if(a < b)
+		return a;
+	return b;
+}
+
+int
+max(int a, int b)
+{
+	if(a > b)
+		return a;
+	return b;
+}
+
+int
+move(Rectangle r, Rectangle picr, Point d, int k, Rectangle *rp)
+{
+	int a[4], i;
+	Rectangle oldr;
+	static int toggle;
+
+	oldr = r;
+	room(picr, r, a);
+	switch(k){
+	case RTopLeft:
+		i = (d.x+d.y)/2;
+		if(i>=Dx(r) || i>=Dy(r))
+			break;
+		i = max(i, a[Left]);
+		i = max(i, a[Top]);
+		r.min.x += i;
+		r.min.y += i;
+		break;
+	case RTop:
+		i = d.y;
+		if(i < 0){
+			/*
+			 * should really check i/2, but this is safe and feedback
+			 * makes the control feel right
+			 */
+			i = -min(-i, a[Right]);
+			i = max(i, a[Left]);
+		}
+		i = max(i, a[Top]);
+		if(i >= Dy(r))
+			break;
+		r.min.y += i;
+		/* divide the half bit equally */
+		toggle = 1-toggle;
+		if(toggle){
+			r.min.x += i/2;
+			r.max.x = r.min.x+Dy(r);
+		}else{
+			r.max.x -= i/2;
+			r.min.x = r.max.x-Dy(r);
+		}
+		break;
+	case RTopRight:
+		i = (-d.x+d.y)/2;
+		if(i>=Dx(r) || i>=Dy(r))
+			break;
+		i = -min(-i, a[Right]);
+		i = max(i, a[Top]);
+		r.max.x -= i;
+		r.min.y += i;
+		break;
+	case RLeft:
+		i = d.x;
+		if(i < 0){
+			i = -min(-i, a[Bottom]);
+			i = max(i, a[Top]);
+		}
+		i = max(i, a[Left]);
+		if(i >= Dx(r))
+			break;
+		r.min.x += i;
+		/* divide the half bit equally */
+		toggle = 1-toggle;
+		if(toggle){
+			r.min.y += i/2;
+			r.max.y = r.min.y+Dx(r);
+		}else{
+			r.max.y -= i/2;
+			r.min.y = r.max.y-Dx(r);
+		}
+		break;
+	case RMiddle:
+		if(d.x >= 0)
+			d.x = min(d.x, a[Right]);
+		else
+			d.x = max(d.x, a[Left]);
+		if(d.y >= 0)
+			d.y = min(d.y, a[Bottom]);
+		else
+			d.y = max(d.y, a[Top]);
+		r = rectaddpt(r, d);
+		break;
+	case RRight:
+		i = d.x;
+		if(i > 0){
+			i = min(i, a[Bottom]);
+			i = -max(-i, a[Top]);
+		}
+		i = min(i, a[Right]);
+		if(-i >= Dx(r))
+			break;
+		r.max.x += i;
+		/* divide the half bit equally */
+		toggle = 1-toggle;
+		if(toggle){
+			r.min.y -= i/2;
+			r.max.y = r.min.y+Dx(r);
+		}else{
+			r.max.y += i/2;
+			r.min.y = r.max.y-Dx(r);
+		}
+		break;
+	case RBotLeft:
+		i = (d.x+-d.y)/2;
+		if(i>=Dx(r) || i>=Dy(r))
+			break;
+		i = max(i, a[Left]);
+		i = -min(-i, a[Bottom]);
+		r.min.x += i;
+		r.max.y -= i;
+		break;
+	case RBot:
+		i = d.y;
+		if(i > 0){
+			i = min(i, a[Right]);
+			i = -max(-i, a[Left]);
+		}
+		i = min(i, a[Bottom]);
+		if(i >= Dy(r))
+			break;
+		r.max.y += i;
+		/* divide the half bit equally */
+		toggle = 1-toggle;
+		if(toggle){
+			r.min.x -= i/2;
+			r.max.x = r.min.x+Dy(r);
+		}else{
+			r.max.x += i/2;
+			r.min.x = r.max.x-Dy(r);
+		}
+		break;
+	case RBotRight:
+		i = (-d.x+-d.y)/2;
+		if(i>=Dx(r) || i>=Dy(r))
+			break;
+		i = -min(-i, a[Right]);
+		i = -min(-i, a[Bottom]);
+		r.max.x -= i;
+		r.max.y -= i;
+		break;
+	}
+	if(Dx(r)<3 || Dy(r)<3){
+		*rp = oldr;
+		return 0;
+	}
+	*rp = r;
+	return !eqrect(r, oldr);
+}
+
+void
+rlist(Rectangle r, Rectangle *ra)
+{
+	Rectangle tr;
+
+	tr = r;
+	tr.max.y = r.min.y+Dy(r)/4;
+	ra[0] = tr;
+	ra[0].max.x = tr.min.x+Dx(tr)/4;
+	ra[1] = tr;
+	ra[1].min.x = ra[0].max.x;
+	ra[1].max.x = tr.max.x-Dx(tr)/4;
+	ra[2] = tr;
+	ra[2].min.x = ra[1].max.x;
+
+	tr.min.y = tr.max.y;
+	tr.max.y = r.max.y-Dy(r)/4;
+	ra[3] = tr;
+	ra[3].max.x = tr.min.x+Dx(tr)/4;
+	ra[4] = tr;
+	ra[4].min.x = ra[3].max.x;
+	ra[4].max.x = tr.max.x-Dx(tr)/4;
+	ra[5] = tr;
+	ra[5].min.x = ra[4].max.x;
+
+	tr.min.y = tr.max.y;
+	tr.max.y = r.max.y;
+	ra[6] = tr;
+	ra[6].max.x = tr.min.x+Dx(tr)/4;
+	ra[7] = tr;
+	ra[7].min.x = ra[6].max.x;
+	ra[7].max.x = tr.max.x-Dx(tr)/4;
+	ra[8] = tr;
+	ra[8].min.x = ra[7].max.x;
+}
+
+int
+abs(int a)
+{
+	if(a < 0)
+		return -a;
+	return a;
+}
+
+void
+usage(void)
+{
+	fprint(2, "usage: mug [file.bit]\n");
+	exits("usage");
+}
+
+void
+eresized(int new)
+{
+	if(new && getwindow(display, Refmesg) < 0)
+		fprint(2,"can't reattach to window");
+	drawscreen(1);
+
+}
+
+/*
+interface notes
+
+cursor changes while in rbig to indicate region.
+only button 1 works for resizing region
+only button 1 works for moving thingy in ramp
+
+button-3 menu: Reset, Depth, Undo, Save, Write
+*/
+
+Cursor tl = {
+	{-4, -4},
+	{0xfe, 0x00, 0x82, 0x00, 0x8c, 0x00, 0x87, 0xff, 
+	 0xa0, 0x01, 0xb0, 0x01, 0xd0, 0x01, 0x11, 0xff, 
+	 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 
+	 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x1f, 0x00, },
+	{0x00, 0x00, 0x7c, 0x00, 0x70, 0x00, 0x78, 0x00, 
+	 0x5f, 0xfe, 0x4f, 0xfe, 0x0f, 0xfe, 0x0e, 0x00, 
+	 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 
+	 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, }
+};
+
+Cursor t = {
+	{-7, -8},
+	{0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x06, 0xc0, 
+	 0x1c, 0x70, 0x10, 0x10, 0x0c, 0x60, 0xfc, 0x7f, 
+	 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xff, 0xff, 
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 
+	 0x03, 0x80, 0x0f, 0xe0, 0x03, 0x80, 0x03, 0x80, 
+	 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 0x00, 0x00, 
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
+};
+
+Cursor tr = {
+	{-11, -4},
+	{0x00, 0x7f, 0x00, 0x41, 0x00, 0x31, 0xff, 0xe1, 
+	 0x80, 0x05, 0x80, 0x0d, 0x80, 0x0b, 0xff, 0x88, 
+	 0x00, 0x88, 0x0, 0x88, 0x00, 0x88, 0x00, 0x88, 
+	 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xf8, },
+	{0x00, 0x00, 0x00, 0x3e, 0x00, 0x0e, 0x00, 0x1e, 
+	 0x7f, 0xfa, 0x7f, 0xf2, 0x7f, 0xf0, 0x00, 0x70, 
+	 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 
+	 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x00, }
+};
+
+Cursor r = {
+	{-8, -7},
+	{0x07, 0xc0, 0x04, 0x40, 0x04, 0x40, 0x04, 0x58, 
+	 0x04, 0x68, 0x04, 0x6c, 0x04, 0x06, 0x04, 0x02, 
+	 0x04, 0x06, 0x04, 0x6c, 0x04, 0x68, 0x04, 0x58, 
+	 0x04, 0x40, 0x04, 0x40, 0x04, 0x40, 0x07, 0xc0, },
+	{0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 
+	 0x03, 0x90, 0x03, 0x90, 0x03, 0xf8, 0x03, 0xfc, 
+	 0x03, 0xf8, 0x03, 0x90, 0x03, 0x90, 0x03, 0x80, 
+	 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, }
+};
+
+Cursor br = {
+	{-11, -11},
+	{0x00, 0xf8, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 
+	 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 
+	 0xff, 0x88, 0x80, 0x0b, 0x80, 0x0d, 0x80, 0x05, 
+	 0xff, 0xe1, 0x00, 0x31, 0x00, 0x41, 0x00, 0x7f, },
+	{0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 
+	 0x0, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 
+	 0x00, 0x70, 0x7f, 0xf0, 0x7f, 0xf2, 0x7f, 0xfa, 
+	 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x3e, 0x00, 0x00, }
+};
+
+Cursor b = {
+	{-7, -7},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	 0xff, 0xff, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 
+	 0xfc, 0x7f, 0x0c, 0x60, 0x10, 0x10, 0x1c, 0x70, 
+	 0x06, 0xc0, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, },
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	 0x00, 0x00, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfe, 
+	 0x03, 0x80, 0x03, 0x80, 0x0f, 0xe0, 0x03, 0x80, 
+	 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
+};
+
+Cursor bl = {
+	{-4, -11},
+	{0x1f, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 
+	 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x00, 
+	 0x11, 0xff, 0xd0, 0x01, 0xb0, 0x01, 0xa0, 0x01, 
+	 0x87, 0xff, 0x8c, 0x00, 0x82, 0x00, 0xfe, 0x00, },
+	{0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 
+	 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 
+	 0x0e, 0x00, 0x0f, 0xfe, 0x4f, 0xfe, 0x5f, 0xfe, 
+	 0x78, 0x00, 0x70, 0x00, 0x7c, 0x00, 0x00, 0x0, }
+};
+
+Cursor l = {
+	{-7, -7},
+	{0x03, 0xe0, 0x02, 0x20, 0x02, 0x20, 0x1a, 0x20, 
+	 0x16, 0x20, 0x36, 0x20, 0x60, 0x20, 0x40, 0x20, 
+	 0x60, 0x20, 0x36, 0x20, 0x16, 0x20, 0x1a, 0x20, 
+	 0x02, 0x20, 0x02, 0x20, 0x02, 0x20, 0x03, 0xe0, },
+	{0x00, 0x00, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 
+	 0x09, 0xc0, 0x09, 0xc0, 0x1f, 0xc0, 0x3f, 0xc0, 
+	 0x1f, 0xc0, 0x09, 0xc0, 0x09, 0xc0, 0x01, 0xc0, 
+	 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x00, 0x00, }
+};
+
+Cursor boxcursor = {
+	{-7, -7},
+	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F,
+	 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xFF, 0xFF,
+	 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },
+	{0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE,
+	 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
+	 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
+	 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00, }
+};
+
+Cursor clearcursor;
+
+Cursor *corners[10] = {
+	&tl,	&t,	&tr,
+	&l,	&boxcursor,	&r,
+	&bl,	&b,	&br,
+	nil,	/* default arrow */
+};
+
+char *item[] = {
+	"Reset",
+	"Depth",
+	"Undo",
+	"Write",
+	"Exit",
+	nil
+};
+
+Menu menu = {
+	item, 
+	nil,
+	2
+};
+
+/*BUG make less flashy */
+void
+moveface(Image *back, Point lastp, Image *face, Point p, Point d)
+{
+	draw(screen, rectaddpt(back->r, subpt(lastp, d)), back, nil, back->r.min);
+	draw(back, back->r, screen, nil, addpt(back->r.min, subpt(p, d)));
+	border(screen, rectaddpt(face->r, subpt(p, d)),
+		 -1, display->black, ZP);
+	draw(screen, rectaddpt(face->r, subpt(p, d)), 
+		face, nil, face->r.min);
+}
+
+int
+dragface(Mouse *m, Image *im, Point d, int x)
+{
+	int i;
+	Point lastp;
+	static Image *back;
+
+	if(back == nil){
+		back = allocimage(display, Rect(-1,-1,49,49), display->image->chan, 0, DNofill);
+		if(back == nil)
+			sysfatal("dragface backing store: %r");
+	}
+
+	lastp = m->xy;
+	draw(back, back->r, screen, nil, addpt(back->r.min, subpt(lastp, d)));
+	esetcursor(&clearcursor);
+	do{
+		moveface(back, lastp, im, m->xy, d);
+		lastp = m->xy;
+	}while(*m=emouse(), m->buttons==1);
+
+	draw(screen, rectaddpt(back->r, subpt(lastp, d)), back, nil, back->r.min);
+	esetcursor(nil);
+	if(m->buttons==0){
+		for(i=0; i<nelem(face); i++)
+			if(ptinrect(m->xy, rface[i]))
+				return i;
+		if(ptinrect(m->xy, rsmall))
+			return -1;
+		return x;
+	}
+	while(*m=emouse(), m->buttons)
+		;
+	return x;
+}
+
+void
+initstate(void)
+{
+	state.black = 0.0;
+	state.white = 1.0;
+	state.stretch = 1.0;
+	state.depth = 4;
+	state.gamma = 1.0;
+	setgtab(&state);
+	state.selr = insetrect(orig->r, 5);
+	sdx = Dx(state.selr);
+	sdy = Dy(state.selr);
+	if(sdx > sdy)
+		state.selr.max.x = state.selr.min.x+sdy;
+	else
+		state.selr.max.y = state.selr.min.y+sdx;
+}
+
+void
+main(int argc, char **argv)
+{
+	int ccursor, i, fd, k, n, y;
+	uchar *data;
+	double gammatab[256];
+	Event e;
+	Mouse m;
+	Point lastp, p;
+	Rectangle nselr, rbig9[9];
+
+	ARGBEGIN{
+	default:
+		usage();
+	}ARGEND
+
+	if(argc > 1)
+		usage();
+	if(argc == 1){
+		if((fd = open(argv[0], OREAD)) < 0)
+			sysfatal("open %s: %r", argv[0]);
+	}else
+		fd = 0;
+
+	initdraw(0, 0, "mug");
+
+	if((orig = readimage(display, fd, 0)) == nil)
+		sysfatal("readimage: %r");
+
+	orig = grey8image(orig);
+
+	initramp();
+	initclamp();
+	initval2cmap();
+	bkgd = allocimagemix(display, DPaleyellow, DWhite);
+	small = allocimage(display, Rect(0,0,48,48), GREY4, 0, DWhite);
+	tmp8 = allocimage(display, Rect(0,0,48,48), GREY8, 0, DWhite);
+	red = allocimage(display, Rect(0,0,1,1), display->image->chan, 1, DRed);
+	green = allocimage(display, Rect(0,0,1,1), display->image->chan, 1, DGreen);
+	blue = allocimage(display, Rect(0,0,1,1), display->image->chan, 1, DBlue);
+	if(bkgd==nil || small==nil || tmp8==nil || red==nil || green==nil || blue==nil)
+		sysfatal("allocimage: %r");
+
+	n = Dx(orig->r)*Dy(orig->r);
+	data = emalloc(n*sizeof data[0]);
+	rdata = emalloc(n*sizeof rdata[0]);
+
+	if(unloadimage(orig, orig->r, data, n) != n)
+		sysfatal("unloadimage: %r");
+	
+	for(i=0; i<256; i++)
+		gammatab[i] = pow((255-i)/(double)255.0, GAMMA);
+
+	for(i=0; i<n; i++)
+		rdata[i] = gammatab[255-data[i]];
+
+	initstate();
+	process(rdata, orig->r, state.selr, small);
+	drawscreen(1);
+	flushimage(display, 1);
+	einit(Emouse|Ekeyboard);
+	ccursor = 9;
+	for(;;){
+		if((n=eread(Emouse|Ekeyboard, &e))==Ekeyboard)
+			continue;
+		if(n != Emouse)
+			break;
+
+		m = e.mouse;
+		if(m.buttons&4){
+			ccursor = 9;
+			esetcursor(corners[ccursor]);
+			switch(emenuhit(3, &m, &menu)){
+			case -1:
+				continue;
+			case 0:	/* Reset */
+				mark();
+				initstate();
+				small = allocimage(display, Rect(0,0,48,48), CHAN1(CGrey, state.depth), 0, DWhite);
+				if(small == nil)
+					sysfatal("allocimage: %r");
+				process(rdata, orig->r, state.selr, small);
+				drawface(-1);
+				drawscreen(0);
+				break;
+			case 1:	/* Depth */
+				mark();
+				/* osmall = small, so no freeimage */
+				state.depth /= 2;
+				if(state.depth == 0)
+					state.depth = 8;
+				small = allocimage(display, Rect(0,0,48,48), CHAN1(CGrey, state.depth), 0, DWhite);
+				if(small == nil)
+					sysfatal("allocimage: %r");
+				process(rdata, orig->r, state.selr, small);
+				drawface(-1);
+				break;
+			case 2:	/* Undo */
+				undo();
+				break;
+			case 3:	/* Write */
+				writeface(nil, small);
+				break;
+			case 4:	/* Exit */
+				exits(nil);
+				break;
+			}
+		}
+			
+		if(ptinrect(m.xy, rbig)){
+			rlist(rectaddpt(state.selr, subpt(rbig.min, orig->r.min)), rbig9);
+			for(i=0; i<9; i++)
+				if(ptinrect(m.xy, rbig9[i]))
+					break;
+			if(i != ccursor){
+				ccursor = i;
+				esetcursor(corners[ccursor]);
+			}
+			if(i==9)
+				continue;
+
+			if(m.buttons & 1){
+				mark();
+				lastp = m.xy;
+				while(m=emouse(), m.buttons&1){
+					if(move(state.selr, orig->r, subpt(m.xy, lastp), i, &nselr)){
+						moveframe(state.selr, nselr);
+						state.selr = nselr;
+						lastp = m.xy;
+						process(rdata, orig->r, state.selr, small);
+						drawface(-1);
+					}
+				}
+			}
+			continue;
+		}
+
+		if(ccursor != 9){	/* default cursor */
+			ccursor = 9;
+			esetcursor(corners[ccursor]);
+		}
+
+		if(ptinrect(m.xy, rramp)){
+			if(m.buttons != 1)
+				continue;
+			mark();
+			y = gamma2y(state.gamma);
+			if(abs(y-(m.xy.y-rramp.min.y)) > 5)
+				continue;
+			k = section(m.xy.x-rramp.min.x);
+			drawrampbar(green, &state);
+			lastp = m.xy;
+			while(m=emouse(), m.buttons&1){
+				if(!ptinrect(m.xy, rramp))
+					continue;
+				switch(k){
+				case -1:
+					continue;
+				case 0:
+					if((m.xy.x-rramp.min.x)/255.0 < state.white){
+						state.black = (m.xy.x-rramp.min.x)/255.0;
+						break;
+					}
+					continue;
+				case 1:
+					state.gamma = y2gamma(m.xy.y-rramp.min.y);
+					setgtab(&state);
+					break;
+				case 2:
+					if((m.xy.x-rramp.min.x)/255.0 > state.black){
+						state.white = (m.xy.x-rramp.min.x)/255.0;
+						break;
+					}
+					continue;
+				case 10:
+					state.black += (m.xy.x-lastp.x)/255.0;
+					state.white += (m.xy.x-lastp.x)/255.0;
+					state.gamma = y2gamma(p.y);
+					break;
+				}
+				process(rdata, orig->r, state.selr, small);
+				drawface(-1);
+				drawrampbar(green, &state);
+			}
+			if(m.buttons == 0){
+				process(rdata, orig->r, state.selr, small);
+				drawface(-1);
+				drawrampbar(red, &state);
+			}else
+				undo();
+			continue;
+		}
+	
+		if(ptinrect(m.xy, rsmall)){
+			if(m.buttons != 1)
+				continue;
+			n=dragface(&m, small, subpt(m.xy, rsmall.min), -1);
+			if(n == -1)
+				continue;
+			saveface(nil, n);
+		}
+	
+		for(i=0; i<nelem(face); i++)
+			if(ptinrect(m.xy, rface[i]))
+				break;
+		if(i<nelem(face) && face[i] != nil){
+			if(m.buttons != 1)
+				continue;
+			n=dragface(&m, face[i]->small, subpt(m.xy, rface[i].min), i);
+			if(n == i)
+				continue;
+			saveface(face[i], n);
+			continue;
+		}
+
+		do
+			m = emouse();
+		while(m.buttons==1);
+	}
+	exits(nil);
+}

+ 1 - 0
sys/src/cmd/wikifs/fs.c

@@ -874,6 +874,7 @@ main(int argc, char **argv)
 		d.mode = perm;
 		if(dirwstat(buf, &d) < 0)
 			fprint(2, "wstat: %r\n");
+		free(buf);
 	}
 	exits(nil);
 }

+ 18 - 4
sys/src/cmd/wikifs/io.c

@@ -219,6 +219,11 @@ voidcache(int n)
 		wlock(c);
 		c->tcurrent = 0;
 		c->thist = 0;
+		/* aggressively free memory */
+		closewhist(c->hist);
+		c->hist = nil;
+		closewhist(c->current);
+		c->current = nil;
 		wunlock(c);
 	}
 	runlock(&cachelock);
@@ -584,11 +589,18 @@ getcurrentbyname(char *s)
 static String*
 Brdstring(Biobuf *b)
 {
+	long len;
 	String *s;
+	Dir *d;
 
-	s = s_new();
-	while(s_read(b, s, 8192) > 0)
-		;
+	d = dirfstat(Bfildes(b));
+	if (d == nil)	/* shouldn't happen, we just opened it */
+		len = 0;
+	else
+		len = d->length;
+	free(d);
+	s = s_newalloc(len);
+	s_read(b, s, len);
 	return s;
 }
 
@@ -624,10 +636,12 @@ writepage(int num, ulong t, String *s, char *title)
 			snprint(err, sizeof err, "bad format in extant file");
 			conflict = 1;
 		}else if(strtoul(p+1, 0, 0) != t){
-			os = Brdstring(b);
+			os = Brdstring(b);	/* why read the whole file? */
 			p = strchr(s_to_c(s), '\n');
 			if(p!=nil && strcmp(p+1, s_to_c(os))==0){	/* ignore dup write */
 				close(lfd);
+				s_free(os);
+				Bterm(b);
 				return 0;
 			}
 			s_free(os);

+ 3 - 3
sys/src/cmd/wikifs/parse.c

@@ -73,10 +73,10 @@ wcondense(Wpage *wtxt)
 		strcat(w->text, " ");
 		strcat(w->text, w->next->text);
 		
-		free(w->next->text);
 		ow = w->next;
-		w->next = w->next->next;
-		free(ow);
+		w->next = ow->next;
+		ow->next = nil;
+		freepage(ow);
 	}
 	return wtxt;
 }

+ 3 - 1
sys/src/cmd/wikifs/tohtml.c

@@ -100,8 +100,10 @@ gettemplate(int type)
 		n = s_read(b, ns, Bsize);
 	while(n > 0);
 	Bterm(b);
-	if(n < 0)
+	if(n < 0) {
+		s_free(ns);
 		goto Return;
+	}
 
 	s_free(cache[type].s);
 	cache[type].s = ns;